@intlayer/cli 7.5.11 → 7.5.12

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.
Files changed (71) hide show
  1. package/dist/cjs/cli.cjs +4 -4
  2. package/dist/cjs/cli.cjs.map +1 -1
  3. package/dist/cjs/index.cjs +4 -5
  4. package/dist/cjs/{reviewDoc.cjs → reviewDoc/reviewDoc.cjs} +17 -15
  5. package/dist/cjs/reviewDoc/reviewDoc.cjs.map +1 -0
  6. package/dist/cjs/{reviewDocBlockAware.cjs → reviewDoc/reviewDocBlockAware.cjs} +12 -8
  7. package/dist/cjs/reviewDoc/reviewDocBlockAware.cjs.map +1 -0
  8. package/dist/cjs/translateDoc/index.cjs +8 -0
  9. package/dist/cjs/translateDoc/translateDoc.cjs +74 -0
  10. package/dist/cjs/translateDoc/translateDoc.cjs.map +1 -0
  11. package/dist/cjs/translateDoc/translateFile.cjs +103 -0
  12. package/dist/cjs/translateDoc/translateFile.cjs.map +1 -0
  13. package/dist/cjs/translateDoc/types.cjs +0 -0
  14. package/dist/cjs/translateDoc/validation.cjs +49 -0
  15. package/dist/cjs/translateDoc/validation.cjs.map +1 -0
  16. package/dist/cjs/translation-alignment/planActions.cjs +2 -4
  17. package/dist/cjs/translation-alignment/planActions.cjs.map +1 -1
  18. package/dist/cjs/translation-alignment/segmentDocument.cjs +35 -101
  19. package/dist/cjs/translation-alignment/segmentDocument.cjs.map +1 -1
  20. package/dist/esm/cli.mjs +2 -2
  21. package/dist/esm/cli.mjs.map +1 -1
  22. package/dist/esm/index.mjs +3 -3
  23. package/dist/esm/{reviewDoc.mjs → reviewDoc/reviewDoc.mjs} +14 -12
  24. package/dist/esm/reviewDoc/reviewDoc.mjs.map +1 -0
  25. package/dist/esm/{reviewDocBlockAware.mjs → reviewDoc/reviewDocBlockAware.mjs} +11 -7
  26. package/dist/esm/reviewDoc/reviewDocBlockAware.mjs.map +1 -0
  27. package/dist/esm/translateDoc/index.mjs +5 -0
  28. package/dist/esm/translateDoc/translateDoc.mjs +72 -0
  29. package/dist/esm/translateDoc/translateDoc.mjs.map +1 -0
  30. package/dist/esm/translateDoc/translateFile.mjs +102 -0
  31. package/dist/esm/translateDoc/translateFile.mjs.map +1 -0
  32. package/dist/esm/translateDoc/types.mjs +0 -0
  33. package/dist/esm/translateDoc/validation.mjs +47 -0
  34. package/dist/esm/translateDoc/validation.mjs.map +1 -0
  35. package/dist/esm/translation-alignment/planActions.mjs +2 -4
  36. package/dist/esm/translation-alignment/planActions.mjs.map +1 -1
  37. package/dist/esm/translation-alignment/segmentDocument.mjs +35 -101
  38. package/dist/esm/translation-alignment/segmentDocument.mjs.map +1 -1
  39. package/dist/types/index.d.ts +3 -3
  40. package/dist/types/pull.d.ts.map +1 -1
  41. package/dist/types/pushConfig.d.ts.map +1 -1
  42. package/dist/types/{reviewDoc.d.ts → reviewDoc/reviewDoc.d.ts} +1 -1
  43. package/dist/types/reviewDoc/reviewDoc.d.ts.map +1 -0
  44. package/dist/types/{reviewDocBlockAware.d.ts → reviewDoc/reviewDocBlockAware.d.ts} +2 -2
  45. package/dist/types/reviewDoc/reviewDocBlockAware.d.ts.map +1 -0
  46. package/dist/types/translateDoc/index.d.ts +5 -0
  47. package/dist/types/translateDoc/translateDoc.d.ts +21 -0
  48. package/dist/types/translateDoc/translateDoc.d.ts.map +1 -0
  49. package/dist/types/translateDoc/translateFile.d.ts +21 -0
  50. package/dist/types/translateDoc/translateFile.d.ts.map +1 -0
  51. package/dist/types/translateDoc/types.d.ts +47 -0
  52. package/dist/types/translateDoc/types.d.ts.map +1 -0
  53. package/dist/types/translateDoc/validation.d.ts +16 -0
  54. package/dist/types/translateDoc/validation.d.ts.map +1 -0
  55. package/dist/types/translation-alignment/planActions.d.ts +2 -2
  56. package/dist/types/translation-alignment/planActions.d.ts.map +1 -1
  57. package/dist/types/translation-alignment/rebuildDocument.d.ts.map +1 -1
  58. package/dist/types/translation-alignment/segmentDocument.d.ts.map +1 -1
  59. package/package.json +11 -11
  60. package/dist/cjs/reviewDoc.cjs.map +0 -1
  61. package/dist/cjs/reviewDocBlockAware.cjs.map +0 -1
  62. package/dist/cjs/translateDoc.cjs +0 -163
  63. package/dist/cjs/translateDoc.cjs.map +0 -1
  64. package/dist/esm/reviewDoc.mjs.map +0 -1
  65. package/dist/esm/reviewDocBlockAware.mjs.map +0 -1
  66. package/dist/esm/translateDoc.mjs +0 -160
  67. package/dist/esm/translateDoc.mjs.map +0 -1
  68. package/dist/types/reviewDoc.d.ts.map +0 -1
  69. package/dist/types/reviewDocBlockAware.d.ts.map +0 -1
  70. package/dist/types/translateDoc.d.ts +0 -56
  71. package/dist/types/translateDoc.d.ts.map +0 -1
