@intlayer/cli 8.1.2 → 8.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/IntlayerEventListener.cjs +1 -186
- package/dist/cjs/IntlayerEventListener.cjs.map +1 -1
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +1 -29
- package/dist/cjs/_virtual/_utils_asset.cjs +2 -98
- package/dist/cjs/auth/login.cjs +2 -85
- package/dist/cjs/auth/login.cjs.map +1 -1
- package/dist/cjs/build.cjs +1 -27
- package/dist/cjs/build.cjs.map +1 -1
- package/dist/cjs/ci.cjs +1 -73
- package/dist/cjs/ci.cjs.map +1 -1
- package/dist/cjs/cli.cjs +1 -476
- package/dist/cjs/cli.cjs.map +1 -1
- package/dist/cjs/config.cjs +1 -12
- package/dist/cjs/config.cjs.map +1 -1
- package/dist/cjs/editor.cjs +1 -50
- package/dist/cjs/editor.cjs.map +1 -1
- package/dist/cjs/extract.cjs +1 -96
- package/dist/cjs/extract.cjs.map +1 -1
- package/dist/cjs/fill/deepMergeContent.cjs +1 -27
- package/dist/cjs/fill/deepMergeContent.cjs.map +1 -1
- package/dist/cjs/fill/fill.cjs +1 -78
- package/dist/cjs/fill/fill.cjs.map +1 -1
- package/dist/cjs/fill/formatAutoFilledFilePath.cjs +1 -29
- package/dist/cjs/fill/formatAutoFilledFilePath.cjs.map +1 -1
- package/dist/cjs/fill/formatFillData.cjs +1 -50
- package/dist/cjs/fill/formatFillData.cjs.map +1 -1
- package/dist/cjs/fill/getAvailableLocalesInDictionary.cjs +1 -26
- package/dist/cjs/fill/getAvailableLocalesInDictionary.cjs.map +1 -1
- package/dist/cjs/fill/getFilterMissingContentPerLocale.cjs +1 -50
- package/dist/cjs/fill/getFilterMissingContentPerLocale.cjs.map +1 -1
- package/dist/cjs/fill/index.cjs +1 -6
- package/dist/cjs/fill/listTranslationsTasks.cjs +1 -70
- package/dist/cjs/fill/listTranslationsTasks.cjs.map +1 -1
- package/dist/cjs/fill/mergeChunks.cjs +1 -28
- package/dist/cjs/fill/mergeChunks.cjs.map +1 -1
- package/dist/cjs/fill/translateDictionary.cjs +1 -205
- package/dist/cjs/fill/translateDictionary.cjs.map +1 -1
- package/dist/cjs/fill/writeFill.cjs +1 -54
- package/dist/cjs/fill/writeFill.cjs.map +1 -1
- package/dist/cjs/getTargetDictionary.cjs +1 -36
- package/dist/cjs/getTargetDictionary.cjs.map +1 -1
- package/dist/cjs/index.cjs +1 -39
- package/dist/cjs/init.cjs +1 -322
- package/dist/cjs/init.cjs.map +1 -1
- package/dist/cjs/initSkills.cjs +2 -0
- package/dist/cjs/initSkills.cjs.map +1 -0
- package/dist/cjs/listContentDeclaration.cjs +1 -41
- package/dist/cjs/listContentDeclaration.cjs.map +1 -1
- package/dist/cjs/listProjects.cjs +1 -28
- package/dist/cjs/listProjects.cjs.map +1 -1
- package/dist/cjs/liveSync.cjs +8 -151
- package/dist/cjs/liveSync.cjs.map +1 -1
- package/dist/cjs/pull.cjs +1 -146
- package/dist/cjs/pull.cjs.map +1 -1
- package/dist/cjs/push/pullLog.cjs +3 -102
- package/dist/cjs/push/pullLog.cjs.map +1 -1
- package/dist/cjs/push/push.cjs +1 -206
- package/dist/cjs/push/push.cjs.map +1 -1
- package/dist/cjs/pushConfig.cjs +1 -19
- package/dist/cjs/pushConfig.cjs.map +1 -1
- package/dist/cjs/pushLog.cjs +3 -84
- package/dist/cjs/pushLog.cjs.map +1 -1
- package/dist/cjs/reviewDoc/reviewDoc.cjs +1 -68
- package/dist/cjs/reviewDoc/reviewDoc.cjs.map +1 -1
- package/dist/cjs/reviewDoc/reviewDocBlockAware.cjs +1 -94
- package/dist/cjs/reviewDoc/reviewDocBlockAware.cjs.map +1 -1
- package/dist/cjs/searchDoc.cjs +1 -38
- package/dist/cjs/searchDoc.cjs.map +1 -1
- package/dist/cjs/test/index.cjs +1 -7
- package/dist/cjs/test/listMissingTranslations.cjs +1 -49
- package/dist/cjs/test/listMissingTranslations.cjs.map +1 -1
- package/dist/cjs/test/test.cjs +1 -53
- package/dist/cjs/test/test.cjs.map +1 -1
- package/dist/cjs/translateDoc/index.cjs +1 -9
- package/dist/cjs/translateDoc/translateDoc.cjs +1 -74
- package/dist/cjs/translateDoc/translateDoc.cjs.map +1 -1
- package/dist/cjs/translateDoc/translateFile.cjs +2 -103
- package/dist/cjs/translateDoc/translateFile.cjs.map +1 -1
- package/dist/cjs/translateDoc/validation.cjs +5 -49
- package/dist/cjs/translateDoc/validation.cjs.map +1 -1
- package/dist/cjs/translation-alignment/alignBlocks.cjs +1 -67
- package/dist/cjs/translation-alignment/alignBlocks.cjs.map +1 -1
- package/dist/cjs/translation-alignment/computeSimilarity.cjs +1 -25
- package/dist/cjs/translation-alignment/computeSimilarity.cjs.map +1 -1
- package/dist/cjs/translation-alignment/fingerprintBlock.cjs +1 -23
- package/dist/cjs/translation-alignment/fingerprintBlock.cjs.map +1 -1
- package/dist/cjs/translation-alignment/index.cjs +1 -22
- package/dist/cjs/translation-alignment/mapChangedLinesToBlocks.cjs +1 -18
- package/dist/cjs/translation-alignment/mapChangedLinesToBlocks.cjs.map +1 -1
- package/dist/cjs/translation-alignment/normalizeBlock.cjs +1 -22
- package/dist/cjs/translation-alignment/normalizeBlock.cjs.map +1 -1
- package/dist/cjs/translation-alignment/pipeline.cjs +1 -37
- package/dist/cjs/translation-alignment/pipeline.cjs.map +1 -1
- package/dist/cjs/translation-alignment/planActions.cjs +1 -46
- package/dist/cjs/translation-alignment/planActions.cjs.map +1 -1
- package/dist/cjs/translation-alignment/rebuildDocument.cjs +2 -49
- package/dist/cjs/translation-alignment/rebuildDocument.cjs.map +1 -1
- package/dist/cjs/translation-alignment/segmentDocument.cjs +5 -66
- package/dist/cjs/translation-alignment/segmentDocument.cjs.map +1 -1
- package/dist/cjs/utils/calculateChunks.cjs +2 -89
- package/dist/cjs/utils/calculateChunks.cjs.map +1 -1
- package/dist/cjs/utils/checkAccess.cjs +1 -81
- package/dist/cjs/utils/checkAccess.cjs.map +1 -1
- package/dist/cjs/utils/checkConfigConsistency.cjs +1 -16
- package/dist/cjs/utils/checkConfigConsistency.cjs.map +1 -1
- package/dist/cjs/utils/checkFileModifiedRange.cjs +1 -81
- package/dist/cjs/utils/checkFileModifiedRange.cjs.map +1 -1
- package/dist/cjs/utils/checkLastUpdateTime.cjs +1 -19
- package/dist/cjs/utils/checkLastUpdateTime.cjs.map +1 -1
- package/dist/cjs/utils/chunkInference.cjs +1 -45
- package/dist/cjs/utils/chunkInference.cjs.map +1 -1
- package/dist/cjs/utils/fixChunkStartEndChars.cjs +3 -27
- package/dist/cjs/utils/fixChunkStartEndChars.cjs.map +1 -1
- package/dist/cjs/utils/formatTimeDiff.cjs +1 -20
- package/dist/cjs/utils/formatTimeDiff.cjs.map +1 -1
- package/dist/cjs/utils/getIsFileUpdatedRecently.cjs +1 -16
- package/dist/cjs/utils/getIsFileUpdatedRecently.cjs.map +1 -1
- package/dist/cjs/utils/getOutputFilePath.cjs +1 -74
- package/dist/cjs/utils/getOutputFilePath.cjs.map +1 -1
- package/dist/cjs/utils/getParentPackageJSON.cjs +1 -20
- package/dist/cjs/utils/getParentPackageJSON.cjs.map +1 -1
- package/dist/cjs/utils/listSpecialChars.cjs +2 -54
- package/dist/cjs/utils/listSpecialChars.cjs.map +1 -1
- package/dist/cjs/utils/mapChunksBetweenFiles.cjs +1 -102
- package/dist/cjs/utils/mapChunksBetweenFiles.cjs.map +1 -1
- package/dist/cjs/utils/openBrowser.cjs +1 -19
- package/dist/cjs/utils/openBrowser.cjs.map +1 -1
- package/dist/cjs/utils/reorderParagraphs.cjs +3 -91
- package/dist/cjs/utils/reorderParagraphs.cjs.map +1 -1
- package/dist/cjs/utils/setupAI.cjs +1 -64
- package/dist/cjs/utils/setupAI.cjs.map +1 -1
- package/dist/cjs/watch.cjs +1 -43
- package/dist/cjs/watch.cjs.map +1 -1
- package/dist/esm/IntlayerEventListener.mjs +1 -183
- package/dist/esm/IntlayerEventListener.mjs.map +1 -1
- package/dist/esm/_virtual/_rolldown/runtime.mjs +1 -8
- package/dist/esm/_virtual/_utils_asset.mjs +2 -97
- package/dist/esm/auth/login.mjs +2 -82
- package/dist/esm/auth/login.mjs.map +1 -1
- package/dist/esm/build.mjs +1 -25
- package/dist/esm/build.mjs.map +1 -1
- package/dist/esm/ci.mjs +1 -71
- package/dist/esm/ci.mjs.map +1 -1
- package/dist/esm/cli.mjs +1 -473
- package/dist/esm/cli.mjs.map +1 -1
- package/dist/esm/config.mjs +1 -10
- package/dist/esm/config.mjs.map +1 -1
- package/dist/esm/editor.mjs +1 -49
- package/dist/esm/editor.mjs.map +1 -1
- package/dist/esm/extract.mjs +1 -93
- package/dist/esm/extract.mjs.map +1 -1
- package/dist/esm/fill/deepMergeContent.mjs +1 -25
- package/dist/esm/fill/deepMergeContent.mjs.map +1 -1
- package/dist/esm/fill/fill.mjs +1 -76
- package/dist/esm/fill/fill.mjs.map +1 -1
- package/dist/esm/fill/formatAutoFilledFilePath.mjs +1 -27
- package/dist/esm/fill/formatAutoFilledFilePath.mjs.map +1 -1
- package/dist/esm/fill/formatFillData.mjs +1 -49
- package/dist/esm/fill/formatFillData.mjs.map +1 -1
- package/dist/esm/fill/getAvailableLocalesInDictionary.mjs +1 -24
- package/dist/esm/fill/getAvailableLocalesInDictionary.mjs.map +1 -1
- package/dist/esm/fill/getFilterMissingContentPerLocale.mjs +1 -48
- package/dist/esm/fill/getFilterMissingContentPerLocale.mjs.map +1 -1
- package/dist/esm/fill/index.mjs +1 -4
- package/dist/esm/fill/listTranslationsTasks.mjs +1 -68
- package/dist/esm/fill/listTranslationsTasks.mjs.map +1 -1
- package/dist/esm/fill/mergeChunks.mjs +1 -26
- package/dist/esm/fill/mergeChunks.mjs.map +1 -1
- package/dist/esm/fill/translateDictionary.mjs +1 -203
- package/dist/esm/fill/translateDictionary.mjs.map +1 -1
- package/dist/esm/fill/writeFill.mjs +1 -52
- package/dist/esm/fill/writeFill.mjs.map +1 -1
- package/dist/esm/getTargetDictionary.mjs +1 -33
- package/dist/esm/getTargetDictionary.mjs.map +1 -1
- package/dist/esm/index.mjs +1 -18
- package/dist/esm/init.mjs +1 -317
- package/dist/esm/init.mjs.map +1 -1
- package/dist/esm/initSkills.mjs +2 -0
- package/dist/esm/initSkills.mjs.map +1 -0
- package/dist/esm/listContentDeclaration.mjs +1 -38
- package/dist/esm/listContentDeclaration.mjs.map +1 -1
- package/dist/esm/listProjects.mjs +1 -26
- package/dist/esm/listProjects.mjs.map +1 -1
- package/dist/esm/liveSync.mjs +8 -148
- package/dist/esm/liveSync.mjs.map +1 -1
- package/dist/esm/pull.mjs +1 -144
- package/dist/esm/pull.mjs.map +1 -1
- package/dist/esm/push/pullLog.mjs +3 -100
- package/dist/esm/push/pullLog.mjs.map +1 -1
- package/dist/esm/push/push.mjs +1 -203
- package/dist/esm/push/push.mjs.map +1 -1
- package/dist/esm/pushConfig.mjs +1 -17
- package/dist/esm/pushConfig.mjs.map +1 -1
- package/dist/esm/pushLog.mjs +3 -82
- package/dist/esm/pushLog.mjs.map +1 -1
- package/dist/esm/reviewDoc/reviewDoc.mjs +1 -65
- package/dist/esm/reviewDoc/reviewDoc.mjs.map +1 -1
- package/dist/esm/reviewDoc/reviewDocBlockAware.mjs +1 -92
- package/dist/esm/reviewDoc/reviewDocBlockAware.mjs.map +1 -1
- package/dist/esm/searchDoc.mjs +1 -36
- package/dist/esm/searchDoc.mjs.map +1 -1
- package/dist/esm/test/index.mjs +1 -4
- package/dist/esm/test/listMissingTranslations.mjs +1 -46
- package/dist/esm/test/listMissingTranslations.mjs.map +1 -1
- package/dist/esm/test/test.mjs +1 -51
- package/dist/esm/test/test.mjs.map +1 -1
- package/dist/esm/translateDoc/index.mjs +1 -5
- package/dist/esm/translateDoc/translateDoc.mjs +1 -71
- package/dist/esm/translateDoc/translateDoc.mjs.map +1 -1
- package/dist/esm/translateDoc/translateFile.mjs +2 -101
- package/dist/esm/translateDoc/translateFile.mjs.map +1 -1
- package/dist/esm/translateDoc/validation.mjs +5 -46
- package/dist/esm/translateDoc/validation.mjs.map +1 -1
- package/dist/esm/translation-alignment/alignBlocks.mjs +1 -66
- package/dist/esm/translation-alignment/alignBlocks.mjs.map +1 -1
- package/dist/esm/translation-alignment/computeSimilarity.mjs +1 -22
- package/dist/esm/translation-alignment/computeSimilarity.mjs.map +1 -1
- package/dist/esm/translation-alignment/fingerprintBlock.mjs +1 -20
- package/dist/esm/translation-alignment/fingerprintBlock.mjs.map +1 -1
- package/dist/esm/translation-alignment/index.mjs +1 -11
- package/dist/esm/translation-alignment/mapChangedLinesToBlocks.mjs +1 -16
- package/dist/esm/translation-alignment/mapChangedLinesToBlocks.mjs.map +1 -1
- package/dist/esm/translation-alignment/normalizeBlock.mjs +1 -20
- package/dist/esm/translation-alignment/normalizeBlock.mjs.map +1 -1
- package/dist/esm/translation-alignment/pipeline.mjs +1 -35
- package/dist/esm/translation-alignment/pipeline.mjs.map +1 -1
- package/dist/esm/translation-alignment/planActions.mjs +1 -44
- package/dist/esm/translation-alignment/planActions.mjs.map +1 -1
- package/dist/esm/translation-alignment/rebuildDocument.mjs +2 -46
- package/dist/esm/translation-alignment/rebuildDocument.mjs.map +1 -1
- package/dist/esm/translation-alignment/segmentDocument.mjs +5 -64
- package/dist/esm/translation-alignment/segmentDocument.mjs.map +1 -1
- package/dist/esm/utils/calculateChunks.mjs +2 -87
- package/dist/esm/utils/calculateChunks.mjs.map +1 -1
- package/dist/esm/utils/checkAccess.mjs +1 -78
- package/dist/esm/utils/checkAccess.mjs.map +1 -1
- package/dist/esm/utils/checkConfigConsistency.mjs +1 -14
- package/dist/esm/utils/checkConfigConsistency.mjs.map +1 -1
- package/dist/esm/utils/checkFileModifiedRange.mjs +1 -80
- package/dist/esm/utils/checkFileModifiedRange.mjs.map +1 -1
- package/dist/esm/utils/checkLastUpdateTime.mjs +1 -17
- package/dist/esm/utils/checkLastUpdateTime.mjs.map +1 -1
- package/dist/esm/utils/chunkInference.mjs +1 -43
- package/dist/esm/utils/chunkInference.mjs.map +1 -1
- package/dist/esm/utils/fixChunkStartEndChars.mjs +3 -25
- package/dist/esm/utils/fixChunkStartEndChars.mjs.map +1 -1
- package/dist/esm/utils/formatTimeDiff.mjs +1 -18
- package/dist/esm/utils/formatTimeDiff.mjs.map +1 -1
- package/dist/esm/utils/getIsFileUpdatedRecently.mjs +1 -14
- package/dist/esm/utils/getIsFileUpdatedRecently.mjs.map +1 -1
- package/dist/esm/utils/getOutputFilePath.mjs +1 -72
- package/dist/esm/utils/getOutputFilePath.mjs.map +1 -1
- package/dist/esm/utils/getParentPackageJSON.mjs +1 -18
- package/dist/esm/utils/getParentPackageJSON.mjs.map +1 -1
- package/dist/esm/utils/listSpecialChars.mjs +2 -52
- package/dist/esm/utils/listSpecialChars.mjs.map +1 -1
- package/dist/esm/utils/mapChunksBetweenFiles.mjs +1 -100
- package/dist/esm/utils/mapChunksBetweenFiles.mjs.map +1 -1
- package/dist/esm/utils/openBrowser.mjs +1 -17
- package/dist/esm/utils/openBrowser.mjs.map +1 -1
- package/dist/esm/utils/reorderParagraphs.mjs +3 -90
- package/dist/esm/utils/reorderParagraphs.mjs.map +1 -1
- package/dist/esm/utils/setupAI.mjs +1 -62
- package/dist/esm/utils/setupAI.mjs.map +1 -1
- package/dist/esm/watch.mjs +1 -41
- package/dist/esm/watch.mjs.map +1 -1
- package/dist/types/auth/login.d.ts +1 -1
- package/dist/types/auth/login.d.ts.map +1 -1
- package/dist/types/build.d.ts +1 -1
- package/dist/types/build.d.ts.map +1 -1
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/config.d.ts +1 -1
- package/dist/types/extract.d.ts +1 -1
- package/dist/types/extract.d.ts.map +1 -1
- package/dist/types/fill/fill.d.ts +1 -1
- package/dist/types/fill/fill.d.ts.map +1 -1
- package/dist/types/fill/translateDictionary.d.ts +2 -2
- package/dist/types/fill/translateDictionary.d.ts.map +1 -1
- package/dist/types/fill/writeFill.d.ts.map +1 -1
- package/dist/types/getTargetDictionary.d.ts +2 -2
- package/dist/types/index.d.ts +7 -3
- package/dist/types/init.d.ts +2 -5
- package/dist/types/init.d.ts.map +1 -1
- package/dist/types/initSkills.d.ts +8 -0
- package/dist/types/initSkills.d.ts.map +1 -0
- package/dist/types/listContentDeclaration.d.ts +1 -1
- package/dist/types/listContentDeclaration.d.ts.map +1 -1
- package/dist/types/liveSync.d.ts +1 -1
- package/dist/types/pull.d.ts +1 -1
- package/dist/types/pull.d.ts.map +1 -1
- package/dist/types/push/pullLog.d.ts +1 -1
- package/dist/types/push/pullLog.d.ts.map +1 -1
- package/dist/types/push/push.d.ts +2 -2
- package/dist/types/pushConfig.d.ts +1 -1
- package/dist/types/reviewDoc/reviewDoc.d.ts +2 -2
- package/dist/types/reviewDoc/reviewDoc.d.ts.map +1 -1
- package/dist/types/reviewDoc/reviewDocBlockAware.d.ts +1 -1
- package/dist/types/reviewDoc/reviewDocBlockAware.d.ts.map +1 -1
- package/dist/types/searchDoc.d.ts +1 -1
- package/dist/types/searchDoc.d.ts.map +1 -1
- package/dist/types/test/listMissingTranslations.d.ts +1 -1
- package/dist/types/test/test.d.ts +1 -1
- package/dist/types/test/test.d.ts.map +1 -1
- package/dist/types/translateDoc/translateDoc.d.ts.map +1 -1
- package/dist/types/translateDoc/types.d.ts +2 -2
- package/dist/types/translateDoc/validation.d.ts +1 -1
- package/dist/types/utils/checkAccess.d.ts.map +1 -1
- package/dist/types/watch.d.ts +1 -1
- package/dist/types/watch.d.ts.map +1 -1
- package/package.json +11 -11
|
@@ -1,93 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { sanitizeChunk, validateTranslation } from "../translateDoc/validation.mjs";
|
|
3
|
-
import { mergeReviewedSegments } from "../translation-alignment/rebuildDocument.mjs";
|
|
4
|
-
import { buildAlignmentPlan } from "../translation-alignment/pipeline.mjs";
|
|
5
|
-
import { chunkInference } from "../utils/chunkInference.mjs";
|
|
6
|
-
import { fixChunkStartEndChars } from "../utils/fixChunkStartEndChars.mjs";
|
|
7
|
-
import { formatLocale, formatPath } from "@intlayer/chokidar";
|
|
8
|
-
import { ANSIColors, colon, colorize, colorizeNumber, getAppLogger, getConfiguration, retryManager } from "@intlayer/config";
|
|
9
|
-
import { dirname } from "node:path";
|
|
10
|
-
import { mkdirSync, writeFileSync } from "node:fs";
|
|
11
|
-
import { readFile } from "node:fs/promises";
|
|
12
|
-
import { getLocaleName } from "@intlayer/core";
|
|
13
|
-
import { Locales } from "@intlayer/types";
|
|
14
|
-
|
|
15
|
-
//#region src/reviewDoc/reviewDocBlockAware.ts
|
|
16
|
-
/**
|
|
17
|
-
* Review a file using block-aware alignment.
|
|
18
|
-
* This approach:
|
|
19
|
-
* 1. Segments both English and French documents into semantic blocks
|
|
20
|
-
* 2. Aligns blocks using structure (special chars, numbers) and context
|
|
21
|
-
* 3. Detects which blocks changed, were added, or deleted
|
|
22
|
-
* 4. Only sends changed/new blocks to AI for translation
|
|
23
|
-
* 5. Handles reordering automatically
|
|
24
|
-
*/
|
|
25
|
-
const reviewFileBlockAware = async (baseFilePath, outputFilePath, locale, baseLocale, aiOptions, configOptions, customInstructions, changedLines, aiClient, aiConfig) => {
|
|
26
|
-
const configuration = getConfiguration(configOptions);
|
|
27
|
-
const applicationLogger = getAppLogger(configuration);
|
|
28
|
-
const englishText = await readFile(baseFilePath, "utf-8");
|
|
29
|
-
const frenchText = await readFile(outputFilePath, "utf-8").catch(() => "");
|
|
30
|
-
const basePrompt = readAsset("./prompts/REVIEW_PROMPT.md", "utf-8").replaceAll("{{localeName}}", `${formatLocale(locale, false)}`).replaceAll("{{baseLocaleName}}", `${formatLocale(baseLocale, false)}`).replace("{{applicationContext}}", aiOptions?.applicationContext ?? "-").replace("{{customInstructions}}", customInstructions ?? "-");
|
|
31
|
-
const filePrefix = [colon(`${ANSIColors.GREY_DARK}[${formatPath(baseFilePath)}${ANSIColors.GREY_DARK}] `, { colSize: 40 }), `→ ${ANSIColors.RESET}`].join("");
|
|
32
|
-
const prefix = [colon(`${ANSIColors.GREY_DARK}[${formatPath(baseFilePath)}${ANSIColors.GREY_DARK}][${formatLocale(locale)}${ANSIColors.GREY_DARK}] `, { colSize: 40 }), `→ ${ANSIColors.RESET}`].join("");
|
|
33
|
-
const { englishBlocks, frenchBlocks, plan, segmentsToReview } = buildAlignmentPlan({
|
|
34
|
-
englishText,
|
|
35
|
-
frenchText,
|
|
36
|
-
changedLines
|
|
37
|
-
});
|
|
38
|
-
applicationLogger(`${filePrefix}Block-aware alignment complete. Total blocks: EN=${colorizeNumber(englishBlocks.length)}, FR=${colorizeNumber(frenchBlocks.length)}`);
|
|
39
|
-
applicationLogger(`${filePrefix}Actions: reuse=${colorizeNumber(plan.actions.filter((a) => a.kind === "reuse").length)}, review=${colorizeNumber(plan.actions.filter((a) => a.kind === "review").length)}, new=${colorizeNumber(plan.actions.filter((a) => a.kind === "insert_new").length)}, delete=${colorizeNumber(plan.actions.filter((a) => a.kind === "delete").length)}`);
|
|
40
|
-
if (segmentsToReview.length === 0) {
|
|
41
|
-
applicationLogger(`${filePrefix}No segments need review, reusing existing translation`);
|
|
42
|
-
mkdirSync(dirname(outputFilePath), { recursive: true });
|
|
43
|
-
writeFileSync(outputFilePath, mergeReviewedSegments(plan, frenchBlocks, /* @__PURE__ */ new Map()));
|
|
44
|
-
applicationLogger(`${colorize("✔", ANSIColors.GREEN)} File ${formatPath(outputFilePath)} updated successfully (no changes needed).`);
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
applicationLogger(`${filePrefix}Segments to review: ${colorizeNumber(segmentsToReview.length)}`);
|
|
48
|
-
const reviewedSegmentsMap = /* @__PURE__ */ new Map();
|
|
49
|
-
for (const segment of segmentsToReview) {
|
|
50
|
-
const segmentNumber = segmentsToReview.indexOf(segment) + 1;
|
|
51
|
-
const englishBlock = segment.englishBlock;
|
|
52
|
-
const getBaseChunkContextPrompt = () => `**BLOCK ${segmentNumber} of ${segmentsToReview.length}** is the base block in ${formatLocale(baseLocale, false)} as reference.\n///chunksStart///\n` + englishBlock.content + `///chunksEnd///`;
|
|
53
|
-
const getFrenchChunkPrompt = () => `**BLOCK ${segmentNumber} of ${segmentsToReview.length}** is the current block to review in ${formatLocale(locale, false)}.\n///chunksStart///\n` + (segment.frenchBlockText ?? "") + `///chunksEnd///`;
|
|
54
|
-
const reviewedChunkResult = await retryManager(async () => {
|
|
55
|
-
const result = await chunkInference([
|
|
56
|
-
{
|
|
57
|
-
role: "system",
|
|
58
|
-
content: basePrompt
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
role: "system",
|
|
62
|
-
content: getBaseChunkContextPrompt()
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
role: "system",
|
|
66
|
-
content: getFrenchChunkPrompt()
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
role: "system",
|
|
70
|
-
content: `The next user message will be the **BLOCK ${colorizeNumber(segmentNumber)} of ${colorizeNumber(segmentsToReview.length)}** that should be translated in ${getLocaleName(locale, Locales.ENGLISH)} (${locale}).`
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
role: "user",
|
|
74
|
-
content: englishBlock.content
|
|
75
|
-
}
|
|
76
|
-
], aiOptions, configuration, aiClient, aiConfig);
|
|
77
|
-
applicationLogger(`${prefix}${colorizeNumber(result.tokenUsed)} tokens used - Block ${colorizeNumber(segmentNumber)} of ${colorizeNumber(segmentsToReview.length)}`);
|
|
78
|
-
let processedChunk = sanitizeChunk(result?.fileContent, englishBlock.content);
|
|
79
|
-
processedChunk = fixChunkStartEndChars(processedChunk, englishBlock.content);
|
|
80
|
-
if (!validateTranslation(englishBlock.content, processedChunk, applicationLogger)) throw new Error("Validation failed for chunk (structure or length mismatch). Retrying...");
|
|
81
|
-
return processedChunk;
|
|
82
|
-
})();
|
|
83
|
-
reviewedSegmentsMap.set(segment.actionIndex, reviewedChunkResult);
|
|
84
|
-
}
|
|
85
|
-
const finalFrenchOutput = mergeReviewedSegments(plan, frenchBlocks, reviewedSegmentsMap);
|
|
86
|
-
mkdirSync(dirname(outputFilePath), { recursive: true });
|
|
87
|
-
writeFileSync(outputFilePath, finalFrenchOutput);
|
|
88
|
-
applicationLogger(`${colorize("✔", ANSIColors.GREEN)} File ${formatPath(outputFilePath)} created/updated successfully.`);
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
//#endregion
|
|
92
|
-
export { reviewFileBlockAware };
|
|
1
|
+
import{readAsset as e}from"../_virtual/_utils_asset.mjs";import{sanitizeChunk as t,validateTranslation as n}from"../translateDoc/validation.mjs";import{mergeReviewedSegments as r}from"../translation-alignment/rebuildDocument.mjs";import{buildAlignmentPlan as i}from"../translation-alignment/pipeline.mjs";import{chunkInference as a}from"../utils/chunkInference.mjs";import{fixChunkStartEndChars as o}from"../utils/fixChunkStartEndChars.mjs";import{formatLocale as s,formatPath as c}from"@intlayer/chokidar/utils";import{getConfiguration as l}from"@intlayer/config/node";import{dirname as u}from"node:path";import{ANSIColors as d,colon as f,colorize as p,colorizeNumber as m,getAppLogger as h}from"@intlayer/config/logger";import{retryManager as g}from"@intlayer/config/utils";import{mkdirSync as _,writeFileSync as v}from"node:fs";import{readFile as y}from"node:fs/promises";import{getLocaleName as b}from"@intlayer/core/localization";import{Locales as x}from"@intlayer/types";const S=async(S,C,w,T,E,D,O,k,A,j)=>{let M=l(D),N=h(M),P=await y(S,`utf-8`),F=await y(C,`utf-8`).catch(()=>``),I=e(`./prompts/REVIEW_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${s(w,!1)}`).replaceAll(`{{baseLocaleName}}`,`${s(T,!1)}`).replace(`{{applicationContext}}`,E?.applicationContext??`-`).replace(`{{customInstructions}}`,O??`-`),L=[f(`${d.GREY_DARK}[${c(S)}${d.GREY_DARK}] `,{colSize:40}),`→ ${d.RESET}`].join(``),R=[f(`${d.GREY_DARK}[${c(S)}${d.GREY_DARK}][${s(w)}${d.GREY_DARK}] `,{colSize:40}),`→ ${d.RESET}`].join(``),{englishBlocks:z,frenchBlocks:B,plan:V,segmentsToReview:H}=i({englishText:P,frenchText:F,changedLines:k});if(N(`${L}Block-aware alignment complete. Total blocks: EN=${m(z.length)}, FR=${m(B.length)}`),N(`${L}Actions: reuse=${m(V.actions.filter(e=>e.kind===`reuse`).length)}, review=${m(V.actions.filter(e=>e.kind===`review`).length)}, new=${m(V.actions.filter(e=>e.kind===`insert_new`).length)}, delete=${m(V.actions.filter(e=>e.kind===`delete`).length)}`),H.length===0){N(`${L}No segments need review, reusing existing translation`),_(u(C),{recursive:!0}),v(C,r(V,B,new Map)),N(`${p(`✔`,d.GREEN)} File ${c(C)} updated successfully (no changes needed).`);return}N(`${L}Segments to review: ${m(H.length)}`);let U=new Map;for(let e of H){let r=H.indexOf(e)+1,i=e.englishBlock,c=()=>`**BLOCK ${r} of ${H.length}** is the base block in ${s(T,!1)} as reference.\n///chunksStart///\n`+i.content+`///chunksEnd///`,l=()=>`**BLOCK ${r} of ${H.length}** is the current block to review in ${s(w,!1)}.\n///chunksStart///\n`+(e.frenchBlockText??``)+`///chunksEnd///`,u=await g(async()=>{let e=await a([{role:`system`,content:I},{role:`system`,content:c()},{role:`system`,content:l()},{role:`system`,content:`The next user message will be the **BLOCK ${m(r)} of ${m(H.length)}** that should be translated in ${b(w,x.ENGLISH)} (${w}).`},{role:`user`,content:i.content}],E,M,A,j);N(`${R}${m(e.tokenUsed)} tokens used - Block ${m(r)} of ${m(H.length)}`);let s=t(e?.fileContent,i.content);if(s=o(s,i.content),!n(i.content,s,N))throw Error(`Validation failed for chunk (structure or length mismatch). Retrying...`);return s})();U.set(e.actionIndex,u)}let W=r(V,B,U);_(u(C),{recursive:!0}),v(C,W),N(`${p(`✔`,d.GREEN)} File ${c(C)} created/updated successfully.`)};export{S as reviewFileBlockAware};
|
|
93
2
|
//# sourceMappingURL=reviewDocBlockAware.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reviewDocBlockAware.mjs","names":[],"sources":["../../../src/reviewDoc/reviewDocBlockAware.ts"],"sourcesContent":["import { mkdirSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { readAsset } from 'utils:asset';\nimport type { AIConfig } from '@intlayer/ai';\nimport type { AIOptions } from '@intlayer/api';\nimport { formatLocale, formatPath } from '@intlayer/chokidar';\nimport {\n ANSIColors,\n colon,\n colorize,\n colorizeNumber,\n type GetConfigurationOptions,\n
|
|
1
|
+
{"version":3,"file":"reviewDocBlockAware.mjs","names":[],"sources":["../../../src/reviewDoc/reviewDocBlockAware.ts"],"sourcesContent":["import { mkdirSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { readAsset } from 'utils:asset';\nimport type { AIConfig } from '@intlayer/ai';\nimport type { AIOptions } from '@intlayer/api';\nimport { formatLocale, formatPath } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colon,\n colorize,\n colorizeNumber,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { retryManager } from '@intlayer/config/utils';\nimport { getLocaleName } from '@intlayer/core/localization';\nimport { type Locale, Locales } from '@intlayer/types';\nimport { sanitizeChunk, validateTranslation } from '../translateDoc/validation';\nimport {\n buildAlignmentPlan,\n mergeReviewedSegments,\n} from '../translation-alignment/pipeline';\nimport { chunkInference } from '../utils/chunkInference';\nimport { fixChunkStartEndChars } from '../utils/fixChunkStartEndChars';\nimport type { AIClient } from '../utils/setupAI';\n\n/**\n * Review a file using block-aware alignment.\n * This approach:\n * 1. Segments both English and French documents into semantic blocks\n * 2. Aligns blocks using structure (special chars, numbers) and context\n * 3. Detects which blocks changed, were added, or deleted\n * 4. Only sends changed/new blocks to AI for translation\n * 5. Handles reordering automatically\n */\nexport const reviewFileBlockAware = async (\n baseFilePath: string,\n outputFilePath: string,\n locale: Locale,\n baseLocale: Locale,\n aiOptions?: AIOptions,\n configOptions?: GetConfigurationOptions,\n customInstructions?: string,\n changedLines?: number[],\n aiClient?: AIClient,\n aiConfig?: AIConfig\n) => {\n const configuration = getConfiguration(configOptions);\n const applicationLogger = getAppLogger(configuration);\n\n const englishText = await readFile(baseFilePath, 'utf-8');\n const frenchText = await readFile(outputFilePath, 'utf-8').catch(() => '');\n\n const basePrompt = readAsset('./prompts/REVIEW_PROMPT.md', 'utf-8')\n .replaceAll('{{localeName}}', `${formatLocale(locale, false)}`)\n .replaceAll('{{baseLocaleName}}', `${formatLocale(baseLocale, false)}`)\n .replace('{{applicationContext}}', aiOptions?.applicationContext ?? '-')\n .replace('{{customInstructions}}', customInstructions ?? '-');\n\n const filePrefixText = `${ANSIColors.GREY_DARK}[${formatPath(baseFilePath)}${ANSIColors.GREY_DARK}] `;\n const filePrefix = [\n colon(filePrefixText, { colSize: 40 }),\n `→ ${ANSIColors.RESET}`,\n ].join('');\n const prefixText = `${ANSIColors.GREY_DARK}[${formatPath(baseFilePath)}${ANSIColors.GREY_DARK}][${formatLocale(locale)}${ANSIColors.GREY_DARK}] `;\n const prefix = [\n colon(prefixText, { colSize: 40 }),\n `→ ${ANSIColors.RESET}`,\n ].join('');\n\n // Build block-aware alignment and plan\n const { englishBlocks, frenchBlocks, plan, segmentsToReview } =\n buildAlignmentPlan({\n englishText,\n frenchText,\n changedLines,\n });\n\n applicationLogger(\n `${filePrefix}Block-aware alignment complete. Total blocks: EN=${colorizeNumber(englishBlocks.length)}, FR=${colorizeNumber(frenchBlocks.length)}`\n );\n applicationLogger(\n `${filePrefix}Actions: reuse=${colorizeNumber(plan.actions.filter((a) => a.kind === 'reuse').length)}, review=${colorizeNumber(plan.actions.filter((a) => a.kind === 'review').length)}, new=${colorizeNumber(plan.actions.filter((a) => a.kind === 'insert_new').length)}, delete=${colorizeNumber(plan.actions.filter((a) => a.kind === 'delete').length)}`\n );\n\n if (segmentsToReview.length === 0) {\n applicationLogger(\n `${filePrefix}No segments need review, reusing existing translation`\n );\n mkdirSync(dirname(outputFilePath), { recursive: true });\n writeFileSync(\n outputFilePath,\n mergeReviewedSegments(plan, frenchBlocks, new Map())\n );\n applicationLogger(\n `${colorize('✔', ANSIColors.GREEN)} File ${formatPath(outputFilePath)} updated successfully (no changes needed).`\n );\n return;\n }\n\n applicationLogger(\n `${filePrefix}Segments to review: ${colorizeNumber(segmentsToReview.length)}`\n );\n\n // Review segments that need AI translation\n const reviewedSegmentsMap = new Map<number, string>();\n\n for (const segment of segmentsToReview) {\n const segmentNumber = segmentsToReview.indexOf(segment) + 1;\n const englishBlock = segment.englishBlock;\n\n const getBaseChunkContextPrompt = () =>\n `**BLOCK ${segmentNumber} of ${segmentsToReview.length}** is the base block in ${formatLocale(baseLocale, false)} as reference.\\n` +\n `///chunksStart///\\n` +\n englishBlock.content +\n `///chunksEnd///`;\n\n const getFrenchChunkPrompt = () =>\n `**BLOCK ${segmentNumber} of ${segmentsToReview.length}** is the current block to review in ${formatLocale(locale, false)}.\\n` +\n `///chunksStart///\\n` +\n (segment.frenchBlockText ?? '') +\n `///chunksEnd///`;\n\n const reviewedChunkResult = await retryManager(async () => {\n const result = await chunkInference(\n [\n { role: 'system', content: basePrompt },\n { role: 'system', content: getBaseChunkContextPrompt() },\n { role: 'system', content: getFrenchChunkPrompt() },\n {\n role: 'system',\n content: `The next user message will be the **BLOCK ${colorizeNumber(segmentNumber)} of ${colorizeNumber(segmentsToReview.length)}** that should be translated in ${getLocaleName(locale, Locales.ENGLISH)} (${locale}).`,\n },\n { role: 'user', content: englishBlock.content },\n ],\n aiOptions,\n configuration,\n aiClient,\n aiConfig\n );\n\n applicationLogger(\n `${prefix}${colorizeNumber(result.tokenUsed)} tokens used - Block ${colorizeNumber(segmentNumber)} of ${colorizeNumber(segmentsToReview.length)}`\n );\n\n // Sanitize artifacts (e.g. Markdown code block wrappers)\n let processedChunk = sanitizeChunk(\n result?.fileContent,\n englishBlock.content\n );\n\n // Fix start/end characters\n processedChunk = fixChunkStartEndChars(\n processedChunk,\n englishBlock.content\n );\n\n // Validate Translation (YAML, Code fences, Length ratio)\n const isValid = validateTranslation(\n englishBlock.content,\n processedChunk,\n applicationLogger\n );\n\n if (!isValid) {\n throw new Error(\n 'Validation failed for chunk (structure or length mismatch). Retrying...'\n );\n }\n\n return processedChunk;\n })();\n\n reviewedSegmentsMap.set(segment.actionIndex, reviewedChunkResult);\n }\n\n // Merge reviewed segments back into final document\n const finalFrenchOutput = mergeReviewedSegments(\n plan,\n frenchBlocks,\n reviewedSegmentsMap\n );\n\n mkdirSync(dirname(outputFilePath), { recursive: true });\n writeFileSync(outputFilePath, finalFrenchOutput);\n\n applicationLogger(\n `${colorize('✔', ANSIColors.GREEN)} File ${formatPath(outputFilePath)} created/updated successfully.`\n );\n};\n"],"mappings":"i9BAuCA,MAAa,EAAuB,MAClC,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,IACG,CACH,IAAM,EAAgB,EAAiB,EAAc,CAC/C,EAAoB,EAAa,EAAc,CAE/C,EAAc,MAAM,EAAS,EAAc,QAAQ,CACnD,EAAa,MAAM,EAAS,EAAgB,QAAQ,CAAC,UAAY,GAAG,CAEpE,EAAa,EAAU,6BAA8B,QAAQ,CAChE,WAAW,iBAAkB,GAAG,EAAa,EAAQ,GAAM,GAAG,CAC9D,WAAW,qBAAsB,GAAG,EAAa,EAAY,GAAM,GAAG,CACtE,QAAQ,yBAA0B,GAAW,oBAAsB,IAAI,CACvE,QAAQ,yBAA0B,GAAsB,IAAI,CAGzD,EAAa,CACjB,EAFqB,GAAG,EAAW,UAAU,GAAG,EAAW,EAAa,GAAG,EAAW,UAAU,IAE1E,CAAE,QAAS,GAAI,CAAC,CACtC,KAAK,EAAW,QACjB,CAAC,KAAK,GAAG,CAEJ,EAAS,CACb,EAFiB,GAAG,EAAW,UAAU,GAAG,EAAW,EAAa,GAAG,EAAW,UAAU,IAAI,EAAa,EAAO,GAAG,EAAW,UAAU,IAE1H,CAAE,QAAS,GAAI,CAAC,CAClC,KAAK,EAAW,QACjB,CAAC,KAAK,GAAG,CAGJ,CAAE,gBAAe,eAAc,OAAM,oBACzC,EAAmB,CACjB,cACA,aACA,eACD,CAAC,CASJ,GAPA,EACE,GAAG,EAAW,mDAAmD,EAAe,EAAc,OAAO,CAAC,OAAO,EAAe,EAAa,OAAO,GACjJ,CACD,EACE,GAAG,EAAW,iBAAiB,EAAe,EAAK,QAAQ,OAAQ,GAAM,EAAE,OAAS,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAe,EAAK,QAAQ,OAAQ,GAAM,EAAE,OAAS,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAe,EAAK,QAAQ,OAAQ,GAAM,EAAE,OAAS,aAAa,CAAC,OAAO,CAAC,WAAW,EAAe,EAAK,QAAQ,OAAQ,GAAM,EAAE,OAAS,SAAS,CAAC,OAAO,GAC5V,CAEG,EAAiB,SAAW,EAAG,CACjC,EACE,GAAG,EAAW,uDACf,CACD,EAAU,EAAQ,EAAe,CAAE,CAAE,UAAW,GAAM,CAAC,CACvD,EACE,EACA,EAAsB,EAAM,EAAc,IAAI,IAAM,CACrD,CACD,EACE,GAAG,EAAS,IAAK,EAAW,MAAM,CAAC,QAAQ,EAAW,EAAe,CAAC,4CACvE,CACD,OAGF,EACE,GAAG,EAAW,sBAAsB,EAAe,EAAiB,OAAO,GAC5E,CAGD,IAAM,EAAsB,IAAI,IAEhC,IAAK,IAAM,KAAW,EAAkB,CACtC,IAAM,EAAgB,EAAiB,QAAQ,EAAQ,CAAG,EACpD,EAAe,EAAQ,aAEvB,MACJ,WAAW,EAAc,MAAM,EAAiB,OAAO,0BAA0B,EAAa,EAAY,GAAM,CAAC,qCAEjH,EAAa,QACb,kBAEI,MACJ,WAAW,EAAc,MAAM,EAAiB,OAAO,uCAAuC,EAAa,EAAQ,GAAM,CAAC,yBAEzH,EAAQ,iBAAmB,IAC5B,kBAEI,EAAsB,MAAM,EAAa,SAAY,CACzD,IAAM,EAAS,MAAM,EACnB,CACE,CAAE,KAAM,SAAU,QAAS,EAAY,CACvC,CAAE,KAAM,SAAU,QAAS,GAA2B,CAAE,CACxD,CAAE,KAAM,SAAU,QAAS,GAAsB,CAAE,CACnD,CACE,KAAM,SACN,QAAS,6CAA6C,EAAe,EAAc,CAAC,MAAM,EAAe,EAAiB,OAAO,CAAC,kCAAkC,EAAc,EAAQ,EAAQ,QAAQ,CAAC,IAAI,EAAO,IACvN,CACD,CAAE,KAAM,OAAQ,QAAS,EAAa,QAAS,CAChD,CACD,EACA,EACA,EACA,EACD,CAED,EACE,GAAG,IAAS,EAAe,EAAO,UAAU,CAAC,uBAAuB,EAAe,EAAc,CAAC,MAAM,EAAe,EAAiB,OAAO,GAChJ,CAGD,IAAI,EAAiB,EACnB,GAAQ,YACR,EAAa,QACd,CAeD,GAZA,EAAiB,EACf,EACA,EAAa,QACd,CASG,CANY,EACd,EAAa,QACb,EACA,EACD,CAGC,MAAU,MACR,0EACD,CAGH,OAAO,GACP,EAAE,CAEJ,EAAoB,IAAI,EAAQ,YAAa,EAAoB,CAInE,IAAM,EAAoB,EACxB,EACA,EACA,EACD,CAED,EAAU,EAAQ,EAAe,CAAE,CAAE,UAAW,GAAM,CAAC,CACvD,EAAc,EAAgB,EAAkB,CAEhD,EACE,GAAG,EAAS,IAAK,EAAW,MAAM,CAAC,QAAQ,EAAW,EAAe,CAAC,gCACvE"}
|
package/dist/esm/searchDoc.mjs
CHANGED
|
@@ -1,37 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { colorizeKey, colorizeNumber, getAppLogger, getConfiguration } from "@intlayer/config";
|
|
3
|
-
|
|
4
|
-
//#region src/searchDoc.ts
|
|
5
|
-
const searchDoc = async ({ query, limit = 10, configOptions }) => {
|
|
6
|
-
const config = getConfiguration(configOptions);
|
|
7
|
-
const appLogger = getAppLogger(config);
|
|
8
|
-
try {
|
|
9
|
-
const { searchDoc } = getSearchAPI(void 0, config);
|
|
10
|
-
const response = await searchDoc({
|
|
11
|
-
input: query,
|
|
12
|
-
limit: limit.toString(),
|
|
13
|
-
returnContent: "true"
|
|
14
|
-
});
|
|
15
|
-
if (!response.data || !Array.isArray(response.data)) {
|
|
16
|
-
appLogger("No relevant chunks found.");
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
const chunks = response.data;
|
|
20
|
-
appLogger(`Found ${colorizeNumber(chunks.length)} relevant chunks:`);
|
|
21
|
-
chunks.forEach((chunk) => {
|
|
22
|
-
appLogger("---");
|
|
23
|
-
appLogger(`${colorizeKey("File")}: ${chunk.fileKey}`);
|
|
24
|
-
appLogger(`${colorizeKey("Title")}: ${chunk.docName}`);
|
|
25
|
-
appLogger(`${colorizeKey("URL")}: ${chunk.docUrl}`);
|
|
26
|
-
appLogger(`${colorizeKey("Chunk")}: ${chunk.chunkNumber}`);
|
|
27
|
-
appLogger(`${colorizeKey("Content")}:`);
|
|
28
|
-
appLogger(chunk.content);
|
|
29
|
-
});
|
|
30
|
-
} catch (error) {
|
|
31
|
-
appLogger(`Search failed: ${error instanceof Error ? error.message : "An unknown error occurred"}`, { level: "error" });
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
//#endregion
|
|
36
|
-
export { searchDoc };
|
|
1
|
+
import{getSearchAPI as e}from"@intlayer/api";import{getConfiguration as t}from"@intlayer/config/node";import{colorizeKey as n,colorizeNumber as r,getAppLogger as i}from"@intlayer/config/logger";const a=async({query:a,limit:o=10,configOptions:s})=>{let c=t(s),l=i(c);try{let{searchDoc:t}=e(void 0,c),i=await t({input:a,limit:o.toString(),returnContent:`true`});if(!i.data||!Array.isArray(i.data)){l(`No relevant chunks found.`);return}let s=i.data;l(`Found ${r(s.length)} relevant chunks:`),s.forEach(e=>{l(`---`),l(`${n(`File`)}: ${e.fileKey}`),l(`${n(`Title`)}: ${e.docName}`),l(`${n(`URL`)}: ${e.docUrl}`),l(`${n(`Chunk`)}: ${e.chunkNumber}`),l(`${n(`Content`)}:`),l(e.content)})}catch(e){l(`Search failed: ${e instanceof Error?e.message:`An unknown error occurred`}`,{level:`error`})}};export{a as searchDoc};
|
|
37
2
|
//# sourceMappingURL=searchDoc.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchDoc.mjs","names":[],"sources":["../../src/searchDoc.ts"],"sourcesContent":["import { getSearchAPI } from '@intlayer/api';\nimport {\n colorizeKey,\n colorizeNumber,\n type GetConfigurationOptions,\n
|
|
1
|
+
{"version":3,"file":"searchDoc.mjs","names":[],"sources":["../../src/searchDoc.ts"],"sourcesContent":["import { getSearchAPI } from '@intlayer/api';\nimport {\n colorizeKey,\n colorizeNumber,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\n\ninterface SearchDocOptions {\n query: string;\n limit?: number;\n configOptions?: GetConfigurationOptions;\n}\n\nexport const searchDoc = async ({\n query,\n limit = 10,\n configOptions,\n}: SearchDocOptions) => {\n const config = getConfiguration(configOptions);\n const appLogger = getAppLogger(config);\n\n try {\n const { searchDoc } = getSearchAPI(undefined, config);\n const response = await searchDoc({\n input: query,\n limit: limit.toString(),\n returnContent: 'true',\n });\n\n if (!response.data || !Array.isArray(response.data)) {\n appLogger('No relevant chunks found.');\n return;\n }\n\n const chunks = response.data;\n\n appLogger(`Found ${colorizeNumber(chunks.length)} relevant chunks:`);\n\n chunks.forEach((chunk: any) => {\n appLogger('---');\n appLogger(`${colorizeKey('File')}: ${chunk.fileKey}`);\n appLogger(`${colorizeKey('Title')}: ${chunk.docName}`);\n appLogger(`${colorizeKey('URL')}: ${chunk.docUrl}`);\n appLogger(`${colorizeKey('Chunk')}: ${chunk.chunkNumber}`);\n appLogger(`${colorizeKey('Content')}:`);\n appLogger(chunk.content);\n });\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n appLogger(`Search failed: ${errorMessage}`, { level: 'error' });\n }\n};\n"],"mappings":"kMAiBA,MAAa,EAAY,MAAO,CAC9B,QACA,QAAQ,GACR,mBACsB,CACtB,IAAM,EAAS,EAAiB,EAAc,CACxC,EAAY,EAAa,EAAO,CAEtC,GAAI,CACF,GAAM,CAAE,aAAc,EAAa,IAAA,GAAW,EAAO,CAC/C,EAAW,MAAM,EAAU,CAC/B,MAAO,EACP,MAAO,EAAM,UAAU,CACvB,cAAe,OAChB,CAAC,CAEF,GAAI,CAAC,EAAS,MAAQ,CAAC,MAAM,QAAQ,EAAS,KAAK,CAAE,CACnD,EAAU,4BAA4B,CACtC,OAGF,IAAM,EAAS,EAAS,KAExB,EAAU,SAAS,EAAe,EAAO,OAAO,CAAC,mBAAmB,CAEpE,EAAO,QAAS,GAAe,CAC7B,EAAU,MAAM,CAChB,EAAU,GAAG,EAAY,OAAO,CAAC,IAAI,EAAM,UAAU,CACrD,EAAU,GAAG,EAAY,QAAQ,CAAC,IAAI,EAAM,UAAU,CACtD,EAAU,GAAG,EAAY,MAAM,CAAC,IAAI,EAAM,SAAS,CACnD,EAAU,GAAG,EAAY,QAAQ,CAAC,IAAI,EAAM,cAAc,CAC1D,EAAU,GAAG,EAAY,UAAU,CAAC,GAAG,CACvC,EAAU,EAAM,QAAQ,EACxB,OACK,EAAO,CAGd,EAAU,kBADR,aAAiB,MAAQ,EAAM,QAAU,8BACC,CAAE,MAAO,QAAS,CAAC"}
|
package/dist/esm/test/index.mjs
CHANGED
|
@@ -1,4 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { testMissingTranslations } from "./test.mjs";
|
|
3
|
-
|
|
4
|
-
export { listMissingTranslations, listMissingTranslationsWithConfig, testMissingTranslations };
|
|
1
|
+
import{listMissingTranslations as e,listMissingTranslationsWithConfig as t}from"./listMissingTranslations.mjs";import{testMissingTranslations as n}from"./test.mjs";export{e as listMissingTranslations,t as listMissingTranslationsWithConfig,n as testMissingTranslations};
|
|
@@ -1,47 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getUnmergedDictionaries } from "@intlayer/unmerged-dictionaries-entry";
|
|
3
|
-
import { getMissingLocalesContentFromDictionary } from "@intlayer/core";
|
|
4
|
-
import { getDictionaries } from "@intlayer/dictionaries-entry";
|
|
5
|
-
|
|
6
|
-
//#region src/test/listMissingTranslations.ts
|
|
7
|
-
const listMissingTranslationsWithConfig = (configuration) => {
|
|
8
|
-
const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);
|
|
9
|
-
const mergedDictionaries = getDictionaries(configuration);
|
|
10
|
-
const missingTranslations = [];
|
|
11
|
-
const { locales, requiredLocales } = configuration.internationalization;
|
|
12
|
-
const dictionariesKeys = Object.keys(unmergedDictionariesRecord);
|
|
13
|
-
for (const dictionaryKey of dictionariesKeys) {
|
|
14
|
-
const dictionaries = unmergedDictionariesRecord[dictionaryKey];
|
|
15
|
-
const multilingualDictionary = dictionaries.filter((dictionary) => !dictionary.locale);
|
|
16
|
-
for (const dictionary of multilingualDictionary) {
|
|
17
|
-
const missingLocales = getMissingLocalesContentFromDictionary(dictionary, locales);
|
|
18
|
-
if (missingLocales.length > 0) missingTranslations.push({
|
|
19
|
-
key: dictionaryKey,
|
|
20
|
-
id: dictionary.id,
|
|
21
|
-
filePath: dictionary.filePath,
|
|
22
|
-
locales: missingLocales
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
if (dictionaries.filter((dictionary) => dictionary.locale).length === 0) continue;
|
|
26
|
-
const mergedDictionary = mergedDictionaries[dictionaryKey];
|
|
27
|
-
const missingLocales = getMissingLocalesContentFromDictionary(mergedDictionary, locales);
|
|
28
|
-
if (missingLocales.length > 0) missingTranslations.push({
|
|
29
|
-
key: dictionaryKey,
|
|
30
|
-
locales: missingLocales
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
const missingLocalesSet = new Set(missingTranslations.flatMap((t) => t.locales));
|
|
34
|
-
const missingLocales = Array.from(missingLocalesSet);
|
|
35
|
-
return {
|
|
36
|
-
missingTranslations,
|
|
37
|
-
missingLocales,
|
|
38
|
-
missingRequiredLocales: missingLocales.filter((locale) => (requiredLocales ?? locales).includes(locale))
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
const listMissingTranslations = (configurationOptions) => {
|
|
42
|
-
return listMissingTranslationsWithConfig(getConfiguration(configurationOptions));
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
//#endregion
|
|
46
|
-
export { listMissingTranslations, listMissingTranslationsWithConfig };
|
|
1
|
+
import{getConfiguration as e}from"@intlayer/config/node";import{getUnmergedDictionaries as t}from"@intlayer/unmerged-dictionaries-entry";import{getMissingLocalesContentFromDictionary as n}from"@intlayer/core/plugins";import{getDictionaries as r}from"@intlayer/dictionaries-entry";const i=e=>{let i=t(e),a=r(e),o=[],{locales:s,requiredLocales:c}=e.internationalization,l=Object.keys(i);for(let e of l){let t=i[e],r=t.filter(e=>!e.locale);for(let t of r){let r=n(t,s);r.length>0&&o.push({key:e,id:t.id,filePath:t.filePath,locales:r})}if(t.filter(e=>e.locale).length===0)continue;let c=a[e],l=n(c,s);l.length>0&&o.push({key:e,locales:l})}let u=new Set(o.flatMap(e=>e.locales)),d=Array.from(u);return{missingTranslations:o,missingLocales:d,missingRequiredLocales:d.filter(e=>(c??s).includes(e))}},a=t=>i(e(t));export{a as listMissingTranslations,i as listMissingTranslationsWithConfig};
|
|
47
2
|
//# sourceMappingURL=listMissingTranslations.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listMissingTranslations.mjs","names":[],"sources":["../../../src/test/listMissingTranslations.ts"],"sourcesContent":["import {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config';\nimport { getMissingLocalesContentFromDictionary } from '@intlayer/core';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type { Dictionary, IntlayerConfig, Locale } from '@intlayer/types';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\n\nexport const listMissingTranslationsWithConfig = (\n configuration: IntlayerConfig\n) => {\n const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);\n const mergedDictionaries = getDictionaries(configuration);\n\n const missingTranslations: {\n key: string;\n filePath?: string;\n id?: string;\n locales: Locale[];\n }[] = [];\n\n const { locales, requiredLocales } = configuration.internationalization;\n\n const dictionariesKeys = Object.keys(unmergedDictionariesRecord);\n\n for (const dictionaryKey of dictionariesKeys) {\n const dictionaries: Dictionary[] =\n unmergedDictionariesRecord[dictionaryKey];\n\n const multilingualDictionary: Dictionary[] = dictionaries.filter(\n (dictionary) => !dictionary.locale\n );\n\n // Test all by merging all dictionaries to ensure no per-locale dictionary is missing\n for (const dictionary of multilingualDictionary) {\n const missingLocales = getMissingLocalesContentFromDictionary(\n dictionary,\n locales\n );\n\n if (missingLocales.length > 0) {\n missingTranslations.push({\n key: dictionaryKey,\n id: dictionary.id,\n filePath: dictionary.filePath,\n locales: missingLocales,\n });\n }\n }\n\n const perLocaleDictionary: Dictionary[] = dictionaries.filter(\n (dictionary) => dictionary.locale\n );\n\n if (perLocaleDictionary.length === 0) {\n continue;\n }\n\n const mergedDictionary = mergedDictionaries[dictionaryKey];\n\n const missingLocales = getMissingLocalesContentFromDictionary(\n mergedDictionary,\n locales\n );\n\n if (missingLocales.length > 0) {\n missingTranslations.push({\n key: dictionaryKey,\n locales: missingLocales,\n });\n }\n }\n\n const missingLocalesSet = new Set(\n missingTranslations.flatMap((t) => t.locales)\n );\n const missingLocales = Array.from(missingLocalesSet);\n\n const missingRequiredLocales = missingLocales.filter((locale) =>\n (requiredLocales ?? locales).includes(locale)\n );\n\n return { missingTranslations, missingLocales, missingRequiredLocales };\n};\n\nexport const listMissingTranslations = (\n configurationOptions?: GetConfigurationOptions\n) => {\n const configuration = getConfiguration(configurationOptions);\n\n return listMissingTranslationsWithConfig(configuration);\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"listMissingTranslations.mjs","names":[],"sources":["../../../src/test/listMissingTranslations.ts"],"sourcesContent":["import {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { getMissingLocalesContentFromDictionary } from '@intlayer/core/plugins';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type { Dictionary, IntlayerConfig, Locale } from '@intlayer/types';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\n\nexport const listMissingTranslationsWithConfig = (\n configuration: IntlayerConfig\n) => {\n const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);\n const mergedDictionaries = getDictionaries(configuration);\n\n const missingTranslations: {\n key: string;\n filePath?: string;\n id?: string;\n locales: Locale[];\n }[] = [];\n\n const { locales, requiredLocales } = configuration.internationalization;\n\n const dictionariesKeys = Object.keys(unmergedDictionariesRecord);\n\n for (const dictionaryKey of dictionariesKeys) {\n const dictionaries: Dictionary[] =\n unmergedDictionariesRecord[dictionaryKey];\n\n const multilingualDictionary: Dictionary[] = dictionaries.filter(\n (dictionary) => !dictionary.locale\n );\n\n // Test all by merging all dictionaries to ensure no per-locale dictionary is missing\n for (const dictionary of multilingualDictionary) {\n const missingLocales = getMissingLocalesContentFromDictionary(\n dictionary,\n locales\n );\n\n if (missingLocales.length > 0) {\n missingTranslations.push({\n key: dictionaryKey,\n id: dictionary.id,\n filePath: dictionary.filePath,\n locales: missingLocales,\n });\n }\n }\n\n const perLocaleDictionary: Dictionary[] = dictionaries.filter(\n (dictionary) => dictionary.locale\n );\n\n if (perLocaleDictionary.length === 0) {\n continue;\n }\n\n const mergedDictionary = mergedDictionaries[dictionaryKey];\n\n const missingLocales = getMissingLocalesContentFromDictionary(\n mergedDictionary,\n locales\n );\n\n if (missingLocales.length > 0) {\n missingTranslations.push({\n key: dictionaryKey,\n locales: missingLocales,\n });\n }\n }\n\n const missingLocalesSet = new Set(\n missingTranslations.flatMap((t) => t.locales)\n );\n const missingLocales = Array.from(missingLocalesSet);\n\n const missingRequiredLocales = missingLocales.filter((locale) =>\n (requiredLocales ?? locales).includes(locale)\n );\n\n return { missingTranslations, missingLocales, missingRequiredLocales };\n};\n\nexport const listMissingTranslations = (\n configurationOptions?: GetConfigurationOptions\n) => {\n const configuration = getConfiguration(configurationOptions);\n\n return listMissingTranslationsWithConfig(configuration);\n};\n"],"mappings":"wRASA,MAAa,EACX,GACG,CACH,IAAM,EAA6B,EAAwB,EAAc,CACnE,EAAqB,EAAgB,EAAc,CAEnD,EAKA,EAAE,CAEF,CAAE,UAAS,mBAAoB,EAAc,qBAE7C,EAAmB,OAAO,KAAK,EAA2B,CAEhE,IAAK,IAAM,KAAiB,EAAkB,CAC5C,IAAM,EACJ,EAA2B,GAEvB,EAAuC,EAAa,OACvD,GAAe,CAAC,EAAW,OAC7B,CAGD,IAAK,IAAM,KAAc,EAAwB,CAC/C,IAAM,EAAiB,EACrB,EACA,EACD,CAEG,EAAe,OAAS,GAC1B,EAAoB,KAAK,CACvB,IAAK,EACL,GAAI,EAAW,GACf,SAAU,EAAW,SACrB,QAAS,EACV,CAAC,CAQN,GAJ0C,EAAa,OACpD,GAAe,EAAW,OAC5B,CAEuB,SAAW,EACjC,SAGF,IAAM,EAAmB,EAAmB,GAEtC,EAAiB,EACrB,EACA,EACD,CAEG,EAAe,OAAS,GAC1B,EAAoB,KAAK,CACvB,IAAK,EACL,QAAS,EACV,CAAC,CAIN,IAAM,EAAoB,IAAI,IAC5B,EAAoB,QAAS,GAAM,EAAE,QAAQ,CAC9C,CACK,EAAiB,MAAM,KAAK,EAAkB,CAMpD,MAAO,CAAE,sBAAqB,iBAAgB,uBAJf,EAAe,OAAQ,IACnD,GAAmB,GAAS,SAAS,EAAO,CAC9C,CAEqE,EAG3D,EACX,GAIO,EAFe,EAAiB,EAAqB,CAEL"}
|
package/dist/esm/test/test.mjs
CHANGED
|
@@ -1,52 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { ANSIColors, colon, colorize, colorizeKey, colorizeNumber, getAppLogger, getConfiguration } from "@intlayer/config";
|
|
3
|
-
import { prepareIntlayer } from "@intlayer/chokidar/build";
|
|
4
|
-
import { formatLocale, formatPath } from "@intlayer/chokidar/utils";
|
|
5
|
-
|
|
6
|
-
//#region src/test/test.ts
|
|
7
|
-
const testMissingTranslations = async (options) => {
|
|
8
|
-
const config = getConfiguration(options?.configOptions);
|
|
9
|
-
const { locales, requiredLocales } = config.internationalization;
|
|
10
|
-
const appLogger = getAppLogger(config);
|
|
11
|
-
if (options?.build === true) await prepareIntlayer(config, { forceRun: true });
|
|
12
|
-
else if (typeof options?.build === "undefined") await prepareIntlayer(config);
|
|
13
|
-
const result = listMissingTranslations(options?.configOptions);
|
|
14
|
-
const maxKeyColSize = result.missingTranslations.map((t) => ` - ${t.key}`).reduce((max, t) => Math.max(max, t.length), 0);
|
|
15
|
-
const maxLocalesColSize = result.missingTranslations.map((t) => formatLocale(t.locales, false)).reduce((max, t) => Math.max(max, t.length), 0);
|
|
16
|
-
const formattedMissingTranslations = result.missingTranslations.map((translation) => [
|
|
17
|
-
colon(` - ${colorizeKey(translation.key)}`, {
|
|
18
|
-
colSize: maxKeyColSize,
|
|
19
|
-
maxSize: 40
|
|
20
|
-
}),
|
|
21
|
-
" - ",
|
|
22
|
-
colon(formatLocale(translation.locales, ANSIColors.RED), {
|
|
23
|
-
colSize: maxLocalesColSize,
|
|
24
|
-
maxSize: 40
|
|
25
|
-
}),
|
|
26
|
-
translation.filePath ? ` - ${formatPath(translation.filePath)}` : "",
|
|
27
|
-
translation.id ? " - remote" : ""
|
|
28
|
-
].join(""));
|
|
29
|
-
appLogger(`Missing translations:`, { level: "info" });
|
|
30
|
-
formattedMissingTranslations.forEach((t) => {
|
|
31
|
-
appLogger(t, { level: "info" });
|
|
32
|
-
});
|
|
33
|
-
appLogger(`Locales: ${formatLocale(locales)}`);
|
|
34
|
-
appLogger(`Required locales: ${formatLocale(requiredLocales ?? locales)}`);
|
|
35
|
-
appLogger(`Missing locales: ${result.missingLocales.length === 0 ? colorize("-", ANSIColors.GREEN) : formatLocale(result.missingLocales, ANSIColors.RED)}`);
|
|
36
|
-
appLogger(`Missing required locales: ${result.missingRequiredLocales.length === 0 ? colorize("-", ANSIColors.GREEN) : formatLocale(result.missingRequiredLocales, ANSIColors.RED)}`);
|
|
37
|
-
appLogger(`Total missing locales: ${colorizeNumber(result.missingLocales.length, {
|
|
38
|
-
one: ANSIColors.RED,
|
|
39
|
-
other: ANSIColors.RED,
|
|
40
|
-
zero: ANSIColors.GREEN
|
|
41
|
-
})}`);
|
|
42
|
-
appLogger(`Total missing required locales: ${colorizeNumber(result.missingRequiredLocales.length, {
|
|
43
|
-
one: ANSIColors.RED,
|
|
44
|
-
other: ANSIColors.RED,
|
|
45
|
-
zero: ANSIColors.GREEN
|
|
46
|
-
})}`);
|
|
47
|
-
if (result.missingRequiredLocales.length > 0) process.exit(1);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
//#endregion
|
|
51
|
-
export { testMissingTranslations };
|
|
1
|
+
import{listMissingTranslations as e}from"./listMissingTranslations.mjs";import{formatLocale as t,formatPath as n}from"@intlayer/chokidar/utils";import{getConfiguration as r}from"@intlayer/config/node";import{ANSIColors as i,colon as a,colorize as o,colorizeKey as s,colorizeNumber as c,getAppLogger as l}from"@intlayer/config/logger";import{prepareIntlayer as u}from"@intlayer/chokidar/build";const d=async d=>{let f=r(d?.configOptions),{locales:p,requiredLocales:m}=f.internationalization,h=l(f);d?.build===!0?await u(f,{forceRun:!0}):d?.build===void 0&&await u(f);let g=e(d?.configOptions),_=g.missingTranslations.map(e=>` - ${e.key}`).reduce((e,t)=>Math.max(e,t.length),0),v=g.missingTranslations.map(e=>t(e.locales,!1)).reduce((e,t)=>Math.max(e,t.length),0),y=g.missingTranslations.map(e=>[a(` - ${s(e.key)}`,{colSize:_,maxSize:40}),` - `,a(t(e.locales,i.RED),{colSize:v,maxSize:40}),e.filePath?` - ${n(e.filePath)}`:``,e.id?` - remote`:``].join(``));h(`Missing translations:`,{level:`info`}),y.forEach(e=>{h(e,{level:`info`})}),h(`Locales: ${t(p)}`),h(`Required locales: ${t(m??p)}`),h(`Missing locales: ${g.missingLocales.length===0?o(`-`,i.GREEN):t(g.missingLocales,i.RED)}`),h(`Missing required locales: ${g.missingRequiredLocales.length===0?o(`-`,i.GREEN):t(g.missingRequiredLocales,i.RED)}`),h(`Total missing locales: ${c(g.missingLocales.length,{one:i.RED,other:i.RED,zero:i.GREEN})}`),h(`Total missing required locales: ${c(g.missingRequiredLocales.length,{one:i.RED,other:i.RED,zero:i.GREEN})}`),g.missingRequiredLocales.length>0&&process.exit(1)};export{d as testMissingTranslations};
|
|
52
2
|
//# sourceMappingURL=test.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.mjs","names":[],"sources":["../../../src/test/test.ts"],"sourcesContent":["import { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { formatLocale, formatPath } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colon,\n colorize,\n colorizeKey,\n colorizeNumber,\n type GetConfigurationOptions,\n
|
|
1
|
+
{"version":3,"file":"test.mjs","names":[],"sources":["../../../src/test/test.ts"],"sourcesContent":["import { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { formatLocale, formatPath } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colon,\n colorize,\n colorizeKey,\n colorizeNumber,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { listMissingTranslations } from './listMissingTranslations';\n\ntype ListMissingTranslationsOptions = {\n configOptions?: GetConfigurationOptions;\n build?: boolean;\n};\n\nexport const testMissingTranslations = async (\n options?: ListMissingTranslationsOptions\n) => {\n const config = getConfiguration(options?.configOptions);\n const { locales, requiredLocales } = config.internationalization;\n\n const appLogger = getAppLogger(config);\n\n if (options?.build === true) {\n await prepareIntlayer(config, { forceRun: true });\n } else if (typeof options?.build === 'undefined') {\n await prepareIntlayer(config);\n }\n\n const result = listMissingTranslations(options?.configOptions);\n\n const maxKeyColSize = result.missingTranslations\n .map((t) => ` - ${t.key}`)\n .reduce((max, t) => Math.max(max, t.length), 0);\n const maxLocalesColSize = result.missingTranslations\n .map((t) => formatLocale(t.locales, false))\n .reduce((max, t) => Math.max(max, t.length), 0);\n\n const formattedMissingTranslations = result.missingTranslations.map(\n (translation) =>\n [\n colon(` - ${colorizeKey(translation.key)}`, {\n colSize: maxKeyColSize,\n maxSize: 40,\n }),\n ' - ',\n colon(formatLocale(translation.locales, ANSIColors.RED), {\n colSize: maxLocalesColSize,\n maxSize: 40,\n }),\n\n translation.filePath ? ` - ${formatPath(translation.filePath)}` : '',\n translation.id ? ' - remote' : '',\n ].join('')\n );\n\n appLogger(`Missing translations:`, {\n level: 'info',\n });\n\n formattedMissingTranslations.forEach((t) => {\n appLogger(t, {\n level: 'info',\n });\n });\n\n appLogger(`Locales: ${formatLocale(locales)}`);\n appLogger(`Required locales: ${formatLocale(requiredLocales ?? locales)}`);\n appLogger(\n `Missing locales: ${result.missingLocales.length === 0 ? colorize('-', ANSIColors.GREEN) : formatLocale(result.missingLocales, ANSIColors.RED)}`\n );\n\n appLogger(\n `Missing required locales: ${result.missingRequiredLocales.length === 0 ? colorize('-', ANSIColors.GREEN) : formatLocale(result.missingRequiredLocales, ANSIColors.RED)}`\n );\n appLogger(\n `Total missing locales: ${colorizeNumber(result.missingLocales.length, {\n one: ANSIColors.RED,\n other: ANSIColors.RED,\n zero: ANSIColors.GREEN,\n })}`\n );\n appLogger(\n `Total missing required locales: ${colorizeNumber(\n result.missingRequiredLocales.length,\n {\n one: ANSIColors.RED,\n other: ANSIColors.RED,\n zero: ANSIColors.GREEN,\n }\n )}`\n );\n\n if (result.missingRequiredLocales.length > 0) {\n process.exit(1);\n }\n};\n"],"mappings":"yYAqBA,MAAa,EAA0B,KACrC,IACG,CACH,IAAM,EAAS,EAAiB,GAAS,cAAc,CACjD,CAAE,UAAS,mBAAoB,EAAO,qBAEtC,EAAY,EAAa,EAAO,CAElC,GAAS,QAAU,GACrB,MAAM,EAAgB,EAAQ,CAAE,SAAU,GAAM,CAAC,CACjC,GAAS,QAAU,QACnC,MAAM,EAAgB,EAAO,CAG/B,IAAM,EAAS,EAAwB,GAAS,cAAc,CAExD,EAAgB,EAAO,oBAC1B,IAAK,GAAM,MAAM,EAAE,MAAM,CACzB,QAAQ,EAAK,IAAM,KAAK,IAAI,EAAK,EAAE,OAAO,CAAE,EAAE,CAC3C,EAAoB,EAAO,oBAC9B,IAAK,GAAM,EAAa,EAAE,QAAS,GAAM,CAAC,CAC1C,QAAQ,EAAK,IAAM,KAAK,IAAI,EAAK,EAAE,OAAO,CAAE,EAAE,CAE3C,EAA+B,EAAO,oBAAoB,IAC7D,GACC,CACE,EAAM,MAAM,EAAY,EAAY,IAAI,GAAI,CAC1C,QAAS,EACT,QAAS,GACV,CAAC,CACF,MACA,EAAM,EAAa,EAAY,QAAS,EAAW,IAAI,CAAE,CACvD,QAAS,EACT,QAAS,GACV,CAAC,CAEF,EAAY,SAAW,MAAM,EAAW,EAAY,SAAS,GAAK,GAClE,EAAY,GAAK,YAAc,GAChC,CAAC,KAAK,GAAG,CACb,CAED,EAAU,wBAAyB,CACjC,MAAO,OACR,CAAC,CAEF,EAA6B,QAAS,GAAM,CAC1C,EAAU,EAAG,CACX,MAAO,OACR,CAAC,EACF,CAEF,EAAU,YAAY,EAAa,EAAQ,GAAG,CAC9C,EAAU,qBAAqB,EAAa,GAAmB,EAAQ,GAAG,CAC1E,EACE,oBAAoB,EAAO,eAAe,SAAW,EAAI,EAAS,IAAK,EAAW,MAAM,CAAG,EAAa,EAAO,eAAgB,EAAW,IAAI,GAC/I,CAED,EACE,6BAA6B,EAAO,uBAAuB,SAAW,EAAI,EAAS,IAAK,EAAW,MAAM,CAAG,EAAa,EAAO,uBAAwB,EAAW,IAAI,GACxK,CACD,EACE,0BAA0B,EAAe,EAAO,eAAe,OAAQ,CACrE,IAAK,EAAW,IAChB,MAAO,EAAW,IAClB,KAAM,EAAW,MAClB,CAAC,GACH,CACD,EACE,mCAAmC,EACjC,EAAO,uBAAuB,OAC9B,CACE,IAAK,EAAW,IAChB,MAAO,EAAW,IAClB,KAAM,EAAW,MAClB,CACF,GACF,CAEG,EAAO,uBAAuB,OAAS,GACzC,QAAQ,KAAK,EAAE"}
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { translateFile } from "./translateFile.mjs";
|
|
3
|
-
import { translateDoc } from "./translateDoc.mjs";
|
|
4
|
-
|
|
5
|
-
export { sanitizeChunk, translateDoc, translateFile, validateTranslation };
|
|
1
|
+
import{sanitizeChunk as e,validateTranslation as t}from"./validation.mjs";import{translateFile as n}from"./translateFile.mjs";import{translateDoc as r}from"./translateDoc.mjs";export{e as sanitizeChunk,r as translateDoc,n as translateFile,t as validateTranslation};
|
|
@@ -1,72 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { checkFileModifiedRange } from "../utils/checkFileModifiedRange.mjs";
|
|
3
|
-
import { getOutputFilePath } from "../utils/getOutputFilePath.mjs";
|
|
4
|
-
import { translateFile } from "./translateFile.mjs";
|
|
5
|
-
import { listGitFiles, pLimit, parallelize } from "@intlayer/chokidar";
|
|
6
|
-
import { ANSIColors, colorize, colorizeNumber, getAppLogger, getConfiguration } from "@intlayer/config";
|
|
7
|
-
import { dirname, join } from "node:path";
|
|
8
|
-
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
9
|
-
import fg from "fast-glob";
|
|
10
|
-
import { performance } from "node:perf_hooks";
|
|
11
|
-
|
|
12
|
-
//#region src/translateDoc/translateDoc.ts
|
|
13
|
-
const translateDoc = async ({ docPattern, locales, excludedGlobPattern, baseLocale, aiOptions, nbSimultaneousFileProcessed = 20, configOptions, customInstructions, skipIfModifiedBefore, skipIfModifiedAfter, skipIfExists, gitOptions, flushStrategy = "incremental" }) => {
|
|
14
|
-
const configuration = getConfiguration(configOptions);
|
|
15
|
-
const appLogger = getAppLogger(configuration);
|
|
16
|
-
const maxConcurrentChunks = nbSimultaneousFileProcessed;
|
|
17
|
-
const globalChunkLimiter = pLimit(maxConcurrentChunks);
|
|
18
|
-
let docList = await fg(docPattern, { ignore: excludedGlobPattern });
|
|
19
|
-
const aiResult = await setupAI(configuration, aiOptions);
|
|
20
|
-
if (!aiResult?.hasAIAccess) return;
|
|
21
|
-
const { aiClient, aiConfig } = aiResult;
|
|
22
|
-
if (gitOptions) {
|
|
23
|
-
const gitChangedFiles = await listGitFiles(gitOptions);
|
|
24
|
-
if (gitChangedFiles) docList = docList.filter((path) => gitChangedFiles.some((gitFile) => join(process.cwd(), path) === gitFile));
|
|
25
|
-
}
|
|
26
|
-
const batchStartTime = performance.now();
|
|
27
|
-
appLogger(`Translating ${colorizeNumber(docList.length)} files to ${colorizeNumber(locales.length)} locales. \nGlobal Concurrency: ${colorizeNumber(maxConcurrentChunks)} chunks in parallel.`);
|
|
28
|
-
const errorState = {
|
|
29
|
-
count: 0,
|
|
30
|
-
maxErrors: 5,
|
|
31
|
-
shouldStop: false
|
|
32
|
-
};
|
|
33
|
-
await parallelize(docList.flatMap((docPath) => locales.map((locale) => async () => {
|
|
34
|
-
if (errorState.shouldStop) return;
|
|
35
|
-
const absoluteBaseFilePath = join(configuration.content.baseDir, docPath);
|
|
36
|
-
const outputFilePath = getOutputFilePath(absoluteBaseFilePath, locale, baseLocale);
|
|
37
|
-
if (skipIfExists && existsSync(outputFilePath)) return;
|
|
38
|
-
if (flushStrategy === "incremental" && !existsSync(outputFilePath)) {
|
|
39
|
-
mkdirSync(dirname(outputFilePath), { recursive: true });
|
|
40
|
-
writeFileSync(outputFilePath, "");
|
|
41
|
-
}
|
|
42
|
-
const fileModificationData = checkFileModifiedRange(outputFilePath, {
|
|
43
|
-
skipIfModifiedBefore,
|
|
44
|
-
skipIfModifiedAfter
|
|
45
|
-
});
|
|
46
|
-
if (fileModificationData.isSkipped) {
|
|
47
|
-
appLogger(fileModificationData.message);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
await translateFile({
|
|
51
|
-
baseFilePath: absoluteBaseFilePath,
|
|
52
|
-
outputFilePath,
|
|
53
|
-
locale,
|
|
54
|
-
baseLocale,
|
|
55
|
-
configuration,
|
|
56
|
-
errorState,
|
|
57
|
-
aiOptions,
|
|
58
|
-
customInstructions,
|
|
59
|
-
aiClient,
|
|
60
|
-
aiConfig,
|
|
61
|
-
flushStrategy,
|
|
62
|
-
limit: globalChunkLimiter
|
|
63
|
-
});
|
|
64
|
-
})), (task) => task(), 50);
|
|
65
|
-
const batchDuration = ((performance.now() - batchStartTime) / 1e3).toFixed(2);
|
|
66
|
-
if (errorState.count > 0) appLogger(`Finished with ${errorState.count} errors in ${batchDuration}s.`);
|
|
67
|
-
else appLogger(`${colorize("✔", ANSIColors.GREEN)} Batch completed successfully in ${colorizeNumber(batchDuration)}s.`);
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
//#endregion
|
|
71
|
-
export { translateDoc };
|
|
1
|
+
import{setupAI as e}from"../utils/setupAI.mjs";import{checkFileModifiedRange as t}from"../utils/checkFileModifiedRange.mjs";import{getOutputFilePath as n}from"../utils/getOutputFilePath.mjs";import{translateFile as r}from"./translateFile.mjs";import{pLimit as i,parallelize as a}from"@intlayer/chokidar/utils";import{getConfiguration as o}from"@intlayer/config/node";import{dirname as s,join as c}from"node:path";import{listGitFiles as l}from"@intlayer/chokidar/cli";import{ANSIColors as u,colorize as d,colorizeNumber as f,getAppLogger as p}from"@intlayer/config/logger";import{existsSync as m,mkdirSync as h,writeFileSync as g}from"node:fs";import _ from"fast-glob";import{performance as v}from"node:perf_hooks";const y=async({docPattern:y,locales:b,excludedGlobPattern:x,baseLocale:S,aiOptions:C,nbSimultaneousFileProcessed:w=20,configOptions:T,customInstructions:E,skipIfModifiedBefore:D,skipIfModifiedAfter:O,skipIfExists:k,gitOptions:A,flushStrategy:j=`incremental`})=>{let M=o(T),N=p(M),P=w,F=i(P),I=await _(y,{ignore:x}),L=await e(M,C);if(!L?.hasAIAccess)return;let{aiClient:R,aiConfig:z}=L;if(A){let e=await l(A);e&&(I=I.filter(t=>e.some(e=>c(process.cwd(),t)===e)))}let B=v.now();N(`Translating ${f(I.length)} files to ${f(b.length)} locales. \nGlobal Concurrency: ${f(P)} chunks in parallel.`);let V={count:0,maxErrors:5,shouldStop:!1};await a(I.flatMap(e=>b.map(i=>async()=>{if(V.shouldStop)return;let a=c(M.content.baseDir,e),o=n(a,i,S);if(k&&m(o))return;j===`incremental`&&!m(o)&&(h(s(o),{recursive:!0}),g(o,``));let l=t(o,{skipIfModifiedBefore:D,skipIfModifiedAfter:O});if(l.isSkipped){N(l.message);return}await r({baseFilePath:a,outputFilePath:o,locale:i,baseLocale:S,configuration:M,errorState:V,aiOptions:C,customInstructions:E,aiClient:R,aiConfig:z,flushStrategy:j,limit:F})})),e=>e(),50);let H=((v.now()-B)/1e3).toFixed(2);V.count>0?N(`Finished with ${V.count} errors in ${H}s.`):N(`${d(`✔`,u.GREEN)} Batch completed successfully in ${f(H)}s.`)};export{y as translateDoc};
|
|
72
2
|
//# sourceMappingURL=translateDoc.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translateDoc.mjs","names":[],"sources":["../../../src/translateDoc/translateDoc.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { performance } from 'node:perf_hooks';\nimport { listGitFiles
|
|
1
|
+
{"version":3,"file":"translateDoc.mjs","names":[],"sources":["../../../src/translateDoc/translateDoc.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { performance } from 'node:perf_hooks';\nimport { listGitFiles } from '@intlayer/chokidar/cli';\nimport { parallelize, pLimit } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizeNumber,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport type { Locale } from '@intlayer/types';\nimport fg from 'fast-glob';\nimport { checkFileModifiedRange } from '../utils/checkFileModifiedRange';\nimport { getOutputFilePath } from '../utils/getOutputFilePath';\nimport { setupAI } from '../utils/setupAI';\nimport { translateFile } from './translateFile';\nimport type { ErrorState, TranslateDocOptions } from './types';\n\nexport const translateDoc = async ({\n docPattern,\n locales,\n excludedGlobPattern,\n baseLocale,\n aiOptions,\n nbSimultaneousFileProcessed = 20, // Default to a higher concurrency for chunks\n configOptions,\n customInstructions,\n skipIfModifiedBefore,\n skipIfModifiedAfter,\n skipIfExists,\n gitOptions,\n flushStrategy = 'incremental',\n}: TranslateDocOptions) => {\n const configuration = getConfiguration(configOptions);\n const appLogger = getAppLogger(configuration);\n\n // 1. GLOBAL QUEUE SETUP\n // We use pLimit to create a single bottleneck for AI requests.\n // This queue is shared across all files and locales.\n const maxConcurrentChunks = nbSimultaneousFileProcessed;\n const globalChunkLimiter = pLimit(maxConcurrentChunks);\n\n let docList: string[] = await fg(docPattern, {\n ignore: excludedGlobPattern,\n });\n\n const aiResult = await setupAI(configuration, aiOptions);\n if (!aiResult?.hasAIAccess) return;\n const { aiClient, aiConfig } = aiResult;\n\n if (gitOptions) {\n const gitChangedFiles = await listGitFiles(gitOptions);\n if (gitChangedFiles) {\n docList = docList.filter((path) =>\n gitChangedFiles.some((gitFile) => join(process.cwd(), path) === gitFile)\n );\n }\n }\n\n const batchStartTime = performance.now();\n\n appLogger(\n `Translating ${colorizeNumber(docList.length)} files to ${colorizeNumber(locales.length)} locales. \\n` +\n `Global Concurrency: ${colorizeNumber(maxConcurrentChunks)} chunks in parallel.`\n );\n\n const errorState: ErrorState = {\n count: 0,\n maxErrors: 5,\n shouldStop: false,\n };\n\n // 2. FLATTENED TASK LIST\n // We create a task for every File x Locale combination.\n const allTasks = docList.flatMap((docPath) =>\n locales.map((locale) => async () => {\n if (errorState.shouldStop) return;\n\n const absoluteBaseFilePath = join(configuration.content.baseDir, docPath);\n const outputFilePath = getOutputFilePath(\n absoluteBaseFilePath,\n locale,\n baseLocale\n );\n\n // Skip logic\n if (skipIfExists && existsSync(outputFilePath)) return;\n\n if (flushStrategy === 'incremental' && !existsSync(outputFilePath)) {\n mkdirSync(dirname(outputFilePath), { recursive: true });\n writeFileSync(outputFilePath, '');\n }\n\n const fileModificationData = checkFileModifiedRange(outputFilePath, {\n skipIfModifiedBefore,\n skipIfModifiedAfter,\n });\n\n if (fileModificationData.isSkipped) {\n appLogger(fileModificationData.message);\n return;\n }\n\n // Execute translation using the SHARED limiter\n await translateFile({\n baseFilePath: absoluteBaseFilePath,\n outputFilePath,\n locale: locale as Locale,\n baseLocale,\n configuration,\n errorState,\n aiOptions,\n customInstructions,\n aiClient,\n aiConfig,\n flushStrategy,\n limit: globalChunkLimiter, // Pass the global queue\n });\n })\n );\n\n // 3. HIGH-THROUGHPUT FILE OPENER\n // We open many files simultaneously (e.g., 50) to ensure the global chunk queue\n // is always saturated with work.\n // If we open too few files, the chunk queue might drain faster than we can read new files.\n const FILE_OPEN_LIMIT = 50;\n\n await parallelize(allTasks, (task) => task(), FILE_OPEN_LIMIT);\n\n const batchEndTime = performance.now();\n const batchDuration = ((batchEndTime - batchStartTime) / 1000).toFixed(2);\n\n if (errorState.count > 0) {\n appLogger(`Finished with ${errorState.count} errors in ${batchDuration}s.`);\n } else {\n appLogger(\n `${colorize('✔', ANSIColors.GREEN)} Batch completed successfully in ${colorizeNumber(batchDuration)}s.`\n );\n }\n};\n"],"mappings":"0sBAoBA,MAAa,EAAe,MAAO,CACjC,aACA,UACA,sBACA,aACA,YACA,8BAA8B,GAC9B,gBACA,qBACA,uBACA,sBACA,eACA,aACA,gBAAgB,iBACS,CACzB,IAAM,EAAgB,EAAiB,EAAc,CAC/C,EAAY,EAAa,EAAc,CAKvC,EAAsB,EACtB,EAAqB,EAAO,EAAoB,CAElD,EAAoB,MAAM,EAAG,EAAY,CAC3C,OAAQ,EACT,CAAC,CAEI,EAAW,MAAM,EAAQ,EAAe,EAAU,CACxD,GAAI,CAAC,GAAU,YAAa,OAC5B,GAAM,CAAE,WAAU,YAAa,EAE/B,GAAI,EAAY,CACd,IAAM,EAAkB,MAAM,EAAa,EAAW,CAClD,IACF,EAAU,EAAQ,OAAQ,GACxB,EAAgB,KAAM,GAAY,EAAK,QAAQ,KAAK,CAAE,EAAK,GAAK,EAAQ,CACzE,EAIL,IAAM,EAAiB,EAAY,KAAK,CAExC,EACE,eAAe,EAAe,EAAQ,OAAO,CAAC,YAAY,EAAe,EAAQ,OAAO,CAAC,kCAChE,EAAe,EAAoB,CAAC,sBAC9D,CAED,IAAM,EAAyB,CAC7B,MAAO,EACP,UAAW,EACX,WAAY,GACb,CAyDD,MAAM,EArDW,EAAQ,QAAS,GAChC,EAAQ,IAAK,GAAW,SAAY,CAClC,GAAI,EAAW,WAAY,OAE3B,IAAM,EAAuB,EAAK,EAAc,QAAQ,QAAS,EAAQ,CACnE,EAAiB,EACrB,EACA,EACA,EACD,CAGD,GAAI,GAAgB,EAAW,EAAe,CAAE,OAE5C,IAAkB,eAAiB,CAAC,EAAW,EAAe,GAChE,EAAU,EAAQ,EAAe,CAAE,CAAE,UAAW,GAAM,CAAC,CACvD,EAAc,EAAgB,GAAG,EAGnC,IAAM,EAAuB,EAAuB,EAAgB,CAClE,uBACA,sBACD,CAAC,CAEF,GAAI,EAAqB,UAAW,CAClC,EAAU,EAAqB,QAAQ,CACvC,OAIF,MAAM,EAAc,CAClB,aAAc,EACd,iBACQ,SACR,aACA,gBACA,aACA,YACA,qBACA,WACA,WACA,gBACA,MAAO,EACR,CAAC,EACF,CACH,CAQ4B,GAAS,GAAM,CAFpB,GAEsC,CAG9D,IAAM,IADe,EAAY,KAAK,CACC,GAAkB,KAAM,QAAQ,EAAE,CAErE,EAAW,MAAQ,EACrB,EAAU,iBAAiB,EAAW,MAAM,aAAa,EAAc,IAAI,CAE3E,EACE,GAAG,EAAS,IAAK,EAAW,MAAM,CAAC,mCAAmC,EAAe,EAAc,CAAC,IACrG"}
|