@@ -1,160 +0,0 @@
1
- import { setupAI } from "./utils/setupAI.mjs";
2
- import { readAsset } from "./_virtual/_utils_asset.mjs";
3
- import { chunkInference } from "./utils/chunkInference.mjs";
4
- import { fixChunkStartEndChars } from "./utils/fixChunkStartEndChars.mjs";
5
- import { checkFileModifiedRange } from "./utils/checkFileModifiedRange.mjs";
6
- import { getOutputFilePath } from "./utils/getOutputFilePath.mjs";
7
- import { chunkText } from "./utils/calculateChunks.mjs";
8
- import { formatLocale, formatPath, getChunk, listGitFiles, parallelize } from "@intlayer/chokidar";
9
- import { ANSIColors, colon, colorize, colorizeNumber, getAppLogger, getConfiguration, retryManager } from "@intlayer/config";
10
- import { dirname, join, relative } from "node:path";
11
- import { existsSync, mkdirSync, writeFileSync } from "node:fs";
12
- import { readFile } from "node:fs/promises";
13
- import fg from "fast-glob";
14
-
15
- //#region src/translateDoc.ts
16
- /**
17
- * Translate a single file for a given locale
18
- * Returns TRUE if successful, FALSE if failed/skipped
19
- */
20
- const translateFile = async (baseFilePath, outputFilePath, locale, baseLocale, configuration, errorState, aiOptions, customInstructions, aiClient, aiConfig) => {
21
- if (errorState.shouldStop) return false;
22
- const appLogger = getAppLogger(configuration, { config: { prefix: "" } });
23
- try {
24
- const fileContent = await readFile(baseFilePath, "utf-8");
25
- let fileResultContent = fileContent;
26
- const filePrefix = [colon(`${ANSIColors.GREY_DARK}[${formatPath(baseFilePath)}${ANSIColors.GREY_DARK}] `, { colSize: 40 }), `→ ${ANSIColors.RESET}`].join("");
27
- const prefix = [colon(`${ANSIColors.GREY_DARK}[${formatPath(baseFilePath)}${ANSIColors.GREY_DARK}][${formatLocale(locale)}${ANSIColors.GREY_DARK}] `, { colSize: 40 }), `→ ${ANSIColors.RESET}`].join("");
28
- const chunks = chunkText(fileContent);
29
- appLogger(`${filePrefix}Base file splitted into ${colorizeNumber(chunks.length)} chunks`);
30
- const translatedParts = [];
31
- const basePrompt = readAsset("./prompts/TRANSLATE_PROMPT.md", "utf-8").replaceAll("{{localeName}}", `${formatLocale(locale, false)}`).replaceAll("{{baseLocaleName}}", `${formatLocale(baseLocale, false)}`).replace("{{applicationContext}}", aiOptions?.applicationContext ?? "-").replace("{{customInstructions}}", customInstructions ?? "-");
32
- for await (const [i, chunk] of chunks.entries()) {
33
- if (errorState.shouldStop) return false;
34
- const isFirstChunk = i === 0;
35
- const fileToTranslateCurrentChunk = chunk.content;
36
- const getPrevChunkPrompt = () => `**CHUNK ${i} of ${chunks.length}** that has been translated in ${formatLocale(locale)}:\n///chunkStart///` + getChunk(translatedParts.join(""), chunks[i - 1]) + `///chunkEnd///`;
37
- const getBaseChunkContextPrompt = () => `**CHUNK ${i + 1} to ${Math.min(i + 3, chunks.length)} of ${chunks.length}** is the base chunk in ${formatLocale(baseLocale, false)} as reference.\n///chunksStart///` + (chunks[i - 1]?.content ?? "") + chunks[i].content + (chunks[i + 1]?.content ?? "") + `///chunksEnd///`;
38
- const chunkTranslation = await retryManager(async () => {
39
- const result = await chunkInference([
40
- {
41
- role: "system",
42
- content: basePrompt
43
- },
44
- {
45
- role: "system",
46
- content: getBaseChunkContextPrompt()
47
- },
48
- ...isFirstChunk ? [] : [{
49
- role: "system",
50
- content: getPrevChunkPrompt()
51
- }],
52
- {
53
- role: "system",
54
- content: `The next user message will be the **CHUNK ${colorizeNumber(i + 1)} of ${colorizeNumber(chunks.length)}** in ${formatLocale(baseLocale, false)} to translate in ${formatLocale(locale, false)}.\n
55
- STRICT INSTRUCTIONS:
56
- 1. Translate ONLY the content of this specific chunk.
57
- 2. Do NOT repeat the content from the previous chunk.
58
- 3. Start the translation exactly where the previous chunk ended.
59
- 4. Preserve all code blocks and formatting exactly.`
60
- },
61
- {
62
- role: "user",
63
- content: fileToTranslateCurrentChunk
64
- }
65
- ], aiOptions, configuration, aiClient, aiConfig);
66
- appLogger([
67
- `${prefix}`,
68
- `${ANSIColors.GREY_DARK}[Chunk `,
69
- colorizeNumber(i + 1),
70
- `${ANSIColors.GREY_DARK} of `,
71
- colorizeNumber(chunks.length),
72
- `${ANSIColors.GREY_DARK}] →${ANSIColors.RESET} `,
73
- `${colorizeNumber(result.tokenUsed)} tokens used`
74
- ].join(""));
75
- return fixChunkStartEndChars(result?.fileContent, fileToTranslateCurrentChunk);
76
- })();
77
- fileResultContent = fileResultContent.replace(fileToTranslateCurrentChunk, chunkTranslation);
78
- }
79
- const finalContent = translatedParts.join("");
80
- mkdirSync(dirname(outputFilePath), { recursive: true });
81
- writeFileSync(outputFilePath, finalContent);
82
- const relativePath = relative(configuration.content.baseDir, outputFilePath);
83
- appLogger(`${colorize("✔", ANSIColors.GREEN)} File ${formatPath(relativePath)} created/updated successfully.`);
84
- return true;
85
- } catch (error) {
86
- errorState.count++;
87
- const errorString = JSON.stringify(error);
88
- const errorMessage = error?.message ?? "";
89
- if (errorString.includes("AI_ACCESS_DENIED") || errorMessage.includes("Access keys") || errorMessage.includes("Access denied") || errorMessage.includes("Invalid Access keys")) {
90
- errorState.count = errorState.maxErrors + 1;
91
- appLogger(`${colorize("✖", ANSIColors.RED)} Critical Authentication Error. Aborting all tasks.`);
92
- }
93
- if (errorState.count >= errorState.maxErrors && !errorState.shouldStop) {
94
- errorState.shouldStop = true;
95
- appLogger(`${colorize("✖", ANSIColors.RED)} Too many errors (${errorState.count}). Stopping process.`);
96
- }
97
- return false;
98
- }
99
- };
100
- /**
101
- * Main translate function: scans all .md files in "en/" (unless you specified DOC_LIST),
102
- * then translates them to each locale in LOCALE_LIST.
103
- */
104
- const translateDoc = async ({ docPattern, locales, excludedGlobPattern, baseLocale, aiOptions, nbSimultaneousFileProcessed, configOptions, customInstructions, skipIfModifiedBefore, skipIfModifiedAfter, skipIfExists, gitOptions }) => {
105
- const configuration = getConfiguration(configOptions);
106
- const appLogger = getAppLogger(configuration);
107
- if (nbSimultaneousFileProcessed && nbSimultaneousFileProcessed > 10) {
108
- appLogger(`Warning: nbSimultaneousFileProcessed is set to ${nbSimultaneousFileProcessed}, which is greater than 10. Setting it to 10.`);
109
- nbSimultaneousFileProcessed = 10;
110
- }
111
- let docList = await fg(docPattern, { ignore: excludedGlobPattern });
112
- const aiResult = await setupAI(configuration, aiOptions);
113
- if (!aiResult?.hasAIAccess) return;
114
- const { aiClient, aiConfig } = aiResult;
115
- if (gitOptions) {
116
- const gitChangedFiles = await listGitFiles(gitOptions);
117
- if (gitChangedFiles) docList = docList.filter((path) => gitChangedFiles.some((gitFile) => join(process.cwd(), path) === gitFile));
118
- }
119
- appLogger(`Base locale is ${formatLocale(baseLocale)}`);
120
- appLogger(`Translating ${colorizeNumber(locales.length)} locales: [ ${formatLocale(locales)} ]`);
121
- appLogger(`Translating ${colorizeNumber(docList.length)} files:`);
122
- docList.forEach((path) => {
123
- appLogger(` - ${formatPath(path)}`);
124
- });
125
- const errorState = {
126
- count: 0,
127
- maxErrors: 5,
128
- shouldStop: false
129
- };
130
- await parallelize(docList.flatMap((docPath) => locales.map((locale) => async () => {
131
- if (errorState.shouldStop) return;
132
- appLogger(`Translating file: ${formatPath(docPath)} to ${formatLocale(locale)}`);
133
- const absoluteBaseFilePath = join(configuration.content.baseDir, docPath);
134
- const outputFilePath = getOutputFilePath(absoluteBaseFilePath, locale, baseLocale);
135
- if (skipIfExists && existsSync(outputFilePath)) {
136
- const relativePath = relative(configuration.content.baseDir, outputFilePath);
137
- appLogger(`${colorize("⊘", ANSIColors.YELLOW)} File ${formatPath(relativePath)} already exists, skipping.`);
138
- return;
139
- }
140
- if (!existsSync(outputFilePath)) {
141
- appLogger(`File ${formatPath(relative(configuration.content.baseDir, outputFilePath))} does not exist, creating it...`);
142
- mkdirSync(dirname(outputFilePath), { recursive: true });
143
- writeFileSync(outputFilePath, "");
144
- }
145
- const fileModificationData = checkFileModifiedRange(outputFilePath, {
146
- skipIfModifiedBefore,
147
- skipIfModifiedAfter
148
- });
149
- if (fileModificationData.isSkipped) {
150
- appLogger(fileModificationData.message);
151
- return;
152
- }
153
- await translateFile(absoluteBaseFilePath, outputFilePath, locale, baseLocale, configuration, errorState, aiOptions, customInstructions, aiClient, aiConfig);
154
- })), (task) => task(), nbSimultaneousFileProcessed ?? 3);
155
- if (errorState.count > 0) appLogger(`Process finished with ${colorizeNumber(errorState.count)} error${errorState.count === 1 ? "" : "s"}.`);
156
- };
157
-
158
- //#endregion
159
- export { translateDoc, translateFile };
160
- //# sourceMappingURL=translateDoc.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"translateDoc.mjs","names":["translatedParts: string[]","error: any","docList: string[]","errorState: ErrorState"],"sources":["../../src/translateDoc.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { readAsset } from 'utils:asset';\nimport type { AIConfig, AIOptions } from '@intlayer/ai';\nimport {\n formatLocale,\n formatPath,\n getChunk,\n type ListGitFilesOptions,\n listGitFiles,\n parallelize,\n} from '@intlayer/chokidar';\nimport {\n ANSIColors,\n colon,\n colorize,\n colorizeNumber,\n type GetConfigurationOptions,\n getAppLogger,\n getConfiguration,\n retryManager,\n} from '@intlayer/config';\nimport type { IntlayerConfig, Locale } from '@intlayer/types';\nimport fg from 'fast-glob';\nimport { chunkText } from './utils/calculateChunks';\nimport { checkFileModifiedRange } from './utils/checkFileModifiedRange';\nimport { chunkInference } from './utils/chunkInference';\nimport { fixChunkStartEndChars } from './utils/fixChunkStartEndChars';\nimport { getOutputFilePath } from './utils/getOutputFilePath';\nimport { type AIClient, setupAI } from './utils/setupAI';\n\n/**\n * Shared error state for circuit breaker pattern\n */\ntype ErrorState = {\n count: number;\n maxErrors: number;\n shouldStop: boolean;\n};\n\n/**\n * Translate a single file for a given locale\n * Returns TRUE if successful, FALSE if failed/skipped\n */\nexport const translateFile = async (\n baseFilePath: string,\n outputFilePath: string,\n locale: Locale,\n baseLocale: Locale,\n configuration: IntlayerConfig,\n errorState: ErrorState,\n aiOptions?: AIOptions,\n customInstructions?: string,\n aiClient?: AIClient,\n aiConfig?: AIConfig\n): Promise<boolean> => {\n // Circuit Breaker Check\n if (errorState.shouldStop) {\n return false;\n }\n\n const appLogger = getAppLogger(configuration, {\n config: {\n prefix: '',\n },\n });\n\n try {\n // Read File\n const fileContent = await readFile(baseFilePath, 'utf-8');\n\n let fileResultContent = fileContent;\n\n // Prepare formatting\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\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 // Chunking\n const chunks = chunkText(fileContent);\n appLogger(\n `${filePrefix}Base file splitted into ${colorizeNumber(chunks.length)} chunks`\n );\n\n // Instead of replacing content in a string, we push to an array\n const translatedParts: string[] = [];\n\n // Prepare Base Prompt\n const basePrompt = readAsset('./prompts/TRANSLATE_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 // Iterate and Translate\n for await (const [i, chunk] of chunks.entries()) {\n // Circuit Breaker Check inside the loop (in case error happened elsewhere while processing)\n if (errorState.shouldStop) return false;\n\n const isFirstChunk = i === 0;\n const fileToTranslateCurrentChunk = chunk.content;\n\n // Build the chunk-specific prompt\n const getPrevChunkPrompt = () =>\n `**CHUNK ${i} of ${chunks.length}** that has been translated in ${formatLocale(locale)}:\\n` +\n `///chunkStart///` +\n getChunk(translatedParts.join(''), chunks[i - 1]) +\n `///chunkEnd///`;\n\n const getBaseChunkContextPrompt = () =>\n `**CHUNK ${i + 1} to ${Math.min(i + 3, chunks.length)} of ${chunks.length}** is the base chunk in ${formatLocale(baseLocale, false)} as reference.\\n` +\n `///chunksStart///` +\n (chunks[i - 1]?.content ?? '') +\n chunks[i].content +\n (chunks[i + 1]?.content ?? '') +\n `///chunksEnd///`;\n\n // Make the actual translation call\n const chunkTranslation = await retryManager(async () => {\n const result = await chunkInference(\n [\n { role: 'system', content: basePrompt },\n { role: 'system', content: getBaseChunkContextPrompt() },\n ...(isFirstChunk\n ? []\n : [{ role: 'system', content: getPrevChunkPrompt() } as const]),\n {\n role: 'system',\n content: `The next user message will be the **CHUNK ${colorizeNumber(i + 1)} of ${colorizeNumber(chunks.length)}** in ${formatLocale(baseLocale, false)} to translate in ${formatLocale(locale, false)}.\\n\n STRICT INSTRUCTIONS:\n 1. Translate ONLY the content of this specific chunk. \n 2. Do NOT repeat the content from the previous chunk.\n 3. Start the translation exactly where the previous chunk ended.\n 4. Preserve all code blocks and formatting exactly.`,\n },\n { role: 'user', content: fileToTranslateCurrentChunk },\n ],\n aiOptions,\n configuration,\n aiClient,\n aiConfig\n );\n\n appLogger(\n [\n `${prefix}`,\n `${ANSIColors.GREY_DARK}[Chunk `,\n colorizeNumber(i + 1),\n `${ANSIColors.GREY_DARK} of `,\n colorizeNumber(chunks.length),\n `${ANSIColors.GREY_DARK}] →${ANSIColors.RESET} `,\n `${colorizeNumber(result.tokenUsed)} tokens used`,\n ].join('')\n );\n\n const fixedTranslatedChunkResult = fixChunkStartEndChars(\n result?.fileContent,\n fileToTranslateCurrentChunk\n );\n\n return fixedTranslatedChunkResult;\n })();\n\n // Replace the chunk in the file content\n fileResultContent = fileResultContent.replace(\n fileToTranslateCurrentChunk,\n chunkTranslation\n );\n }\n\n // Write final file by joining parts\n const finalContent = translatedParts.join('');\n\n mkdirSync(dirname(outputFilePath), { recursive: true });\n writeFileSync(outputFilePath, finalContent);\n\n const relativePath = relative(\n configuration.content.baseDir,\n outputFilePath\n );\n\n appLogger(\n `${colorize('✔', ANSIColors.GREEN)} File ${formatPath(relativePath)} created/updated successfully.`\n );\n\n return true; // Success\n } catch (error: any) {\n // Handle Errors and Update State\n\n errorState.count++;\n\n // If it's an Access Denied error, stop immediately (set count to max)\n const errorString = JSON.stringify(error);\n const errorMessage = error?.message ?? '';\n if (\n errorString.includes('AI_ACCESS_DENIED') ||\n errorMessage.includes('Access keys') ||\n errorMessage.includes('Access denied') ||\n errorMessage.includes('Invalid Access keys')\n ) {\n errorState.count = errorState.maxErrors + 1;\n appLogger(\n `${colorize('✖', ANSIColors.RED)} Critical Authentication Error. Aborting all tasks.`\n );\n }\n\n if (errorState.count >= errorState.maxErrors && !errorState.shouldStop) {\n errorState.shouldStop = true;\n appLogger(\n `${colorize('✖', ANSIColors.RED)} Too many errors (${errorState.count}). Stopping process.`\n );\n }\n\n return false; // Failed\n }\n};\n\ntype TranslateDocOptions = {\n docPattern: string[];\n locales: Locale[];\n excludedGlobPattern: string[];\n baseLocale: Locale;\n aiOptions?: AIOptions;\n nbSimultaneousFileProcessed?: number;\n configOptions?: GetConfigurationOptions;\n customInstructions?: string;\n skipIfModifiedBefore?: number | string | Date;\n skipIfModifiedAfter?: number | string | Date;\n skipIfExists?: boolean;\n gitOptions?: ListGitFilesOptions;\n};\n\n/**\n * Main translate function: scans all .md files in \"en/\" (unless you specified DOC_LIST),\n * then translates them to each locale in LOCALE_LIST.\n */\nexport const translateDoc = async ({\n docPattern,\n locales,\n excludedGlobPattern,\n baseLocale,\n aiOptions,\n nbSimultaneousFileProcessed,\n configOptions,\n customInstructions,\n skipIfModifiedBefore,\n skipIfModifiedAfter,\n skipIfExists,\n gitOptions,\n}: TranslateDocOptions) => {\n const configuration = getConfiguration(configOptions);\n const appLogger = getAppLogger(configuration);\n\n if (nbSimultaneousFileProcessed && nbSimultaneousFileProcessed > 10) {\n appLogger(\n `Warning: nbSimultaneousFileProcessed is set to ${nbSimultaneousFileProcessed}, which is greater than 10. Setting it to 10.`\n );\n nbSimultaneousFileProcessed = 10; // Limit the number of simultaneous file processed to 10\n }\n\n let docList: string[] = await fg(docPattern, {\n ignore: excludedGlobPattern,\n });\n\n const aiResult = await setupAI(configuration, aiOptions);\n\n if (!aiResult?.hasAIAccess) return;\n\n const { aiClient, aiConfig } = aiResult;\n\n if (gitOptions) {\n const gitChangedFiles = await listGitFiles(gitOptions);\n\n if (gitChangedFiles) {\n // Convert dictionary file paths to be relative to git root for comparison\n\n // Filter dictionaries based on git changed files\n docList = docList.filter((path) =>\n gitChangedFiles.some((gitFile) => join(process.cwd(), path) === gitFile)\n );\n }\n }\n\n // OAuth handled by API proxy internally\n\n appLogger(`Base locale is ${formatLocale(baseLocale)}`);\n appLogger(\n `Translating ${colorizeNumber(locales.length)} locales: [ ${formatLocale(locales)} ]`\n );\n\n appLogger(`Translating ${colorizeNumber(docList.length)} files:`);\n docList.forEach((path) => {\n appLogger(` - ${formatPath(path)}`);\n });\n\n // Initialize Error State\n const MAX_ALLOWED_ERRORS = 5;\n const errorState: ErrorState = {\n count: 0,\n maxErrors: MAX_ALLOWED_ERRORS,\n shouldStop: false,\n };\n\n // Create all tasks to be processed\n const allTasks = docList.flatMap((docPath) =>\n locales.map((locale) => async () => {\n // Early exit if too many errors\n if (errorState.shouldStop) return;\n\n appLogger(\n `Translating file: ${formatPath(docPath)} to ${formatLocale(locale)}`\n );\n\n const absoluteBaseFilePath = join(configuration.content.baseDir, docPath);\n const outputFilePath = getOutputFilePath(\n absoluteBaseFilePath,\n locale,\n baseLocale\n );\n\n // Skip if file exists and skipIfExists option is enabled\n if (skipIfExists && existsSync(outputFilePath)) {\n const relativePath = relative(\n configuration.content.baseDir,\n outputFilePath\n );\n appLogger(\n `${colorize('⊘', ANSIColors.YELLOW)} File ${formatPath(relativePath)} already exists, skipping.`\n );\n return;\n }\n\n // check if the file exist, otherwise create it\n if (!existsSync(outputFilePath)) {\n const relativePath = relative(\n configuration.content.baseDir,\n outputFilePath\n );\n appLogger(\n `File ${formatPath(relativePath)} does not exist, creating it...`\n );\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 // Call translateFile with errorState\n await translateFile(\n absoluteBaseFilePath,\n outputFilePath,\n locale as Locale,\n baseLocale,\n configuration,\n errorState,\n aiOptions,\n customInstructions,\n aiClient,\n aiConfig\n );\n })\n );\n\n await parallelize(\n allTasks,\n (task) => task(),\n nbSimultaneousFileProcessed ?? 3\n );\n\n if (errorState.count > 0) {\n appLogger(\n `Process finished with ${colorizeNumber(errorState.count)} error${errorState.count === 1 ? '' : 's'}.`\n );\n }\n};\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"reviewDoc.d.ts","names":[],"sources":["../../src/reviewDoc.ts"],"sourcesContent":[],"mappings":";;;;;;KA0BK,gBAAA;;EAAA,OAAA,EAEM,MAFN,EAAA;EAEM,mBAAA,EAAA,MAAA,EAAA;EAEG,UAAA,EAAA,MAAA;EACA,SAAA,CAAA,EAAA,SAAA;EAEI,2BAAA,CAAA,EAAA,MAAA;EAEyB,aAAA,CAAA,EAFzB,uBAEyB;EACD,kBAAA,CAAA,EAAA,MAAA;EAE3B,oBAAA,CAAA,EAAA,MAAA,GAAA,MAAA,GAH4B,IAG5B;EAAmB,mBAAA,CAAA,EAAA,MAAA,GAAA,MAAA,GAFQ,IAER;EAOrB,YA6HZ,CAAA,EAAA,OAAA;EA7H+B,UAAA,CAAA,EAPjB,mBAOiB;CAAA;;;;;AAAA,cAAnB,SAAmB,EAAA,CAAA;EAAA,UAAA;EAAA,OAAA;EAAA,mBAAA;EAAA,UAAA;EAAA,SAAA;EAAA,2BAAA;EAAA,aAAA;EAAA,kBAAA;EAAA,oBAAA;EAAA,mBAAA;EAAA,YAAA;EAAA;AAAA,CAAA,EAa7B,gBAb6B,EAAA,GAab,OAba,CAAA,IAAA,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"reviewDocBlockAware.d.ts","names":[],"sources":["../../src/reviewDocBlockAware.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAoCA;;;;;;;AAUqB,cAVR,oBAUQ,EAAA,CAAA,YAAA,EAAA,MAAA,EAAA,cAAA,EAAA,MAAA,EAAA,MAAA,EAPX,MAOW,EAAA,UAAA,EANP,MAMO,EAAA,SAAA,CAAA,EALP,SAKO,EAAA,aAAA,CAAA,EAJH,uBAIG,EAAA,kBAAA,CAAA,EAAA,MAAA,EAAA,YAAA,CAAA,EAAA,MAAA,EAAA,EAAA,QAAA,CAAA,EADR,QACQ,EAAA,QAAA,CAAA,EAAR,QAAQ,EAAA,GAAA,OAAA,CAAA,IAAA,CAAA"}
@@ -1,56 +0,0 @@
1
- import { AIClient } from "./utils/setupAI.js";
2
- import { IntlayerConfig, Locale } from "@intlayer/types";
3
- import { GetConfigurationOptions } from "@intlayer/config";
4
- import { ListGitFilesOptions } from "@intlayer/chokidar";
5
- import { AIConfig, AIOptions } from "@intlayer/ai";
6
-
7
- //#region src/translateDoc.d.ts
8
-
9
- /**
10
- * Shared error state for circuit breaker pattern
11
- */
12
- type ErrorState = {
13
- count: number;
14
- maxErrors: number;
15
- shouldStop: boolean;
16
- };
17
- /**
18
- * Translate a single file for a given locale
19
- * Returns TRUE if successful, FALSE if failed/skipped
20
- */
21
- declare const translateFile: (baseFilePath: string, outputFilePath: string, locale: Locale, baseLocale: Locale, configuration: IntlayerConfig, errorState: ErrorState, aiOptions?: AIOptions, customInstructions?: string, aiClient?: AIClient, aiConfig?: AIConfig) => Promise<boolean>;
22
- type TranslateDocOptions = {
23
- docPattern: string[];
24
- locales: Locale[];
25
- excludedGlobPattern: string[];
26
- baseLocale: Locale;
27
- aiOptions?: AIOptions;
28
- nbSimultaneousFileProcessed?: number;
29
- configOptions?: GetConfigurationOptions;
30
- customInstructions?: string;
31
- skipIfModifiedBefore?: number | string | Date;
32
- skipIfModifiedAfter?: number | string | Date;
33
- skipIfExists?: boolean;
34
- gitOptions?: ListGitFilesOptions;
35
- };
36
- /**
37
- * Main translate function: scans all .md files in "en/" (unless you specified DOC_LIST),
38
- * then translates them to each locale in LOCALE_LIST.
39
- */
40
- declare const translateDoc: ({
41
- docPattern,
42
- locales,
43
- excludedGlobPattern,
44
- baseLocale,
45
- aiOptions,
46
- nbSimultaneousFileProcessed,
47
- configOptions,
48
- customInstructions,
49
- skipIfModifiedBefore,
50
- skipIfModifiedAfter,
51
- skipIfExists,
52
- gitOptions
53
- }: TranslateDocOptions) => Promise<void>;
54
- //#endregion
55
- export { translateDoc, translateFile };
56
- //# sourceMappingURL=translateDoc.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"translateDoc.d.ts","names":[],"sources":["../../src/translateDoc.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AA8ByD;AAezD,KAVK,UAAA,GAUQ;EAGH,KAAA,EAAA,MAAA;EACI,SAAA,EAAA,MAAA;EACG,UAAA,EAAA,OAAA;CACH;;;;;AAKJ,cAXG,aAWH,EAAA,CAAA,YAAA,EAAA,MAAA,EAAA,cAAA,EAAA,MAAA,EAAA,MAAA,EARA,MAQA,EAAA,UAAA,EAPI,MAOJ,EAAA,aAAA,EANO,cAMP,EAAA,UAAA,EALI,UAKJ,EAAA,SAAA,CAAA,EAJI,SAIJ,EAAA,kBAAA,CAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAFG,QAEH,EAAA,QAAA,CAAA,EADG,QACH,EAAA,GAAP,OAAO,CAAA,OAAA,CAAA;AAwKR,KAEG,mBAAA,GAAmB;EAEb,UAAA,EAAA,MAAA,EAAA;EAEG,OAAA,EAFH,MAEG,EAAA;EACA,mBAAA,EAAA,MAAA,EAAA;EAEI,UAAA,EAHJ,MAGI;EAEyB,SAAA,CAAA,EAJ7B,SAI6B;EACD,2BAAA,CAAA,EAAA,MAAA;EAE3B,aAAA,CAAA,EALG,uBAKH;EAAmB,kBAAA,CAAA,EAAA,MAAA;EAOrB,oBAkJZ,CAAA,EAAA,MAAA,GAAA,MAAA,GA5J0C,IA4J1C;EAlJkC,mBAAA,CAAA,EAAA,MAAA,GAAA,MAAA,GATO,IASP;EAAA,YAAA,CAAA,EAAA,OAAA;EAAA,UAAA,CAAA,EAPpB,mBAOoB;CAAA;;;;;AAAA,cAAtB,YAAsB,EAAA,CAAA;EAAA,UAAA;EAAA,OAAA;EAAA,mBAAA;EAAA,UAAA;EAAA,SAAA;EAAA,2BAAA;EAAA,aAAA;EAAA,kBAAA;EAAA,oBAAA;EAAA,mBAAA;EAAA,YAAA;EAAA;AAAA,CAAA,EAahC,mBAbgC,EAAA,GAab,OAba,CAAA,IAAA,CAAA"}