@intlayer/cli 8.3.0-canary.4 → 8.3.1

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 (39) hide show
  1. package/dist/cjs/build.cjs +1 -1
  2. package/dist/cjs/extract.cjs +1 -1
  3. package/dist/cjs/extract.cjs.map +1 -1
  4. package/dist/cjs/fill/fill.cjs +1 -1
  5. package/dist/cjs/fill/formatFillData.cjs.map +1 -1
  6. package/dist/cjs/fill/listTranslationsTasks.cjs +1 -1
  7. package/dist/cjs/fill/translateDictionary.cjs +1 -1
  8. package/dist/cjs/fill/writeFill.cjs +1 -1
  9. package/dist/cjs/listContentDeclaration.cjs +1 -1
  10. package/dist/cjs/liveSync.cjs +3 -3
  11. package/dist/cjs/pull.cjs +1 -1
  12. package/dist/cjs/push/push.cjs +1 -1
  13. package/dist/cjs/reviewDoc/reviewDoc.cjs +1 -1
  14. package/dist/cjs/reviewDoc/reviewDoc.cjs.map +1 -1
  15. package/dist/cjs/reviewDoc/reviewDocBlockAware.cjs +1 -1
  16. package/dist/cjs/test/test.cjs +1 -1
  17. package/dist/cjs/translateDoc/translateDoc.cjs +1 -1
  18. package/dist/cjs/translateDoc/translateFile.cjs +2 -2
  19. package/dist/cjs/watch.cjs +1 -1
  20. package/dist/esm/build.mjs +1 -1
  21. package/dist/esm/extract.mjs +1 -1
  22. package/dist/esm/extract.mjs.map +1 -1
  23. package/dist/esm/fill/fill.mjs +1 -1
  24. package/dist/esm/fill/formatFillData.mjs.map +1 -1
  25. package/dist/esm/fill/listTranslationsTasks.mjs +1 -1
  26. package/dist/esm/fill/translateDictionary.mjs +1 -1
  27. package/dist/esm/fill/writeFill.mjs +1 -1
  28. package/dist/esm/listContentDeclaration.mjs +1 -1
  29. package/dist/esm/liveSync.mjs +2 -2
  30. package/dist/esm/pull.mjs +1 -1
  31. package/dist/esm/push/push.mjs +1 -1
  32. package/dist/esm/reviewDoc/reviewDoc.mjs +1 -1
  33. package/dist/esm/reviewDoc/reviewDocBlockAware.mjs +1 -1
  34. package/dist/esm/test/test.mjs +1 -1
  35. package/dist/esm/translateDoc/translateDoc.mjs +1 -1
  36. package/dist/esm/translateDoc/translateFile.mjs +2 -2
  37. package/dist/esm/watch.mjs +1 -1
  38. package/dist/types/extract.d.ts.map +1 -1
  39. package/package.json +12 -12
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`@intlayer/chokidar/cli`),t=require(`@intlayer/config/node`),n=require(`@intlayer/chokidar/utils`),r=require(`@intlayer/chokidar/watcher`);const i=async i=>{let a=(0,t.getConfiguration)(i?.configOptions);(0,e.logConfigDetails)(i?.configOptions);let o=null;i?.with&&(o=(0,n.runParallel)(i.with),o.result.catch(()=>{})),await(0,r.buildAndWatchIntlayer)({persistent:i?.watch??!1,skipPrepare:i?.skipPrepare??!1,configuration:a}),!i?.watch&&o&&o.kill()};exports.build=i;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`@intlayer/chokidar/cli`),t=require(`@intlayer/chokidar/utils`),n=require(`@intlayer/config/node`),r=require(`@intlayer/chokidar/watcher`);const i=async i=>{let a=(0,n.getConfiguration)(i?.configOptions);(0,e.logConfigDetails)(i?.configOptions);let o=null;i?.with&&(o=(0,t.runParallel)(i.with),o.result.catch(()=>{})),await(0,r.buildAndWatchIntlayer)({persistent:i?.watch??!1,skipPrepare:i?.skipPrepare??!1,configuration:a}),!i?.watch&&o&&o.kill()};exports.build=i;
2
2
  //# sourceMappingURL=build.cjs.map
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./_virtual/_rolldown/runtime.cjs`);let t=require(`node:fs`),n=require(`node:path`),r=require(`@intlayer/babel`),i=require(`@intlayer/chokidar/cli`),a=require(`@intlayer/config/logger`),o=require(`@intlayer/config/node`),s=require(`@intlayer/unmerged-dictionaries-entry`),c=require(`enquirer`);c=e.__toESM(c);let l=require(`fast-glob`);l=e.__toESM(l);const u=async e=>{let u=(0,o.getConfiguration)(e.configOptions);(0,i.logConfigDetails)(e?.configOptions);let d=(0,a.getAppLogger)(u),{baseDir:f}=u.system,{codeDir:p,excludedPath:m}=u.content,{traversePattern:h}=u.build,g=e=>(0,a.colorizePath)((0,n.relative)(f,e)),_=(0,r.detectPackageName)(f),v=e.files??[];if(v.length===0){let e=e=>(m??[]).some(t=>{let n=t.split(`/`).filter(e=>!e.includes(`*`)&&e.length>0),r=e.split(`/`);return n.some(e=>r.includes(e))}),r=(await Promise.all(p.filter(t=>!e(t)).map(e=>(0,l.default)(h,{cwd:e,ignore:m,absolute:!0})))).flat(),i=[...new Set(r)].filter(e=>(0,t.existsSync)(e)).map(e=>({value:e,label:(0,n.relative)(f,e)}));if(i.length===0){d(`No extractable files found in the project.`);return}let a=`__select_all__`,o;try{let e=Math.max((process.stdout.columns||80)-15,20),t=t=>t.length>e?`...${t.slice(-(e-3))}`:t,{files:n}=await c.default.prompt({type:`autocomplete`,name:`files`,message:`Select files to extract (Type to search):`,multiple:!0,limit:40,choices:[{name:a,message:`────── Select all ──────`},...i.map(e=>({name:e.value,message:t(e.label)}))],async toggle(e,t){if(!(!e||e.disabled))return e.enabled=t??!e.enabled,e.name===a&&this.choices.filter(e=>e.name!==a).forEach(t=>{t.enabled=e.enabled}),this.render()},format(){return this.state?.submitted&&this.options?.multiple?`${this.selected.filter(e=>e.name!==a).length} file(s) selected`:this.input??``}});o=n.filter(e=>e!==a)}catch{o=Symbol(`cancel`)}typeof o==`symbol`&&process.exit(0),v=o}if(v.length===0){d(`No files selected for extraction.`);return}let y=v.map(e=>(0,n.resolve)(f,e)).filter(e=>(0,t.existsSync)(e)?!0:(d(`File not found: ${g(e)}`),!1));if(y.length===0)return;let b=(0,s.getUnmergedDictionaries)(u);await Promise.all(y.map(async t=>{try{await(0,r.extractContent)(t,_,{unmergedDictionaries:b,configuration:u,codeOnly:e.codeOnly,declarationOnly:e.declarationOnly})}catch(e){d(`Failed to transform ${t}: ${e.message}`)}}))};exports.extract=u;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./_virtual/_rolldown/runtime.cjs`);let t=require(`node:fs`),n=require(`node:path`),r=require(`@intlayer/babel`),i=require(`@intlayer/chokidar/build`),a=require(`@intlayer/chokidar/cli`),o=require(`@intlayer/chokidar/utils`),s=require(`@intlayer/config/logger`),c=require(`@intlayer/config/node`),l=require(`@intlayer/unmerged-dictionaries-entry`),u=require(`enquirer`);u=e.__toESM(u);const d=async e=>{let d=(0,c.getConfiguration)(e.configOptions);(0,a.logConfigDetails)(e?.configOptions);let f=(0,s.getAppLogger)(d),{baseDir:p}=d.system,{output:m}=d.compiler,h=e=>(0,s.colorizePath)((0,n.relative)(p,e));if(!m){f(`${s.x} No output configuration found. Add a ${(0,s.colorize)(`compiler.output`,s.ANSIColors.BLUE)} in your configuration.`,{level:`error`});return}let g=(0,r.detectPackageName)(p),_=e.files??[];if(_.length===0){let e=(0,o.buildComponentFilesList)(d).map(e=>({value:e,label:(0,n.relative)(p,e)}));if(e.length===0){f(`No extractable files found in the project.`);return}let t=`__select_all__`,r;try{let n=Math.max((process.stdout.columns||80)-15,20),i=e=>e.length>n?`...${e.slice(-(n-3))}`:e,{files:a}=await u.default.prompt({type:`autocomplete`,name:`files`,message:`Select files to extract (Type to search):`,multiple:!0,limit:40,choices:[{name:t,message:`────── Select all ──────`},...e.map(e=>({name:e.value,message:i(e.label)}))],async toggle(e,n){if(!(!e||e.disabled))return e.enabled=n??!e.enabled,e.name===t&&this.choices.filter(e=>e.name!==t).forEach(t=>{t.enabled=e.enabled}),this.render()},format(){return this.state?.submitted&&this.options?.multiple?`${this.selected.filter(e=>e.name!==t).length} file(s) selected`:this.input??``}});r=a.filter(e=>e!==t)}catch{r=Symbol(`cancel`)}typeof r==`symbol`&&process.exit(0),_=r}if(_.length===0){f(`No files selected for extraction.`);return}let v=_.map(e=>(0,n.resolve)(p,e)).filter(e=>(0,t.existsSync)(e)?!0:(f(`File not found: ${h(e)}`),!1));if(v.length===0)return;let y=(0,l.getUnmergedDictionaries)(d);await Promise.all(v.map(async t=>{try{await(0,r.extractContent)(t,g,{unmergedDictionaries:y,configuration:d,codeOnly:e.codeOnly,declarationOnly:e.declarationOnly})}catch(e){f(`Failed to transform ${t}: ${e.message}`)}})),await(0,i.prepareIntlayer)(d)};exports.extract=d;
2
2
  //# sourceMappingURL=extract.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extract.cjs","names":[],"sources":["../../src/extract.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport {\n detectPackageName,\n extractContent,\n type PackageName,\n} from '@intlayer/babel';\nimport { logConfigDetails } from '@intlayer/chokidar/cli';\nimport { colorizePath, getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { FilePathPattern } from '@intlayer/types/filePathPattern';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport enquirer from 'enquirer';\nimport fg from 'fast-glob';\n\ntype ExtractOptions = {\n files?: string[];\n output?: FilePathPattern;\n configOptions?: GetConfigurationOptions;\n codeOnly?: boolean;\n declarationOnly?: boolean;\n};\n\nexport const extract = async (options: ExtractOptions) => {\n const configuration = getConfiguration(options.configOptions);\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(configuration);\n const { baseDir } = configuration.system;\n const { codeDir, excludedPath } = configuration.content;\n const { traversePattern } = configuration.build;\n\n const formatPath = (path: string) => {\n const relativePath = relative(baseDir, path);\n return colorizePath(relativePath);\n };\n\n // Detect package\n const packageName: PackageName = detectPackageName(baseDir);\n\n let filesToExtract = options.files ?? [];\n\n if (filesToExtract.length === 0) {\n // Filter out codeDirs that are themselves inside an excluded path (e.g. dist, node_modules)\n const isDirExcluded = (dirPath: string): boolean =>\n (excludedPath ?? []).some((pattern) => {\n const segments = pattern\n .split('/')\n .filter((s) => !s.includes('*') && s.length > 0);\n const parts = dirPath.split('/');\n return segments.some((seg) => parts.includes(seg));\n });\n\n // Await all promises simultaneously\n const resultsArray = await Promise.all(\n codeDir\n .filter((dir) => !isDirExcluded(dir))\n .map((dir) =>\n fg(traversePattern, {\n cwd: dir,\n ignore: excludedPath,\n absolute: true,\n })\n )\n );\n\n // Flatten the nested arrays and remove duplicates\n const allFiles = resultsArray.flat();\n\n const uniqueFiles = [...new Set(allFiles)].filter((file) =>\n existsSync(file)\n );\n\n // Relative paths for selection\n const choices = uniqueFiles.map((file) => {\n const relPath = relative(baseDir, file);\n return {\n value: file,\n label: relPath,\n };\n });\n\n if (choices.length === 0) {\n appLogger('No extractable files found in the project.');\n return;\n }\n\n const SELECT_ALL = '__select_all__';\n\n type PromptChoice = {\n name: string;\n enabled: boolean;\n disabled?: boolean | string;\n };\n\n type PromptContext = {\n choices: PromptChoice[];\n render(): void | Promise<void>;\n state: { submitted: boolean };\n selected: PromptChoice[];\n input: string;\n options: { multiple?: boolean };\n };\n\n let selectedFiles: string[] | symbol;\n try {\n const maxLen = Math.max((process.stdout.columns || 80) - 15, 20);\n const truncatePath = (path: string) =>\n path.length > maxLen ? `...${path.slice(-(maxLen - 3))}` : path;\n\n const { files: enquirerSelectedFiles } = await enquirer.prompt<{\n files: string[];\n }>({\n type: 'autocomplete',\n name: 'files',\n message: 'Select files to extract (Type to search):',\n multiple: true,\n // @ts-ignore limit exist but is not typed\n limit: 40,\n choices: [\n { name: SELECT_ALL, message: '────── Select all ──────' },\n ...choices.map((choice) => ({\n name: choice.value,\n message: truncatePath(choice.label),\n })),\n ],\n async toggle(\n this: PromptContext,\n choice: PromptChoice,\n enabled?: boolean\n ) {\n if (!choice || choice.disabled) return;\n choice.enabled = enabled == null ? !choice.enabled : enabled;\n\n if (choice.name === SELECT_ALL) {\n this.choices\n .filter((choiceEl) => choiceEl.name !== SELECT_ALL)\n .forEach((choiceEl) => {\n choiceEl.enabled = choice.enabled;\n });\n }\n\n return this.render();\n },\n format(this: PromptContext) {\n if (this.state?.submitted && this.options?.multiple) {\n return `${this.selected.filter((s) => s.name !== SELECT_ALL).length} file(s) selected`;\n }\n return this.input ?? '';\n },\n });\n\n selectedFiles = enquirerSelectedFiles.filter((f) => f !== SELECT_ALL);\n } catch {\n selectedFiles = Symbol('cancel');\n }\n\n if (typeof selectedFiles === 'symbol') {\n // User cancelled\n process.exit(0);\n }\n\n filesToExtract = selectedFiles as string[];\n }\n\n if (filesToExtract.length === 0) {\n appLogger('No files selected for extraction.');\n return;\n }\n\n const absoluteFiles = filesToExtract\n .map((file) => resolve(baseDir, file))\n .filter((file) => {\n if (!existsSync(file)) {\n appLogger(`File not found: ${formatPath(file)}`);\n return false;\n }\n return true;\n });\n\n if (absoluteFiles.length === 0) {\n return;\n }\n\n const unmergedDictionaries = getUnmergedDictionaries(configuration);\n\n await Promise.all(\n absoluteFiles.map(async (filePath) => {\n try {\n await extractContent(filePath, packageName, {\n unmergedDictionaries,\n configuration,\n codeOnly: options.codeOnly,\n declarationOnly: options.declarationOnly,\n });\n } catch (error) {\n appLogger(\n `Failed to transform ${filePath}: ${(error as Error).message}`\n );\n }\n })\n );\n};\n"],"mappings":"kbA2BA,MAAa,EAAU,KAAO,IAA4B,CACxD,IAAM,GAAA,EAAA,EAAA,kBAAiC,EAAQ,cAAc,EAC7D,EAAA,EAAA,kBAAiB,GAAS,cAAc,CAExC,IAAM,GAAA,EAAA,EAAA,cAAyB,EAAc,CACvC,CAAE,WAAY,EAAc,OAC5B,CAAE,UAAS,gBAAiB,EAAc,QAC1C,CAAE,mBAAoB,EAAc,MAEpC,EAAc,IAElB,EAAA,EAAA,eAAA,EAAA,EAAA,UAD8B,EAAS,EAAK,CACX,CAI7B,GAAA,EAAA,EAAA,mBAA6C,EAAQ,CAEvD,EAAiB,EAAQ,OAAS,EAAE,CAExC,GAAI,EAAe,SAAW,EAAG,CAE/B,IAAM,EAAiB,IACpB,GAAgB,EAAE,EAAE,KAAM,GAAY,CACrC,IAAM,EAAW,EACd,MAAM,IAAI,CACV,OAAQ,GAAM,CAAC,EAAE,SAAS,IAAI,EAAI,EAAE,OAAS,EAAE,CAC5C,EAAQ,EAAQ,MAAM,IAAI,CAChC,OAAO,EAAS,KAAM,GAAQ,EAAM,SAAS,EAAI,CAAC,EAClD,CAgBE,GAbe,MAAM,QAAQ,IACjC,EACG,OAAQ,GAAQ,CAAC,EAAc,EAAI,CAAC,CACpC,IAAK,IAAA,EAAA,EAAA,SACD,EAAiB,CAClB,IAAK,EACL,OAAQ,EACR,SAAU,GACX,CAAC,CACH,CACJ,EAG6B,MAAM,CAO9B,EALc,CAAC,GAAG,IAAI,IAAI,EAAS,CAAC,CAAC,OAAQ,IAAA,EAAA,EAAA,YACtC,EAAK,CACjB,CAG2B,IAAK,IAExB,CACL,MAAO,EACP,OAAA,EAAA,EAAA,UAHuB,EAAS,EAAK,CAItC,EACD,CAEF,GAAI,EAAQ,SAAW,EAAG,CACxB,EAAU,6CAA6C,CACvD,OAGF,IAAM,EAAa,iBAiBf,EACJ,GAAI,CACF,IAAM,EAAS,KAAK,KAAK,QAAQ,OAAO,SAAW,IAAM,GAAI,GAAG,CAC1D,EAAgB,GACpB,EAAK,OAAS,EAAS,MAAM,EAAK,MAAM,EAAE,EAAS,GAAG,GAAK,EAEvD,CAAE,MAAO,GAA0B,MAAM,EAAA,QAAS,OAErD,CACD,KAAM,eACN,KAAM,QACN,QAAS,4CACT,SAAU,GAEV,MAAO,GACP,QAAS,CACP,CAAE,KAAM,EAAY,QAAS,2BAA4B,CACzD,GAAG,EAAQ,IAAK,IAAY,CAC1B,KAAM,EAAO,MACb,QAAS,EAAa,EAAO,MAAM,CACpC,EAAE,CACJ,CACD,MAAM,OAEJ,EACA,EACA,CACI,MAAC,GAAU,EAAO,UAWtB,MAVA,GAAO,QAAU,GAAkB,CAAC,EAAO,QAEvC,EAAO,OAAS,GAClB,KAAK,QACF,OAAQ,GAAa,EAAS,OAAS,EAAW,CAClD,QAAS,GAAa,CACrB,EAAS,QAAU,EAAO,SAC1B,CAGC,KAAK,QAAQ,EAEtB,QAA4B,CAI1B,OAHI,KAAK,OAAO,WAAa,KAAK,SAAS,SAClC,GAAG,KAAK,SAAS,OAAQ,GAAM,EAAE,OAAS,EAAW,CAAC,OAAO,mBAE/D,KAAK,OAAS,IAExB,CAAC,CAEF,EAAgB,EAAsB,OAAQ,GAAM,IAAM,EAAW,MAC/D,CACN,EAAgB,OAAO,SAAS,CAG9B,OAAO,GAAkB,UAE3B,QAAQ,KAAK,EAAE,CAGjB,EAAiB,EAGnB,GAAI,EAAe,SAAW,EAAG,CAC/B,EAAU,oCAAoC,CAC9C,OAGF,IAAM,EAAgB,EACnB,IAAK,IAAA,EAAA,EAAA,SAAiB,EAAS,EAAK,CAAC,CACrC,OAAQ,IACH,EAAA,EAAA,YAAY,EAAK,CAId,IAHL,EAAU,mBAAmB,EAAW,EAAK,GAAG,CACzC,IAGT,CAEJ,GAAI,EAAc,SAAW,EAC3B,OAGF,IAAM,GAAA,EAAA,EAAA,yBAA+C,EAAc,CAEnE,MAAM,QAAQ,IACZ,EAAc,IAAI,KAAO,IAAa,CACpC,GAAI,CACF,MAAA,EAAA,EAAA,gBAAqB,EAAU,EAAa,CAC1C,uBACA,gBACA,SAAU,EAAQ,SAClB,gBAAiB,EAAQ,gBAC1B,CAAC,OACK,EAAO,CACd,EACE,uBAAuB,EAAS,IAAK,EAAgB,UACtD,GAEH,CACH"}
1
+ {"version":3,"file":"extract.cjs","names":["x","ANSIColors"],"sources":["../../src/extract.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { relative, resolve } from 'node:path';\nimport {\n detectPackageName,\n extractContent,\n type PackageName,\n} from '@intlayer/babel';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { logConfigDetails } from '@intlayer/chokidar/cli';\nimport { buildComponentFilesList } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizePath,\n getAppLogger,\n x,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { FilePathPattern } from '@intlayer/types/filePathPattern';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport enquirer from 'enquirer';\n\ntype ExtractOptions = {\n files?: string[];\n output?: FilePathPattern;\n configOptions?: GetConfigurationOptions;\n codeOnly?: boolean;\n declarationOnly?: boolean;\n};\n\nexport const extract = async (options: ExtractOptions) => {\n const configuration = getConfiguration(options.configOptions);\n\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(configuration);\n\n const { baseDir } = configuration.system;\n const { output } = configuration.compiler;\n\n const formatPath = (path: string) => {\n const relativePath = relative(baseDir, path);\n return colorizePath(relativePath);\n };\n\n if (!output) {\n appLogger(\n `${x} No output configuration found. Add a ${colorize('compiler.output', ANSIColors.BLUE)} in your configuration.`,\n {\n level: 'error',\n }\n );\n return;\n }\n\n // Detect package\n const packageName: PackageName = detectPackageName(baseDir);\n\n let filesToExtract = options.files ?? [];\n\n if (filesToExtract.length === 0) {\n // Await all promises simultaneously\n const fileList = buildComponentFilesList(configuration);\n\n // Flatten the nested arrays and remove duplicates\n // Relative paths for selection\n const choices = fileList.map((file) => {\n const relPath = relative(baseDir, file);\n return {\n value: file,\n label: relPath,\n };\n });\n\n if (choices.length === 0) {\n appLogger('No extractable files found in the project.');\n return;\n }\n\n const SELECT_ALL = '__select_all__';\n\n type PromptChoice = {\n name: string;\n enabled: boolean;\n disabled?: boolean | string;\n };\n\n type PromptContext = {\n choices: PromptChoice[];\n render(): void | Promise<void>;\n state: { submitted: boolean };\n selected: PromptChoice[];\n input: string;\n options: { multiple?: boolean };\n };\n\n let selectedFiles: string[] | symbol;\n try {\n const maxLen = Math.max((process.stdout.columns || 80) - 15, 20);\n const truncatePath = (path: string) =>\n path.length > maxLen ? `...${path.slice(-(maxLen - 3))}` : path;\n\n const { files: enquirerSelectedFiles } = await enquirer.prompt<{\n files: string[];\n }>({\n type: 'autocomplete',\n name: 'files',\n message: 'Select files to extract (Type to search):',\n multiple: true,\n // @ts-ignore limit exist but is not typed\n limit: 40,\n choices: [\n { name: SELECT_ALL, message: '────── Select all ──────' },\n ...choices.map((choice) => ({\n name: choice.value,\n message: truncatePath(choice.label),\n })),\n ],\n async toggle(\n this: PromptContext,\n choice: PromptChoice,\n enabled?: boolean\n ) {\n if (!choice || choice.disabled) return;\n choice.enabled = enabled == null ? !choice.enabled : enabled;\n\n if (choice.name === SELECT_ALL) {\n this.choices\n .filter((choiceEl) => choiceEl.name !== SELECT_ALL)\n .forEach((choiceEl) => {\n choiceEl.enabled = choice.enabled;\n });\n }\n\n return this.render();\n },\n format(this: PromptContext) {\n if (this.state?.submitted && this.options?.multiple) {\n return `${this.selected.filter((s) => s.name !== SELECT_ALL).length} file(s) selected`;\n }\n return this.input ?? '';\n },\n });\n\n selectedFiles = enquirerSelectedFiles.filter((f) => f !== SELECT_ALL);\n } catch {\n selectedFiles = Symbol('cancel');\n }\n\n if (typeof selectedFiles === 'symbol') {\n // User cancelled\n process.exit(0);\n }\n\n filesToExtract = selectedFiles as string[];\n }\n\n if (filesToExtract.length === 0) {\n appLogger('No files selected for extraction.');\n return;\n }\n\n const absoluteFiles = filesToExtract\n .map((file) => resolve(baseDir, file))\n .filter((file) => {\n if (!existsSync(file)) {\n appLogger(`File not found: ${formatPath(file)}`);\n return false;\n }\n return true;\n });\n\n if (absoluteFiles.length === 0) {\n return;\n }\n\n const unmergedDictionaries = getUnmergedDictionaries(configuration);\n\n await Promise.all(\n absoluteFiles.map(async (filePath) => {\n try {\n await extractContent(filePath, packageName, {\n unmergedDictionaries,\n configuration,\n codeOnly: options.codeOnly,\n declarationOnly: options.declarationOnly,\n });\n } catch (error) {\n appLogger(\n `Failed to transform ${filePath}: ${(error as Error).message}`\n );\n }\n })\n );\n\n await prepareIntlayer(configuration); // Prepare Intlayer to apply the changes\n};\n"],"mappings":"odAiCA,MAAa,EAAU,KAAO,IAA4B,CACxD,IAAM,GAAA,EAAA,EAAA,kBAAiC,EAAQ,cAAc,EAE7D,EAAA,EAAA,kBAAiB,GAAS,cAAc,CAExC,IAAM,GAAA,EAAA,EAAA,cAAyB,EAAc,CAEvC,CAAE,WAAY,EAAc,OAC5B,CAAE,UAAW,EAAc,SAE3B,EAAc,IAElB,EAAA,EAAA,eAAA,EAAA,EAAA,UAD8B,EAAS,EAAK,CACX,CAGnC,GAAI,CAAC,EAAQ,CACX,EACE,GAAGA,EAAAA,EAAE,yCAAA,EAAA,EAAA,UAAiD,kBAAmBC,EAAAA,WAAW,KAAK,CAAC,yBAC1F,CACE,MAAO,QACR,CACF,CACD,OAIF,IAAM,GAAA,EAAA,EAAA,mBAA6C,EAAQ,CAEvD,EAAiB,EAAQ,OAAS,EAAE,CAExC,GAAI,EAAe,SAAW,EAAG,CAM/B,IAAM,GAAA,EAAA,EAAA,yBAJmC,EAAc,CAI9B,IAAK,IAErB,CACL,MAAO,EACP,OAAA,EAAA,EAAA,UAHuB,EAAS,EAAK,CAItC,EACD,CAEF,GAAI,EAAQ,SAAW,EAAG,CACxB,EAAU,6CAA6C,CACvD,OAGF,IAAM,EAAa,iBAiBf,EACJ,GAAI,CACF,IAAM,EAAS,KAAK,KAAK,QAAQ,OAAO,SAAW,IAAM,GAAI,GAAG,CAC1D,EAAgB,GACpB,EAAK,OAAS,EAAS,MAAM,EAAK,MAAM,EAAE,EAAS,GAAG,GAAK,EAEvD,CAAE,MAAO,GAA0B,MAAM,EAAA,QAAS,OAErD,CACD,KAAM,eACN,KAAM,QACN,QAAS,4CACT,SAAU,GAEV,MAAO,GACP,QAAS,CACP,CAAE,KAAM,EAAY,QAAS,2BAA4B,CACzD,GAAG,EAAQ,IAAK,IAAY,CAC1B,KAAM,EAAO,MACb,QAAS,EAAa,EAAO,MAAM,CACpC,EAAE,CACJ,CACD,MAAM,OAEJ,EACA,EACA,CACI,MAAC,GAAU,EAAO,UAWtB,MAVA,GAAO,QAAU,GAAkB,CAAC,EAAO,QAEvC,EAAO,OAAS,GAClB,KAAK,QACF,OAAQ,GAAa,EAAS,OAAS,EAAW,CAClD,QAAS,GAAa,CACrB,EAAS,QAAU,EAAO,SAC1B,CAGC,KAAK,QAAQ,EAEtB,QAA4B,CAI1B,OAHI,KAAK,OAAO,WAAa,KAAK,SAAS,SAClC,GAAG,KAAK,SAAS,OAAQ,GAAM,EAAE,OAAS,EAAW,CAAC,OAAO,mBAE/D,KAAK,OAAS,IAExB,CAAC,CAEF,EAAgB,EAAsB,OAAQ,GAAM,IAAM,EAAW,MAC/D,CACN,EAAgB,OAAO,SAAS,CAG9B,OAAO,GAAkB,UAE3B,QAAQ,KAAK,EAAE,CAGjB,EAAiB,EAGnB,GAAI,EAAe,SAAW,EAAG,CAC/B,EAAU,oCAAoC,CAC9C,OAGF,IAAM,EAAgB,EACnB,IAAK,IAAA,EAAA,EAAA,SAAiB,EAAS,EAAK,CAAC,CACrC,OAAQ,IACH,EAAA,EAAA,YAAY,EAAK,CAId,IAHL,EAAU,mBAAmB,EAAW,EAAK,GAAG,CACzC,IAGT,CAEJ,GAAI,EAAc,SAAW,EAC3B,OAGF,IAAM,GAAA,EAAA,EAAA,yBAA+C,EAAc,CAEnE,MAAM,QAAQ,IACZ,EAAc,IAAI,KAAO,IAAa,CACpC,GAAI,CACF,MAAA,EAAA,EAAA,gBAAqB,EAAU,EAAa,CAC1C,uBACA,gBACA,SAAU,EAAQ,SAClB,gBAAiB,EAAQ,gBAC1B,CAAC,OACK,EAAO,CACd,EACE,uBAAuB,EAAS,IAAK,EAAgB,UACtD,GAEH,CACH,CAED,MAAA,EAAA,EAAA,iBAAsB,EAAc"}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../getTargetDictionary.cjs`),t=require(`../utils/setupAI.cjs`),n=require(`./listTranslationsTasks.cjs`),r=require(`./translateDictionary.cjs`),i=require(`./writeFill.cjs`);let a=require(`node:path`),o=require(`@intlayer/chokidar/cli`),s=require(`@intlayer/config/logger`),c=require(`@intlayer/config/node`),l=require(`@intlayer/chokidar/build`),u=require(`@intlayer/chokidar/utils`);const d=async d=>{let f=(0,c.getConfiguration)(d?.configOptions);(0,o.logConfigDetails)(d?.configOptions);let p=(0,s.getAppLogger)(f);d?.build===!0?await(0,l.prepareIntlayer)(f,{forceRun:!0}):d?.build===void 0&&await(0,l.prepareIntlayer)(f);let{defaultLocale:m,locales:h}=f.internationalization,g=d?.mode??`complete`,_=d?.sourceLocale??m,v=d?.outputLocales?e.ensureArray(d.outputLocales):h,y=await t.setupAI(f,d?.aiOptions);if(!y?.hasAIAccess)return;let{aiClient:b,aiConfig:x}=y,S=await e.getTargetUnmergedDictionaries(d),C=new Set;S.forEach(e=>{C.add(e.key)});let w=Array.from(C);if(p([`Affected dictionary keys for processing:`,w.length>0?w.map(e=>(0,s.colorizeKey)(e)).join(`, `):(0,s.colorize)(`No keys found`,s.ANSIColors.YELLOW)]),w.length===0)return;let T=n.listTranslationsTasks(S.map(e=>e.localId),v,g,_,f),E=d?.nbConcurrentTranslations??7,D=(0,u.getGlobalLimiter)(E),O=(0,u.getTaskLimiter)(Math.max(1,Math.min(d?.nbConcurrentTasks??E,T.length))),k=T.map(e=>O(async()=>{let t=(0,a.relative)(f?.content?.baseDir??process.cwd(),e?.dictionaryFilePath??``);p(`${e.dictionaryPreset} Processing ${(0,s.colorizePath)((0,a.basename)(t))}`,{level:`info`});let n=await r.translateDictionary(e,f,{mode:g,aiOptions:d?.aiOptions,fillMetadata:!d?.skipMetadata,onHandle:D,aiClient:b,aiConfig:x});if(!n?.dictionaryOutput)return;let{dictionaryOutput:o,sourceLocale:c}=n,m=typeof o.fill==`string`||typeof o.fill==`object`,h=typeof o.locale==`string`,_=m?o.fill:h?f.dictionary?.fill??!0:!1;typeof _==`string`||typeof _==`object`?await i.writeFill({...o,fill:_},v,[c],f):(await(0,l.writeContentDeclaration)(o,f),o.filePath&&p(`${e.dictionaryPreset} Content declaration written to ${(0,u.formatPath)((0,a.basename)(o.filePath))}`,{level:`info`}))}));await Promise.all(k),await D.onIdle()};exports.fill=d;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../getTargetDictionary.cjs`),t=require(`../utils/setupAI.cjs`),n=require(`./listTranslationsTasks.cjs`),r=require(`./translateDictionary.cjs`),i=require(`./writeFill.cjs`);let a=require(`node:path`),o=require(`@intlayer/chokidar/build`),s=require(`@intlayer/chokidar/cli`),c=require(`@intlayer/chokidar/utils`),l=require(`@intlayer/config/logger`),u=require(`@intlayer/config/node`);const d=async d=>{let f=(0,u.getConfiguration)(d?.configOptions);(0,s.logConfigDetails)(d?.configOptions);let p=(0,l.getAppLogger)(f);d?.build===!0?await(0,o.prepareIntlayer)(f,{forceRun:!0}):d?.build===void 0&&await(0,o.prepareIntlayer)(f);let{defaultLocale:m,locales:h}=f.internationalization,g=d?.mode??`complete`,_=d?.sourceLocale??m,v=d?.outputLocales?e.ensureArray(d.outputLocales):h,y=await t.setupAI(f,d?.aiOptions);if(!y?.hasAIAccess)return;let{aiClient:b,aiConfig:x}=y,S=await e.getTargetUnmergedDictionaries(d),C=new Set;S.forEach(e=>{C.add(e.key)});let w=Array.from(C);if(p([`Affected dictionary keys for processing:`,w.length>0?w.map(e=>(0,l.colorizeKey)(e)).join(`, `):(0,l.colorize)(`No keys found`,l.ANSIColors.YELLOW)]),w.length===0)return;let T=n.listTranslationsTasks(S.map(e=>e.localId),v,g,_,f),E=d?.nbConcurrentTranslations??7,D=(0,c.getGlobalLimiter)(E),O=(0,c.getTaskLimiter)(Math.max(1,Math.min(d?.nbConcurrentTasks??E,T.length))),k=T.map(e=>O(async()=>{let t=(0,a.relative)(f?.content?.baseDir??process.cwd(),e?.dictionaryFilePath??``);p(`${e.dictionaryPreset} Processing ${(0,l.colorizePath)((0,a.basename)(t))}`,{level:`info`});let n=await r.translateDictionary(e,f,{mode:g,aiOptions:d?.aiOptions,fillMetadata:!d?.skipMetadata,onHandle:D,aiClient:b,aiConfig:x});if(!n?.dictionaryOutput)return;let{dictionaryOutput:s,sourceLocale:u}=n,m=typeof s.fill==`string`||typeof s.fill==`object`,h=typeof s.locale==`string`,_=m?s.fill:h?f.dictionary?.fill??!0:!1;typeof _==`string`||typeof _==`object`?await i.writeFill({...s,fill:_},v,[u],f):(await(0,o.writeContentDeclaration)(s,f),s.filePath&&p(`${e.dictionaryPreset} Content declaration written to ${(0,c.formatPath)((0,a.basename)(s.filePath))}`,{level:`info`}))}));await Promise.all(k),await D.onIdle()};exports.fill=d;
2
2
  //# sourceMappingURL=fill.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatFillData.cjs","names":[],"sources":["../../../src/fill/formatFillData.ts"],"sourcesContent":["import { basename, dirname, extname, relative } from 'node:path';\nimport {\n getFormatFromExtension,\n resolveRelativePath,\n} from '@intlayer/chokidar/utils';\nimport { parseStringPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { DictionaryKey, Fill } from '@intlayer/types/dictionary';\nimport type {\n FilePathPattern,\n FilePathPatternContext,\n} from '@intlayer/types/filePathPattern';\n\nexport type FillData = {\n localeList: Locale[];\n filePath: string;\n isPerLocale: boolean;\n};\n\nexport const formatFillData = async (\n fillField: Fill,\n localeList: Locale[],\n filePath: string,\n dictionaryKey: DictionaryKey,\n configuration: IntlayerConfig\n): Promise<FillData[]> => {\n if (!fillField || typeof fillField === 'boolean') return [];\n\n const { baseDir } = configuration.system;\n const { defaultLocale } = configuration.internationalization;\n\n const extension = extname(filePath);\n const base = basename(filePath);\n\n // Extract the original filename without extensions\n const cleanComponentFileName = base.includes('.content.')\n ? base.split('.content.')[0]\n : base.split('.')[0];\n\n const uncapitalizedName =\n cleanComponentFileName.charAt(0).toLowerCase() +\n cleanComponentFileName.slice(1);\n\n const componentFormat = getFormatFromExtension(extension as any);\n\n const getContext = (\n locale: Locale,\n patternType?: FilePathPattern\n ): FilePathPatternContext => {\n let format: FilePathPatternContext['format'] = 'json';\n if (typeof patternType === 'string') {\n const extFormat = getFormatFromExtension(extname(patternType) as any);\n if (extFormat) {\n format = extFormat as any;\n }\n }\n\n return {\n key: dictionaryKey,\n componentDirPath: relative(baseDir, dirname(filePath)),\n componentFileName: cleanComponentFileName,\n fileName: uncapitalizedName,\n componentFormat:\n componentFormat as FilePathPatternContext['componentFormat'],\n componentExtension:\n extension as FilePathPatternContext['componentExtension'],\n format,\n locale,\n extension: configuration.content.fileExtensions[0] as any,\n };\n };\n\n const processPattern = async (\n pattern: FilePathPattern,\n locales: Locale[]\n ): Promise<FillData[]> => {\n const dummyLocale = '###########locale###########' as Locale;\n let isPatternPerLocale = false;\n\n if (typeof pattern === 'string') {\n isPatternPerLocale = pattern.includes('{{locale}}');\n } else if (typeof pattern === 'function') {\n const pathWithDummy = await pattern(getContext(dummyLocale, pattern));\n isPatternPerLocale = pathWithDummy.includes(dummyLocale);\n }\n\n if (isPatternPerLocale) {\n const resolvedPaths: FillData[] = [];\n\n // Generate one path per locale\n for (const locale of locales) {\n const rawPath =\n typeof pattern === 'string'\n ? parseStringPattern(pattern, getContext(locale, pattern))\n : await pattern(getContext(locale, pattern));\n\n const absolutePath = resolveRelativePath(rawPath, filePath, baseDir);\n\n resolvedPaths.push({\n filePath: absolutePath,\n localeList: [locale],\n isPerLocale: true,\n });\n }\n\n // Group by filePath in case multiple locales resolve to the same path\n const groupedByFilePath = resolvedPaths.reduce((acc, curr) => {\n const existing = acc.find((item) => item.filePath === curr.filePath);\n if (existing) {\n if (!existing.localeList.includes(curr.localeList[0])) {\n existing.localeList.push(...curr.localeList);\n }\n // If multiple locales share a path, it's no longer strictly per-locale\n existing.isPerLocale = false;\n } else {\n acc.push(curr);\n }\n return acc;\n }, [] as FillData[]);\n\n return groupedByFilePath;\n } else {\n // Single multi-lingual path using default locale for pattern resolution\n const rawPath =\n typeof pattern === 'string'\n ? parseStringPattern(pattern, getContext(defaultLocale, pattern))\n : await pattern(getContext(defaultLocale, pattern));\n\n const absolutePath = resolveRelativePath(rawPath, filePath, baseDir);\n\n return [\n {\n filePath: absolutePath,\n localeList: locales,\n isPerLocale: false,\n },\n ];\n }\n };\n\n // 1. Handle Record of Locales\n if (typeof fillField === 'object' && fillField !== null) {\n const results: FillData[] = [];\n\n for (const locale of localeList) {\n const pattern = (fillField as Record<string, any>)[locale];\n if (pattern && typeof pattern !== 'boolean') {\n const res = await processPattern(pattern as FilePathPattern, [locale]);\n results.push(...res);\n }\n }\n\n // Merge identical file paths if they stem from different locales having the same output path\n const grouped = results.reduce((acc, curr) => {\n const existing = acc.find((item) => item.filePath === curr.filePath);\n if (existing) {\n for (const loc of curr.localeList) {\n if (!existing.localeList.includes(loc)) {\n existing.localeList.push(loc);\n }\n }\n existing.isPerLocale = false;\n } else {\n acc.push(curr);\n }\n return acc;\n }, [] as FillData[]);\n\n return grouped;\n }\n\n // 2. Handle static string or function patterns\n if (typeof fillField === 'string' || typeof fillField === 'function') {\n return processPattern(fillField as FilePathPattern, localeList);\n }\n\n return [];\n};\n"],"mappings":"qNAoBA,MAAa,EAAiB,MAC5B,EACA,EACA,EACA,EACA,IACwB,CACxB,GAAI,CAAC,GAAa,OAAO,GAAc,UAAW,MAAO,EAAE,CAE3D,GAAM,CAAE,WAAY,EAAc,OAC5B,CAAE,iBAAkB,EAAc,qBAElC,GAAA,EAAA,EAAA,SAAoB,EAAS,CAC7B,GAAA,EAAA,EAAA,UAAgB,EAAS,CAGzB,EAAyB,EAAK,SAAS,YAAY,CACrD,EAAK,MAAM,YAAY,CAAC,GACxB,EAAK,MAAM,IAAI,CAAC,GAEd,EACJ,EAAuB,OAAO,EAAE,CAAC,aAAa,CAC9C,EAAuB,MAAM,EAAE,CAE3B,GAAA,EAAA,EAAA,wBAAyC,EAAiB,CAE1D,GACJ,EACA,IAC2B,CAC3B,IAAI,EAA2C,OAC/C,GAAI,OAAO,GAAgB,SAAU,CACnC,IAAM,GAAA,EAAA,EAAA,yBAAA,EAAA,EAAA,SAA2C,EAAY,CAAQ,CACjE,IACF,EAAS,GAIb,MAAO,CACL,IAAK,EACL,kBAAA,EAAA,EAAA,UAA2B,GAAA,EAAA,EAAA,SAAiB,EAAS,CAAC,CACtD,kBAAmB,EACnB,SAAU,EAER,kBACF,mBACE,EACF,SACA,SACA,UAAW,EAAc,QAAQ,eAAe,GACjD,EAGG,EAAiB,MACrB,EACA,IACwB,CACxB,IAAM,EAAc,+BAChB,EAAqB,GASzB,GAPI,OAAO,GAAY,SACrB,EAAqB,EAAQ,SAAS,aAAa,CAC1C,OAAO,GAAY,aAE5B,GADsB,MAAM,EAAQ,EAAW,EAAa,EAAQ,CAAC,EAClC,SAAS,EAAY,EAGtD,EAAoB,CACtB,IAAM,EAA4B,EAAE,CAGpC,IAAK,IAAM,KAAU,EAAS,CAM5B,IAAM,GAAA,EAAA,EAAA,qBAJJ,OAAO,GAAY,UAAA,EAAA,EAAA,oBACI,EAAS,EAAW,EAAQ,EAAQ,CAAC,CACxD,MAAM,EAAQ,EAAW,EAAQ,EAAQ,CAAC,CAEE,EAAU,EAAQ,CAEpE,EAAc,KAAK,CACjB,SAAU,EACV,WAAY,CAAC,EAAO,CACpB,YAAa,GACd,CAAC,CAkBJ,OAd0B,EAAc,QAAQ,EAAK,IAAS,CAC5D,IAAM,EAAW,EAAI,KAAM,GAAS,EAAK,WAAa,EAAK,SAAS,CAUpE,OATI,GACG,EAAS,WAAW,SAAS,EAAK,WAAW,GAAG,EACnD,EAAS,WAAW,KAAK,GAAG,EAAK,WAAW,CAG9C,EAAS,YAAc,IAEvB,EAAI,KAAK,EAAK,CAET,GACN,EAAE,CAAe,MAYpB,MAAO,CACL,CACE,UAAA,EAAA,EAAA,qBARF,OAAO,GAAY,UAAA,EAAA,EAAA,oBACI,EAAS,EAAW,EAAe,EAAQ,CAAC,CAC/D,MAAM,EAAQ,EAAW,EAAe,EAAQ,CAAC,CAEL,EAAU,EAAQ,CAKhE,WAAY,EACZ,YAAa,GACd,CACF,EAKL,GAAI,OAAO,GAAc,UAAY,EAAoB,CACvD,IAAM,EAAsB,EAAE,CAE9B,IAAK,IAAM,KAAU,EAAY,CAC/B,IAAM,EAAW,EAAkC,GACnD,GAAI,GAAW,OAAO,GAAY,UAAW,CAC3C,IAAM,EAAM,MAAM,EAAe,EAA4B,CAAC,EAAO,CAAC,CACtE,EAAQ,KAAK,GAAG,EAAI,EAoBxB,OAfgB,EAAQ,QAAQ,EAAK,IAAS,CAC5C,IAAM,EAAW,EAAI,KAAM,GAAS,EAAK,WAAa,EAAK,SAAS,CACpE,GAAI,EAAU,CACZ,IAAK,IAAM,KAAO,EAAK,WAChB,EAAS,WAAW,SAAS,EAAI,EACpC,EAAS,WAAW,KAAK,EAAI,CAGjC,EAAS,YAAc,QAEvB,EAAI,KAAK,EAAK,CAEhB,OAAO,GACN,EAAE,CAAe,CAUtB,OAJI,OAAO,GAAc,UAAY,OAAO,GAAc,WACjD,EAAe,EAA8B,EAAW,CAG1D,EAAE"}
1
+ {"version":3,"file":"formatFillData.cjs","names":[],"sources":["../../../src/fill/formatFillData.ts"],"sourcesContent":["import { basename, dirname, extname, relative } from 'node:path';\nimport {\n getFormatFromExtension,\n resolveRelativePath,\n} from '@intlayer/chokidar/utils';\nimport { parseStringPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { DictionaryKey, Fill } from '@intlayer/types/dictionary';\nimport type {\n FilePathPattern,\n FilePathPatternContext,\n} from '@intlayer/types/filePathPattern';\n\nexport type FillData = {\n localeList: Locale[];\n filePath: string;\n isPerLocale: boolean;\n};\n\nexport const formatFillData = async (\n fillField: Fill,\n localeList: Locale[],\n filePath: string,\n dictionaryKey: DictionaryKey,\n configuration: IntlayerConfig\n): Promise<FillData[]> => {\n if (!fillField || typeof fillField === 'boolean') return [];\n\n const { baseDir } = configuration.system;\n const { defaultLocale } = configuration.internationalization;\n\n const extension = extname(filePath);\n const base = basename(filePath);\n\n // Extract the original filename without extensions\n const cleanComponentFileName = base.includes('.content.')\n ? base.split('.content.')[0]\n : base.split('.')[0];\n\n const uncapitalizedName =\n cleanComponentFileName.charAt(0).toLowerCase() +\n cleanComponentFileName.slice(1);\n\n const componentFormat = getFormatFromExtension(extension);\n\n const getContext = (\n locale: Locale,\n patternType?: FilePathPattern\n ): FilePathPatternContext => {\n let format: FilePathPatternContext['format'] = 'json';\n if (typeof patternType === 'string') {\n const extFormat = getFormatFromExtension(extname(patternType) as any);\n if (extFormat) {\n format = extFormat as any;\n }\n }\n\n return {\n key: dictionaryKey,\n componentDirPath: relative(baseDir, dirname(filePath)),\n componentFileName: cleanComponentFileName,\n fileName: uncapitalizedName,\n componentFormat:\n componentFormat as FilePathPatternContext['componentFormat'],\n componentExtension:\n extension as FilePathPatternContext['componentExtension'],\n format,\n locale,\n extension: configuration.content.fileExtensions[0],\n };\n };\n\n const processPattern = async (\n pattern: FilePathPattern,\n locales: Locale[]\n ): Promise<FillData[]> => {\n const dummyLocale = '###########locale###########' as Locale;\n let isPatternPerLocale = false;\n\n if (typeof pattern === 'string') {\n isPatternPerLocale = pattern.includes('{{locale}}');\n } else if (typeof pattern === 'function') {\n const pathWithDummy = await pattern(getContext(dummyLocale, pattern));\n isPatternPerLocale = pathWithDummy.includes(dummyLocale);\n }\n\n if (isPatternPerLocale) {\n const resolvedPaths: FillData[] = [];\n\n // Generate one path per locale\n for (const locale of locales) {\n const rawPath =\n typeof pattern === 'string'\n ? parseStringPattern(pattern, getContext(locale, pattern))\n : await pattern(getContext(locale, pattern));\n\n const absolutePath = resolveRelativePath(rawPath, filePath, baseDir);\n\n resolvedPaths.push({\n filePath: absolutePath,\n localeList: [locale],\n isPerLocale: true,\n });\n }\n\n // Group by filePath in case multiple locales resolve to the same path\n const groupedByFilePath = resolvedPaths.reduce((acc, curr) => {\n const existing = acc.find((item) => item.filePath === curr.filePath);\n if (existing) {\n if (!existing.localeList.includes(curr.localeList[0])) {\n existing.localeList.push(...curr.localeList);\n }\n // If multiple locales share a path, it's no longer strictly per-locale\n existing.isPerLocale = false;\n } else {\n acc.push(curr);\n }\n return acc;\n }, [] as FillData[]);\n\n return groupedByFilePath;\n } else {\n // Single multi-lingual path using default locale for pattern resolution\n const rawPath =\n typeof pattern === 'string'\n ? parseStringPattern(pattern, getContext(defaultLocale, pattern))\n : await pattern(getContext(defaultLocale, pattern));\n\n const absolutePath = resolveRelativePath(rawPath, filePath, baseDir);\n\n return [\n {\n filePath: absolutePath,\n localeList: locales,\n isPerLocale: false,\n },\n ];\n }\n };\n\n // Handle Record of Locales\n if (typeof fillField === 'object' && fillField !== null) {\n const results: FillData[] = [];\n\n for (const locale of localeList) {\n const pattern = (fillField as Record<string, any>)[locale];\n if (pattern && typeof pattern !== 'boolean') {\n const res = await processPattern(pattern as FilePathPattern, [locale]);\n results.push(...res);\n }\n }\n\n // Merge identical file paths if they stem from different locales having the same output path\n const grouped = results.reduce((acc, curr) => {\n const existing = acc.find((item) => item.filePath === curr.filePath);\n if (existing) {\n for (const loc of curr.localeList) {\n if (!existing.localeList.includes(loc)) {\n existing.localeList.push(loc);\n }\n }\n existing.isPerLocale = false;\n } else {\n acc.push(curr);\n }\n return acc;\n }, [] as FillData[]);\n\n return grouped;\n }\n\n // Handle static string or function patterns\n if (typeof fillField === 'string' || typeof fillField === 'function') {\n return processPattern(fillField as FilePathPattern, localeList);\n }\n\n return [];\n};\n"],"mappings":"qNAoBA,MAAa,EAAiB,MAC5B,EACA,EACA,EACA,EACA,IACwB,CACxB,GAAI,CAAC,GAAa,OAAO,GAAc,UAAW,MAAO,EAAE,CAE3D,GAAM,CAAE,WAAY,EAAc,OAC5B,CAAE,iBAAkB,EAAc,qBAElC,GAAA,EAAA,EAAA,SAAoB,EAAS,CAC7B,GAAA,EAAA,EAAA,UAAgB,EAAS,CAGzB,EAAyB,EAAK,SAAS,YAAY,CACrD,EAAK,MAAM,YAAY,CAAC,GACxB,EAAK,MAAM,IAAI,CAAC,GAEd,EACJ,EAAuB,OAAO,EAAE,CAAC,aAAa,CAC9C,EAAuB,MAAM,EAAE,CAE3B,GAAA,EAAA,EAAA,wBAAyC,EAAU,CAEnD,GACJ,EACA,IAC2B,CAC3B,IAAI,EAA2C,OAC/C,GAAI,OAAO,GAAgB,SAAU,CACnC,IAAM,GAAA,EAAA,EAAA,yBAAA,EAAA,EAAA,SAA2C,EAAY,CAAQ,CACjE,IACF,EAAS,GAIb,MAAO,CACL,IAAK,EACL,kBAAA,EAAA,EAAA,UAA2B,GAAA,EAAA,EAAA,SAAiB,EAAS,CAAC,CACtD,kBAAmB,EACnB,SAAU,EAER,kBACF,mBACE,EACF,SACA,SACA,UAAW,EAAc,QAAQ,eAAe,GACjD,EAGG,EAAiB,MACrB,EACA,IACwB,CACxB,IAAM,EAAc,+BAChB,EAAqB,GASzB,GAPI,OAAO,GAAY,SACrB,EAAqB,EAAQ,SAAS,aAAa,CAC1C,OAAO,GAAY,aAE5B,GADsB,MAAM,EAAQ,EAAW,EAAa,EAAQ,CAAC,EAClC,SAAS,EAAY,EAGtD,EAAoB,CACtB,IAAM,EAA4B,EAAE,CAGpC,IAAK,IAAM,KAAU,EAAS,CAM5B,IAAM,GAAA,EAAA,EAAA,qBAJJ,OAAO,GAAY,UAAA,EAAA,EAAA,oBACI,EAAS,EAAW,EAAQ,EAAQ,CAAC,CACxD,MAAM,EAAQ,EAAW,EAAQ,EAAQ,CAAC,CAEE,EAAU,EAAQ,CAEpE,EAAc,KAAK,CACjB,SAAU,EACV,WAAY,CAAC,EAAO,CACpB,YAAa,GACd,CAAC,CAkBJ,OAd0B,EAAc,QAAQ,EAAK,IAAS,CAC5D,IAAM,EAAW,EAAI,KAAM,GAAS,EAAK,WAAa,EAAK,SAAS,CAUpE,OATI,GACG,EAAS,WAAW,SAAS,EAAK,WAAW,GAAG,EACnD,EAAS,WAAW,KAAK,GAAG,EAAK,WAAW,CAG9C,EAAS,YAAc,IAEvB,EAAI,KAAK,EAAK,CAET,GACN,EAAE,CAAe,MAYpB,MAAO,CACL,CACE,UAAA,EAAA,EAAA,qBARF,OAAO,GAAY,UAAA,EAAA,EAAA,oBACI,EAAS,EAAW,EAAe,EAAQ,CAAC,CAC/D,MAAM,EAAQ,EAAW,EAAe,EAAQ,CAAC,CAEL,EAAU,EAAQ,CAKhE,WAAY,EACZ,YAAa,GACd,CACF,EAKL,GAAI,OAAO,GAAc,UAAY,EAAoB,CACvD,IAAM,EAAsB,EAAE,CAE9B,IAAK,IAAM,KAAU,EAAY,CAC/B,IAAM,EAAW,EAAkC,GACnD,GAAI,GAAW,OAAO,GAAY,UAAW,CAC3C,IAAM,EAAM,MAAM,EAAe,EAA4B,CAAC,EAAO,CAAC,CACtE,EAAQ,KAAK,GAAG,EAAI,EAoBxB,OAfgB,EAAQ,QAAQ,EAAK,IAAS,CAC5C,IAAM,EAAW,EAAI,KAAM,GAAS,EAAK,WAAa,EAAK,SAAS,CACpE,GAAI,EAAU,CACZ,IAAK,IAAM,KAAO,EAAK,WAChB,EAAS,WAAW,SAAS,EAAI,EACpC,EAAS,WAAW,KAAK,EAAI,CAGjC,EAAS,YAAc,QAEvB,EAAI,KAAK,EAAK,CAEhB,OAAO,GACN,EAAE,CAAe,CAUtB,OAJI,OAAO,GAAc,UAAY,OAAO,GAAc,WACjD,EAAe,EAA8B,EAAW,CAG1D,EAAE"}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../test/listMissingTranslations.cjs`);let t=require(`node:path`),n=require(`@intlayer/config/logger`),r=require(`@intlayer/unmerged-dictionaries-entry`),i=require(`@intlayer/chokidar/utils`),a=require(`@intlayer/core/plugins`),o=require(`@intlayer/dictionaries-entry`);const s=(s,c,l,u,d)=>{let f=(0,n.getAppLogger)(d),p=(0,o.getDictionaries)(d),m=(0,r.getUnmergedDictionaries)(d),h=Object.values(m).flat().filter(e=>s.includes(e.localId)),{missingTranslations:g}=e.listMissingTranslationsWithConfig(d),_=Math.max(...h.map(e=>e.key.length)),v=[];for(let e of h){let r=(0,n.colon)([` - `,(0,n.colorize)(`[`,n.ANSIColors.GREY_DARK),(0,n.colorizeKey)(e.key),(0,n.colorize)(`]`,n.ANSIColors.GREY_DARK)].join(``),{colSize:_+6}),o=e.key,s=e.localId,m=p[o];if((e.filled??!1)===!0||(e.fill??d.dictionary?.fill??!1)===!1)continue;let h=e.locale??u;if(!m){f(`${r} Dictionary not found in dictionariesRecord. Skipping.`,{level:`warn`});continue}if(!e.filePath){f(`${r} Dictionary has no file path. Skipping.`,{level:`warn`});continue}let y=(0,a.getFilterTranslationsOnlyDictionary)(m,h);if(Object.keys(y).length===0){f(`${r} No content found for dictionary in source locale ${(0,i.formatLocale)(h)}. Skipping translation for this dictionary.`,{level:`warn`});continue}let b=c;if(l===`complete`&&(b=g.find(e=>e.key===o)?.locales.filter(e=>c.includes(e))??[]),b.length===0){f(`${r} ${(0,n.colorize)(`No locales to fill, Skipping`,n.ANSIColors.GREY_DARK)} ${(0,n.colorizePath)((0,t.basename)(e.filePath))}`,{level:`warn`});continue}v.push({dictionaryKey:o,dictionaryLocalId:s,sourceLocale:h,targetLocales:b,dictionaryPreset:r,dictionaryFilePath:e.filePath})}return v};exports.listTranslationsTasks=s;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../test/listMissingTranslations.cjs`);let t=require(`node:path`),n=require(`@intlayer/chokidar/utils`),r=require(`@intlayer/config/logger`),i=require(`@intlayer/unmerged-dictionaries-entry`),a=require(`@intlayer/core/plugins`),o=require(`@intlayer/dictionaries-entry`);const s=(s,c,l,u,d)=>{let f=(0,r.getAppLogger)(d),p=(0,o.getDictionaries)(d),m=(0,i.getUnmergedDictionaries)(d),h=Object.values(m).flat().filter(e=>s.includes(e.localId)),{missingTranslations:g}=e.listMissingTranslationsWithConfig(d),_=Math.max(...h.map(e=>e.key.length)),v=[];for(let e of h){let i=(0,r.colon)([` - `,(0,r.colorize)(`[`,r.ANSIColors.GREY_DARK),(0,r.colorizeKey)(e.key),(0,r.colorize)(`]`,r.ANSIColors.GREY_DARK)].join(``),{colSize:_+6}),o=e.key,s=e.localId,m=p[o];if((e.filled??!1)===!0||(e.fill??d.dictionary?.fill??!1)===!1)continue;let h=e.locale??u;if(!m){f(`${i} Dictionary not found in dictionariesRecord. Skipping.`,{level:`warn`});continue}if(!e.filePath){f(`${i} Dictionary has no file path. Skipping.`,{level:`warn`});continue}let y=(0,a.getFilterTranslationsOnlyDictionary)(m,h);if(Object.keys(y).length===0){f(`${i} No content found for dictionary in source locale ${(0,n.formatLocale)(h)}. Skipping translation for this dictionary.`,{level:`warn`});continue}let b=c;if(l===`complete`&&(b=g.find(e=>e.key===o)?.locales.filter(e=>c.includes(e))??[]),b.length===0){f(`${i} ${(0,r.colorize)(`No locales to fill, Skipping`,r.ANSIColors.GREY_DARK)} ${(0,r.colorizePath)((0,t.basename)(e.filePath))}`,{level:`warn`});continue}v.push({dictionaryKey:o,dictionaryLocalId:s,sourceLocale:h,targetLocales:b,dictionaryPreset:i,dictionaryFilePath:e.filePath})}return v};exports.listTranslationsTasks=s;
2
2
  //# sourceMappingURL=listTranslationsTasks.cjs.map
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./deepMergeContent.cjs`),t=require(`./getFilterMissingContentPerLocale.cjs`);let n=require(`node:path`),r=require(`@intlayer/config/logger`),i=require(`@intlayer/unmerged-dictionaries-entry`),a=require(`@intlayer/chokidar/utils`),o=require(`@intlayer/core/plugins`),s=require(`@intlayer/api`),c=require(`@intlayer/config/utils`);const l=e=>!e.description||!e.title||!e.tags,u=e=>{if(typeof e!=`object`||!e||Array.isArray(e))return{content:e,nulls:void 0,hasNulls:!1};let t={},n={},r=!1;for(let[i,a]of Object.entries(e))if(a===null)n[i]=null,r=!0;else{let e=u(a);t[i]=e.content,e.hasNulls&&(n[i]=e.nulls,r=!0)}return{content:t,nulls:r?n:void 0,hasNulls:r}},d=1e3*10;let f=0;const p=async(p,m,h)=>{let g=(0,r.getAppLogger)(m),_=(0,s.getIntlayerAPIProxy)(void 0,m),{mode:v,aiOptions:y,fillMetadata:b,aiClient:x,aiConfig:S}={mode:`complete`,fillMetadata:!0,...h},C=()=>{f=0,h?.onSuccess?.()};return await(0,c.retryManager)(async()=>{let s=(0,i.getUnmergedDictionaries)(m),w=s[p.dictionaryKey].find(e=>e.localId===p.dictionaryLocalId);if(!w)return g(`${p.dictionaryPreset}Dictionary not found in unmergedDictionariesRecord. Skipping.`,{level:`warn`}),{...p,dictionaryOutput:null};let T;if(b&&(l(w)||v===`review`)){let e=(0,o.getPerLocaleDictionary)(w,m.internationalization.defaultLocale);g(`${p.dictionaryPreset} Filling missing metadata for ${(0,r.colorizePath)((0,n.basename)(w.filePath))}`,{level:`info`});let t=async()=>x&&S?{data:await x.auditDictionaryMetadata({fileContent:JSON.stringify(e),aiConfig:S})}:await _.ai.auditContentDeclarationMetadata({fileContent:JSON.stringify(e),aiOptions:y});T=(h?.onHandle?await h.onHandle(t):await t()).data?.fileContent}let E=await Promise.all(p.targetLocales.map(async i=>{let l=structuredClone(w),m;if(typeof w.locale==`string`){let e=w.filePath?.replace(RegExp(`/${p.sourceLocale}/`,`g`),`/${i}/`),n=e?s[p.dictionaryKey]?.find(t=>t.filePath===e&&t.locale===i):void 0;m=n??{key:w.key,content:{},filePath:e,locale:i},v===`complete`&&(l=t.getFilterMissingContentPerLocale(l,n))}else v===`complete`&&(l=(0,o.getFilterMissingTranslationsDictionary)(l,i)),l=(0,o.getPerLocaleDictionary)(l,p.sourceLocale),m=(0,o.getPerLocaleDictionary)(w,i);let b=(0,r.colon)([(0,r.colorize)(`[`,r.ANSIColors.GREY_DARK),(0,a.formatLocale)(i),(0,r.colorize)(`]`,r.ANSIColors.GREY_DARK)].join(``),{colSize:18}),E=(e,t)=>t<=1?``:(0,r.colon)([(0,r.colorize)(`[`,r.ANSIColors.GREY_DARK),(0,r.colorizeNumber)(e+1),(0,r.colorize)(`/${t}`,r.ANSIColors.GREY_DARK),(0,r.colorize)(`]`,r.ANSIColors.GREY_DARK)].join(``),{colSize:5});g(`${p.dictionaryPreset}${b} Preparing ${(0,r.colorizePath)((0,n.basename)(m.filePath))}`,{level:`info`});let D=typeof l.content==`object`&&l.content!==null||Array.isArray(l.content),{content:O,nulls:k}=u(D?l.content:{__INTLAYER_ROOT_PRIMITIVE_CONTENT__:l.content}),A=(0,a.chunkJSON)(O,7e3),j=A.length;j>1&&g(`${p.dictionaryPreset}${b} Split into ${(0,r.colorizeNumber)(j)} chunks for translation`,{level:`info`});let M=[],N=A.map(e=>{let t=E(e.index,e.total);j>1&&g(`${p.dictionaryPreset}${b}${t} Translating chunk`,{level:`info`});let n=(0,a.reconstructFromSingleChunk)(e),o=(0,a.reduceObjectFormat)(D?m.content:{__INTLAYER_ROOT_PRIMITIVE_CONTENT__:m.content},n),s=async()=>await(0,c.retryManager)(async()=>{let e;if(e=x&&S?await x.translateJSON({entryFileContent:n,presetOutputContent:o,dictionaryDescription:l.description??T?.description??``,entryLocale:p.sourceLocale,outputLocale:i,mode:v,aiConfig:S}):await _.ai.translateJSON({entryFileContent:n,presetOutputContent:o,dictionaryDescription:l.description??T?.description??``,entryLocale:p.sourceLocale,outputLocale:i,mode:v,aiOptions:y}).then(e=>e.data),!e?.fileContent)throw Error(`No content result`);let{isIdentic:t}=(0,a.verifyIdenticObjectFormat)(e.fileContent,n);if(!t)throw Error(`Translation result does not match expected format`);return C(),e.fileContent},{maxRetry:3,delay:d,onError:({error:t,attempt:n,maxRetry:i})=>{let a=E(e.index,e.total);g(`${p.dictionaryPreset}${b}${a} ${(0,r.colorize)(`Error filling:`,r.ANSIColors.RED)} ${(0,r.colorize)(typeof t==`string`?t:JSON.stringify(t),r.ANSIColors.GREY_DARK)} - Attempt ${(0,r.colorizeNumber)(n+1)} of ${(0,r.colorizeNumber)(i)}`,{level:`error`}),f+=1,f>=10&&(g(`There is something wrong.`,{level:`error`}),process.exit(1))}})();return(h?.onHandle?h.onHandle(s):s()).then(t=>({chunk:e,result:t}))});(await Promise.all(N)).sort((e,t)=>e.chunk.index-t.chunk.index).forEach(({result:e})=>{M.push(e)});let P=(0,a.mergeChunks)(M);k&&(P=e.deepMergeContent(P,k));let F={...l,content:P}.content;return D||(F=F?.__INTLAYER_ROOT_PRIMITIVE_CONTENT__),typeof w.locale==`string`&&(F=e.deepMergeContent(m.content??{},F)),[i,F]})),D=Object.fromEntries(E),O={...(0,o.getMultilingualDictionary)(w.locale?{...w,key:w.key,content:{}}:w),locale:void 0,...T};for(let e of p.targetLocales)D[e]&&(O=(0,o.insertContentInDictionary)(O,D[e],e));if(g(`${p.dictionaryPreset} ${(0,r.colorize)(`Translation completed successfully`,r.ANSIColors.GREEN)} for ${(0,r.colorizePath)((0,n.basename)(O.filePath))}`,{level:`info`}),w.locale&&(w.fill===!0||w.fill===void 0)&&w.location===`local`){let e=w.filePath.split(`.`).slice(0,-1),t=e[e.length-1];return JSON.parse(JSON.stringify({...p,dictionaryOutput:{...O,fill:void 0,filled:!0}}).replaceAll(RegExp(`\\.${t}\\.[a-zA-Z0-9]+`,`g`),`.filled.${t}.json`))}return{...p,dictionaryOutput:O}},{maxRetry:2,delay:d,onError:({error:e,attempt:t,maxRetry:n})=>g(`${p.dictionaryPreset} ${(0,r.colorize)(`Error:`,r.ANSIColors.RED)} ${(0,r.colorize)(typeof e==`string`?e:JSON.stringify(e),r.ANSIColors.GREY_DARK)} - Attempt ${(0,r.colorizeNumber)(t+1)} of ${(0,r.colorizeNumber)(n)}`,{level:`error`}),onMaxTryReached:({error:e})=>g(`${p.dictionaryPreset} ${(0,r.colorize)(`Maximum number of retries reached:`,r.ANSIColors.RED)} ${(0,r.colorize)(typeof e==`string`?e:JSON.stringify(e),r.ANSIColors.GREY_DARK)}`,{level:`error`})})()};exports.translateDictionary=p;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./deepMergeContent.cjs`),t=require(`./getFilterMissingContentPerLocale.cjs`);let n=require(`node:path`),r=require(`@intlayer/chokidar/utils`),i=require(`@intlayer/config/logger`),a=require(`@intlayer/unmerged-dictionaries-entry`),o=require(`@intlayer/core/plugins`),s=require(`@intlayer/api`),c=require(`@intlayer/config/utils`);const l=e=>!e.description||!e.title||!e.tags,u=e=>{if(typeof e!=`object`||!e||Array.isArray(e))return{content:e,nulls:void 0,hasNulls:!1};let t={},n={},r=!1;for(let[i,a]of Object.entries(e))if(a===null)n[i]=null,r=!0;else{let e=u(a);t[i]=e.content,e.hasNulls&&(n[i]=e.nulls,r=!0)}return{content:t,nulls:r?n:void 0,hasNulls:r}},d=1e3*10;let f=0;const p=async(p,m,h)=>{let g=(0,i.getAppLogger)(m),_=(0,s.getIntlayerAPIProxy)(void 0,m),{mode:v,aiOptions:y,fillMetadata:b,aiClient:x,aiConfig:S}={mode:`complete`,fillMetadata:!0,...h},C=()=>{f=0,h?.onSuccess?.()};return await(0,c.retryManager)(async()=>{let s=(0,a.getUnmergedDictionaries)(m),w=s[p.dictionaryKey].find(e=>e.localId===p.dictionaryLocalId);if(!w)return g(`${p.dictionaryPreset}Dictionary not found in unmergedDictionariesRecord. Skipping.`,{level:`warn`}),{...p,dictionaryOutput:null};let T;if(b&&(l(w)||v===`review`)){let e=(0,o.getPerLocaleDictionary)(w,m.internationalization.defaultLocale);g(`${p.dictionaryPreset} Filling missing metadata for ${(0,i.colorizePath)((0,n.basename)(w.filePath))}`,{level:`info`});let t=async()=>x&&S?{data:await x.auditDictionaryMetadata({fileContent:JSON.stringify(e),aiConfig:S})}:await _.ai.auditContentDeclarationMetadata({fileContent:JSON.stringify(e),aiOptions:y});T=(h?.onHandle?await h.onHandle(t):await t()).data?.fileContent}let E=await Promise.all(p.targetLocales.map(async a=>{let l=structuredClone(w),m;if(typeof w.locale==`string`){let e=w.filePath?.replace(RegExp(`/${p.sourceLocale}/`,`g`),`/${a}/`),n=e?s[p.dictionaryKey]?.find(t=>t.filePath===e&&t.locale===a):void 0;m=n??{key:w.key,content:{},filePath:e,locale:a},v===`complete`&&(l=t.getFilterMissingContentPerLocale(l,n))}else v===`complete`&&(l=(0,o.getFilterMissingTranslationsDictionary)(l,a)),l=(0,o.getPerLocaleDictionary)(l,p.sourceLocale),m=(0,o.getPerLocaleDictionary)(w,a);let b=(0,i.colon)([(0,i.colorize)(`[`,i.ANSIColors.GREY_DARK),(0,r.formatLocale)(a),(0,i.colorize)(`]`,i.ANSIColors.GREY_DARK)].join(``),{colSize:18}),E=(e,t)=>t<=1?``:(0,i.colon)([(0,i.colorize)(`[`,i.ANSIColors.GREY_DARK),(0,i.colorizeNumber)(e+1),(0,i.colorize)(`/${t}`,i.ANSIColors.GREY_DARK),(0,i.colorize)(`]`,i.ANSIColors.GREY_DARK)].join(``),{colSize:5});g(`${p.dictionaryPreset}${b} Preparing ${(0,i.colorizePath)((0,n.basename)(m.filePath))}`,{level:`info`});let D=typeof l.content==`object`&&l.content!==null||Array.isArray(l.content),{content:O,nulls:k}=u(D?l.content:{__INTLAYER_ROOT_PRIMITIVE_CONTENT__:l.content}),A=(0,r.chunkJSON)(O,7e3),j=A.length;j>1&&g(`${p.dictionaryPreset}${b} Split into ${(0,i.colorizeNumber)(j)} chunks for translation`,{level:`info`});let M=[],N=A.map(e=>{let t=E(e.index,e.total);j>1&&g(`${p.dictionaryPreset}${b}${t} Translating chunk`,{level:`info`});let n=(0,r.reconstructFromSingleChunk)(e),o=(0,r.reduceObjectFormat)(D?m.content:{__INTLAYER_ROOT_PRIMITIVE_CONTENT__:m.content},n),s=async()=>await(0,c.retryManager)(async()=>{let e;if(e=x&&S?await x.translateJSON({entryFileContent:n,presetOutputContent:o,dictionaryDescription:l.description??T?.description??``,entryLocale:p.sourceLocale,outputLocale:a,mode:v,aiConfig:S}):await _.ai.translateJSON({entryFileContent:n,presetOutputContent:o,dictionaryDescription:l.description??T?.description??``,entryLocale:p.sourceLocale,outputLocale:a,mode:v,aiOptions:y}).then(e=>e.data),!e?.fileContent)throw Error(`No content result`);let{isIdentic:t}=(0,r.verifyIdenticObjectFormat)(e.fileContent,n);if(!t)throw Error(`Translation result does not match expected format`);return C(),e.fileContent},{maxRetry:3,delay:d,onError:({error:t,attempt:n,maxRetry:r})=>{let a=E(e.index,e.total);g(`${p.dictionaryPreset}${b}${a} ${(0,i.colorize)(`Error filling:`,i.ANSIColors.RED)} ${(0,i.colorize)(typeof t==`string`?t:JSON.stringify(t),i.ANSIColors.GREY_DARK)} - Attempt ${(0,i.colorizeNumber)(n+1)} of ${(0,i.colorizeNumber)(r)}`,{level:`error`}),f+=1,f>=10&&(g(`There is something wrong.`,{level:`error`}),process.exit(1))}})();return(h?.onHandle?h.onHandle(s):s()).then(t=>({chunk:e,result:t}))});(await Promise.all(N)).sort((e,t)=>e.chunk.index-t.chunk.index).forEach(({result:e})=>{M.push(e)});let P=(0,r.mergeChunks)(M);k&&(P=e.deepMergeContent(P,k));let F={...l,content:P}.content;return D||(F=F?.__INTLAYER_ROOT_PRIMITIVE_CONTENT__),typeof w.locale==`string`&&(F=e.deepMergeContent(m.content??{},F)),[a,F]})),D=Object.fromEntries(E),O={...(0,o.getMultilingualDictionary)(w.locale?{...w,key:w.key,content:{}}:w),locale:void 0,...T};for(let e of p.targetLocales)D[e]&&(O=(0,o.insertContentInDictionary)(O,D[e],e));if(g(`${p.dictionaryPreset} ${(0,i.colorize)(`Translation completed successfully`,i.ANSIColors.GREEN)} for ${(0,i.colorizePath)((0,n.basename)(O.filePath))}`,{level:`info`}),w.locale&&(w.fill===!0||w.fill===void 0)&&w.location===`local`){let e=w.filePath.split(`.`).slice(0,-1),t=e[e.length-1];return JSON.parse(JSON.stringify({...p,dictionaryOutput:{...O,fill:void 0,filled:!0}}).replaceAll(RegExp(`\\.${t}\\.[a-zA-Z0-9]+`,`g`),`.filled.${t}.json`))}return{...p,dictionaryOutput:O}},{maxRetry:2,delay:d,onError:({error:e,attempt:t,maxRetry:n})=>g(`${p.dictionaryPreset} ${(0,i.colorize)(`Error:`,i.ANSIColors.RED)} ${(0,i.colorize)(typeof e==`string`?e:JSON.stringify(e),i.ANSIColors.GREY_DARK)} - Attempt ${(0,i.colorizeNumber)(t+1)} of ${(0,i.colorizeNumber)(n)}`,{level:`error`}),onMaxTryReached:({error:e})=>g(`${p.dictionaryPreset} ${(0,i.colorize)(`Maximum number of retries reached:`,i.ANSIColors.RED)} ${(0,i.colorize)(typeof e==`string`?e:JSON.stringify(e),i.ANSIColors.GREY_DARK)}`,{level:`error`})})()};exports.translateDictionary=p;
2
2
  //# sourceMappingURL=translateDictionary.cjs.map
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./formatFillData.cjs`),t=require(`./getAvailableLocalesInDictionary.cjs`);let n=require(`node:path`),r=require(`@intlayer/config/logger`),i=require(`@intlayer/chokidar/build`),a=require(`@intlayer/chokidar/utils`),o=require(`@intlayer/dictionaries-entry`);const s=async(s,c,l,u)=>{let d=(0,r.getAppLogger)(u),f=(0,o.getDictionaries)(u)[s.key],{filePath:p}=s;if(!p){d(`No file path found for dictionary`,{level:`error`});return}let m=s.fill??u.dictionary?.fill??!0;if(m===!1){d(`Auto fill is disabled for '${(0,r.colorizeKey)(f.key)}'`,{level:`info`});return}let h=(c??u.internationalization.locales).filter(e=>!l?.includes(e)),g=t.getAvailableLocalesInDictionary(s),_=h.filter(e=>g.includes(e));if(_.length===0){d(`No translations available for dictionary '${(0,r.colorizeKey)(f.key)}'`,{level:`info`});return}let v=await e.formatFillData(m,_,p,f.key,u);for await(let e of v){if(!e.filePath){d(`No file path found for auto filled content declaration for '${(0,r.colorizeKey)(f.key)}'`,{level:`error`});continue}let{fill:t,...o}=s,c=(0,n.relative)(u.system.baseDir,e.filePath);if(await(0,i.writeContentDeclaration)({...o,filled:!0,locale:e.isPerLocale?e.localeList[0]:void 0,localId:`${s.key}::local::${c}`,filePath:c},u,{localeList:e.localeList}),e.isPerLocale){let t=e.localeList[0];d(`Auto filled per-locale content declaration for '${(0,r.colorizeKey)(f.key)}' written to ${(0,a.formatPath)(e.filePath)} for locale ${(0,a.formatLocale)(t)}`,{level:`info`})}else d(`Auto filled content declaration for '${(0,r.colorizeKey)(f.key)}' written to ${(0,a.formatPath)(e.filePath)}`,{level:`info`})}};exports.writeFill=s;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./formatFillData.cjs`),t=require(`./getAvailableLocalesInDictionary.cjs`);let n=require(`node:path`),r=require(`@intlayer/chokidar/build`),i=require(`@intlayer/chokidar/utils`),a=require(`@intlayer/config/logger`),o=require(`@intlayer/dictionaries-entry`);const s=async(s,c,l,u)=>{let d=(0,a.getAppLogger)(u),f=(0,o.getDictionaries)(u)[s.key],{filePath:p}=s;if(!p){d(`No file path found for dictionary`,{level:`error`});return}let m=s.fill??u.dictionary?.fill??!0;if(m===!1){d(`Auto fill is disabled for '${(0,a.colorizeKey)(f.key)}'`,{level:`info`});return}let h=(c??u.internationalization.locales).filter(e=>!l?.includes(e)),g=t.getAvailableLocalesInDictionary(s),_=h.filter(e=>g.includes(e));if(_.length===0){d(`No translations available for dictionary '${(0,a.colorizeKey)(f.key)}'`,{level:`info`});return}let v=await e.formatFillData(m,_,p,f.key,u);for await(let e of v){if(!e.filePath){d(`No file path found for auto filled content declaration for '${(0,a.colorizeKey)(f.key)}'`,{level:`error`});continue}let{fill:t,...o}=s,c=(0,n.relative)(u.system.baseDir,e.filePath);if(await(0,r.writeContentDeclaration)({...o,filled:!0,locale:e.isPerLocale?e.localeList[0]:void 0,localId:`${s.key}::local::${c}`,filePath:c},u,{localeList:e.localeList}),e.isPerLocale){let t=e.localeList[0];d(`Auto filled per-locale content declaration for '${(0,a.colorizeKey)(f.key)}' written to ${(0,i.formatPath)(e.filePath)} for locale ${(0,i.formatLocale)(t)}`,{level:`info`})}else d(`Auto filled content declaration for '${(0,a.colorizeKey)(f.key)}' written to ${(0,i.formatPath)(e.filePath)}`,{level:`info`})}};exports.writeFill=s;
2
2
  //# sourceMappingURL=writeFill.cjs.map
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`node:path`),t=require(`@intlayer/config/logger`),n=require(`@intlayer/config/node`),r=require(`@intlayer/unmerged-dictionaries-entry`),i=require(`@intlayer/chokidar/utils`);const a=t=>{let i=(0,n.getConfiguration)(t?.configOptions),a=(0,r.getUnmergedDictionaries)(i);return Object.values(a).flat().map(n=>({key:n.key??``,path:t?.absolute?n.filePath??`Remote`:(0,e.relative)(i.system.baseDir,n.filePath??`Remote`)}))},o=e=>{let r=a(e);if(e?.json){console.log(JSON.stringify(r));return}let o=(0,t.getAppLogger)((0,n.getConfiguration)(e?.configOptions)),s=r.map(e=>[(0,t.colon)(` - ${(0,t.colorizeKey)(e.key)}`,{colSize:r.map(e=>e.key.length),maxSize:60}),` - `,(0,i.formatPath)(e.path)].join(``));o(`Content declaration files:`),s.forEach(e=>{o(e,{level:`info`})}),o(`Total content declaration files: ${(0,t.colorizeNumber)(r.length)}`)};exports.listContentDeclaration=o,exports.listContentDeclarationRows=a;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`node:path`),t=require(`@intlayer/chokidar/utils`),n=require(`@intlayer/config/logger`),r=require(`@intlayer/config/node`),i=require(`@intlayer/unmerged-dictionaries-entry`);const a=t=>{let n=(0,r.getConfiguration)(t?.configOptions),a=(0,i.getUnmergedDictionaries)(n);return Object.values(a).flat().map(r=>({key:r.key??``,path:t?.absolute?r.filePath??`Remote`:(0,e.relative)(n.system.baseDir,r.filePath??`Remote`)}))},o=e=>{let i=a(e);if(e?.json){console.log(JSON.stringify(i));return}let o=(0,n.getAppLogger)((0,r.getConfiguration)(e?.configOptions)),s=i.map(e=>[(0,n.colon)(` - ${(0,n.colorizeKey)(e.key)}`,{colSize:i.map(e=>e.key.length),maxSize:60}),` - `,(0,t.formatPath)(e.path)].join(``));o(`Content declaration files:`),s.forEach(e=>{o(e,{level:`info`})}),o(`Total content declaration files: ${(0,n.colorizeNumber)(i.length)}`)};exports.listContentDeclaration=o,exports.listContentDeclarationRows=a;
2
2
  //# sourceMappingURL=listContentDeclaration.cjs.map
@@ -1,10 +1,10 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./_virtual/_rolldown/runtime.cjs`),t=require(`./IntlayerEventListener.cjs`);let n=require(`@intlayer/config/logger`),r=require(`@intlayer/config/node`),i=require(`@intlayer/unmerged-dictionaries-entry`),a=require(`node:http`),o=require(`@intlayer/chokidar/build`),s=require(`@intlayer/chokidar/utils`),c=require(`@intlayer/config/package.json`);c=e.__toESM(c);let l=require(`@intlayer/core/plugins`),u=require(`@intlayer/dictionaries-entry`);const d=async(e,t)=>{(0,n.getAppLogger)(t)(`Writing dictionary ${e.key}`),await(0,o.buildDictionary)([e],t)},f=async e=>{let o=(0,r.getConfiguration)(e?.configOptions),f=(0,n.getAppLogger)(o),{liveSyncPort:p,liveSyncURL:m}=o.editor,h=null,g=null;if(e?.with&&(h=(0,s.runParallel)(e.with),h.result.catch(()=>{})),o.editor.liveSync&&o.editor.backendURL&&o.editor.clientId&&o.editor.clientSecret){g=new t.IntlayerEventListener(o),g.onConnectionOpen=()=>{f(`Live sync connection established`)},g.onConnectionError=e=>{let t=e;f(`Live sync connection error: ${t.message??`Unknown error`}`,{level:`warn`}),(t.message?.includes(`terminated`)||t.message?.includes(`closed`))&&f(`Server connection was terminated, automatic reconnection will be attempted...`,{level:`info`})},g.onDictionaryAdded=e=>d(e,o),g.onDictionaryChange=e=>d(e,o),g.onDictionaryDeleted=e=>d(e,o);try{await g.initialize()}catch(e){f(`Failed to initialize IntlayerEventListener:`,{level:`error`}),f(`Error: ${e instanceof Error?e.message:String(e)}`,{level:`error`})}}else o.editor.liveSync?(!o.editor.clientId||!o.editor.clientSecret)&&f(`Missing client credentials for hot reload. Please configure clientId and clientSecret`):f(`Hot reload is disabled. Please enable it in the configuration (editor.liveSync).`);let _=(0,a.createServer)(async(e,t)=>{if(e.method===`OPTIONS`){t.writeHead(200,{"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`}),t.end();return}if(e.url?.startsWith(`/dictionaries`)){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`});let n=(0,u.getDictionaries)(o);if(e.url.startsWith(`/dictionaries/`)){let[r,i]=decodeURIComponent(e.url).slice(14).split(`/`),a=n[r]??null;if(i){let e=(0,l.getLocalizedContent)(a.content,i,{dictionaryKey:r,keyPath:[]});t.end(JSON.stringify(e));return}t.end(JSON.stringify(a));return}t.end(JSON.stringify(n));return}if(e.url?.startsWith(`/unmerged_dictionaries`)){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`});let n=(0,i.getUnmergedDictionaries)(o);if(e.url.startsWith(`/unmerged_dictionaries/`)){let r=n[decodeURIComponent(e.url.slice(23))]??null;t.end(JSON.stringify(r));return}t.end(JSON.stringify(n));return}if(e.url===`/configuration`){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`}),t.end(JSON.stringify(o));return}if(e.url===`/health`){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`}),t.end(JSON.stringify({status:`ok`}));return}t.end(`Not found`)}),v=()=>o.editor.liveSync?`\x1B[32m✓ Enabled\x1B[0m`:`\x1B[31m✗ Disabled\x1B[0m`;_.listen(p,()=>{console.log(`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./_virtual/_rolldown/runtime.cjs`),t=require(`./IntlayerEventListener.cjs`);let n=require(`@intlayer/chokidar/build`),r=require(`@intlayer/chokidar/utils`),i=require(`@intlayer/config/logger`),a=require(`@intlayer/config/node`),o=require(`@intlayer/unmerged-dictionaries-entry`),s=require(`node:http`),c=require(`@intlayer/config/package.json`);c=e.__toESM(c);let l=require(`@intlayer/core/plugins`),u=require(`@intlayer/dictionaries-entry`);const d=async(e,t)=>{(0,i.getAppLogger)(t)(`Writing dictionary ${e.key}`),await(0,n.buildDictionary)([e],t)},f=async e=>{let n=(0,a.getConfiguration)(e?.configOptions),f=(0,i.getAppLogger)(n),{liveSyncPort:p,liveSyncURL:m}=n.editor,h=null,g=null;if(e?.with&&(h=(0,r.runParallel)(e.with),h.result.catch(()=>{})),n.editor.liveSync&&n.editor.backendURL&&n.editor.clientId&&n.editor.clientSecret){g=new t.IntlayerEventListener(n),g.onConnectionOpen=()=>{f(`Live sync connection established`)},g.onConnectionError=e=>{let t=e;f(`Live sync connection error: ${t.message??`Unknown error`}`,{level:`warn`}),(t.message?.includes(`terminated`)||t.message?.includes(`closed`))&&f(`Server connection was terminated, automatic reconnection will be attempted...`,{level:`info`})},g.onDictionaryAdded=e=>d(e,n),g.onDictionaryChange=e=>d(e,n),g.onDictionaryDeleted=e=>d(e,n);try{await g.initialize()}catch(e){f(`Failed to initialize IntlayerEventListener:`,{level:`error`}),f(`Error: ${e instanceof Error?e.message:String(e)}`,{level:`error`})}}else n.editor.liveSync?(!n.editor.clientId||!n.editor.clientSecret)&&f(`Missing client credentials for hot reload. Please configure clientId and clientSecret`):f(`Hot reload is disabled. Please enable it in the configuration (editor.liveSync).`);let _=(0,s.createServer)(async(e,t)=>{if(e.method===`OPTIONS`){t.writeHead(200,{"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`}),t.end();return}if(e.url?.startsWith(`/dictionaries`)){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`});let r=(0,u.getDictionaries)(n);if(e.url.startsWith(`/dictionaries/`)){let[n,i]=decodeURIComponent(e.url).slice(14).split(`/`),a=r[n]??null;if(i){let e=(0,l.getLocalizedContent)(a.content,i,{dictionaryKey:n,keyPath:[]});t.end(JSON.stringify(e));return}t.end(JSON.stringify(a));return}t.end(JSON.stringify(r));return}if(e.url?.startsWith(`/unmerged_dictionaries`)){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`});let r=(0,o.getUnmergedDictionaries)(n);if(e.url.startsWith(`/unmerged_dictionaries/`)){let n=r[decodeURIComponent(e.url.slice(23))]??null;t.end(JSON.stringify(n));return}t.end(JSON.stringify(r));return}if(e.url===`/configuration`){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`}),t.end(JSON.stringify(n));return}if(e.url===`/health`){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`}),t.end(JSON.stringify({status:`ok`}));return}t.end(`Not found`)}),v=()=>n.editor.liveSync?`\x1B[32m✓ Enabled\x1B[0m`:`\x1B[31m✗ Disabled\x1B[0m`;_.listen(p,()=>{console.log(`
2
2
  \x1b[1;90mINTLAYER v${c.default.version}\x1b[0m
3
3
 
4
4
  Live server running at: \x1b[90m${m}\x1b[0m
5
- - Backend URL: \x1b[90m${o.editor.backendURL??`-`}\x1b[0m
5
+ - Backend URL: \x1b[90m${n.editor.backendURL??`-`}\x1b[0m
6
6
  - Live sync: ${v()}
7
7
  - Parallel process: ${e?.with?`\x1b[90m${Array.isArray(e.with)?e.with.join(` `):e.with}\x1b[0m`:`-`}
8
- - Access key: ${o.editor.clientId??`-`}
8
+ - Access key: ${n.editor.clientId??`-`}
9
9
  `)});let y=()=>{g&&(f(`Closing SSE connection...`),g.cleanup()),h&&h.kill(),_.close(()=>{f(`Live sync server stopped`),process.exit(0)})};process.on(`SIGINT`,y),process.on(`SIGTERM`,y),process.on(`exit`,y)};exports.liveSync=f;
10
10
  //# sourceMappingURL=liveSync.cjs.map
package/dist/cjs/pull.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./utils/checkAccess.cjs`),t=require(`./push/pullLog.cjs`);let n=require(`node:fs`),r=require(`node:path`),i=require(`@intlayer/chokidar/cli`),a=require(`@intlayer/config/logger`),o=require(`@intlayer/config/node`),s=require(`@intlayer/unmerged-dictionaries-entry`),c=require(`@intlayer/chokidar/build`),l=require(`@intlayer/chokidar/utils`),u=require(`@intlayer/api`),d=require(`@intlayer/config/utils`);const f=async f=>{let p=(0,a.getAppLogger)(f?.configOptions?.override);try{let m=(0,o.getConfiguration)(f?.configOptions);if((0,i.logConfigDetails)(f?.configOptions),!await e.checkCMSAuth(m))return;let h=(0,u.getIntlayerAPIProxy)(void 0,m),g=(0,s.getUnmergedDictionaries)(m),_=await h.dictionary.getDictionariesUpdateTimestamp();if(!_.data)throw Error(`No distant dictionaries found`);let v=_.data;f?.dictionaries&&(v=Object.fromEntries(Object.entries(v).filter(([e])=>f.dictionaries?.includes(e)))),v=Object.fromEntries(Object.entries(v).filter(([e])=>{let t=g[e]?.[0]?.location??m.dictionary?.location??`remote`;return t===`remote`||t===`hybrid`}));let y=(0,r.join)(m.system.mainDir,`remote_dictionaries.cjs`),b=m.build?.require??(0,d.getProjectRequire)(),x=(0,n.existsSync)(y)?b(y):{},S=Object.entries(v),C=S.filter(([e,t])=>{if(!t)return!0;let n=typeof t==`object`?t.updatedAt:t,r=x[e];if(!r)return!0;let i=r?.updatedAt,a=typeof i==`number`?i:i?new Date(i).getTime():void 0;return typeof a==`number`?n>a:!0}).map(([e])=>e),w=S.filter(([e,t])=>{let n=typeof t==`object`?t.updatedAt:t,r=x[e]?.updatedAt,i=typeof r==`number`?r:r?new Date(r).getTime():void 0;return typeof i==`number`&&typeof n==`number`&&i>=n}).map(([e])=>e);if(S.length===0){p(`No dictionaries to fetch`,{level:`error`});return}p(`Fetching dictionaries:`);let T=[...w.map(e=>({dictionaryKey:e,status:`imported`})),...C.map(e=>({dictionaryKey:e,status:`pending`}))],E=new t.PullLogger;E.update(T.map(e=>({dictionaryKey:e.dictionaryKey,status:e.status})));let D=[];await(0,l.parallelize)(T,async e=>{let t=e.status===`imported`||e.status===`up-to-date`;t||(e.status=`fetching`,E.update([{dictionaryKey:e.dictionaryKey,status:`fetching`}]));try{let n;if(t&&(n=x[e.dictionaryKey]),n||=(await h.dictionary.getDictionary(e.dictionaryKey)).data,!n)throw Error(`Dictionary ${e.dictionaryKey} not found on remote`);let r=g[e.dictionaryKey]?.find(e=>e.location===`hybrid`);r&&(n={...n,location:`hybrid`,filePath:r.filePath,localId:r.localId});let{status:i}=await(0,c.writeContentDeclaration)(n,m,f);e.status=i,E.update([{dictionaryKey:e.dictionaryKey,status:i}]),D.push(n)}catch(t){e.status=`error`,e.error=t,e.errorMessage=`Error fetching dictionary ${e.dictionaryKey}: ${t}`,E.update([{dictionaryKey:e.dictionaryKey,status:`error`}])}},5),E.finish();let O=e=>{switch(e){case`fetched`:case`imported`:case`updated`:case`up-to-date`:case`reimported in JSON`:case`new content file`:return`✔`;case`error`:return`✖`;default:return`⏲`}},k=e=>{switch(e){case`fetched`:case`imported`:case`updated`:case`up-to-date`:return a.ANSIColors.GREEN;case`reimported in JSON`:case`new content file`:return a.ANSIColors.YELLOW;case`error`:return a.ANSIColors.RED;default:return a.ANSIColors.BLUE}};for(let e of T){let t=O(e.status),n=k(e.status);p(` - ${e.dictionaryKey} ${a.ANSIColors.GREY}[${n}${t} ${e.status}${a.ANSIColors.GREY}]${a.ANSIColors.RESET}`)}for(let e of T)e.errorMessage&&p(e.errorMessage,{level:`error`})}catch(e){p(e,{level:`error`})}};exports.pull=f;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./utils/checkAccess.cjs`),t=require(`./push/pullLog.cjs`);let n=require(`node:fs`),r=require(`node:path`),i=require(`@intlayer/chokidar/build`),a=require(`@intlayer/chokidar/cli`),o=require(`@intlayer/chokidar/utils`),s=require(`@intlayer/config/logger`),c=require(`@intlayer/config/node`),l=require(`@intlayer/unmerged-dictionaries-entry`),u=require(`@intlayer/api`),d=require(`@intlayer/config/utils`);const f=async f=>{let p=(0,s.getAppLogger)(f?.configOptions?.override);try{let m=(0,c.getConfiguration)(f?.configOptions);if((0,a.logConfigDetails)(f?.configOptions),!await e.checkCMSAuth(m))return;let h=(0,u.getIntlayerAPIProxy)(void 0,m),g=(0,l.getUnmergedDictionaries)(m),_=await h.dictionary.getDictionariesUpdateTimestamp();if(!_.data)throw Error(`No distant dictionaries found`);let v=_.data;f?.dictionaries&&(v=Object.fromEntries(Object.entries(v).filter(([e])=>f.dictionaries?.includes(e)))),v=Object.fromEntries(Object.entries(v).filter(([e])=>{let t=g[e]?.[0]?.location??m.dictionary?.location??`remote`;return t===`remote`||t===`hybrid`}));let y=(0,r.join)(m.system.mainDir,`remote_dictionaries.cjs`),b=m.build?.require??(0,d.getProjectRequire)(),x=(0,n.existsSync)(y)?b(y):{},S=Object.entries(v),C=S.filter(([e,t])=>{if(!t)return!0;let n=typeof t==`object`?t.updatedAt:t,r=x[e];if(!r)return!0;let i=r?.updatedAt,a=typeof i==`number`?i:i?new Date(i).getTime():void 0;return typeof a==`number`?n>a:!0}).map(([e])=>e),w=S.filter(([e,t])=>{let n=typeof t==`object`?t.updatedAt:t,r=x[e]?.updatedAt,i=typeof r==`number`?r:r?new Date(r).getTime():void 0;return typeof i==`number`&&typeof n==`number`&&i>=n}).map(([e])=>e);if(S.length===0){p(`No dictionaries to fetch`,{level:`error`});return}p(`Fetching dictionaries:`);let T=[...w.map(e=>({dictionaryKey:e,status:`imported`})),...C.map(e=>({dictionaryKey:e,status:`pending`}))],E=new t.PullLogger;E.update(T.map(e=>({dictionaryKey:e.dictionaryKey,status:e.status})));let D=[];await(0,o.parallelize)(T,async e=>{let t=e.status===`imported`||e.status===`up-to-date`;t||(e.status=`fetching`,E.update([{dictionaryKey:e.dictionaryKey,status:`fetching`}]));try{let n;if(t&&(n=x[e.dictionaryKey]),n||=(await h.dictionary.getDictionary(e.dictionaryKey)).data,!n)throw Error(`Dictionary ${e.dictionaryKey} not found on remote`);let r=g[e.dictionaryKey]?.find(e=>e.location===`hybrid`);r&&(n={...n,location:`hybrid`,filePath:r.filePath,localId:r.localId});let{status:a}=await(0,i.writeContentDeclaration)(n,m,f);e.status=a,E.update([{dictionaryKey:e.dictionaryKey,status:a}]),D.push(n)}catch(t){e.status=`error`,e.error=t,e.errorMessage=`Error fetching dictionary ${e.dictionaryKey}: ${t}`,E.update([{dictionaryKey:e.dictionaryKey,status:`error`}])}},5),E.finish();let O=e=>{switch(e){case`fetched`:case`imported`:case`updated`:case`up-to-date`:case`reimported in JSON`:case`new content file`:return`✔`;case`error`:return`✖`;default:return`⏲`}},k=e=>{switch(e){case`fetched`:case`imported`:case`updated`:case`up-to-date`:return s.ANSIColors.GREEN;case`reimported in JSON`:case`new content file`:return s.ANSIColors.YELLOW;case`error`:return s.ANSIColors.RED;default:return s.ANSIColors.BLUE}};for(let e of T){let t=O(e.status),n=k(e.status);p(` - ${e.dictionaryKey} ${s.ANSIColors.GREY}[${n}${t} ${e.status}${s.ANSIColors.GREY}]${s.ANSIColors.RESET}`)}for(let e of T)e.errorMessage&&p(e.errorMessage,{level:`error`})}catch(e){p(e,{level:`error`})}};exports.pull=f;
2
2
  //# sourceMappingURL=pull.cjs.map
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/checkAccess.cjs`),n=require(`../pushLog.cjs`);let r=require(`node:path`),i=require(`@intlayer/chokidar/cli`),a=require(`@intlayer/config/logger`),o=require(`@intlayer/config/node`),s=require(`@intlayer/unmerged-dictionaries-entry`),c=require(`@intlayer/chokidar/build`),l=require(`@intlayer/chokidar/utils`),u=require(`@intlayer/api`),d=require(`node:fs/promises`);d=e.__toESM(d);const f={pushed:{icon:`✔`,color:a.ANSIColors.GREEN},modified:{icon:`✔`,color:a.ANSIColors.GREEN},error:{icon:`✖`,color:a.ANSIColors.RED},default:{icon:`⏲`,color:a.ANSIColors.BLUE}},p=e=>f[e]??f.default,m=async e=>{let d=(0,o.getConfiguration)(e?.configOptions);(0,i.logConfigDetails)(e?.configOptions);let f=(0,a.getAppLogger)(d);e?.build===!0?await(0,c.prepareIntlayer)(d,{forceRun:!0}):e?.build===void 0&&await(0,c.prepareIntlayer)(d);try{if(!await t.checkCMSAuth(d))return;let o=(0,u.getIntlayerAPIProxy)(void 0,d),m=(0,s.getUnmergedDictionaries)(d),g=Object.values(m).flat(),_=Array.from(new Set(g.map(e=>e.location).filter(e=>e&&![`remote`,`local`,`hybrid`].includes(e)))),v=[];if(_.length>0){let{multiselect:e,confirm:t,isCancel:n}=await import(`@clack/prompts`);if(_.length===1){let e=await t({message:`Do you want to push dictionaries with custom location ${(0,a.colorize)(_[0],a.ANSIColors.BLUE,a.ANSIColors.RESET)}?`,initialValue:!1});if(n(e))return;e&&(v=[_[0]])}else{let t=await e({message:`Select custom locations to push:`,options:_.map(e=>({value:e,label:e})),required:!1});if(n(t))return;v=t}}let y=g.filter(e=>{let t=e.location??d.dictionary?.location??`local`;return t===`remote`||t===`hybrid`||v.includes(t)});if(y.length===0){f(`No dictionaries found to push. Only dictionaries with location ${(0,a.colorize)(`remote`,a.ANSIColors.BLUE,a.ANSIColors.RESET)}, ${(0,a.colorize)(`hybrid`,a.ANSIColors.BLUE,a.ANSIColors.RESET)} or selected custom locations are pushed.`,{level:`warn`}),f(`You can set the location in your dictionary file (e.g. ${(0,a.colorize)(`{ key: 'my-key', location: 'hybrid', ... }`,a.ANSIColors.BLUE,a.ANSIColors.RESET)} or globally in your intlayer.config.ts file (e.g. ${(0,a.colorize)(`{ dictionary: { location: 'hybrid' } }`,a.ANSIColors.BLUE,a.ANSIColors.RESET)}).`,{level:`info`});return}let b=Object.keys(m);if(e?.dictionaries){let t=e.dictionaries.filter(e=>!b.includes(e));t.length>0&&f(`The following dictionaries do not exist: ${t.join(`, `)} and have been ignored.`,{level:`error`}),y=y.filter(t=>e.dictionaries?.includes(t.key))}if(e?.gitOptions){let t=await(0,i.listGitFiles)(e.gitOptions);y=y.filter(e=>t.includes((0,r.join)(d.system.baseDir,e.filePath??``)))}if(y.length===0){f(`No local dictionaries found`,{level:`error`});return}f(`Pushing dictionaries:`);let x=y.map(e=>({dictionary:e,status:`pending`})),S=new n.PushLogger;S.update(x.map(e=>({dictionaryKey:e.dictionary.key,status:`pending`})));let C=[];await(0,l.parallelize)(x,async e=>{e.status=`pushing`,S.update([{dictionaryKey:e.dictionary.key,status:`pushing`}]);try{let t=await o.dictionary.pushDictionaries([e.dictionary]),n=t.data?.updatedDictionaries??[],r=t.data?.newDictionaries??[],i=[...n,...r];for(let e of i){let t=m[e.key]?.find(t=>t.localId===e.localId);t&&await(0,c.writeContentDeclaration)({...t,id:e.id},d)}n.some(t=>t.key===e.dictionary.key)?(e.status=`modified`,C.push(e.dictionary),S.update([{dictionaryKey:e.dictionary.key,status:`modified`}])):r.some(t=>t.key===e.dictionary.key)?(e.status=`pushed`,C.push(e.dictionary),S.update([{dictionaryKey:e.dictionary.key,status:`pushed`}])):e.status=`unknown`}catch(t){e.status=`error`,e.error=t,e.errorMessage=`Error pushing dictionary ${e.dictionary.key}: ${t}`,S.update([{dictionaryKey:e.dictionary.key,status:`error`}])}},5),S.finish();for(let e of x){let{icon:t,color:n}=p(e.status);f(` - ${(0,a.colorizeKey)(e.dictionary.key)} ${a.ANSIColors.GREY}[${n}${t} ${e.status}${a.ANSIColors.GREY}]${a.ANSIColors.RESET}`)}for(let e of x)e.errorMessage&&f(e.errorMessage,{level:`error`});let w=e?.deleteLocaleDictionary,T=e?.keepLocaleDictionary;if(w&&T)throw Error(`Cannot specify both --deleteLocaleDictionary and --keepLocaleDictionary options.`);if(w)await h(C,e);else if(!T){let t=C.filter(e=>e.location===`remote`),n=t.map(e=>e.key);if(t.length>0){let{confirm:r,isCancel:i}=await import(`@clack/prompts`),o=await r({message:`Do you want to delete the local dictionaries that were successfully pushed? ${(0,a.colorize)(`(Dictionaries:`,a.ANSIColors.GREY,a.ANSIColors.RESET)} ${(0,a.colorizeKey)(n)}${(0,a.colorize)(`)`,a.ANSIColors.GREY,a.ANSIColors.RESET)}`,initialValue:!1});if(i(o))return;o&&await h(t,e)}}}catch(e){f(e,{level:`error`})}},h=async(e,t)=>{let n=(0,a.getAppLogger)((0,o.getConfiguration)(t?.configOptions)),r=new Set;for(let t of e){let{filePath:e}=t;if(!e){n(`Dictionary ${(0,a.colorizeKey)(t.key)} does not have a file path`,{level:`error`});continue}r.add(e)}for(let e of r)try{let t=await d.lstat(e);t.isFile()?(await d.unlink(e),n(`Deleted file ${(0,l.formatPath)(e)}`,{})):t.isDirectory()?n(`Path is a directory ${(0,l.formatPath)(e)}, skipping.`,{}):n(`Unknown file type for ${(0,l.formatPath)(e)}, skipping.`,{})}catch(t){n(`Error deleting ${(0,l.formatPath)(e)}: ${t}`,{level:`error`})}};exports.push=m;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/checkAccess.cjs`),n=require(`../pushLog.cjs`);let r=require(`node:path`),i=require(`@intlayer/chokidar/build`),a=require(`@intlayer/chokidar/cli`),o=require(`@intlayer/chokidar/utils`),s=require(`@intlayer/config/logger`),c=require(`@intlayer/config/node`),l=require(`@intlayer/unmerged-dictionaries-entry`),u=require(`@intlayer/api`),d=require(`node:fs/promises`);d=e.__toESM(d);const f={pushed:{icon:`✔`,color:s.ANSIColors.GREEN},modified:{icon:`✔`,color:s.ANSIColors.GREEN},error:{icon:`✖`,color:s.ANSIColors.RED},default:{icon:`⏲`,color:s.ANSIColors.BLUE}},p=e=>f[e]??f.default,m=async e=>{let d=(0,c.getConfiguration)(e?.configOptions);(0,a.logConfigDetails)(e?.configOptions);let f=(0,s.getAppLogger)(d);e?.build===!0?await(0,i.prepareIntlayer)(d,{forceRun:!0}):e?.build===void 0&&await(0,i.prepareIntlayer)(d);try{if(!await t.checkCMSAuth(d))return;let c=(0,u.getIntlayerAPIProxy)(void 0,d),m=(0,l.getUnmergedDictionaries)(d),g=Object.values(m).flat(),_=Array.from(new Set(g.map(e=>e.location).filter(e=>e&&![`remote`,`local`,`hybrid`].includes(e)))),v=[];if(_.length>0){let{multiselect:e,confirm:t,isCancel:n}=await import(`@clack/prompts`);if(_.length===1){let e=await t({message:`Do you want to push dictionaries with custom location ${(0,s.colorize)(_[0],s.ANSIColors.BLUE,s.ANSIColors.RESET)}?`,initialValue:!1});if(n(e))return;e&&(v=[_[0]])}else{let t=await e({message:`Select custom locations to push:`,options:_.map(e=>({value:e,label:e})),required:!1});if(n(t))return;v=t}}let y=g.filter(e=>{let t=e.location??d.dictionary?.location??`local`;return t===`remote`||t===`hybrid`||v.includes(t)});if(y.length===0){f(`No dictionaries found to push. Only dictionaries with location ${(0,s.colorize)(`remote`,s.ANSIColors.BLUE,s.ANSIColors.RESET)}, ${(0,s.colorize)(`hybrid`,s.ANSIColors.BLUE,s.ANSIColors.RESET)} or selected custom locations are pushed.`,{level:`warn`}),f(`You can set the location in your dictionary file (e.g. ${(0,s.colorize)(`{ key: 'my-key', location: 'hybrid', ... }`,s.ANSIColors.BLUE,s.ANSIColors.RESET)} or globally in your intlayer.config.ts file (e.g. ${(0,s.colorize)(`{ dictionary: { location: 'hybrid' } }`,s.ANSIColors.BLUE,s.ANSIColors.RESET)}).`,{level:`info`});return}let b=Object.keys(m);if(e?.dictionaries){let t=e.dictionaries.filter(e=>!b.includes(e));t.length>0&&f(`The following dictionaries do not exist: ${t.join(`, `)} and have been ignored.`,{level:`error`}),y=y.filter(t=>e.dictionaries?.includes(t.key))}if(e?.gitOptions){let t=await(0,a.listGitFiles)(e.gitOptions);y=y.filter(e=>t.includes((0,r.join)(d.system.baseDir,e.filePath??``)))}if(y.length===0){f(`No local dictionaries found`,{level:`error`});return}f(`Pushing dictionaries:`);let x=y.map(e=>({dictionary:e,status:`pending`})),S=new n.PushLogger;S.update(x.map(e=>({dictionaryKey:e.dictionary.key,status:`pending`})));let C=[];await(0,o.parallelize)(x,async e=>{e.status=`pushing`,S.update([{dictionaryKey:e.dictionary.key,status:`pushing`}]);try{let t=await c.dictionary.pushDictionaries([e.dictionary]),n=t.data?.updatedDictionaries??[],r=t.data?.newDictionaries??[],a=[...n,...r];for(let e of a){let t=m[e.key]?.find(t=>t.localId===e.localId);t&&await(0,i.writeContentDeclaration)({...t,id:e.id},d)}n.some(t=>t.key===e.dictionary.key)?(e.status=`modified`,C.push(e.dictionary),S.update([{dictionaryKey:e.dictionary.key,status:`modified`}])):r.some(t=>t.key===e.dictionary.key)?(e.status=`pushed`,C.push(e.dictionary),S.update([{dictionaryKey:e.dictionary.key,status:`pushed`}])):e.status=`unknown`}catch(t){e.status=`error`,e.error=t,e.errorMessage=`Error pushing dictionary ${e.dictionary.key}: ${t}`,S.update([{dictionaryKey:e.dictionary.key,status:`error`}])}},5),S.finish();for(let e of x){let{icon:t,color:n}=p(e.status);f(` - ${(0,s.colorizeKey)(e.dictionary.key)} ${s.ANSIColors.GREY}[${n}${t} ${e.status}${s.ANSIColors.GREY}]${s.ANSIColors.RESET}`)}for(let e of x)e.errorMessage&&f(e.errorMessage,{level:`error`});let w=e?.deleteLocaleDictionary,T=e?.keepLocaleDictionary;if(w&&T)throw Error(`Cannot specify both --deleteLocaleDictionary and --keepLocaleDictionary options.`);if(w)await h(C,e);else if(!T){let t=C.filter(e=>e.location===`remote`),n=t.map(e=>e.key);if(t.length>0){let{confirm:r,isCancel:i}=await import(`@clack/prompts`),a=await r({message:`Do you want to delete the local dictionaries that were successfully pushed? ${(0,s.colorize)(`(Dictionaries:`,s.ANSIColors.GREY,s.ANSIColors.RESET)} ${(0,s.colorizeKey)(n)}${(0,s.colorize)(`)`,s.ANSIColors.GREY,s.ANSIColors.RESET)}`,initialValue:!1});if(i(a))return;a&&await h(t,e)}}}catch(e){f(e,{level:`error`})}},h=async(e,t)=>{let n=(0,s.getAppLogger)((0,c.getConfiguration)(t?.configOptions)),r=new Set;for(let t of e){let{filePath:e}=t;if(!e){n(`Dictionary ${(0,s.colorizeKey)(t.key)} does not have a file path`,{level:`error`});continue}r.add(e)}for(let e of r)try{let t=await d.lstat(e);t.isFile()?(await d.unlink(e),n(`Deleted file ${(0,o.formatPath)(e)}`,{})):t.isDirectory()?n(`Path is a directory ${(0,o.formatPath)(e)}, skipping.`,{}):n(`Unknown file type for ${(0,o.formatPath)(e)}, skipping.`,{})}catch(t){n(`Error deleting ${(0,o.formatPath)(e)}: ${t}`,{level:`error`})}};exports.push=m;
2
2
  //# sourceMappingURL=push.cjs.map
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/setupAI.cjs`),n=require(`../utils/checkFileModifiedRange.cjs`),r=require(`../utils/getOutputFilePath.cjs`),i=require(`./reviewDocBlockAware.cjs`);let a=require(`node:fs`),o=require(`node:path`),s=require(`@intlayer/chokidar/cli`),c=require(`@intlayer/config/logger`),l=require(`@intlayer/config/node`),u=require(`fast-glob`);u=e.__toESM(u);let d=require(`@intlayer/chokidar/utils`);const f=async({docPattern:e,locales:f,excludedGlobPattern:p,baseLocale:m,aiOptions:h,nbSimultaneousFileProcessed:g,configOptions:_,customInstructions:v,skipIfModifiedBefore:y,skipIfModifiedAfter:b,skipIfExists:x,gitOptions:S})=>{let C=(0,l.getConfiguration)(_);(0,s.logConfigDetails)(_);let w=(0,c.getAppLogger)(C),T=await t.setupAI(C,h);if(!T?.hasAIAccess)return;let{aiClient:E,aiConfig:D}=T;g&&g>10&&(w(`Warning: nbSimultaneousFileProcessed is set to ${g}, which is greater than 10. Setting it to 10.`),g=10);let O=await(0,u.default)(e,{ignore:p});if(S){let e=await(0,s.listGitFiles)(S);e&&(O=O.filter(t=>e.some(e=>(0,o.join)(process.cwd(),t)===e)))}w(`Base locale is ${(0,d.formatLocale)(m)}`),w(`Reviewing ${(0,c.colorizeNumber)(f.length)} locales: [ ${(0,d.formatLocale)(f)} ]`),w(`Reviewing ${(0,c.colorizeNumber)(O.length)} files:`),w(O.map(e=>` - ${(0,d.formatPath)(e)}\n`)),await(0,d.parallelize)(O.flatMap(e=>f.map(t=>async()=>{w(`Reviewing file: ${(0,d.formatPath)(e)} to ${(0,d.formatLocale)(t)}`);let l=(0,o.join)(C.system.baseDir,e),u=r.getOutputFilePath(l,t,m);if(x&&(0,a.existsSync)(u)){let e=(0,o.relative)(C.system.baseDir,u);w(`${(0,c.colorize)(`⊘`,c.ANSIColors.YELLOW)} File ${(0,d.formatPath)(e)} already exists, skipping.`);return}if((0,a.existsSync)(u)){let e=n.checkFileModifiedRange(u,{skipIfModifiedBefore:y,skipIfModifiedAfter:b});if(e.isSkipped){w(e.message);return}}else (y||b)&&w(`${(0,c.colorize)(`!`,c.ANSIColors.YELLOW)} File ${(0,d.formatPath)(u)} does not exist, skipping modification date check.`);let f;if(S){let e=await(0,s.listGitLines)(l,S);w(`Git changed lines: ${e.join(`, `)}`),f=e}await i.reviewFileBlockAware(l,u,t,m,h,_,v,f,E,D)})),e=>e(),g??3)};exports.reviewDoc=f;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/setupAI.cjs`),n=require(`../utils/checkFileModifiedRange.cjs`),r=require(`../utils/getOutputFilePath.cjs`),i=require(`./reviewDocBlockAware.cjs`);let a=require(`node:fs`),o=require(`node:path`),s=require(`@intlayer/chokidar/cli`),c=require(`@intlayer/chokidar/utils`),l=require(`@intlayer/config/logger`),u=require(`@intlayer/config/node`),d=require(`fast-glob`);d=e.__toESM(d);const f=async({docPattern:e,locales:f,excludedGlobPattern:p,baseLocale:m,aiOptions:h,nbSimultaneousFileProcessed:g,configOptions:_,customInstructions:v,skipIfModifiedBefore:y,skipIfModifiedAfter:b,skipIfExists:x,gitOptions:S})=>{let C=(0,u.getConfiguration)(_);(0,s.logConfigDetails)(_);let w=(0,l.getAppLogger)(C),T=await t.setupAI(C,h);if(!T?.hasAIAccess)return;let{aiClient:E,aiConfig:D}=T;g&&g>10&&(w(`Warning: nbSimultaneousFileProcessed is set to ${g}, which is greater than 10. Setting it to 10.`),g=10);let O=await(0,d.default)(e,{ignore:p});if(S){let e=await(0,s.listGitFiles)(S);e&&(O=O.filter(t=>e.some(e=>(0,o.join)(process.cwd(),t)===e)))}w(`Base locale is ${(0,c.formatLocale)(m)}`),w(`Reviewing ${(0,l.colorizeNumber)(f.length)} locales: [ ${(0,c.formatLocale)(f)} ]`),w(`Reviewing ${(0,l.colorizeNumber)(O.length)} files:`),w(O.map(e=>` - ${(0,c.formatPath)(e)}\n`)),await(0,c.parallelize)(O.flatMap(e=>f.map(t=>async()=>{w(`Reviewing file: ${(0,c.formatPath)(e)} to ${(0,c.formatLocale)(t)}`);let u=(0,o.join)(C.system.baseDir,e),d=r.getOutputFilePath(u,t,m);if(x&&(0,a.existsSync)(d)){let e=(0,o.relative)(C.system.baseDir,d);w(`${(0,l.colorize)(`⊘`,l.ANSIColors.YELLOW)} File ${(0,c.formatPath)(e)} already exists, skipping.`);return}if((0,a.existsSync)(d)){let e=n.checkFileModifiedRange(d,{skipIfModifiedBefore:y,skipIfModifiedAfter:b});if(e.isSkipped){w(e.message);return}}else (y||b)&&w(`${(0,l.colorize)(`!`,l.ANSIColors.YELLOW)} File ${(0,c.formatPath)(d)} does not exist, skipping modification date check.`);let f;if(S){let e=await(0,s.listGitLines)(u,S);w(`Git changed lines: ${e.join(`, `)}`),f=e}await i.reviewFileBlockAware(u,d,t,m,h,_,v,f,E,D)})),e=>e(),g??3)};exports.reviewDoc=f;
2
2
  //# sourceMappingURL=reviewDoc.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"reviewDoc.cjs","names":["setupAI","getOutputFilePath","ANSIColors","checkFileModifiedRange","reviewFileBlockAware"],"sources":["../../../src/reviewDoc/reviewDoc.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { join, relative } from 'node:path';\nimport type { AIOptions } from '@intlayer/api';\nimport {\n type ListGitFilesOptions,\n listGitFiles,\n listGitLines,\n logConfigDetails,\n} from '@intlayer/chokidar/cli';\nimport {\n formatLocale,\n formatPath,\n parallelize,\n} from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizeNumber,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport fg from 'fast-glob';\nimport { checkFileModifiedRange } from '../utils/checkFileModifiedRange';\nimport { getOutputFilePath } from '../utils/getOutputFilePath';\nimport { setupAI } from '../utils/setupAI';\nimport { reviewFileBlockAware } from './reviewDocBlockAware';\n\ntype ReviewDocOptions = {\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 audit function: scans all .md files in \"en/\" (unless you specified DOC_LIST),\n * then audits them to each locale in LOCALE_LIST.\n */\nexport const reviewDoc = 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}: ReviewDocOptions) => {\n const configuration = getConfiguration(configOptions);\n logConfigDetails(configOptions);\n\n const appLogger = getAppLogger(configuration);\n\n const aiResult = await setupAI(configuration, aiOptions);\n\n if (!aiResult?.hasAIAccess) return;\n\n const { aiClient, aiConfig } = aiResult;\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 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 `Reviewing ${colorizeNumber(locales.length)} locales: [ ${formatLocale(locales)} ]`\n );\n\n appLogger(`Reviewing ${colorizeNumber(docList.length)} files:`);\n appLogger(docList.map((path) => ` - ${formatPath(path)}\\n`));\n\n // Create all tasks to be processed\n const allTasks = docList.flatMap((docPath) =>\n locales.map((locale) => async () => {\n appLogger(\n `Reviewing file: ${formatPath(docPath)} to ${formatLocale(locale)}`\n );\n\n const absoluteBaseFilePath = join(configuration.system.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.system.baseDir,\n outputFilePath\n );\n appLogger(\n `${colorize('⊘', ANSIColors.YELLOW)} File ${formatPath(relativePath)} already exists, skipping.`\n );\n return;\n }\n\n // Check modification range only if the file exists\n if (existsSync(outputFilePath)) {\n const fileModificationData = checkFileModifiedRange(outputFilePath, {\n skipIfModifiedBefore,\n skipIfModifiedAfter,\n });\n\n if (fileModificationData.isSkipped) {\n appLogger(fileModificationData.message);\n return;\n }\n } else if (skipIfModifiedBefore || skipIfModifiedAfter) {\n // Log if we intended to check modification time but couldn't because the file doesn't exist\n appLogger(\n `${colorize('!', ANSIColors.YELLOW)} File ${formatPath(outputFilePath)} does not exist, skipping modification date check.`\n );\n }\n\n let changedLines: number[] | undefined;\n // FIXED: Enable git optimization that was previously commented out\n if (gitOptions) {\n const gitChangedLines = await listGitLines(\n absoluteBaseFilePath,\n gitOptions\n );\n\n appLogger(`Git changed lines: ${gitChangedLines.join(', ')}`);\n changedLines = gitChangedLines;\n }\n\n await reviewFileBlockAware(\n absoluteBaseFilePath,\n outputFilePath,\n locale as Locale,\n baseLocale,\n aiOptions,\n configOptions,\n customInstructions,\n changedLines,\n aiClient,\n aiConfig\n );\n })\n );\n\n await parallelize(\n allTasks,\n (task) => task(),\n nbSimultaneousFileProcessed ?? 3\n );\n};\n"],"mappings":"0gBAkDA,MAAa,EAAY,MAAO,CAC9B,aACA,UACA,sBACA,aACA,YACA,8BACA,gBACA,qBACA,uBACA,sBACA,eACA,gBACsB,CACtB,IAAM,GAAA,EAAA,EAAA,kBAAiC,EAAc,EACrD,EAAA,EAAA,kBAAiB,EAAc,CAE/B,IAAM,GAAA,EAAA,EAAA,cAAyB,EAAc,CAEvC,EAAW,MAAMA,EAAAA,QAAQ,EAAe,EAAU,CAExD,GAAI,CAAC,GAAU,YAAa,OAE5B,GAAM,CAAE,WAAU,YAAa,EAE3B,GAA+B,EAA8B,KAC/D,EACE,kDAAkD,EAA4B,+CAC/E,CACD,EAA8B,IAGhC,IAAI,EAAoB,MAAA,EAAA,EAAA,SAAS,EAAY,CAC3C,OAAQ,EACT,CAAC,CAEF,GAAI,EAAY,CACd,IAAM,EAAkB,MAAA,EAAA,EAAA,cAAmB,EAAW,CAElD,IAIF,EAAU,EAAQ,OAAQ,GACxB,EAAgB,KAAM,IAAA,EAAA,EAAA,MAAiB,QAAQ,KAAK,CAAE,EAAK,GAAK,EAAQ,CACzE,EAML,EAAU,mBAAA,EAAA,EAAA,cAA+B,EAAW,GAAG,CACvD,EACE,cAAA,EAAA,EAAA,gBAA4B,EAAQ,OAAO,CAAC,eAAA,EAAA,EAAA,cAA2B,EAAQ,CAAC,IACjF,CAED,EAAU,cAAA,EAAA,EAAA,gBAA4B,EAAQ,OAAO,CAAC,SAAS,CAC/D,EAAU,EAAQ,IAAK,GAAS,OAAA,EAAA,EAAA,YAAiB,EAAK,CAAC,IAAI,CAAC,CAyE5D,MAAA,EAAA,EAAA,aAtEiB,EAAQ,QAAS,GAChC,EAAQ,IAAK,GAAW,SAAY,CAClC,EACE,oBAAA,EAAA,EAAA,YAA8B,EAAQ,CAAC,OAAA,EAAA,EAAA,cAAmB,EAAO,GAClE,CAED,IAAM,GAAA,EAAA,EAAA,MAA4B,EAAc,OAAO,QAAS,EAAQ,CAClE,EAAiBC,EAAAA,kBACrB,EACA,EACA,EACD,CAGD,GAAI,IAAA,EAAA,EAAA,YAA2B,EAAe,CAAE,CAC9C,IAAM,GAAA,EAAA,EAAA,UACJ,EAAc,OAAO,QACrB,EACD,CACD,EACE,IAAA,EAAA,EAAA,UAAY,IAAKC,EAAAA,WAAW,OAAO,CAAC,SAAA,EAAA,EAAA,YAAmB,EAAa,CAAC,4BACtE,CACD,OAIF,IAAA,EAAA,EAAA,YAAe,EAAe,CAAE,CAC9B,IAAM,EAAuBC,EAAAA,uBAAuB,EAAgB,CAClE,uBACA,sBACD,CAAC,CAEF,GAAI,EAAqB,UAAW,CAClC,EAAU,EAAqB,QAAQ,CACvC,cAEO,GAAwB,IAEjC,EACE,IAAA,EAAA,EAAA,UAAY,IAAKD,EAAAA,WAAW,OAAO,CAAC,SAAA,EAAA,EAAA,YAAmB,EAAe,CAAC,oDACxE,CAGH,IAAI,EAEJ,GAAI,EAAY,CACd,IAAM,EAAkB,MAAA,EAAA,EAAA,cACtB,EACA,EACD,CAED,EAAU,sBAAsB,EAAgB,KAAK,KAAK,GAAG,CAC7D,EAAe,EAGjB,MAAME,EAAAA,qBACJ,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACD,EACD,CACH,CAIE,GAAS,GAAM,CAChB,GAA+B,EAChC"}
1
+ {"version":3,"file":"reviewDoc.cjs","names":["setupAI","getOutputFilePath","ANSIColors","checkFileModifiedRange","reviewFileBlockAware"],"sources":["../../../src/reviewDoc/reviewDoc.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { join, relative } from 'node:path';\nimport type { AIOptions } from '@intlayer/api';\nimport {\n type ListGitFilesOptions,\n listGitFiles,\n listGitLines,\n logConfigDetails,\n} from '@intlayer/chokidar/cli';\nimport {\n formatLocale,\n formatPath,\n parallelize,\n} from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizeNumber,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport fg from 'fast-glob';\nimport { checkFileModifiedRange } from '../utils/checkFileModifiedRange';\nimport { getOutputFilePath } from '../utils/getOutputFilePath';\nimport { setupAI } from '../utils/setupAI';\nimport { reviewFileBlockAware } from './reviewDocBlockAware';\n\ntype ReviewDocOptions = {\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 audit function: scans all .md files in \"en/\" (unless you specified DOC_LIST),\n * then audits them to each locale in LOCALE_LIST.\n */\nexport const reviewDoc = 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}: ReviewDocOptions) => {\n const configuration = getConfiguration(configOptions);\n logConfigDetails(configOptions);\n\n const appLogger = getAppLogger(configuration);\n\n const aiResult = await setupAI(configuration, aiOptions);\n\n if (!aiResult?.hasAIAccess) return;\n\n const { aiClient, aiConfig } = aiResult;\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 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 `Reviewing ${colorizeNumber(locales.length)} locales: [ ${formatLocale(locales)} ]`\n );\n\n appLogger(`Reviewing ${colorizeNumber(docList.length)} files:`);\n appLogger(docList.map((path) => ` - ${formatPath(path)}\\n`));\n\n // Create all tasks to be processed\n const allTasks = docList.flatMap((docPath) =>\n locales.map((locale) => async () => {\n appLogger(\n `Reviewing file: ${formatPath(docPath)} to ${formatLocale(locale)}`\n );\n\n const absoluteBaseFilePath = join(configuration.system.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.system.baseDir,\n outputFilePath\n );\n appLogger(\n `${colorize('⊘', ANSIColors.YELLOW)} File ${formatPath(relativePath)} already exists, skipping.`\n );\n return;\n }\n\n // Check modification range only if the file exists\n if (existsSync(outputFilePath)) {\n const fileModificationData = checkFileModifiedRange(outputFilePath, {\n skipIfModifiedBefore,\n skipIfModifiedAfter,\n });\n\n if (fileModificationData.isSkipped) {\n appLogger(fileModificationData.message);\n return;\n }\n } else if (skipIfModifiedBefore || skipIfModifiedAfter) {\n // Log if we intended to check modification time but couldn't because the file doesn't exist\n appLogger(\n `${colorize('!', ANSIColors.YELLOW)} File ${formatPath(outputFilePath)} does not exist, skipping modification date check.`\n );\n }\n\n let changedLines: number[] | undefined;\n // FIXED: Enable git optimization that was previously commented out\n if (gitOptions) {\n const gitChangedLines = await listGitLines(\n absoluteBaseFilePath,\n gitOptions\n );\n\n appLogger(`Git changed lines: ${gitChangedLines.join(', ')}`);\n changedLines = gitChangedLines;\n }\n\n await reviewFileBlockAware(\n absoluteBaseFilePath,\n outputFilePath,\n locale as Locale,\n baseLocale,\n aiOptions,\n configOptions,\n customInstructions,\n changedLines,\n aiClient,\n aiConfig\n );\n })\n );\n\n await parallelize(\n allTasks,\n (task) => task(),\n nbSimultaneousFileProcessed ?? 3\n );\n};\n"],"mappings":"sgBAkDA,MAAa,EAAY,MAAO,CAC9B,aACA,UACA,sBACA,aACA,YACA,8BACA,gBACA,qBACA,uBACA,sBACA,eACA,gBACsB,CACtB,IAAM,GAAA,EAAA,EAAA,kBAAiC,EAAc,EACrD,EAAA,EAAA,kBAAiB,EAAc,CAE/B,IAAM,GAAA,EAAA,EAAA,cAAyB,EAAc,CAEvC,EAAW,MAAMA,EAAAA,QAAQ,EAAe,EAAU,CAExD,GAAI,CAAC,GAAU,YAAa,OAE5B,GAAM,CAAE,WAAU,YAAa,EAE3B,GAA+B,EAA8B,KAC/D,EACE,kDAAkD,EAA4B,+CAC/E,CACD,EAA8B,IAGhC,IAAI,EAAoB,MAAA,EAAA,EAAA,SAAS,EAAY,CAC3C,OAAQ,EACT,CAAC,CAEF,GAAI,EAAY,CACd,IAAM,EAAkB,MAAA,EAAA,EAAA,cAAmB,EAAW,CAElD,IAIF,EAAU,EAAQ,OAAQ,GACxB,EAAgB,KAAM,IAAA,EAAA,EAAA,MAAiB,QAAQ,KAAK,CAAE,EAAK,GAAK,EAAQ,CACzE,EAML,EAAU,mBAAA,EAAA,EAAA,cAA+B,EAAW,GAAG,CACvD,EACE,cAAA,EAAA,EAAA,gBAA4B,EAAQ,OAAO,CAAC,eAAA,EAAA,EAAA,cAA2B,EAAQ,CAAC,IACjF,CAED,EAAU,cAAA,EAAA,EAAA,gBAA4B,EAAQ,OAAO,CAAC,SAAS,CAC/D,EAAU,EAAQ,IAAK,GAAS,OAAA,EAAA,EAAA,YAAiB,EAAK,CAAC,IAAI,CAAC,CAyE5D,MAAA,EAAA,EAAA,aAtEiB,EAAQ,QAAS,GAChC,EAAQ,IAAK,GAAW,SAAY,CAClC,EACE,oBAAA,EAAA,EAAA,YAA8B,EAAQ,CAAC,OAAA,EAAA,EAAA,cAAmB,EAAO,GAClE,CAED,IAAM,GAAA,EAAA,EAAA,MAA4B,EAAc,OAAO,QAAS,EAAQ,CAClE,EAAiBC,EAAAA,kBACrB,EACA,EACA,EACD,CAGD,GAAI,IAAA,EAAA,EAAA,YAA2B,EAAe,CAAE,CAC9C,IAAM,GAAA,EAAA,EAAA,UACJ,EAAc,OAAO,QACrB,EACD,CACD,EACE,IAAA,EAAA,EAAA,UAAY,IAAKC,EAAAA,WAAW,OAAO,CAAC,SAAA,EAAA,EAAA,YAAmB,EAAa,CAAC,4BACtE,CACD,OAIF,IAAA,EAAA,EAAA,YAAe,EAAe,CAAE,CAC9B,IAAM,EAAuBC,EAAAA,uBAAuB,EAAgB,CAClE,uBACA,sBACD,CAAC,CAEF,GAAI,EAAqB,UAAW,CAClC,EAAU,EAAqB,QAAQ,CACvC,cAEO,GAAwB,IAEjC,EACE,IAAA,EAAA,EAAA,UAAY,IAAKD,EAAAA,WAAW,OAAO,CAAC,SAAA,EAAA,EAAA,YAAmB,EAAe,CAAC,oDACxE,CAGH,IAAI,EAEJ,GAAI,EAAY,CACd,IAAM,EAAkB,MAAA,EAAA,EAAA,cACtB,EACA,EACD,CAED,EAAU,sBAAsB,EAAgB,KAAK,KAAK,GAAG,CAC7D,EAAe,EAGjB,MAAME,EAAAA,qBACJ,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACD,EACD,CACH,CAIE,GAAS,GAAM,CAChB,GAA+B,EAChC"}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../_virtual/_utils_asset.cjs`),n=require(`../translateDoc/validation.cjs`),r=require(`../translation-alignment/rebuildDocument.cjs`),i=require(`../translation-alignment/pipeline.cjs`),a=require(`../utils/chunkInference.cjs`),o=require(`../utils/fixChunkStartEndChars.cjs`);let s=require(`node:fs`),c=require(`node:path`),l=require(`@intlayer/config/logger`),u=require(`@intlayer/config/node`),d=require(`@intlayer/chokidar/utils`),f=require(`@intlayer/config/utils`),p=require(`node:fs/promises`),m=require(`@intlayer/core/localization`),h=require(`@intlayer/types/locales`);h=e.__toESM(h);const g=async(e,g,_,v,y,b,x,S,C,w)=>{let T=(0,u.getConfiguration)(b),E=(0,l.getAppLogger)(T),D=await(0,p.readFile)(e,`utf-8`),O=await(0,p.readFile)(g,`utf-8`).catch(()=>``),k=t.readAsset(`./prompts/REVIEW_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${(0,d.formatLocale)(_,!1)}`).replaceAll(`{{baseLocaleName}}`,`${(0,d.formatLocale)(v,!1)}`).replace(`{{applicationContext}}`,y?.applicationContext??`-`).replace(`{{customInstructions}}`,x??`-`),A=[(0,l.colon)(`${l.ANSIColors.GREY_DARK}[${(0,d.formatPath)(e)}${l.ANSIColors.GREY_DARK}] `,{colSize:40}),`→ ${l.ANSIColors.RESET}`].join(``),j=[(0,l.colon)(`${l.ANSIColors.GREY_DARK}[${(0,d.formatPath)(e)}${l.ANSIColors.GREY_DARK}][${(0,d.formatLocale)(_)}${l.ANSIColors.GREY_DARK}] `,{colSize:40}),`→ ${l.ANSIColors.RESET}`].join(``),{englishBlocks:M,frenchBlocks:N,plan:P,segmentsToReview:F}=i.buildAlignmentPlan({englishText:D,frenchText:O,changedLines:S});if(E(`${A}Block-aware alignment complete. Total blocks: EN=${(0,l.colorizeNumber)(M.length)}, FR=${(0,l.colorizeNumber)(N.length)}`),E(`${A}Actions: reuse=${(0,l.colorizeNumber)(P.actions.filter(e=>e.kind===`reuse`).length)}, review=${(0,l.colorizeNumber)(P.actions.filter(e=>e.kind===`review`).length)}, new=${(0,l.colorizeNumber)(P.actions.filter(e=>e.kind===`insert_new`).length)}, delete=${(0,l.colorizeNumber)(P.actions.filter(e=>e.kind===`delete`).length)}`),F.length===0){E(`${A}No segments need review, reusing existing translation`),(0,s.mkdirSync)((0,c.dirname)(g),{recursive:!0}),(0,s.writeFileSync)(g,r.mergeReviewedSegments(P,N,new Map)),E(`${(0,l.colorize)(`✔`,l.ANSIColors.GREEN)} File ${(0,d.formatPath)(g)} updated successfully (no changes needed).`);return}E(`${A}Segments to review: ${(0,l.colorizeNumber)(F.length)}`);let I=new Map;for(let e of F){let t=F.indexOf(e)+1,r=e.englishBlock,i=()=>`**BLOCK ${t} of ${F.length}** is the base block in ${(0,d.formatLocale)(v,!1)} as reference.\n///chunksStart///\n`+r.content+`///chunksEnd///`,s=()=>`**BLOCK ${t} of ${F.length}** is the current block to review in ${(0,d.formatLocale)(_,!1)}.\n///chunksStart///\n`+(e.frenchBlockText??``)+`///chunksEnd///`,c=await(0,f.retryManager)(async()=>{let e=await a.chunkInference([{role:`system`,content:k},{role:`system`,content:i()},{role:`system`,content:s()},{role:`system`,content:`The next user message will be the **BLOCK ${(0,l.colorizeNumber)(t)} of ${(0,l.colorizeNumber)(F.length)}** that should be translated in ${(0,m.getLocaleName)(_,h.ENGLISH)} (${_}).`},{role:`user`,content:r.content}],y,T,C,w);E(`${j}${(0,l.colorizeNumber)(e.tokenUsed)} tokens used - Block ${(0,l.colorizeNumber)(t)} of ${(0,l.colorizeNumber)(F.length)}`);let c=n.sanitizeChunk(e?.fileContent,r.content);if(c=o.fixChunkStartEndChars(c,r.content),!n.validateTranslation(r.content,c,E))throw Error(`Validation failed for chunk (structure or length mismatch). Retrying...`);return c})();I.set(e.actionIndex,c)}let L=r.mergeReviewedSegments(P,N,I);(0,s.mkdirSync)((0,c.dirname)(g),{recursive:!0}),(0,s.writeFileSync)(g,L),E(`${(0,l.colorize)(`✔`,l.ANSIColors.GREEN)} File ${(0,d.formatPath)(g)} created/updated successfully.`)};exports.reviewFileBlockAware=g;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../_virtual/_utils_asset.cjs`),n=require(`../translateDoc/validation.cjs`),r=require(`../translation-alignment/rebuildDocument.cjs`),i=require(`../translation-alignment/pipeline.cjs`),a=require(`../utils/chunkInference.cjs`),o=require(`../utils/fixChunkStartEndChars.cjs`);let s=require(`node:fs`),c=require(`node:path`),l=require(`@intlayer/chokidar/utils`),u=require(`@intlayer/config/logger`),d=require(`@intlayer/config/node`),f=require(`@intlayer/config/utils`),p=require(`node:fs/promises`),m=require(`@intlayer/core/localization`),h=require(`@intlayer/types/locales`);h=e.__toESM(h);const g=async(e,g,_,v,y,b,x,S,C,w)=>{let T=(0,d.getConfiguration)(b),E=(0,u.getAppLogger)(T),D=await(0,p.readFile)(e,`utf-8`),O=await(0,p.readFile)(g,`utf-8`).catch(()=>``),k=t.readAsset(`./prompts/REVIEW_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${(0,l.formatLocale)(_,!1)}`).replaceAll(`{{baseLocaleName}}`,`${(0,l.formatLocale)(v,!1)}`).replace(`{{applicationContext}}`,y?.applicationContext??`-`).replace(`{{customInstructions}}`,x??`-`),A=[(0,u.colon)(`${u.ANSIColors.GREY_DARK}[${(0,l.formatPath)(e)}${u.ANSIColors.GREY_DARK}] `,{colSize:40}),`→ ${u.ANSIColors.RESET}`].join(``),j=[(0,u.colon)(`${u.ANSIColors.GREY_DARK}[${(0,l.formatPath)(e)}${u.ANSIColors.GREY_DARK}][${(0,l.formatLocale)(_)}${u.ANSIColors.GREY_DARK}] `,{colSize:40}),`→ ${u.ANSIColors.RESET}`].join(``),{englishBlocks:M,frenchBlocks:N,plan:P,segmentsToReview:F}=i.buildAlignmentPlan({englishText:D,frenchText:O,changedLines:S});if(E(`${A}Block-aware alignment complete. Total blocks: EN=${(0,u.colorizeNumber)(M.length)}, FR=${(0,u.colorizeNumber)(N.length)}`),E(`${A}Actions: reuse=${(0,u.colorizeNumber)(P.actions.filter(e=>e.kind===`reuse`).length)}, review=${(0,u.colorizeNumber)(P.actions.filter(e=>e.kind===`review`).length)}, new=${(0,u.colorizeNumber)(P.actions.filter(e=>e.kind===`insert_new`).length)}, delete=${(0,u.colorizeNumber)(P.actions.filter(e=>e.kind===`delete`).length)}`),F.length===0){E(`${A}No segments need review, reusing existing translation`),(0,s.mkdirSync)((0,c.dirname)(g),{recursive:!0}),(0,s.writeFileSync)(g,r.mergeReviewedSegments(P,N,new Map)),E(`${(0,u.colorize)(`✔`,u.ANSIColors.GREEN)} File ${(0,l.formatPath)(g)} updated successfully (no changes needed).`);return}E(`${A}Segments to review: ${(0,u.colorizeNumber)(F.length)}`);let I=new Map;for(let e of F){let t=F.indexOf(e)+1,r=e.englishBlock,i=()=>`**BLOCK ${t} of ${F.length}** is the base block in ${(0,l.formatLocale)(v,!1)} as reference.\n///chunksStart///\n`+r.content+`///chunksEnd///`,s=()=>`**BLOCK ${t} of ${F.length}** is the current block to review in ${(0,l.formatLocale)(_,!1)}.\n///chunksStart///\n`+(e.frenchBlockText??``)+`///chunksEnd///`,c=await(0,f.retryManager)(async()=>{let e=await a.chunkInference([{role:`system`,content:k},{role:`system`,content:i()},{role:`system`,content:s()},{role:`system`,content:`The next user message will be the **BLOCK ${(0,u.colorizeNumber)(t)} of ${(0,u.colorizeNumber)(F.length)}** that should be translated in ${(0,m.getLocaleName)(_,h.ENGLISH)} (${_}).`},{role:`user`,content:r.content}],y,T,C,w);E(`${j}${(0,u.colorizeNumber)(e.tokenUsed)} tokens used - Block ${(0,u.colorizeNumber)(t)} of ${(0,u.colorizeNumber)(F.length)}`);let c=n.sanitizeChunk(e?.fileContent,r.content);if(c=o.fixChunkStartEndChars(c,r.content),!n.validateTranslation(r.content,c,E))throw Error(`Validation failed for chunk (structure or length mismatch). Retrying...`);return c})();I.set(e.actionIndex,c)}let L=r.mergeReviewedSegments(P,N,I);(0,s.mkdirSync)((0,c.dirname)(g),{recursive:!0}),(0,s.writeFileSync)(g,L),E(`${(0,u.colorize)(`✔`,u.ANSIColors.GREEN)} File ${(0,l.formatPath)(g)} created/updated successfully.`)};exports.reviewFileBlockAware=g;
2
2
  //# sourceMappingURL=reviewDocBlockAware.cjs.map
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./listMissingTranslations.cjs`);let t=require(`@intlayer/config/logger`),n=require(`@intlayer/config/node`),r=require(`@intlayer/chokidar/build`),i=require(`@intlayer/chokidar/utils`);const a=async a=>{let o=(0,n.getConfiguration)(a?.configOptions),{locales:s,requiredLocales:c}=o.internationalization,l=(0,t.getAppLogger)(o);a?.build===!0?await(0,r.prepareIntlayer)(o,{forceRun:!0}):a?.build===void 0&&await(0,r.prepareIntlayer)(o);let u=e.listMissingTranslations(a?.configOptions),d=u.missingTranslations.map(e=>` - ${e.key}`).reduce((e,t)=>Math.max(e,t.length),0),f=u.missingTranslations.map(e=>(0,i.formatLocale)(e.locales,!1)).reduce((e,t)=>Math.max(e,t.length),0),p=u.missingTranslations.map(e=>[(0,t.colon)(` - ${(0,t.colorizeKey)(e.key)}`,{colSize:d,maxSize:40}),` - `,(0,t.colon)((0,i.formatLocale)(e.locales,t.ANSIColors.RED),{colSize:f,maxSize:40}),e.filePath?` - ${(0,i.formatPath)(e.filePath)}`:``,e.id?` - remote`:``].join(``));l(`Missing translations:`,{level:`info`}),p.forEach(e=>{l(e,{level:`info`})}),l(`Locales: ${(0,i.formatLocale)(s)}`),l(`Required locales: ${(0,i.formatLocale)(c??s)}`),l(`Missing locales: ${u.missingLocales.length===0?(0,t.colorize)(`-`,t.ANSIColors.GREEN):(0,i.formatLocale)(u.missingLocales,t.ANSIColors.RED)}`),l(`Missing required locales: ${u.missingRequiredLocales.length===0?(0,t.colorize)(`-`,t.ANSIColors.GREEN):(0,i.formatLocale)(u.missingRequiredLocales,t.ANSIColors.RED)}`),l(`Total missing locales: ${(0,t.colorizeNumber)(u.missingLocales.length,{one:t.ANSIColors.RED,other:t.ANSIColors.RED,zero:t.ANSIColors.GREEN})}`),l(`Total missing required locales: ${(0,t.colorizeNumber)(u.missingRequiredLocales.length,{one:t.ANSIColors.RED,other:t.ANSIColors.RED,zero:t.ANSIColors.GREEN})}`),u.missingRequiredLocales.length>0&&process.exit(1)};exports.testMissingTranslations=a;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./listMissingTranslations.cjs`);let t=require(`@intlayer/chokidar/build`),n=require(`@intlayer/chokidar/utils`),r=require(`@intlayer/config/logger`),i=require(`@intlayer/config/node`);const a=async a=>{let o=(0,i.getConfiguration)(a?.configOptions),{locales:s,requiredLocales:c}=o.internationalization,l=(0,r.getAppLogger)(o);a?.build===!0?await(0,t.prepareIntlayer)(o,{forceRun:!0}):a?.build===void 0&&await(0,t.prepareIntlayer)(o);let u=e.listMissingTranslations(a?.configOptions),d=u.missingTranslations.map(e=>` - ${e.key}`).reduce((e,t)=>Math.max(e,t.length),0),f=u.missingTranslations.map(e=>(0,n.formatLocale)(e.locales,!1)).reduce((e,t)=>Math.max(e,t.length),0),p=u.missingTranslations.map(e=>[(0,r.colon)(` - ${(0,r.colorizeKey)(e.key)}`,{colSize:d,maxSize:40}),` - `,(0,r.colon)((0,n.formatLocale)(e.locales,r.ANSIColors.RED),{colSize:f,maxSize:40}),e.filePath?` - ${(0,n.formatPath)(e.filePath)}`:``,e.id?` - remote`:``].join(``));l(`Missing translations:`,{level:`info`}),p.forEach(e=>{l(e,{level:`info`})}),l(`Locales: ${(0,n.formatLocale)(s)}`),l(`Required locales: ${(0,n.formatLocale)(c??s)}`),l(`Missing locales: ${u.missingLocales.length===0?(0,r.colorize)(`-`,r.ANSIColors.GREEN):(0,n.formatLocale)(u.missingLocales,r.ANSIColors.RED)}`),l(`Missing required locales: ${u.missingRequiredLocales.length===0?(0,r.colorize)(`-`,r.ANSIColors.GREEN):(0,n.formatLocale)(u.missingRequiredLocales,r.ANSIColors.RED)}`),l(`Total missing locales: ${(0,r.colorizeNumber)(u.missingLocales.length,{one:r.ANSIColors.RED,other:r.ANSIColors.RED,zero:r.ANSIColors.GREEN})}`),l(`Total missing required locales: ${(0,r.colorizeNumber)(u.missingRequiredLocales.length,{one:r.ANSIColors.RED,other:r.ANSIColors.RED,zero:r.ANSIColors.GREEN})}`),u.missingRequiredLocales.length>0&&process.exit(1)};exports.testMissingTranslations=a;
2
2
  //# sourceMappingURL=test.cjs.map
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/setupAI.cjs`),n=require(`../utils/checkFileModifiedRange.cjs`),r=require(`../utils/getOutputFilePath.cjs`),i=require(`./translateFile.cjs`);let a=require(`node:fs`),o=require(`node:path`),s=require(`@intlayer/chokidar/cli`),c=require(`@intlayer/config/logger`),l=require(`@intlayer/config/node`),u=require(`fast-glob`);u=e.__toESM(u);let d=require(`@intlayer/chokidar/utils`),f=require(`node:perf_hooks`);const p=async({docPattern:e,locales:p,excludedGlobPattern:m,baseLocale:h,aiOptions:g,nbSimultaneousFileProcessed:_=20,configOptions:v,customInstructions:y,skipIfModifiedBefore:b,skipIfModifiedAfter:x,skipIfExists:S,gitOptions:C,flushStrategy:w=`incremental`})=>{let T=(0,l.getConfiguration)(v);(0,s.logConfigDetails)(v);let E=(0,c.getAppLogger)(T),D=_,O=(0,d.pLimit)(D),k=await(0,u.default)(e,{ignore:m}),A=await t.setupAI(T,g);if(!A?.hasAIAccess)return;let{aiClient:j,aiConfig:M}=A;if(C){let e=await(0,s.listGitFiles)(C);e&&(k=k.filter(t=>e.some(e=>(0,o.join)(process.cwd(),t)===e)))}let N=f.performance.now();E(`Translating ${(0,c.colorizeNumber)(k.length)} files to ${(0,c.colorizeNumber)(p.length)} locales. \nGlobal Concurrency: ${(0,c.colorizeNumber)(D)} chunks in parallel.`);let P={count:0,maxErrors:5,shouldStop:!1};await(0,d.parallelize)(k.flatMap(e=>p.map(t=>async()=>{if(P.shouldStop)return;let s=(0,o.join)(T.system.baseDir,e),c=r.getOutputFilePath(s,t,h);if(S&&(0,a.existsSync)(c))return;w===`incremental`&&!(0,a.existsSync)(c)&&((0,a.mkdirSync)((0,o.dirname)(c),{recursive:!0}),(0,a.writeFileSync)(c,``));let l=n.checkFileModifiedRange(c,{skipIfModifiedBefore:b,skipIfModifiedAfter:x});if(l.isSkipped){E(l.message);return}await i.translateFile({baseFilePath:s,outputFilePath:c,locale:t,baseLocale:h,configuration:T,errorState:P,aiOptions:g,customInstructions:y,aiClient:j,aiConfig:M,flushStrategy:w,limit:O})})),e=>e(),50);let F=((f.performance.now()-N)/1e3).toFixed(2);P.count>0?E(`Finished with ${P.count} errors in ${F}s.`):E(`${(0,c.colorize)(`✔`,c.ANSIColors.GREEN)} Batch completed successfully in ${(0,c.colorizeNumber)(F)}s.`)};exports.translateDoc=p;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/setupAI.cjs`),n=require(`../utils/checkFileModifiedRange.cjs`),r=require(`../utils/getOutputFilePath.cjs`),i=require(`./translateFile.cjs`);let a=require(`node:fs`),o=require(`node:path`),s=require(`@intlayer/chokidar/cli`),c=require(`@intlayer/chokidar/utils`),l=require(`@intlayer/config/logger`),u=require(`@intlayer/config/node`),d=require(`fast-glob`);d=e.__toESM(d);let f=require(`node:perf_hooks`);const p=async({docPattern:e,locales:p,excludedGlobPattern:m,baseLocale:h,aiOptions:g,nbSimultaneousFileProcessed:_=20,configOptions:v,customInstructions:y,skipIfModifiedBefore:b,skipIfModifiedAfter:x,skipIfExists:S,gitOptions:C,flushStrategy:w=`incremental`})=>{let T=(0,u.getConfiguration)(v);(0,s.logConfigDetails)(v);let E=(0,l.getAppLogger)(T),D=_,O=(0,c.pLimit)(D),k=await(0,d.default)(e,{ignore:m}),A=await t.setupAI(T,g);if(!A?.hasAIAccess)return;let{aiClient:j,aiConfig:M}=A;if(C){let e=await(0,s.listGitFiles)(C);e&&(k=k.filter(t=>e.some(e=>(0,o.join)(process.cwd(),t)===e)))}let N=f.performance.now();E(`Translating ${(0,l.colorizeNumber)(k.length)} files to ${(0,l.colorizeNumber)(p.length)} locales. \nGlobal Concurrency: ${(0,l.colorizeNumber)(D)} chunks in parallel.`);let P={count:0,maxErrors:5,shouldStop:!1};await(0,c.parallelize)(k.flatMap(e=>p.map(t=>async()=>{if(P.shouldStop)return;let s=(0,o.join)(T.system.baseDir,e),c=r.getOutputFilePath(s,t,h);if(S&&(0,a.existsSync)(c))return;w===`incremental`&&!(0,a.existsSync)(c)&&((0,a.mkdirSync)((0,o.dirname)(c),{recursive:!0}),(0,a.writeFileSync)(c,``));let l=n.checkFileModifiedRange(c,{skipIfModifiedBefore:b,skipIfModifiedAfter:x});if(l.isSkipped){E(l.message);return}await i.translateFile({baseFilePath:s,outputFilePath:c,locale:t,baseLocale:h,configuration:T,errorState:P,aiOptions:g,customInstructions:y,aiClient:j,aiConfig:M,flushStrategy:w,limit:O})})),e=>e(),50);let F=((f.performance.now()-N)/1e3).toFixed(2);P.count>0?E(`Finished with ${P.count} errors in ${F}s.`):E(`${(0,l.colorize)(`✔`,l.ANSIColors.GREEN)} Batch completed successfully in ${(0,l.colorizeNumber)(F)}s.`)};exports.translateDoc=p;
2
2
  //# sourceMappingURL=translateDoc.cjs.map
@@ -1,3 +1,3 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../_virtual/_utils_asset.cjs`),t=require(`./validation.cjs`),n=require(`../utils/chunkInference.cjs`),r=require(`../utils/fixChunkStartEndChars.cjs`),i=require(`../utils/calculateChunks.cjs`);let a=require(`node:fs`),o=require(`node:path`),s=require(`@intlayer/config/logger`),c=require(`@intlayer/chokidar/utils`),l=require(`@intlayer/config/utils`),u=require(`node:fs/promises`),d=require(`node:perf_hooks`);const f=async({baseFilePath:f,outputFilePath:p,locale:m,baseLocale:h,configuration:g,errorState:_,aiOptions:v,customInstructions:y,aiClient:b,aiConfig:x,flushStrategy:S=`incremental`,onChunkReceive:C,limit:w})=>{if(_.shouldStop)return null;let T=(0,s.getAppLogger)(g,{config:{prefix:``}}),E=d.performance.now();try{let D=i.chunkText(await(0,u.readFile)(f,`utf-8`)),O=D.length,k=`${(0,s.colon)(`${s.ANSIColors.GREY_DARK}[${(0,c.formatPath)(f)}${s.ANSIColors.GREY_DARK}] `,{colSize:40})}${s.ANSIColors.RESET}`,A=`${(0,s.colon)(`${s.ANSIColors.GREY_DARK}[${(0,c.formatPath)(f)}${s.ANSIColors.GREY_DARK}][${(0,c.formatLocale)(m)}${s.ANSIColors.GREY_DARK}] `,{colSize:40})}${s.ANSIColors.RESET}`;T(`${k}Split into ${(0,s.colorizeNumber)(O)} chunks. Queuing...`);let j=e.readAsset(`./prompts/TRANSLATE_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${(0,c.formatLocale)(m,!1)}`).replaceAll(`{{baseLocaleName}}`,`${(0,c.formatLocale)(h,!1)}`).replace(`{{applicationContext}}`,v?.applicationContext??`-`).replace(`{{customInstructions}}`,y??`-`),M=Array(O).fill(``),N=w??(e=>e()),P=D.map((e,i)=>N(async()=>{if(_.shouldStop)return null;let c=(0,s.getAppLogger)(g,{config:{prefix:`${A} ${s.ANSIColors.GREY_DARK}[${i+1}/${O}] ${s.ANSIColors.RESET}`}}),u=d.performance.now(),f=i===0,m=e.content,h=()=>">>> CONTEXT: PREVIOUS SOURCE CONTENT <<<\n```\n"+(D[i-1]?.content??``)+"\n```\n>>> END PREVIOUS CONTEXT <<<",y=()=>">>> CONTEXT: NEXT CONTENT <<<\n```\n"+(D[i+1]?.content??``)+"\n```\n>>> END NEXT CONTEXT <<<";c(`Process started`);let{content:w,tokens:T}=await(0,l.retryManager)(async()=>{let e=await n.chunkInference([{role:`system`,content:j},...D[i+1]?[{role:`system`,content:y()}]:[],...f?[]:[{role:`system`,content:h()}],{role:`system`,content:[`You are translating TARGET CHUNK (${i+1}/${O}).`,`Translate ONLY the target chunk. Preserve frontmatter/code exactly.`].join(`
2
- `)},{role:`user`,content:`>>> TARGET CHUNK START <<<\n${m}\n>>> TARGET CHUNK END <<<`}],v,g,b,x),a=t.sanitizeChunk(e?.fileContent,m);if(a=r.fixChunkStartEndChars(a,m),!t.validateTranslation(m,a,c))throw Error(`Validation failed for chunk ${i+1}/${O}`);return{content:a,tokens:e.tokenUsed}})(),E=(d.performance.now()-u).toFixed(0);if(M[i]=w,C&&C(w,i,O),S===`incremental`&&M.slice(0,i+1).every(e=>e&&e!==``)){let e=0;for(;e<O&&M[e]&&M[e]!==``;)e++;let t=M.slice(0,e).join(``);(0,a.mkdirSync)((0,o.dirname)(p),{recursive:!0}),(0,a.writeFileSync)(p,t)}c([`${(0,s.colorizeNumber)(T)} tokens used `,`${s.ANSIColors.GREY_DARK}in ${(0,s.colorizeNumber)(E)}ms${s.ANSIColors.RESET}`].join(``))}));await Promise.all(P);let F=M.join(``);(S===`end`||S===`incremental`)&&((0,a.mkdirSync)((0,o.dirname)(p),{recursive:!0}),(0,a.writeFileSync)(p,F));let I=((d.performance.now()-E)/1e3).toFixed(2),L=(0,o.relative)(g.system.baseDir,p);return T(`${(0,s.colorize)(`✔`,s.ANSIColors.GREEN)} File ${(0,c.formatPath)(L)} completed in ${(0,s.colorizeNumber)(I)}s.`),F}catch(e){_.count++;let t=e?.message??JSON.stringify(e);return T(`${(0,s.colorize)(`✖`,s.ANSIColors.RED)} Error: ${t}`),_.count>=_.maxErrors&&(_.shouldStop=!0),null}};exports.translateFile=f;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../_virtual/_utils_asset.cjs`),t=require(`./validation.cjs`),n=require(`../utils/chunkInference.cjs`),r=require(`../utils/fixChunkStartEndChars.cjs`),i=require(`../utils/calculateChunks.cjs`);let a=require(`node:fs`),o=require(`node:path`),s=require(`@intlayer/chokidar/utils`),c=require(`@intlayer/config/logger`),l=require(`@intlayer/config/utils`),u=require(`node:fs/promises`),d=require(`node:perf_hooks`);const f=async({baseFilePath:f,outputFilePath:p,locale:m,baseLocale:h,configuration:g,errorState:_,aiOptions:v,customInstructions:y,aiClient:b,aiConfig:x,flushStrategy:S=`incremental`,onChunkReceive:C,limit:w})=>{if(_.shouldStop)return null;let T=(0,c.getAppLogger)(g,{config:{prefix:``}}),E=d.performance.now();try{let D=i.chunkText(await(0,u.readFile)(f,`utf-8`)),O=D.length,k=`${(0,c.colon)(`${c.ANSIColors.GREY_DARK}[${(0,s.formatPath)(f)}${c.ANSIColors.GREY_DARK}] `,{colSize:40})}${c.ANSIColors.RESET}`,A=`${(0,c.colon)(`${c.ANSIColors.GREY_DARK}[${(0,s.formatPath)(f)}${c.ANSIColors.GREY_DARK}][${(0,s.formatLocale)(m)}${c.ANSIColors.GREY_DARK}] `,{colSize:40})}${c.ANSIColors.RESET}`;T(`${k}Split into ${(0,c.colorizeNumber)(O)} chunks. Queuing...`);let j=e.readAsset(`./prompts/TRANSLATE_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${(0,s.formatLocale)(m,!1)}`).replaceAll(`{{baseLocaleName}}`,`${(0,s.formatLocale)(h,!1)}`).replace(`{{applicationContext}}`,v?.applicationContext??`-`).replace(`{{customInstructions}}`,y??`-`),M=Array(O).fill(``),N=w??(e=>e()),P=D.map((e,i)=>N(async()=>{if(_.shouldStop)return null;let s=(0,c.getAppLogger)(g,{config:{prefix:`${A} ${c.ANSIColors.GREY_DARK}[${i+1}/${O}] ${c.ANSIColors.RESET}`}}),u=d.performance.now(),f=i===0,m=e.content,h=()=>">>> CONTEXT: PREVIOUS SOURCE CONTENT <<<\n```\n"+(D[i-1]?.content??``)+"\n```\n>>> END PREVIOUS CONTEXT <<<",y=()=>">>> CONTEXT: NEXT CONTENT <<<\n```\n"+(D[i+1]?.content??``)+"\n```\n>>> END NEXT CONTEXT <<<";s(`Process started`);let{content:w,tokens:T}=await(0,l.retryManager)(async()=>{let e=await n.chunkInference([{role:`system`,content:j},...D[i+1]?[{role:`system`,content:y()}]:[],...f?[]:[{role:`system`,content:h()}],{role:`system`,content:[`You are translating TARGET CHUNK (${i+1}/${O}).`,`Translate ONLY the target chunk. Preserve frontmatter/code exactly.`].join(`
2
+ `)},{role:`user`,content:`>>> TARGET CHUNK START <<<\n${m}\n>>> TARGET CHUNK END <<<`}],v,g,b,x),a=t.sanitizeChunk(e?.fileContent,m);if(a=r.fixChunkStartEndChars(a,m),!t.validateTranslation(m,a,s))throw Error(`Validation failed for chunk ${i+1}/${O}`);return{content:a,tokens:e.tokenUsed}})(),E=(d.performance.now()-u).toFixed(0);if(M[i]=w,C&&C(w,i,O),S===`incremental`&&M.slice(0,i+1).every(e=>e&&e!==``)){let e=0;for(;e<O&&M[e]&&M[e]!==``;)e++;let t=M.slice(0,e).join(``);(0,a.mkdirSync)((0,o.dirname)(p),{recursive:!0}),(0,a.writeFileSync)(p,t)}s([`${(0,c.colorizeNumber)(T)} tokens used `,`${c.ANSIColors.GREY_DARK}in ${(0,c.colorizeNumber)(E)}ms${c.ANSIColors.RESET}`].join(``))}));await Promise.all(P);let F=M.join(``);(S===`end`||S===`incremental`)&&((0,a.mkdirSync)((0,o.dirname)(p),{recursive:!0}),(0,a.writeFileSync)(p,F));let I=((d.performance.now()-E)/1e3).toFixed(2),L=(0,o.relative)(g.system.baseDir,p);return T(`${(0,c.colorize)(`✔`,c.ANSIColors.GREEN)} File ${(0,s.formatPath)(L)} completed in ${(0,c.colorizeNumber)(I)}s.`),F}catch(e){_.count++;let t=e?.message??JSON.stringify(e);return T(`${(0,c.colorize)(`✖`,c.ANSIColors.RED)} Error: ${t}`),_.count>=_.maxErrors&&(_.shouldStop=!0),null}};exports.translateFile=f;
3
3
  //# sourceMappingURL=translateFile.cjs.map
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`@intlayer/chokidar/cli`),t=require(`@intlayer/config/logger`),n=require(`@intlayer/config/node`),r=require(`@intlayer/chokidar/utils`),i=require(`@intlayer/chokidar/watcher`);const a=async a=>{let o=(0,n.getConfiguration)(a?.configOptions);(0,e.logConfigDetails)(a?.configOptions);let s=(0,t.getAppLogger)(o),c;a?.with&&(c=(0,r.runParallel)(a.with),c.result.catch(()=>{process.exit(1)}));let l=(0,i.watch)({persistent:!0,skipPrepare:a?.skipPrepare??!1}),u=async()=>{process.off(`SIGINT`,u),process.off(`SIGTERM`,u),s(`Stopping Intlayer watcher...`);try{await l.close(),c&&`child`in c&&c.child?.kill(`SIGTERM`)}catch(e){console.error(`Error during shutdown:`,e)}finally{process.exit(0)}};process.on(`SIGINT`,u),process.on(`SIGTERM`,u)};exports.watchContentDeclaration=a;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`@intlayer/chokidar/cli`),t=require(`@intlayer/chokidar/utils`),n=require(`@intlayer/config/logger`),r=require(`@intlayer/config/node`),i=require(`@intlayer/chokidar/watcher`);const a=async a=>{let o=(0,r.getConfiguration)(a?.configOptions);(0,e.logConfigDetails)(a?.configOptions);let s=(0,n.getAppLogger)(o),c;a?.with&&(c=(0,t.runParallel)(a.with),c.result.catch(()=>{process.exit(1)}));let l=(0,i.watch)({persistent:!0,skipPrepare:a?.skipPrepare??!1}),u=async()=>{process.off(`SIGINT`,u),process.off(`SIGTERM`,u),s(`Stopping Intlayer watcher...`);try{await l.close(),c&&`child`in c&&c.child?.kill(`SIGTERM`)}catch(e){console.error(`Error during shutdown:`,e)}finally{process.exit(0)}};process.on(`SIGINT`,u),process.on(`SIGTERM`,u)};exports.watchContentDeclaration=a;
2
2
  //# sourceMappingURL=watch.cjs.map
@@ -1,2 +1,2 @@
1
- import{logConfigDetails as e}from"@intlayer/chokidar/cli";import{getConfiguration as t}from"@intlayer/config/node";import{runParallel as n}from"@intlayer/chokidar/utils";import{buildAndWatchIntlayer as r}from"@intlayer/chokidar/watcher";const i=async i=>{let a=t(i?.configOptions);e(i?.configOptions);let o=null;i?.with&&(o=n(i.with),o.result.catch(()=>{})),await r({persistent:i?.watch??!1,skipPrepare:i?.skipPrepare??!1,configuration:a}),!i?.watch&&o&&o.kill()};export{i as build};
1
+ import{logConfigDetails as e}from"@intlayer/chokidar/cli";import{runParallel as t}from"@intlayer/chokidar/utils";import{getConfiguration as n}from"@intlayer/config/node";import{buildAndWatchIntlayer as r}from"@intlayer/chokidar/watcher";const i=async i=>{let a=n(i?.configOptions);e(i?.configOptions);let o=null;i?.with&&(o=t(i.with),o.result.catch(()=>{})),await r({persistent:i?.watch??!1,skipPrepare:i?.skipPrepare??!1,configuration:a}),!i?.watch&&o&&o.kill()};export{i as build};
2
2
  //# sourceMappingURL=build.mjs.map
@@ -1,2 +1,2 @@
1
- import{existsSync as e}from"node:fs";import{relative as t,resolve as n}from"node:path";import{detectPackageName as r,extractContent as i}from"@intlayer/babel";import{logConfigDetails as a}from"@intlayer/chokidar/cli";import{colorizePath as o,getAppLogger as s}from"@intlayer/config/logger";import{getConfiguration as c}from"@intlayer/config/node";import{getUnmergedDictionaries as l}from"@intlayer/unmerged-dictionaries-entry";import u from"enquirer";import d from"fast-glob";const f=async f=>{let p=c(f.configOptions);a(f?.configOptions);let m=s(p),{baseDir:h}=p.system,{codeDir:g,excludedPath:_}=p.content,{traversePattern:v}=p.build,y=e=>o(t(h,e)),b=r(h),x=f.files??[];if(x.length===0){let n=e=>(_??[]).some(t=>{let n=t.split(`/`).filter(e=>!e.includes(`*`)&&e.length>0),r=e.split(`/`);return n.some(e=>r.includes(e))}),r=(await Promise.all(g.filter(e=>!n(e)).map(e=>d(v,{cwd:e,ignore:_,absolute:!0})))).flat(),i=[...new Set(r)].filter(t=>e(t)).map(e=>({value:e,label:t(h,e)}));if(i.length===0){m(`No extractable files found in the project.`);return}let a=`__select_all__`,o;try{let e=Math.max((process.stdout.columns||80)-15,20),t=t=>t.length>e?`...${t.slice(-(e-3))}`:t,{files:n}=await u.prompt({type:`autocomplete`,name:`files`,message:`Select files to extract (Type to search):`,multiple:!0,limit:40,choices:[{name:a,message:`────── Select all ──────`},...i.map(e=>({name:e.value,message:t(e.label)}))],async toggle(e,t){if(!(!e||e.disabled))return e.enabled=t??!e.enabled,e.name===a&&this.choices.filter(e=>e.name!==a).forEach(t=>{t.enabled=e.enabled}),this.render()},format(){return this.state?.submitted&&this.options?.multiple?`${this.selected.filter(e=>e.name!==a).length} file(s) selected`:this.input??``}});o=n.filter(e=>e!==a)}catch{o=Symbol(`cancel`)}typeof o==`symbol`&&process.exit(0),x=o}if(x.length===0){m(`No files selected for extraction.`);return}let S=x.map(e=>n(h,e)).filter(t=>e(t)?!0:(m(`File not found: ${y(t)}`),!1));if(S.length===0)return;let C=l(p);await Promise.all(S.map(async e=>{try{await i(e,b,{unmergedDictionaries:C,configuration:p,codeOnly:f.codeOnly,declarationOnly:f.declarationOnly})}catch(t){m(`Failed to transform ${e}: ${t.message}`)}}))};export{f as extract};
1
+ import{existsSync as e}from"node:fs";import{relative as t,resolve as n}from"node:path";import{detectPackageName as r,extractContent as i}from"@intlayer/babel";import{prepareIntlayer as a}from"@intlayer/chokidar/build";import{logConfigDetails as o}from"@intlayer/chokidar/cli";import{buildComponentFilesList as s}from"@intlayer/chokidar/utils";import{ANSIColors as c,colorize as l,colorizePath as u,getAppLogger as d,x as f}from"@intlayer/config/logger";import{getConfiguration as p}from"@intlayer/config/node";import{getUnmergedDictionaries as m}from"@intlayer/unmerged-dictionaries-entry";import h from"enquirer";const g=async g=>{let _=p(g.configOptions);o(g?.configOptions);let v=d(_),{baseDir:y}=_.system,{output:b}=_.compiler,x=e=>u(t(y,e));if(!b){v(`${f} No output configuration found. Add a ${l(`compiler.output`,c.BLUE)} in your configuration.`,{level:`error`});return}let S=r(y),C=g.files??[];if(C.length===0){let e=s(_).map(e=>({value:e,label:t(y,e)}));if(e.length===0){v(`No extractable files found in the project.`);return}let n=`__select_all__`,r;try{let t=Math.max((process.stdout.columns||80)-15,20),i=e=>e.length>t?`...${e.slice(-(t-3))}`:e,{files:a}=await h.prompt({type:`autocomplete`,name:`files`,message:`Select files to extract (Type to search):`,multiple:!0,limit:40,choices:[{name:n,message:`────── Select all ──────`},...e.map(e=>({name:e.value,message:i(e.label)}))],async toggle(e,t){if(!(!e||e.disabled))return e.enabled=t??!e.enabled,e.name===n&&this.choices.filter(e=>e.name!==n).forEach(t=>{t.enabled=e.enabled}),this.render()},format(){return this.state?.submitted&&this.options?.multiple?`${this.selected.filter(e=>e.name!==n).length} file(s) selected`:this.input??``}});r=a.filter(e=>e!==n)}catch{r=Symbol(`cancel`)}typeof r==`symbol`&&process.exit(0),C=r}if(C.length===0){v(`No files selected for extraction.`);return}let w=C.map(e=>n(y,e)).filter(t=>e(t)?!0:(v(`File not found: ${x(t)}`),!1));if(w.length===0)return;let T=m(_);await Promise.all(w.map(async e=>{try{await i(e,S,{unmergedDictionaries:T,configuration:_,codeOnly:g.codeOnly,declarationOnly:g.declarationOnly})}catch(t){v(`Failed to transform ${e}: ${t.message}`)}})),await a(_)};export{g as extract};
2
2
  //# sourceMappingURL=extract.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extract.mjs","names":[],"sources":["../../src/extract.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport {\n detectPackageName,\n extractContent,\n type PackageName,\n} from '@intlayer/babel';\nimport { logConfigDetails } from '@intlayer/chokidar/cli';\nimport { colorizePath, getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { FilePathPattern } from '@intlayer/types/filePathPattern';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport enquirer from 'enquirer';\nimport fg from 'fast-glob';\n\ntype ExtractOptions = {\n files?: string[];\n output?: FilePathPattern;\n configOptions?: GetConfigurationOptions;\n codeOnly?: boolean;\n declarationOnly?: boolean;\n};\n\nexport const extract = async (options: ExtractOptions) => {\n const configuration = getConfiguration(options.configOptions);\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(configuration);\n const { baseDir } = configuration.system;\n const { codeDir, excludedPath } = configuration.content;\n const { traversePattern } = configuration.build;\n\n const formatPath = (path: string) => {\n const relativePath = relative(baseDir, path);\n return colorizePath(relativePath);\n };\n\n // Detect package\n const packageName: PackageName = detectPackageName(baseDir);\n\n let filesToExtract = options.files ?? [];\n\n if (filesToExtract.length === 0) {\n // Filter out codeDirs that are themselves inside an excluded path (e.g. dist, node_modules)\n const isDirExcluded = (dirPath: string): boolean =>\n (excludedPath ?? []).some((pattern) => {\n const segments = pattern\n .split('/')\n .filter((s) => !s.includes('*') && s.length > 0);\n const parts = dirPath.split('/');\n return segments.some((seg) => parts.includes(seg));\n });\n\n // Await all promises simultaneously\n const resultsArray = await Promise.all(\n codeDir\n .filter((dir) => !isDirExcluded(dir))\n .map((dir) =>\n fg(traversePattern, {\n cwd: dir,\n ignore: excludedPath,\n absolute: true,\n })\n )\n );\n\n // Flatten the nested arrays and remove duplicates\n const allFiles = resultsArray.flat();\n\n const uniqueFiles = [...new Set(allFiles)].filter((file) =>\n existsSync(file)\n );\n\n // Relative paths for selection\n const choices = uniqueFiles.map((file) => {\n const relPath = relative(baseDir, file);\n return {\n value: file,\n label: relPath,\n };\n });\n\n if (choices.length === 0) {\n appLogger('No extractable files found in the project.');\n return;\n }\n\n const SELECT_ALL = '__select_all__';\n\n type PromptChoice = {\n name: string;\n enabled: boolean;\n disabled?: boolean | string;\n };\n\n type PromptContext = {\n choices: PromptChoice[];\n render(): void | Promise<void>;\n state: { submitted: boolean };\n selected: PromptChoice[];\n input: string;\n options: { multiple?: boolean };\n };\n\n let selectedFiles: string[] | symbol;\n try {\n const maxLen = Math.max((process.stdout.columns || 80) - 15, 20);\n const truncatePath = (path: string) =>\n path.length > maxLen ? `...${path.slice(-(maxLen - 3))}` : path;\n\n const { files: enquirerSelectedFiles } = await enquirer.prompt<{\n files: string[];\n }>({\n type: 'autocomplete',\n name: 'files',\n message: 'Select files to extract (Type to search):',\n multiple: true,\n // @ts-ignore limit exist but is not typed\n limit: 40,\n choices: [\n { name: SELECT_ALL, message: '────── Select all ──────' },\n ...choices.map((choice) => ({\n name: choice.value,\n message: truncatePath(choice.label),\n })),\n ],\n async toggle(\n this: PromptContext,\n choice: PromptChoice,\n enabled?: boolean\n ) {\n if (!choice || choice.disabled) return;\n choice.enabled = enabled == null ? !choice.enabled : enabled;\n\n if (choice.name === SELECT_ALL) {\n this.choices\n .filter((choiceEl) => choiceEl.name !== SELECT_ALL)\n .forEach((choiceEl) => {\n choiceEl.enabled = choice.enabled;\n });\n }\n\n return this.render();\n },\n format(this: PromptContext) {\n if (this.state?.submitted && this.options?.multiple) {\n return `${this.selected.filter((s) => s.name !== SELECT_ALL).length} file(s) selected`;\n }\n return this.input ?? '';\n },\n });\n\n selectedFiles = enquirerSelectedFiles.filter((f) => f !== SELECT_ALL);\n } catch {\n selectedFiles = Symbol('cancel');\n }\n\n if (typeof selectedFiles === 'symbol') {\n // User cancelled\n process.exit(0);\n }\n\n filesToExtract = selectedFiles as string[];\n }\n\n if (filesToExtract.length === 0) {\n appLogger('No files selected for extraction.');\n return;\n }\n\n const absoluteFiles = filesToExtract\n .map((file) => resolve(baseDir, file))\n .filter((file) => {\n if (!existsSync(file)) {\n appLogger(`File not found: ${formatPath(file)}`);\n return false;\n }\n return true;\n });\n\n if (absoluteFiles.length === 0) {\n return;\n }\n\n const unmergedDictionaries = getUnmergedDictionaries(configuration);\n\n await Promise.all(\n absoluteFiles.map(async (filePath) => {\n try {\n await extractContent(filePath, packageName, {\n unmergedDictionaries,\n configuration,\n codeOnly: options.codeOnly,\n declarationOnly: options.declarationOnly,\n });\n } catch (error) {\n appLogger(\n `Failed to transform ${filePath}: ${(error as Error).message}`\n );\n }\n })\n );\n};\n"],"mappings":"4dA2BA,MAAa,EAAU,KAAO,IAA4B,CACxD,IAAM,EAAgB,EAAiB,EAAQ,cAAc,CAC7D,EAAiB,GAAS,cAAc,CAExC,IAAM,EAAY,EAAa,EAAc,CACvC,CAAE,WAAY,EAAc,OAC5B,CAAE,UAAS,gBAAiB,EAAc,QAC1C,CAAE,mBAAoB,EAAc,MAEpC,EAAc,GAEX,EADc,EAAS,EAAS,EAAK,CACX,CAI7B,EAA2B,EAAkB,EAAQ,CAEvD,EAAiB,EAAQ,OAAS,EAAE,CAExC,GAAI,EAAe,SAAW,EAAG,CAE/B,IAAM,EAAiB,IACpB,GAAgB,EAAE,EAAE,KAAM,GAAY,CACrC,IAAM,EAAW,EACd,MAAM,IAAI,CACV,OAAQ,GAAM,CAAC,EAAE,SAAS,IAAI,EAAI,EAAE,OAAS,EAAE,CAC5C,EAAQ,EAAQ,MAAM,IAAI,CAChC,OAAO,EAAS,KAAM,GAAQ,EAAM,SAAS,EAAI,CAAC,EAClD,CAgBE,GAbe,MAAM,QAAQ,IACjC,EACG,OAAQ,GAAQ,CAAC,EAAc,EAAI,CAAC,CACpC,IAAK,GACJ,EAAG,EAAiB,CAClB,IAAK,EACL,OAAQ,EACR,SAAU,GACX,CAAC,CACH,CACJ,EAG6B,MAAM,CAO9B,EALc,CAAC,GAAG,IAAI,IAAI,EAAS,CAAC,CAAC,OAAQ,GACjD,EAAW,EAAK,CACjB,CAG2B,IAAK,IAExB,CACL,MAAO,EACP,MAHc,EAAS,EAAS,EAAK,CAItC,EACD,CAEF,GAAI,EAAQ,SAAW,EAAG,CACxB,EAAU,6CAA6C,CACvD,OAGF,IAAM,EAAa,iBAiBf,EACJ,GAAI,CACF,IAAM,EAAS,KAAK,KAAK,QAAQ,OAAO,SAAW,IAAM,GAAI,GAAG,CAC1D,EAAgB,GACpB,EAAK,OAAS,EAAS,MAAM,EAAK,MAAM,EAAE,EAAS,GAAG,GAAK,EAEvD,CAAE,MAAO,GAA0B,MAAM,EAAS,OAErD,CACD,KAAM,eACN,KAAM,QACN,QAAS,4CACT,SAAU,GAEV,MAAO,GACP,QAAS,CACP,CAAE,KAAM,EAAY,QAAS,2BAA4B,CACzD,GAAG,EAAQ,IAAK,IAAY,CAC1B,KAAM,EAAO,MACb,QAAS,EAAa,EAAO,MAAM,CACpC,EAAE,CACJ,CACD,MAAM,OAEJ,EACA,EACA,CACI,MAAC,GAAU,EAAO,UAWtB,MAVA,GAAO,QAAU,GAAkB,CAAC,EAAO,QAEvC,EAAO,OAAS,GAClB,KAAK,QACF,OAAQ,GAAa,EAAS,OAAS,EAAW,CAClD,QAAS,GAAa,CACrB,EAAS,QAAU,EAAO,SAC1B,CAGC,KAAK,QAAQ,EAEtB,QAA4B,CAI1B,OAHI,KAAK,OAAO,WAAa,KAAK,SAAS,SAClC,GAAG,KAAK,SAAS,OAAQ,GAAM,EAAE,OAAS,EAAW,CAAC,OAAO,mBAE/D,KAAK,OAAS,IAExB,CAAC,CAEF,EAAgB,EAAsB,OAAQ,GAAM,IAAM,EAAW,MAC/D,CACN,EAAgB,OAAO,SAAS,CAG9B,OAAO,GAAkB,UAE3B,QAAQ,KAAK,EAAE,CAGjB,EAAiB,EAGnB,GAAI,EAAe,SAAW,EAAG,CAC/B,EAAU,oCAAoC,CAC9C,OAGF,IAAM,EAAgB,EACnB,IAAK,GAAS,EAAQ,EAAS,EAAK,CAAC,CACrC,OAAQ,GACF,EAAW,EAAK,CAId,IAHL,EAAU,mBAAmB,EAAW,EAAK,GAAG,CACzC,IAGT,CAEJ,GAAI,EAAc,SAAW,EAC3B,OAGF,IAAM,EAAuB,EAAwB,EAAc,CAEnE,MAAM,QAAQ,IACZ,EAAc,IAAI,KAAO,IAAa,CACpC,GAAI,CACF,MAAM,EAAe,EAAU,EAAa,CAC1C,uBACA,gBACA,SAAU,EAAQ,SAClB,gBAAiB,EAAQ,gBAC1B,CAAC,OACK,EAAO,CACd,EACE,uBAAuB,EAAS,IAAK,EAAgB,UACtD,GAEH,CACH"}
1
+ {"version":3,"file":"extract.mjs","names":[],"sources":["../../src/extract.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { relative, resolve } from 'node:path';\nimport {\n detectPackageName,\n extractContent,\n type PackageName,\n} from '@intlayer/babel';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { logConfigDetails } from '@intlayer/chokidar/cli';\nimport { buildComponentFilesList } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizePath,\n getAppLogger,\n x,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { FilePathPattern } from '@intlayer/types/filePathPattern';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport enquirer from 'enquirer';\n\ntype ExtractOptions = {\n files?: string[];\n output?: FilePathPattern;\n configOptions?: GetConfigurationOptions;\n codeOnly?: boolean;\n declarationOnly?: boolean;\n};\n\nexport const extract = async (options: ExtractOptions) => {\n const configuration = getConfiguration(options.configOptions);\n\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(configuration);\n\n const { baseDir } = configuration.system;\n const { output } = configuration.compiler;\n\n const formatPath = (path: string) => {\n const relativePath = relative(baseDir, path);\n return colorizePath(relativePath);\n };\n\n if (!output) {\n appLogger(\n `${x} No output configuration found. Add a ${colorize('compiler.output', ANSIColors.BLUE)} in your configuration.`,\n {\n level: 'error',\n }\n );\n return;\n }\n\n // Detect package\n const packageName: PackageName = detectPackageName(baseDir);\n\n let filesToExtract = options.files ?? [];\n\n if (filesToExtract.length === 0) {\n // Await all promises simultaneously\n const fileList = buildComponentFilesList(configuration);\n\n // Flatten the nested arrays and remove duplicates\n // Relative paths for selection\n const choices = fileList.map((file) => {\n const relPath = relative(baseDir, file);\n return {\n value: file,\n label: relPath,\n };\n });\n\n if (choices.length === 0) {\n appLogger('No extractable files found in the project.');\n return;\n }\n\n const SELECT_ALL = '__select_all__';\n\n type PromptChoice = {\n name: string;\n enabled: boolean;\n disabled?: boolean | string;\n };\n\n type PromptContext = {\n choices: PromptChoice[];\n render(): void | Promise<void>;\n state: { submitted: boolean };\n selected: PromptChoice[];\n input: string;\n options: { multiple?: boolean };\n };\n\n let selectedFiles: string[] | symbol;\n try {\n const maxLen = Math.max((process.stdout.columns || 80) - 15, 20);\n const truncatePath = (path: string) =>\n path.length > maxLen ? `...${path.slice(-(maxLen - 3))}` : path;\n\n const { files: enquirerSelectedFiles } = await enquirer.prompt<{\n files: string[];\n }>({\n type: 'autocomplete',\n name: 'files',\n message: 'Select files to extract (Type to search):',\n multiple: true,\n // @ts-ignore limit exist but is not typed\n limit: 40,\n choices: [\n { name: SELECT_ALL, message: '────── Select all ──────' },\n ...choices.map((choice) => ({\n name: choice.value,\n message: truncatePath(choice.label),\n })),\n ],\n async toggle(\n this: PromptContext,\n choice: PromptChoice,\n enabled?: boolean\n ) {\n if (!choice || choice.disabled) return;\n choice.enabled = enabled == null ? !choice.enabled : enabled;\n\n if (choice.name === SELECT_ALL) {\n this.choices\n .filter((choiceEl) => choiceEl.name !== SELECT_ALL)\n .forEach((choiceEl) => {\n choiceEl.enabled = choice.enabled;\n });\n }\n\n return this.render();\n },\n format(this: PromptContext) {\n if (this.state?.submitted && this.options?.multiple) {\n return `${this.selected.filter((s) => s.name !== SELECT_ALL).length} file(s) selected`;\n }\n return this.input ?? '';\n },\n });\n\n selectedFiles = enquirerSelectedFiles.filter((f) => f !== SELECT_ALL);\n } catch {\n selectedFiles = Symbol('cancel');\n }\n\n if (typeof selectedFiles === 'symbol') {\n // User cancelled\n process.exit(0);\n }\n\n filesToExtract = selectedFiles as string[];\n }\n\n if (filesToExtract.length === 0) {\n appLogger('No files selected for extraction.');\n return;\n }\n\n const absoluteFiles = filesToExtract\n .map((file) => resolve(baseDir, file))\n .filter((file) => {\n if (!existsSync(file)) {\n appLogger(`File not found: ${formatPath(file)}`);\n return false;\n }\n return true;\n });\n\n if (absoluteFiles.length === 0) {\n return;\n }\n\n const unmergedDictionaries = getUnmergedDictionaries(configuration);\n\n await Promise.all(\n absoluteFiles.map(async (filePath) => {\n try {\n await extractContent(filePath, packageName, {\n unmergedDictionaries,\n configuration,\n codeOnly: options.codeOnly,\n declarationOnly: options.declarationOnly,\n });\n } catch (error) {\n appLogger(\n `Failed to transform ${filePath}: ${(error as Error).message}`\n );\n }\n })\n );\n\n await prepareIntlayer(configuration); // Prepare Intlayer to apply the changes\n};\n"],"mappings":"smBAiCA,MAAa,EAAU,KAAO,IAA4B,CACxD,IAAM,EAAgB,EAAiB,EAAQ,cAAc,CAE7D,EAAiB,GAAS,cAAc,CAExC,IAAM,EAAY,EAAa,EAAc,CAEvC,CAAE,WAAY,EAAc,OAC5B,CAAE,UAAW,EAAc,SAE3B,EAAc,GAEX,EADc,EAAS,EAAS,EAAK,CACX,CAGnC,GAAI,CAAC,EAAQ,CACX,EACE,GAAG,EAAE,wCAAwC,EAAS,kBAAmB,EAAW,KAAK,CAAC,yBAC1F,CACE,MAAO,QACR,CACF,CACD,OAIF,IAAM,EAA2B,EAAkB,EAAQ,CAEvD,EAAiB,EAAQ,OAAS,EAAE,CAExC,GAAI,EAAe,SAAW,EAAG,CAM/B,IAAM,EAJW,EAAwB,EAAc,CAI9B,IAAK,IAErB,CACL,MAAO,EACP,MAHc,EAAS,EAAS,EAAK,CAItC,EACD,CAEF,GAAI,EAAQ,SAAW,EAAG,CACxB,EAAU,6CAA6C,CACvD,OAGF,IAAM,EAAa,iBAiBf,EACJ,GAAI,CACF,IAAM,EAAS,KAAK,KAAK,QAAQ,OAAO,SAAW,IAAM,GAAI,GAAG,CAC1D,EAAgB,GACpB,EAAK,OAAS,EAAS,MAAM,EAAK,MAAM,EAAE,EAAS,GAAG,GAAK,EAEvD,CAAE,MAAO,GAA0B,MAAM,EAAS,OAErD,CACD,KAAM,eACN,KAAM,QACN,QAAS,4CACT,SAAU,GAEV,MAAO,GACP,QAAS,CACP,CAAE,KAAM,EAAY,QAAS,2BAA4B,CACzD,GAAG,EAAQ,IAAK,IAAY,CAC1B,KAAM,EAAO,MACb,QAAS,EAAa,EAAO,MAAM,CACpC,EAAE,CACJ,CACD,MAAM,OAEJ,EACA,EACA,CACI,MAAC,GAAU,EAAO,UAWtB,MAVA,GAAO,QAAU,GAAkB,CAAC,EAAO,QAEvC,EAAO,OAAS,GAClB,KAAK,QACF,OAAQ,GAAa,EAAS,OAAS,EAAW,CAClD,QAAS,GAAa,CACrB,EAAS,QAAU,EAAO,SAC1B,CAGC,KAAK,QAAQ,EAEtB,QAA4B,CAI1B,OAHI,KAAK,OAAO,WAAa,KAAK,SAAS,SAClC,GAAG,KAAK,SAAS,OAAQ,GAAM,EAAE,OAAS,EAAW,CAAC,OAAO,mBAE/D,KAAK,OAAS,IAExB,CAAC,CAEF,EAAgB,EAAsB,OAAQ,GAAM,IAAM,EAAW,MAC/D,CACN,EAAgB,OAAO,SAAS,CAG9B,OAAO,GAAkB,UAE3B,QAAQ,KAAK,EAAE,CAGjB,EAAiB,EAGnB,GAAI,EAAe,SAAW,EAAG,CAC/B,EAAU,oCAAoC,CAC9C,OAGF,IAAM,EAAgB,EACnB,IAAK,GAAS,EAAQ,EAAS,EAAK,CAAC,CACrC,OAAQ,GACF,EAAW,EAAK,CAId,IAHL,EAAU,mBAAmB,EAAW,EAAK,GAAG,CACzC,IAGT,CAEJ,GAAI,EAAc,SAAW,EAC3B,OAGF,IAAM,EAAuB,EAAwB,EAAc,CAEnE,MAAM,QAAQ,IACZ,EAAc,IAAI,KAAO,IAAa,CACpC,GAAI,CACF,MAAM,EAAe,EAAU,EAAa,CAC1C,uBACA,gBACA,SAAU,EAAQ,SAClB,gBAAiB,EAAQ,gBAC1B,CAAC,OACK,EAAO,CACd,EACE,uBAAuB,EAAS,IAAK,EAAgB,UACtD,GAEH,CACH,CAED,MAAM,EAAgB,EAAc"}
@@ -1,2 +1,2 @@
1
- import{ensureArray as e,getTargetUnmergedDictionaries as t}from"../getTargetDictionary.mjs";import{setupAI as n}from"../utils/setupAI.mjs";import{listTranslationsTasks as r}from"./listTranslationsTasks.mjs";import{translateDictionary as i}from"./translateDictionary.mjs";import{writeFill as a}from"./writeFill.mjs";import{basename as o,relative as s}from"node:path";import{logConfigDetails as c}from"@intlayer/chokidar/cli";import{ANSIColors as l,colorize as u,colorizeKey as d,colorizePath as f,getAppLogger as p}from"@intlayer/config/logger";import{getConfiguration as m}from"@intlayer/config/node";import{prepareIntlayer as h,writeContentDeclaration as g}from"@intlayer/chokidar/build";import{formatPath as _,getGlobalLimiter as v,getTaskLimiter as y}from"@intlayer/chokidar/utils";const b=async b=>{let x=m(b?.configOptions);c(b?.configOptions);let S=p(x);b?.build===!0?await h(x,{forceRun:!0}):b?.build===void 0&&await h(x);let{defaultLocale:C,locales:w}=x.internationalization,T=b?.mode??`complete`,E=b?.sourceLocale??C,D=b?.outputLocales?e(b.outputLocales):w,O=await n(x,b?.aiOptions);if(!O?.hasAIAccess)return;let{aiClient:k,aiConfig:A}=O,j=await t(b),M=new Set;j.forEach(e=>{M.add(e.key)});let N=Array.from(M);if(S([`Affected dictionary keys for processing:`,N.length>0?N.map(e=>d(e)).join(`, `):u(`No keys found`,l.YELLOW)]),N.length===0)return;let P=r(j.map(e=>e.localId),D,T,E,x),F=b?.nbConcurrentTranslations??7,I=v(F),L=y(Math.max(1,Math.min(b?.nbConcurrentTasks??F,P.length))),R=P.map(e=>L(async()=>{let t=s(x?.content?.baseDir??process.cwd(),e?.dictionaryFilePath??``);S(`${e.dictionaryPreset} Processing ${f(o(t))}`,{level:`info`});let n=await i(e,x,{mode:T,aiOptions:b?.aiOptions,fillMetadata:!b?.skipMetadata,onHandle:I,aiClient:k,aiConfig:A});if(!n?.dictionaryOutput)return;let{dictionaryOutput:r,sourceLocale:c}=n,l=typeof r.fill==`string`||typeof r.fill==`object`,u=typeof r.locale==`string`,d=l?r.fill:u?x.dictionary?.fill??!0:!1;typeof d==`string`||typeof d==`object`?await a({...r,fill:d},D,[c],x):(await g(r,x),r.filePath&&S(`${e.dictionaryPreset} Content declaration written to ${_(o(r.filePath))}`,{level:`info`}))}));await Promise.all(R),await I.onIdle()};export{b as fill};
1
+ import{ensureArray as e,getTargetUnmergedDictionaries as t}from"../getTargetDictionary.mjs";import{setupAI as n}from"../utils/setupAI.mjs";import{listTranslationsTasks as r}from"./listTranslationsTasks.mjs";import{translateDictionary as i}from"./translateDictionary.mjs";import{writeFill as a}from"./writeFill.mjs";import{basename as o,relative as s}from"node:path";import{prepareIntlayer as c,writeContentDeclaration as l}from"@intlayer/chokidar/build";import{logConfigDetails as u}from"@intlayer/chokidar/cli";import{formatPath as d,getGlobalLimiter as f,getTaskLimiter as p}from"@intlayer/chokidar/utils";import{ANSIColors as m,colorize as h,colorizeKey as g,colorizePath as _,getAppLogger as v}from"@intlayer/config/logger";import{getConfiguration as y}from"@intlayer/config/node";const b=async b=>{let x=y(b?.configOptions);u(b?.configOptions);let S=v(x);b?.build===!0?await c(x,{forceRun:!0}):b?.build===void 0&&await c(x);let{defaultLocale:C,locales:w}=x.internationalization,T=b?.mode??`complete`,E=b?.sourceLocale??C,D=b?.outputLocales?e(b.outputLocales):w,O=await n(x,b?.aiOptions);if(!O?.hasAIAccess)return;let{aiClient:k,aiConfig:A}=O,j=await t(b),M=new Set;j.forEach(e=>{M.add(e.key)});let N=Array.from(M);if(S([`Affected dictionary keys for processing:`,N.length>0?N.map(e=>g(e)).join(`, `):h(`No keys found`,m.YELLOW)]),N.length===0)return;let P=r(j.map(e=>e.localId),D,T,E,x),F=b?.nbConcurrentTranslations??7,I=f(F),L=p(Math.max(1,Math.min(b?.nbConcurrentTasks??F,P.length))),R=P.map(e=>L(async()=>{let t=s(x?.content?.baseDir??process.cwd(),e?.dictionaryFilePath??``);S(`${e.dictionaryPreset} Processing ${_(o(t))}`,{level:`info`});let n=await i(e,x,{mode:T,aiOptions:b?.aiOptions,fillMetadata:!b?.skipMetadata,onHandle:I,aiClient:k,aiConfig:A});if(!n?.dictionaryOutput)return;let{dictionaryOutput:r,sourceLocale:c}=n,u=typeof r.fill==`string`||typeof r.fill==`object`,f=typeof r.locale==`string`,p=u?r.fill:f?x.dictionary?.fill??!0:!1;typeof p==`string`||typeof p==`object`?await a({...r,fill:p},D,[c],x):(await l(r,x),r.filePath&&S(`${e.dictionaryPreset} Content declaration written to ${d(o(r.filePath))}`,{level:`info`}))}));await Promise.all(R),await I.onIdle()};export{b as fill};
2
2
  //# sourceMappingURL=fill.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatFillData.mjs","names":[],"sources":["../../../src/fill/formatFillData.ts"],"sourcesContent":["import { basename, dirname, extname, relative } from 'node:path';\nimport {\n getFormatFromExtension,\n resolveRelativePath,\n} from '@intlayer/chokidar/utils';\nimport { parseStringPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { DictionaryKey, Fill } from '@intlayer/types/dictionary';\nimport type {\n FilePathPattern,\n FilePathPatternContext,\n} from '@intlayer/types/filePathPattern';\n\nexport type FillData = {\n localeList: Locale[];\n filePath: string;\n isPerLocale: boolean;\n};\n\nexport const formatFillData = async (\n fillField: Fill,\n localeList: Locale[],\n filePath: string,\n dictionaryKey: DictionaryKey,\n configuration: IntlayerConfig\n): Promise<FillData[]> => {\n if (!fillField || typeof fillField === 'boolean') return [];\n\n const { baseDir } = configuration.system;\n const { defaultLocale } = configuration.internationalization;\n\n const extension = extname(filePath);\n const base = basename(filePath);\n\n // Extract the original filename without extensions\n const cleanComponentFileName = base.includes('.content.')\n ? base.split('.content.')[0]\n : base.split('.')[0];\n\n const uncapitalizedName =\n cleanComponentFileName.charAt(0).toLowerCase() +\n cleanComponentFileName.slice(1);\n\n const componentFormat = getFormatFromExtension(extension as any);\n\n const getContext = (\n locale: Locale,\n patternType?: FilePathPattern\n ): FilePathPatternContext => {\n let format: FilePathPatternContext['format'] = 'json';\n if (typeof patternType === 'string') {\n const extFormat = getFormatFromExtension(extname(patternType) as any);\n if (extFormat) {\n format = extFormat as any;\n }\n }\n\n return {\n key: dictionaryKey,\n componentDirPath: relative(baseDir, dirname(filePath)),\n componentFileName: cleanComponentFileName,\n fileName: uncapitalizedName,\n componentFormat:\n componentFormat as FilePathPatternContext['componentFormat'],\n componentExtension:\n extension as FilePathPatternContext['componentExtension'],\n format,\n locale,\n extension: configuration.content.fileExtensions[0] as any,\n };\n };\n\n const processPattern = async (\n pattern: FilePathPattern,\n locales: Locale[]\n ): Promise<FillData[]> => {\n const dummyLocale = '###########locale###########' as Locale;\n let isPatternPerLocale = false;\n\n if (typeof pattern === 'string') {\n isPatternPerLocale = pattern.includes('{{locale}}');\n } else if (typeof pattern === 'function') {\n const pathWithDummy = await pattern(getContext(dummyLocale, pattern));\n isPatternPerLocale = pathWithDummy.includes(dummyLocale);\n }\n\n if (isPatternPerLocale) {\n const resolvedPaths: FillData[] = [];\n\n // Generate one path per locale\n for (const locale of locales) {\n const rawPath =\n typeof pattern === 'string'\n ? parseStringPattern(pattern, getContext(locale, pattern))\n : await pattern(getContext(locale, pattern));\n\n const absolutePath = resolveRelativePath(rawPath, filePath, baseDir);\n\n resolvedPaths.push({\n filePath: absolutePath,\n localeList: [locale],\n isPerLocale: true,\n });\n }\n\n // Group by filePath in case multiple locales resolve to the same path\n const groupedByFilePath = resolvedPaths.reduce((acc, curr) => {\n const existing = acc.find((item) => item.filePath === curr.filePath);\n if (existing) {\n if (!existing.localeList.includes(curr.localeList[0])) {\n existing.localeList.push(...curr.localeList);\n }\n // If multiple locales share a path, it's no longer strictly per-locale\n existing.isPerLocale = false;\n } else {\n acc.push(curr);\n }\n return acc;\n }, [] as FillData[]);\n\n return groupedByFilePath;\n } else {\n // Single multi-lingual path using default locale for pattern resolution\n const rawPath =\n typeof pattern === 'string'\n ? parseStringPattern(pattern, getContext(defaultLocale, pattern))\n : await pattern(getContext(defaultLocale, pattern));\n\n const absolutePath = resolveRelativePath(rawPath, filePath, baseDir);\n\n return [\n {\n filePath: absolutePath,\n localeList: locales,\n isPerLocale: false,\n },\n ];\n }\n };\n\n // 1. Handle Record of Locales\n if (typeof fillField === 'object' && fillField !== null) {\n const results: FillData[] = [];\n\n for (const locale of localeList) {\n const pattern = (fillField as Record<string, any>)[locale];\n if (pattern && typeof pattern !== 'boolean') {\n const res = await processPattern(pattern as FilePathPattern, [locale]);\n results.push(...res);\n }\n }\n\n // Merge identical file paths if they stem from different locales having the same output path\n const grouped = results.reduce((acc, curr) => {\n const existing = acc.find((item) => item.filePath === curr.filePath);\n if (existing) {\n for (const loc of curr.localeList) {\n if (!existing.localeList.includes(loc)) {\n existing.localeList.push(loc);\n }\n }\n existing.isPerLocale = false;\n } else {\n acc.push(curr);\n }\n return acc;\n }, [] as FillData[]);\n\n return grouped;\n }\n\n // 2. Handle static string or function patterns\n if (typeof fillField === 'string' || typeof fillField === 'function') {\n return processPattern(fillField as FilePathPattern, localeList);\n }\n\n return [];\n};\n"],"mappings":"oOAoBA,MAAa,EAAiB,MAC5B,EACA,EACA,EACA,EACA,IACwB,CACxB,GAAI,CAAC,GAAa,OAAO,GAAc,UAAW,MAAO,EAAE,CAE3D,GAAM,CAAE,WAAY,EAAc,OAC5B,CAAE,iBAAkB,EAAc,qBAElC,EAAY,EAAQ,EAAS,CAC7B,EAAO,EAAS,EAAS,CAGzB,EAAyB,EAAK,SAAS,YAAY,CACrD,EAAK,MAAM,YAAY,CAAC,GACxB,EAAK,MAAM,IAAI,CAAC,GAEd,EACJ,EAAuB,OAAO,EAAE,CAAC,aAAa,CAC9C,EAAuB,MAAM,EAAE,CAE3B,EAAkB,EAAuB,EAAiB,CAE1D,GACJ,EACA,IAC2B,CAC3B,IAAI,EAA2C,OAC/C,GAAI,OAAO,GAAgB,SAAU,CACnC,IAAM,EAAY,EAAuB,EAAQ,EAAY,CAAQ,CACjE,IACF,EAAS,GAIb,MAAO,CACL,IAAK,EACL,iBAAkB,EAAS,EAAS,EAAQ,EAAS,CAAC,CACtD,kBAAmB,EACnB,SAAU,EAER,kBACF,mBACE,EACF,SACA,SACA,UAAW,EAAc,QAAQ,eAAe,GACjD,EAGG,EAAiB,MACrB,EACA,IACwB,CACxB,IAAM,EAAc,+BAChB,EAAqB,GASzB,GAPI,OAAO,GAAY,SACrB,EAAqB,EAAQ,SAAS,aAAa,CAC1C,OAAO,GAAY,aAE5B,GADsB,MAAM,EAAQ,EAAW,EAAa,EAAQ,CAAC,EAClC,SAAS,EAAY,EAGtD,EAAoB,CACtB,IAAM,EAA4B,EAAE,CAGpC,IAAK,IAAM,KAAU,EAAS,CAM5B,IAAM,EAAe,EAJnB,OAAO,GAAY,SACf,EAAmB,EAAS,EAAW,EAAQ,EAAQ,CAAC,CACxD,MAAM,EAAQ,EAAW,EAAQ,EAAQ,CAAC,CAEE,EAAU,EAAQ,CAEpE,EAAc,KAAK,CACjB,SAAU,EACV,WAAY,CAAC,EAAO,CACpB,YAAa,GACd,CAAC,CAkBJ,OAd0B,EAAc,QAAQ,EAAK,IAAS,CAC5D,IAAM,EAAW,EAAI,KAAM,GAAS,EAAK,WAAa,EAAK,SAAS,CAUpE,OATI,GACG,EAAS,WAAW,SAAS,EAAK,WAAW,GAAG,EACnD,EAAS,WAAW,KAAK,GAAG,EAAK,WAAW,CAG9C,EAAS,YAAc,IAEvB,EAAI,KAAK,EAAK,CAET,GACN,EAAE,CAAe,MAYpB,MAAO,CACL,CACE,SAJiB,EAJnB,OAAO,GAAY,SACf,EAAmB,EAAS,EAAW,EAAe,EAAQ,CAAC,CAC/D,MAAM,EAAQ,EAAW,EAAe,EAAQ,CAAC,CAEL,EAAU,EAAQ,CAKhE,WAAY,EACZ,YAAa,GACd,CACF,EAKL,GAAI,OAAO,GAAc,UAAY,EAAoB,CACvD,IAAM,EAAsB,EAAE,CAE9B,IAAK,IAAM,KAAU,EAAY,CAC/B,IAAM,EAAW,EAAkC,GACnD,GAAI,GAAW,OAAO,GAAY,UAAW,CAC3C,IAAM,EAAM,MAAM,EAAe,EAA4B,CAAC,EAAO,CAAC,CACtE,EAAQ,KAAK,GAAG,EAAI,EAoBxB,OAfgB,EAAQ,QAAQ,EAAK,IAAS,CAC5C,IAAM,EAAW,EAAI,KAAM,GAAS,EAAK,WAAa,EAAK,SAAS,CACpE,GAAI,EAAU,CACZ,IAAK,IAAM,KAAO,EAAK,WAChB,EAAS,WAAW,SAAS,EAAI,EACpC,EAAS,WAAW,KAAK,EAAI,CAGjC,EAAS,YAAc,QAEvB,EAAI,KAAK,EAAK,CAEhB,OAAO,GACN,EAAE,CAAe,CAUtB,OAJI,OAAO,GAAc,UAAY,OAAO,GAAc,WACjD,EAAe,EAA8B,EAAW,CAG1D,EAAE"}
1
+ {"version":3,"file":"formatFillData.mjs","names":[],"sources":["../../../src/fill/formatFillData.ts"],"sourcesContent":["import { basename, dirname, extname, relative } from 'node:path';\nimport {\n getFormatFromExtension,\n resolveRelativePath,\n} from '@intlayer/chokidar/utils';\nimport { parseStringPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { DictionaryKey, Fill } from '@intlayer/types/dictionary';\nimport type {\n FilePathPattern,\n FilePathPatternContext,\n} from '@intlayer/types/filePathPattern';\n\nexport type FillData = {\n localeList: Locale[];\n filePath: string;\n isPerLocale: boolean;\n};\n\nexport const formatFillData = async (\n fillField: Fill,\n localeList: Locale[],\n filePath: string,\n dictionaryKey: DictionaryKey,\n configuration: IntlayerConfig\n): Promise<FillData[]> => {\n if (!fillField || typeof fillField === 'boolean') return [];\n\n const { baseDir } = configuration.system;\n const { defaultLocale } = configuration.internationalization;\n\n const extension = extname(filePath);\n const base = basename(filePath);\n\n // Extract the original filename without extensions\n const cleanComponentFileName = base.includes('.content.')\n ? base.split('.content.')[0]\n : base.split('.')[0];\n\n const uncapitalizedName =\n cleanComponentFileName.charAt(0).toLowerCase() +\n cleanComponentFileName.slice(1);\n\n const componentFormat = getFormatFromExtension(extension);\n\n const getContext = (\n locale: Locale,\n patternType?: FilePathPattern\n ): FilePathPatternContext => {\n let format: FilePathPatternContext['format'] = 'json';\n if (typeof patternType === 'string') {\n const extFormat = getFormatFromExtension(extname(patternType) as any);\n if (extFormat) {\n format = extFormat as any;\n }\n }\n\n return {\n key: dictionaryKey,\n componentDirPath: relative(baseDir, dirname(filePath)),\n componentFileName: cleanComponentFileName,\n fileName: uncapitalizedName,\n componentFormat:\n componentFormat as FilePathPatternContext['componentFormat'],\n componentExtension:\n extension as FilePathPatternContext['componentExtension'],\n format,\n locale,\n extension: configuration.content.fileExtensions[0],\n };\n };\n\n const processPattern = async (\n pattern: FilePathPattern,\n locales: Locale[]\n ): Promise<FillData[]> => {\n const dummyLocale = '###########locale###########' as Locale;\n let isPatternPerLocale = false;\n\n if (typeof pattern === 'string') {\n isPatternPerLocale = pattern.includes('{{locale}}');\n } else if (typeof pattern === 'function') {\n const pathWithDummy = await pattern(getContext(dummyLocale, pattern));\n isPatternPerLocale = pathWithDummy.includes(dummyLocale);\n }\n\n if (isPatternPerLocale) {\n const resolvedPaths: FillData[] = [];\n\n // Generate one path per locale\n for (const locale of locales) {\n const rawPath =\n typeof pattern === 'string'\n ? parseStringPattern(pattern, getContext(locale, pattern))\n : await pattern(getContext(locale, pattern));\n\n const absolutePath = resolveRelativePath(rawPath, filePath, baseDir);\n\n resolvedPaths.push({\n filePath: absolutePath,\n localeList: [locale],\n isPerLocale: true,\n });\n }\n\n // Group by filePath in case multiple locales resolve to the same path\n const groupedByFilePath = resolvedPaths.reduce((acc, curr) => {\n const existing = acc.find((item) => item.filePath === curr.filePath);\n if (existing) {\n if (!existing.localeList.includes(curr.localeList[0])) {\n existing.localeList.push(...curr.localeList);\n }\n // If multiple locales share a path, it's no longer strictly per-locale\n existing.isPerLocale = false;\n } else {\n acc.push(curr);\n }\n return acc;\n }, [] as FillData[]);\n\n return groupedByFilePath;\n } else {\n // Single multi-lingual path using default locale for pattern resolution\n const rawPath =\n typeof pattern === 'string'\n ? parseStringPattern(pattern, getContext(defaultLocale, pattern))\n : await pattern(getContext(defaultLocale, pattern));\n\n const absolutePath = resolveRelativePath(rawPath, filePath, baseDir);\n\n return [\n {\n filePath: absolutePath,\n localeList: locales,\n isPerLocale: false,\n },\n ];\n }\n };\n\n // Handle Record of Locales\n if (typeof fillField === 'object' && fillField !== null) {\n const results: FillData[] = [];\n\n for (const locale of localeList) {\n const pattern = (fillField as Record<string, any>)[locale];\n if (pattern && typeof pattern !== 'boolean') {\n const res = await processPattern(pattern as FilePathPattern, [locale]);\n results.push(...res);\n }\n }\n\n // Merge identical file paths if they stem from different locales having the same output path\n const grouped = results.reduce((acc, curr) => {\n const existing = acc.find((item) => item.filePath === curr.filePath);\n if (existing) {\n for (const loc of curr.localeList) {\n if (!existing.localeList.includes(loc)) {\n existing.localeList.push(loc);\n }\n }\n existing.isPerLocale = false;\n } else {\n acc.push(curr);\n }\n return acc;\n }, [] as FillData[]);\n\n return grouped;\n }\n\n // Handle static string or function patterns\n if (typeof fillField === 'string' || typeof fillField === 'function') {\n return processPattern(fillField as FilePathPattern, localeList);\n }\n\n return [];\n};\n"],"mappings":"oOAoBA,MAAa,EAAiB,MAC5B,EACA,EACA,EACA,EACA,IACwB,CACxB,GAAI,CAAC,GAAa,OAAO,GAAc,UAAW,MAAO,EAAE,CAE3D,GAAM,CAAE,WAAY,EAAc,OAC5B,CAAE,iBAAkB,EAAc,qBAElC,EAAY,EAAQ,EAAS,CAC7B,EAAO,EAAS,EAAS,CAGzB,EAAyB,EAAK,SAAS,YAAY,CACrD,EAAK,MAAM,YAAY,CAAC,GACxB,EAAK,MAAM,IAAI,CAAC,GAEd,EACJ,EAAuB,OAAO,EAAE,CAAC,aAAa,CAC9C,EAAuB,MAAM,EAAE,CAE3B,EAAkB,EAAuB,EAAU,CAEnD,GACJ,EACA,IAC2B,CAC3B,IAAI,EAA2C,OAC/C,GAAI,OAAO,GAAgB,SAAU,CACnC,IAAM,EAAY,EAAuB,EAAQ,EAAY,CAAQ,CACjE,IACF,EAAS,GAIb,MAAO,CACL,IAAK,EACL,iBAAkB,EAAS,EAAS,EAAQ,EAAS,CAAC,CACtD,kBAAmB,EACnB,SAAU,EAER,kBACF,mBACE,EACF,SACA,SACA,UAAW,EAAc,QAAQ,eAAe,GACjD,EAGG,EAAiB,MACrB,EACA,IACwB,CACxB,IAAM,EAAc,+BAChB,EAAqB,GASzB,GAPI,OAAO,GAAY,SACrB,EAAqB,EAAQ,SAAS,aAAa,CAC1C,OAAO,GAAY,aAE5B,GADsB,MAAM,EAAQ,EAAW,EAAa,EAAQ,CAAC,EAClC,SAAS,EAAY,EAGtD,EAAoB,CACtB,IAAM,EAA4B,EAAE,CAGpC,IAAK,IAAM,KAAU,EAAS,CAM5B,IAAM,EAAe,EAJnB,OAAO,GAAY,SACf,EAAmB,EAAS,EAAW,EAAQ,EAAQ,CAAC,CACxD,MAAM,EAAQ,EAAW,EAAQ,EAAQ,CAAC,CAEE,EAAU,EAAQ,CAEpE,EAAc,KAAK,CACjB,SAAU,EACV,WAAY,CAAC,EAAO,CACpB,YAAa,GACd,CAAC,CAkBJ,OAd0B,EAAc,QAAQ,EAAK,IAAS,CAC5D,IAAM,EAAW,EAAI,KAAM,GAAS,EAAK,WAAa,EAAK,SAAS,CAUpE,OATI,GACG,EAAS,WAAW,SAAS,EAAK,WAAW,GAAG,EACnD,EAAS,WAAW,KAAK,GAAG,EAAK,WAAW,CAG9C,EAAS,YAAc,IAEvB,EAAI,KAAK,EAAK,CAET,GACN,EAAE,CAAe,MAYpB,MAAO,CACL,CACE,SAJiB,EAJnB,OAAO,GAAY,SACf,EAAmB,EAAS,EAAW,EAAe,EAAQ,CAAC,CAC/D,MAAM,EAAQ,EAAW,EAAe,EAAQ,CAAC,CAEL,EAAU,EAAQ,CAKhE,WAAY,EACZ,YAAa,GACd,CACF,EAKL,GAAI,OAAO,GAAc,UAAY,EAAoB,CACvD,IAAM,EAAsB,EAAE,CAE9B,IAAK,IAAM,KAAU,EAAY,CAC/B,IAAM,EAAW,EAAkC,GACnD,GAAI,GAAW,OAAO,GAAY,UAAW,CAC3C,IAAM,EAAM,MAAM,EAAe,EAA4B,CAAC,EAAO,CAAC,CACtE,EAAQ,KAAK,GAAG,EAAI,EAoBxB,OAfgB,EAAQ,QAAQ,EAAK,IAAS,CAC5C,IAAM,EAAW,EAAI,KAAM,GAAS,EAAK,WAAa,EAAK,SAAS,CACpE,GAAI,EAAU,CACZ,IAAK,IAAM,KAAO,EAAK,WAChB,EAAS,WAAW,SAAS,EAAI,EACpC,EAAS,WAAW,KAAK,EAAI,CAGjC,EAAS,YAAc,QAEvB,EAAI,KAAK,EAAK,CAEhB,OAAO,GACN,EAAE,CAAe,CAUtB,OAJI,OAAO,GAAc,UAAY,OAAO,GAAc,WACjD,EAAe,EAA8B,EAAW,CAG1D,EAAE"}
@@ -1,2 +1,2 @@
1
- import{listMissingTranslationsWithConfig as e}from"../test/listMissingTranslations.mjs";import{basename as t}from"node:path";import{ANSIColors as n,colon as r,colorize as i,colorizeKey as a,colorizePath as o,getAppLogger as s}from"@intlayer/config/logger";import{getUnmergedDictionaries as c}from"@intlayer/unmerged-dictionaries-entry";import{formatLocale as l}from"@intlayer/chokidar/utils";import{getFilterTranslationsOnlyDictionary as u}from"@intlayer/core/plugins";import{getDictionaries as d}from"@intlayer/dictionaries-entry";const f=(f,p,m,h,g)=>{let _=s(g),v=d(g),y=c(g),b=Object.values(y).flat().filter(e=>f.includes(e.localId)),{missingTranslations:x}=e(g),S=Math.max(...b.map(e=>e.key.length)),C=[];for(let e of b){let s=r([` - `,i(`[`,n.GREY_DARK),a(e.key),i(`]`,n.GREY_DARK)].join(``),{colSize:S+6}),c=e.key,d=e.localId,f=v[c];if((e.filled??!1)===!0||(e.fill??g.dictionary?.fill??!1)===!1)continue;let y=e.locale??h;if(!f){_(`${s} Dictionary not found in dictionariesRecord. Skipping.`,{level:`warn`});continue}if(!e.filePath){_(`${s} Dictionary has no file path. Skipping.`,{level:`warn`});continue}let b=u(f,y);if(Object.keys(b).length===0){_(`${s} No content found for dictionary in source locale ${l(y)}. Skipping translation for this dictionary.`,{level:`warn`});continue}let w=p;if(m===`complete`&&(w=x.find(e=>e.key===c)?.locales.filter(e=>p.includes(e))??[]),w.length===0){_(`${s} ${i(`No locales to fill, Skipping`,n.GREY_DARK)} ${o(t(e.filePath))}`,{level:`warn`});continue}C.push({dictionaryKey:c,dictionaryLocalId:d,sourceLocale:y,targetLocales:w,dictionaryPreset:s,dictionaryFilePath:e.filePath})}return C};export{f as listTranslationsTasks};
1
+ import{listMissingTranslationsWithConfig as e}from"../test/listMissingTranslations.mjs";import{basename as t}from"node:path";import{formatLocale as n}from"@intlayer/chokidar/utils";import{ANSIColors as r,colon as i,colorize as a,colorizeKey as o,colorizePath as s,getAppLogger as c}from"@intlayer/config/logger";import{getUnmergedDictionaries as l}from"@intlayer/unmerged-dictionaries-entry";import{getFilterTranslationsOnlyDictionary as u}from"@intlayer/core/plugins";import{getDictionaries as d}from"@intlayer/dictionaries-entry";const f=(f,p,m,h,g)=>{let _=c(g),v=d(g),y=l(g),b=Object.values(y).flat().filter(e=>f.includes(e.localId)),{missingTranslations:x}=e(g),S=Math.max(...b.map(e=>e.key.length)),C=[];for(let e of b){let c=i([` - `,a(`[`,r.GREY_DARK),o(e.key),a(`]`,r.GREY_DARK)].join(``),{colSize:S+6}),l=e.key,d=e.localId,f=v[l];if((e.filled??!1)===!0||(e.fill??g.dictionary?.fill??!1)===!1)continue;let y=e.locale??h;if(!f){_(`${c} Dictionary not found in dictionariesRecord. Skipping.`,{level:`warn`});continue}if(!e.filePath){_(`${c} Dictionary has no file path. Skipping.`,{level:`warn`});continue}let b=u(f,y);if(Object.keys(b).length===0){_(`${c} No content found for dictionary in source locale ${n(y)}. Skipping translation for this dictionary.`,{level:`warn`});continue}let w=p;if(m===`complete`&&(w=x.find(e=>e.key===l)?.locales.filter(e=>p.includes(e))??[]),w.length===0){_(`${c} ${a(`No locales to fill, Skipping`,r.GREY_DARK)} ${s(t(e.filePath))}`,{level:`warn`});continue}C.push({dictionaryKey:l,dictionaryLocalId:d,sourceLocale:y,targetLocales:w,dictionaryPreset:c,dictionaryFilePath:e.filePath})}return C};export{f as listTranslationsTasks};
2
2
  //# sourceMappingURL=listTranslationsTasks.mjs.map
@@ -1,2 +1,2 @@
1
- import{deepMergeContent as e}from"./deepMergeContent.mjs";import{getFilterMissingContentPerLocale as t}from"./getFilterMissingContentPerLocale.mjs";import{basename as n}from"node:path";import{ANSIColors as r,colon as i,colorize as a,colorizeNumber as o,colorizePath as s,getAppLogger as c}from"@intlayer/config/logger";import{getUnmergedDictionaries as l}from"@intlayer/unmerged-dictionaries-entry";import{chunkJSON as u,formatLocale as d,mergeChunks as f,reconstructFromSingleChunk as p,reduceObjectFormat as m,verifyIdenticObjectFormat as h}from"@intlayer/chokidar/utils";import{getFilterMissingTranslationsDictionary as g,getMultilingualDictionary as _,getPerLocaleDictionary as v,insertContentInDictionary as y}from"@intlayer/core/plugins";import{getIntlayerAPIProxy as b}from"@intlayer/api";import{retryManager as x}from"@intlayer/config/utils";const S=e=>!e.description||!e.title||!e.tags,C=e=>{if(typeof e!=`object`||!e||Array.isArray(e))return{content:e,nulls:void 0,hasNulls:!1};let t={},n={},r=!1;for(let[i,a]of Object.entries(e))if(a===null)n[i]=null,r=!0;else{let e=C(a);t[i]=e.content,e.hasNulls&&(n[i]=e.nulls,r=!0)}return{content:t,nulls:r?n:void 0,hasNulls:r}},w=1e3*10;let T=0;const E=async(E,D,O)=>{let k=c(D),A=b(void 0,D),{mode:j,aiOptions:M,fillMetadata:N,aiClient:P,aiConfig:F}={mode:`complete`,fillMetadata:!0,...O},I=()=>{T=0,O?.onSuccess?.()};return await x(async()=>{let c=l(D),b=c[E.dictionaryKey].find(e=>e.localId===E.dictionaryLocalId);if(!b)return k(`${E.dictionaryPreset}Dictionary not found in unmergedDictionariesRecord. Skipping.`,{level:`warn`}),{...E,dictionaryOutput:null};let L;if(N&&(S(b)||j===`review`)){let e=v(b,D.internationalization.defaultLocale);k(`${E.dictionaryPreset} Filling missing metadata for ${s(n(b.filePath))}`,{level:`info`});let t=async()=>P&&F?{data:await P.auditDictionaryMetadata({fileContent:JSON.stringify(e),aiConfig:F})}:await A.ai.auditContentDeclarationMetadata({fileContent:JSON.stringify(e),aiOptions:M});L=(O?.onHandle?await O.onHandle(t):await t()).data?.fileContent}let R=await Promise.all(E.targetLocales.map(async l=>{let _=structuredClone(b),y;if(typeof b.locale==`string`){let e=b.filePath?.replace(RegExp(`/${E.sourceLocale}/`,`g`),`/${l}/`),n=e?c[E.dictionaryKey]?.find(t=>t.filePath===e&&t.locale===l):void 0;y=n??{key:b.key,content:{},filePath:e,locale:l},j===`complete`&&(_=t(_,n))}else j===`complete`&&(_=g(_,l)),_=v(_,E.sourceLocale),y=v(b,l);let S=i([a(`[`,r.GREY_DARK),d(l),a(`]`,r.GREY_DARK)].join(``),{colSize:18}),D=(e,t)=>t<=1?``:i([a(`[`,r.GREY_DARK),o(e+1),a(`/${t}`,r.GREY_DARK),a(`]`,r.GREY_DARK)].join(``),{colSize:5});k(`${E.dictionaryPreset}${S} Preparing ${s(n(y.filePath))}`,{level:`info`});let N=typeof _.content==`object`&&_.content!==null||Array.isArray(_.content),{content:R,nulls:z}=C(N?_.content:{__INTLAYER_ROOT_PRIMITIVE_CONTENT__:_.content}),B=u(R,7e3),V=B.length;V>1&&k(`${E.dictionaryPreset}${S} Split into ${o(V)} chunks for translation`,{level:`info`});let H=[],U=B.map(e=>{let t=D(e.index,e.total);V>1&&k(`${E.dictionaryPreset}${S}${t} Translating chunk`,{level:`info`});let n=p(e),i=m(N?y.content:{__INTLAYER_ROOT_PRIMITIVE_CONTENT__:y.content},n),s=async()=>await x(async()=>{let e;if(e=P&&F?await P.translateJSON({entryFileContent:n,presetOutputContent:i,dictionaryDescription:_.description??L?.description??``,entryLocale:E.sourceLocale,outputLocale:l,mode:j,aiConfig:F}):await A.ai.translateJSON({entryFileContent:n,presetOutputContent:i,dictionaryDescription:_.description??L?.description??``,entryLocale:E.sourceLocale,outputLocale:l,mode:j,aiOptions:M}).then(e=>e.data),!e?.fileContent)throw Error(`No content result`);let{isIdentic:t}=h(e.fileContent,n);if(!t)throw Error(`Translation result does not match expected format`);return I(),e.fileContent},{maxRetry:3,delay:w,onError:({error:t,attempt:n,maxRetry:i})=>{let s=D(e.index,e.total);k(`${E.dictionaryPreset}${S}${s} ${a(`Error filling:`,r.RED)} ${a(typeof t==`string`?t:JSON.stringify(t),r.GREY_DARK)} - Attempt ${o(n+1)} of ${o(i)}`,{level:`error`}),T+=1,T>=10&&(k(`There is something wrong.`,{level:`error`}),process.exit(1))}})();return(O?.onHandle?O.onHandle(s):s()).then(t=>({chunk:e,result:t}))});(await Promise.all(U)).sort((e,t)=>e.chunk.index-t.chunk.index).forEach(({result:e})=>{H.push(e)});let W=f(H);z&&(W=e(W,z));let G={..._,content:W}.content;return N||(G=G?.__INTLAYER_ROOT_PRIMITIVE_CONTENT__),typeof b.locale==`string`&&(G=e(y.content??{},G)),[l,G]})),z=Object.fromEntries(R),B={..._(b.locale?{...b,key:b.key,content:{}}:b),locale:void 0,...L};for(let e of E.targetLocales)z[e]&&(B=y(B,z[e],e));if(k(`${E.dictionaryPreset} ${a(`Translation completed successfully`,r.GREEN)} for ${s(n(B.filePath))}`,{level:`info`}),b.locale&&(b.fill===!0||b.fill===void 0)&&b.location===`local`){let e=b.filePath.split(`.`).slice(0,-1),t=e[e.length-1];return JSON.parse(JSON.stringify({...E,dictionaryOutput:{...B,fill:void 0,filled:!0}}).replaceAll(RegExp(`\\.${t}\\.[a-zA-Z0-9]+`,`g`),`.filled.${t}.json`))}return{...E,dictionaryOutput:B}},{maxRetry:2,delay:w,onError:({error:e,attempt:t,maxRetry:n})=>k(`${E.dictionaryPreset} ${a(`Error:`,r.RED)} ${a(typeof e==`string`?e:JSON.stringify(e),r.GREY_DARK)} - Attempt ${o(t+1)} of ${o(n)}`,{level:`error`}),onMaxTryReached:({error:e})=>k(`${E.dictionaryPreset} ${a(`Maximum number of retries reached:`,r.RED)} ${a(typeof e==`string`?e:JSON.stringify(e),r.GREY_DARK)}`,{level:`error`})})()};export{E as translateDictionary};
1
+ import{deepMergeContent as e}from"./deepMergeContent.mjs";import{getFilterMissingContentPerLocale as t}from"./getFilterMissingContentPerLocale.mjs";import{basename as n}from"node:path";import{chunkJSON as r,formatLocale as i,mergeChunks as a,reconstructFromSingleChunk as o,reduceObjectFormat as s,verifyIdenticObjectFormat as c}from"@intlayer/chokidar/utils";import{ANSIColors as l,colon as u,colorize as d,colorizeNumber as f,colorizePath as p,getAppLogger as m}from"@intlayer/config/logger";import{getUnmergedDictionaries as h}from"@intlayer/unmerged-dictionaries-entry";import{getFilterMissingTranslationsDictionary as g,getMultilingualDictionary as _,getPerLocaleDictionary as v,insertContentInDictionary as y}from"@intlayer/core/plugins";import{getIntlayerAPIProxy as b}from"@intlayer/api";import{retryManager as x}from"@intlayer/config/utils";const S=e=>!e.description||!e.title||!e.tags,C=e=>{if(typeof e!=`object`||!e||Array.isArray(e))return{content:e,nulls:void 0,hasNulls:!1};let t={},n={},r=!1;for(let[i,a]of Object.entries(e))if(a===null)n[i]=null,r=!0;else{let e=C(a);t[i]=e.content,e.hasNulls&&(n[i]=e.nulls,r=!0)}return{content:t,nulls:r?n:void 0,hasNulls:r}},w=1e3*10;let T=0;const E=async(E,D,O)=>{let k=m(D),A=b(void 0,D),{mode:j,aiOptions:M,fillMetadata:N,aiClient:P,aiConfig:F}={mode:`complete`,fillMetadata:!0,...O},I=()=>{T=0,O?.onSuccess?.()};return await x(async()=>{let m=h(D),b=m[E.dictionaryKey].find(e=>e.localId===E.dictionaryLocalId);if(!b)return k(`${E.dictionaryPreset}Dictionary not found in unmergedDictionariesRecord. Skipping.`,{level:`warn`}),{...E,dictionaryOutput:null};let L;if(N&&(S(b)||j===`review`)){let e=v(b,D.internationalization.defaultLocale);k(`${E.dictionaryPreset} Filling missing metadata for ${p(n(b.filePath))}`,{level:`info`});let t=async()=>P&&F?{data:await P.auditDictionaryMetadata({fileContent:JSON.stringify(e),aiConfig:F})}:await A.ai.auditContentDeclarationMetadata({fileContent:JSON.stringify(e),aiOptions:M});L=(O?.onHandle?await O.onHandle(t):await t()).data?.fileContent}let R=await Promise.all(E.targetLocales.map(async h=>{let _=structuredClone(b),y;if(typeof b.locale==`string`){let e=b.filePath?.replace(RegExp(`/${E.sourceLocale}/`,`g`),`/${h}/`),n=e?m[E.dictionaryKey]?.find(t=>t.filePath===e&&t.locale===h):void 0;y=n??{key:b.key,content:{},filePath:e,locale:h},j===`complete`&&(_=t(_,n))}else j===`complete`&&(_=g(_,h)),_=v(_,E.sourceLocale),y=v(b,h);let S=u([d(`[`,l.GREY_DARK),i(h),d(`]`,l.GREY_DARK)].join(``),{colSize:18}),D=(e,t)=>t<=1?``:u([d(`[`,l.GREY_DARK),f(e+1),d(`/${t}`,l.GREY_DARK),d(`]`,l.GREY_DARK)].join(``),{colSize:5});k(`${E.dictionaryPreset}${S} Preparing ${p(n(y.filePath))}`,{level:`info`});let N=typeof _.content==`object`&&_.content!==null||Array.isArray(_.content),{content:R,nulls:z}=C(N?_.content:{__INTLAYER_ROOT_PRIMITIVE_CONTENT__:_.content}),B=r(R,7e3),V=B.length;V>1&&k(`${E.dictionaryPreset}${S} Split into ${f(V)} chunks for translation`,{level:`info`});let H=[],U=B.map(e=>{let t=D(e.index,e.total);V>1&&k(`${E.dictionaryPreset}${S}${t} Translating chunk`,{level:`info`});let n=o(e),r=s(N?y.content:{__INTLAYER_ROOT_PRIMITIVE_CONTENT__:y.content},n),i=async()=>await x(async()=>{let e;if(e=P&&F?await P.translateJSON({entryFileContent:n,presetOutputContent:r,dictionaryDescription:_.description??L?.description??``,entryLocale:E.sourceLocale,outputLocale:h,mode:j,aiConfig:F}):await A.ai.translateJSON({entryFileContent:n,presetOutputContent:r,dictionaryDescription:_.description??L?.description??``,entryLocale:E.sourceLocale,outputLocale:h,mode:j,aiOptions:M}).then(e=>e.data),!e?.fileContent)throw Error(`No content result`);let{isIdentic:t}=c(e.fileContent,n);if(!t)throw Error(`Translation result does not match expected format`);return I(),e.fileContent},{maxRetry:3,delay:w,onError:({error:t,attempt:n,maxRetry:r})=>{let i=D(e.index,e.total);k(`${E.dictionaryPreset}${S}${i} ${d(`Error filling:`,l.RED)} ${d(typeof t==`string`?t:JSON.stringify(t),l.GREY_DARK)} - Attempt ${f(n+1)} of ${f(r)}`,{level:`error`}),T+=1,T>=10&&(k(`There is something wrong.`,{level:`error`}),process.exit(1))}})();return(O?.onHandle?O.onHandle(i):i()).then(t=>({chunk:e,result:t}))});(await Promise.all(U)).sort((e,t)=>e.chunk.index-t.chunk.index).forEach(({result:e})=>{H.push(e)});let W=a(H);z&&(W=e(W,z));let G={..._,content:W}.content;return N||(G=G?.__INTLAYER_ROOT_PRIMITIVE_CONTENT__),typeof b.locale==`string`&&(G=e(y.content??{},G)),[h,G]})),z=Object.fromEntries(R),B={..._(b.locale?{...b,key:b.key,content:{}}:b),locale:void 0,...L};for(let e of E.targetLocales)z[e]&&(B=y(B,z[e],e));if(k(`${E.dictionaryPreset} ${d(`Translation completed successfully`,l.GREEN)} for ${p(n(B.filePath))}`,{level:`info`}),b.locale&&(b.fill===!0||b.fill===void 0)&&b.location===`local`){let e=b.filePath.split(`.`).slice(0,-1),t=e[e.length-1];return JSON.parse(JSON.stringify({...E,dictionaryOutput:{...B,fill:void 0,filled:!0}}).replaceAll(RegExp(`\\.${t}\\.[a-zA-Z0-9]+`,`g`),`.filled.${t}.json`))}return{...E,dictionaryOutput:B}},{maxRetry:2,delay:w,onError:({error:e,attempt:t,maxRetry:n})=>k(`${E.dictionaryPreset} ${d(`Error:`,l.RED)} ${d(typeof e==`string`?e:JSON.stringify(e),l.GREY_DARK)} - Attempt ${f(t+1)} of ${f(n)}`,{level:`error`}),onMaxTryReached:({error:e})=>k(`${E.dictionaryPreset} ${d(`Maximum number of retries reached:`,l.RED)} ${d(typeof e==`string`?e:JSON.stringify(e),l.GREY_DARK)}`,{level:`error`})})()};export{E as translateDictionary};
2
2
  //# sourceMappingURL=translateDictionary.mjs.map
@@ -1,2 +1,2 @@
1
- import{formatFillData as e}from"./formatFillData.mjs";import{getAvailableLocalesInDictionary as t}from"./getAvailableLocalesInDictionary.mjs";import{relative as n}from"node:path";import{colorizeKey as r,getAppLogger as i}from"@intlayer/config/logger";import{writeContentDeclaration as a}from"@intlayer/chokidar/build";import{formatLocale as o,formatPath as s}from"@intlayer/chokidar/utils";import{getDictionaries as c}from"@intlayer/dictionaries-entry";const l=async(l,u,d,f)=>{let p=i(f),m=c(f)[l.key],{filePath:h}=l;if(!h){p(`No file path found for dictionary`,{level:`error`});return}let g=l.fill??f.dictionary?.fill??!0;if(g===!1){p(`Auto fill is disabled for '${r(m.key)}'`,{level:`info`});return}let _=(u??f.internationalization.locales).filter(e=>!d?.includes(e)),v=t(l),y=_.filter(e=>v.includes(e));if(y.length===0){p(`No translations available for dictionary '${r(m.key)}'`,{level:`info`});return}let b=await e(g,y,h,m.key,f);for await(let e of b){if(!e.filePath){p(`No file path found for auto filled content declaration for '${r(m.key)}'`,{level:`error`});continue}let{fill:t,...i}=l,c=n(f.system.baseDir,e.filePath);if(await a({...i,filled:!0,locale:e.isPerLocale?e.localeList[0]:void 0,localId:`${l.key}::local::${c}`,filePath:c},f,{localeList:e.localeList}),e.isPerLocale){let t=e.localeList[0];p(`Auto filled per-locale content declaration for '${r(m.key)}' written to ${s(e.filePath)} for locale ${o(t)}`,{level:`info`})}else p(`Auto filled content declaration for '${r(m.key)}' written to ${s(e.filePath)}`,{level:`info`})}};export{l as writeFill};
1
+ import{formatFillData as e}from"./formatFillData.mjs";import{getAvailableLocalesInDictionary as t}from"./getAvailableLocalesInDictionary.mjs";import{relative as n}from"node:path";import{writeContentDeclaration as r}from"@intlayer/chokidar/build";import{formatLocale as i,formatPath as a}from"@intlayer/chokidar/utils";import{colorizeKey as o,getAppLogger as s}from"@intlayer/config/logger";import{getDictionaries as c}from"@intlayer/dictionaries-entry";const l=async(l,u,d,f)=>{let p=s(f),m=c(f)[l.key],{filePath:h}=l;if(!h){p(`No file path found for dictionary`,{level:`error`});return}let g=l.fill??f.dictionary?.fill??!0;if(g===!1){p(`Auto fill is disabled for '${o(m.key)}'`,{level:`info`});return}let _=(u??f.internationalization.locales).filter(e=>!d?.includes(e)),v=t(l),y=_.filter(e=>v.includes(e));if(y.length===0){p(`No translations available for dictionary '${o(m.key)}'`,{level:`info`});return}let b=await e(g,y,h,m.key,f);for await(let e of b){if(!e.filePath){p(`No file path found for auto filled content declaration for '${o(m.key)}'`,{level:`error`});continue}let{fill:t,...s}=l,c=n(f.system.baseDir,e.filePath);if(await r({...s,filled:!0,locale:e.isPerLocale?e.localeList[0]:void 0,localId:`${l.key}::local::${c}`,filePath:c},f,{localeList:e.localeList}),e.isPerLocale){let t=e.localeList[0];p(`Auto filled per-locale content declaration for '${o(m.key)}' written to ${a(e.filePath)} for locale ${i(t)}`,{level:`info`})}else p(`Auto filled content declaration for '${o(m.key)}' written to ${a(e.filePath)}`,{level:`info`})}};export{l as writeFill};
2
2
  //# sourceMappingURL=writeFill.mjs.map
@@ -1,2 +1,2 @@
1
- import{relative as e}from"node:path";import{colon as t,colorizeKey as n,colorizeNumber as r,getAppLogger as i}from"@intlayer/config/logger";import{getConfiguration as a}from"@intlayer/config/node";import{getUnmergedDictionaries as o}from"@intlayer/unmerged-dictionaries-entry";import{formatPath as s}from"@intlayer/chokidar/utils";const c=t=>{let n=a(t?.configOptions),r=o(n);return Object.values(r).flat().map(r=>({key:r.key??``,path:t?.absolute?r.filePath??`Remote`:e(n.system.baseDir,r.filePath??`Remote`)}))},l=e=>{let o=c(e);if(e?.json){console.log(JSON.stringify(o));return}let l=i(a(e?.configOptions)),u=o.map(e=>[t(` - ${n(e.key)}`,{colSize:o.map(e=>e.key.length),maxSize:60}),` - `,s(e.path)].join(``));l(`Content declaration files:`),u.forEach(e=>{l(e,{level:`info`})}),l(`Total content declaration files: ${r(o.length)}`)};export{l as listContentDeclaration,c as listContentDeclarationRows};
1
+ import{relative as e}from"node:path";import{formatPath as t}from"@intlayer/chokidar/utils";import{colon as n,colorizeKey as r,colorizeNumber as i,getAppLogger as a}from"@intlayer/config/logger";import{getConfiguration as o}from"@intlayer/config/node";import{getUnmergedDictionaries as s}from"@intlayer/unmerged-dictionaries-entry";const c=t=>{let n=o(t?.configOptions),r=s(n);return Object.values(r).flat().map(r=>({key:r.key??``,path:t?.absolute?r.filePath??`Remote`:e(n.system.baseDir,r.filePath??`Remote`)}))},l=e=>{let s=c(e);if(e?.json){console.log(JSON.stringify(s));return}let l=a(o(e?.configOptions)),u=s.map(e=>[n(` - ${r(e.key)}`,{colSize:s.map(e=>e.key.length),maxSize:60}),` - `,t(e.path)].join(``));l(`Content declaration files:`),u.forEach(e=>{l(e,{level:`info`})}),l(`Total content declaration files: ${i(s.length)}`)};export{l as listContentDeclaration,c as listContentDeclarationRows};
2
2
  //# sourceMappingURL=listContentDeclaration.mjs.map
@@ -1,10 +1,10 @@
1
- import{IntlayerEventListener as e}from"./IntlayerEventListener.mjs";import{getAppLogger as t}from"@intlayer/config/logger";import{getConfiguration as n}from"@intlayer/config/node";import{getUnmergedDictionaries as r}from"@intlayer/unmerged-dictionaries-entry";import{createServer as i}from"node:http";import{buildDictionary as a}from"@intlayer/chokidar/build";import{runParallel as o}from"@intlayer/chokidar/utils";import s from"@intlayer/config/package.json"with{type:"json"};import{getLocalizedContent as c}from"@intlayer/core/plugins";import{getDictionaries as l}from"@intlayer/dictionaries-entry";const u=async(e,n)=>{t(n)(`Writing dictionary ${e.key}`),await a([e],n)},d=async a=>{let d=n(a?.configOptions),f=t(d),{liveSyncPort:p,liveSyncURL:m}=d.editor,h=null,g=null;if(a?.with&&(h=o(a.with),h.result.catch(()=>{})),d.editor.liveSync&&d.editor.backendURL&&d.editor.clientId&&d.editor.clientSecret){g=new e(d),g.onConnectionOpen=()=>{f(`Live sync connection established`)},g.onConnectionError=e=>{let t=e;f(`Live sync connection error: ${t.message??`Unknown error`}`,{level:`warn`}),(t.message?.includes(`terminated`)||t.message?.includes(`closed`))&&f(`Server connection was terminated, automatic reconnection will be attempted...`,{level:`info`})},g.onDictionaryAdded=e=>u(e,d),g.onDictionaryChange=e=>u(e,d),g.onDictionaryDeleted=e=>u(e,d);try{await g.initialize()}catch(e){f(`Failed to initialize IntlayerEventListener:`,{level:`error`}),f(`Error: ${e instanceof Error?e.message:String(e)}`,{level:`error`})}}else d.editor.liveSync?(!d.editor.clientId||!d.editor.clientSecret)&&f(`Missing client credentials for hot reload. Please configure clientId and clientSecret`):f(`Hot reload is disabled. Please enable it in the configuration (editor.liveSync).`);let _=i(async(e,t)=>{if(e.method===`OPTIONS`){t.writeHead(200,{"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`}),t.end();return}if(e.url?.startsWith(`/dictionaries`)){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`});let n=l(d);if(e.url.startsWith(`/dictionaries/`)){let[r,i]=decodeURIComponent(e.url).slice(14).split(`/`),a=n[r]??null;if(i){let e=c(a.content,i,{dictionaryKey:r,keyPath:[]});t.end(JSON.stringify(e));return}t.end(JSON.stringify(a));return}t.end(JSON.stringify(n));return}if(e.url?.startsWith(`/unmerged_dictionaries`)){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`});let n=r(d);if(e.url.startsWith(`/unmerged_dictionaries/`)){let r=n[decodeURIComponent(e.url.slice(23))]??null;t.end(JSON.stringify(r));return}t.end(JSON.stringify(n));return}if(e.url===`/configuration`){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`}),t.end(JSON.stringify(d));return}if(e.url===`/health`){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`}),t.end(JSON.stringify({status:`ok`}));return}t.end(`Not found`)}),v=()=>d.editor.liveSync?`\x1B[32m✓ Enabled\x1B[0m`:`\x1B[31m✗ Disabled\x1B[0m`;_.listen(p,()=>{console.log(`
1
+ import{IntlayerEventListener as e}from"./IntlayerEventListener.mjs";import{buildDictionary as t}from"@intlayer/chokidar/build";import{runParallel as n}from"@intlayer/chokidar/utils";import{getAppLogger as r}from"@intlayer/config/logger";import{getConfiguration as i}from"@intlayer/config/node";import{getUnmergedDictionaries as a}from"@intlayer/unmerged-dictionaries-entry";import{createServer as o}from"node:http";import s from"@intlayer/config/package.json"with{type:"json"};import{getLocalizedContent as c}from"@intlayer/core/plugins";import{getDictionaries as l}from"@intlayer/dictionaries-entry";const u=async(e,n)=>{r(n)(`Writing dictionary ${e.key}`),await t([e],n)},d=async t=>{let d=i(t?.configOptions),f=r(d),{liveSyncPort:p,liveSyncURL:m}=d.editor,h=null,g=null;if(t?.with&&(h=n(t.with),h.result.catch(()=>{})),d.editor.liveSync&&d.editor.backendURL&&d.editor.clientId&&d.editor.clientSecret){g=new e(d),g.onConnectionOpen=()=>{f(`Live sync connection established`)},g.onConnectionError=e=>{let t=e;f(`Live sync connection error: ${t.message??`Unknown error`}`,{level:`warn`}),(t.message?.includes(`terminated`)||t.message?.includes(`closed`))&&f(`Server connection was terminated, automatic reconnection will be attempted...`,{level:`info`})},g.onDictionaryAdded=e=>u(e,d),g.onDictionaryChange=e=>u(e,d),g.onDictionaryDeleted=e=>u(e,d);try{await g.initialize()}catch(e){f(`Failed to initialize IntlayerEventListener:`,{level:`error`}),f(`Error: ${e instanceof Error?e.message:String(e)}`,{level:`error`})}}else d.editor.liveSync?(!d.editor.clientId||!d.editor.clientSecret)&&f(`Missing client credentials for hot reload. Please configure clientId and clientSecret`):f(`Hot reload is disabled. Please enable it in the configuration (editor.liveSync).`);let _=o(async(e,t)=>{if(e.method===`OPTIONS`){t.writeHead(200,{"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`}),t.end();return}if(e.url?.startsWith(`/dictionaries`)){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`});let n=l(d);if(e.url.startsWith(`/dictionaries/`)){let[r,i]=decodeURIComponent(e.url).slice(14).split(`/`),a=n[r]??null;if(i){let e=c(a.content,i,{dictionaryKey:r,keyPath:[]});t.end(JSON.stringify(e));return}t.end(JSON.stringify(a));return}t.end(JSON.stringify(n));return}if(e.url?.startsWith(`/unmerged_dictionaries`)){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`});let n=a(d);if(e.url.startsWith(`/unmerged_dictionaries/`)){let r=n[decodeURIComponent(e.url.slice(23))]??null;t.end(JSON.stringify(r));return}t.end(JSON.stringify(n));return}if(e.url===`/configuration`){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`}),t.end(JSON.stringify(d));return}if(e.url===`/health`){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`}),t.end(JSON.stringify({status:`ok`}));return}t.end(`Not found`)}),v=()=>d.editor.liveSync?`\x1B[32m✓ Enabled\x1B[0m`:`\x1B[31m✗ Disabled\x1B[0m`;_.listen(p,()=>{console.log(`
2
2
  \x1b[1;90mINTLAYER v${s.version}\x1b[0m
3
3
 
4
4
  Live server running at: \x1b[90m${m}\x1b[0m
5
5
  - Backend URL: \x1b[90m${d.editor.backendURL??`-`}\x1b[0m
6
6
  - Live sync: ${v()}
7
- - Parallel process: ${a?.with?`\x1b[90m${Array.isArray(a.with)?a.with.join(` `):a.with}\x1b[0m`:`-`}
7
+ - Parallel process: ${t?.with?`\x1b[90m${Array.isArray(t.with)?t.with.join(` `):t.with}\x1b[0m`:`-`}
8
8
  - Access key: ${d.editor.clientId??`-`}
9
9
  `)});let y=()=>{g&&(f(`Closing SSE connection...`),g.cleanup()),h&&h.kill(),_.close(()=>{f(`Live sync server stopped`),process.exit(0)})};process.on(`SIGINT`,y),process.on(`SIGTERM`,y),process.on(`exit`,y)};export{d as liveSync};
10
10
  //# sourceMappingURL=liveSync.mjs.map
package/dist/esm/pull.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{checkCMSAuth as e}from"./utils/checkAccess.mjs";import{PullLogger as t}from"./push/pullLog.mjs";import{existsSync as n}from"node:fs";import{join as r}from"node:path";import{logConfigDetails as i}from"@intlayer/chokidar/cli";import{ANSIColors as a,getAppLogger as o}from"@intlayer/config/logger";import{getConfiguration as s}from"@intlayer/config/node";import{getUnmergedDictionaries as c}from"@intlayer/unmerged-dictionaries-entry";import{writeContentDeclaration as l}from"@intlayer/chokidar/build";import{parallelize as u}from"@intlayer/chokidar/utils";import{getIntlayerAPIProxy as d}from"@intlayer/api";import{getProjectRequire as f}from"@intlayer/config/utils";const p=async p=>{let m=o(p?.configOptions?.override);try{let o=s(p?.configOptions);if(i(p?.configOptions),!await e(o))return;let h=d(void 0,o),g=c(o),_=await h.dictionary.getDictionariesUpdateTimestamp();if(!_.data)throw Error(`No distant dictionaries found`);let v=_.data;p?.dictionaries&&(v=Object.fromEntries(Object.entries(v).filter(([e])=>p.dictionaries?.includes(e)))),v=Object.fromEntries(Object.entries(v).filter(([e])=>{let t=g[e]?.[0]?.location??o.dictionary?.location??`remote`;return t===`remote`||t===`hybrid`}));let y=r(o.system.mainDir,`remote_dictionaries.cjs`),b=o.build?.require??f(),x=n(y)?b(y):{},S=Object.entries(v),C=S.filter(([e,t])=>{if(!t)return!0;let n=typeof t==`object`?t.updatedAt:t,r=x[e];if(!r)return!0;let i=r?.updatedAt,a=typeof i==`number`?i:i?new Date(i).getTime():void 0;return typeof a==`number`?n>a:!0}).map(([e])=>e),w=S.filter(([e,t])=>{let n=typeof t==`object`?t.updatedAt:t,r=x[e]?.updatedAt,i=typeof r==`number`?r:r?new Date(r).getTime():void 0;return typeof i==`number`&&typeof n==`number`&&i>=n}).map(([e])=>e);if(S.length===0){m(`No dictionaries to fetch`,{level:`error`});return}m(`Fetching dictionaries:`);let T=[...w.map(e=>({dictionaryKey:e,status:`imported`})),...C.map(e=>({dictionaryKey:e,status:`pending`}))],E=new t;E.update(T.map(e=>({dictionaryKey:e.dictionaryKey,status:e.status})));let D=[];await u(T,async e=>{let t=e.status===`imported`||e.status===`up-to-date`;t||(e.status=`fetching`,E.update([{dictionaryKey:e.dictionaryKey,status:`fetching`}]));try{let n;if(t&&(n=x[e.dictionaryKey]),n||=(await h.dictionary.getDictionary(e.dictionaryKey)).data,!n)throw Error(`Dictionary ${e.dictionaryKey} not found on remote`);let r=g[e.dictionaryKey]?.find(e=>e.location===`hybrid`);r&&(n={...n,location:`hybrid`,filePath:r.filePath,localId:r.localId});let{status:i}=await l(n,o,p);e.status=i,E.update([{dictionaryKey:e.dictionaryKey,status:i}]),D.push(n)}catch(t){e.status=`error`,e.error=t,e.errorMessage=`Error fetching dictionary ${e.dictionaryKey}: ${t}`,E.update([{dictionaryKey:e.dictionaryKey,status:`error`}])}},5),E.finish();let O=e=>{switch(e){case`fetched`:case`imported`:case`updated`:case`up-to-date`:case`reimported in JSON`:case`new content file`:return`✔`;case`error`:return`✖`;default:return`⏲`}},k=e=>{switch(e){case`fetched`:case`imported`:case`updated`:case`up-to-date`:return a.GREEN;case`reimported in JSON`:case`new content file`:return a.YELLOW;case`error`:return a.RED;default:return a.BLUE}};for(let e of T){let t=O(e.status),n=k(e.status);m(` - ${e.dictionaryKey} ${a.GREY}[${n}${t} ${e.status}${a.GREY}]${a.RESET}`)}for(let e of T)e.errorMessage&&m(e.errorMessage,{level:`error`})}catch(e){m(e,{level:`error`})}};export{p as pull};
1
+ import{checkCMSAuth as e}from"./utils/checkAccess.mjs";import{PullLogger as t}from"./push/pullLog.mjs";import{existsSync as n}from"node:fs";import{join as r}from"node:path";import{writeContentDeclaration as i}from"@intlayer/chokidar/build";import{logConfigDetails as a}from"@intlayer/chokidar/cli";import{parallelize as o}from"@intlayer/chokidar/utils";import{ANSIColors as s,getAppLogger as c}from"@intlayer/config/logger";import{getConfiguration as l}from"@intlayer/config/node";import{getUnmergedDictionaries as u}from"@intlayer/unmerged-dictionaries-entry";import{getIntlayerAPIProxy as d}from"@intlayer/api";import{getProjectRequire as f}from"@intlayer/config/utils";const p=async p=>{let m=c(p?.configOptions?.override);try{let c=l(p?.configOptions);if(a(p?.configOptions),!await e(c))return;let h=d(void 0,c),g=u(c),_=await h.dictionary.getDictionariesUpdateTimestamp();if(!_.data)throw Error(`No distant dictionaries found`);let v=_.data;p?.dictionaries&&(v=Object.fromEntries(Object.entries(v).filter(([e])=>p.dictionaries?.includes(e)))),v=Object.fromEntries(Object.entries(v).filter(([e])=>{let t=g[e]?.[0]?.location??c.dictionary?.location??`remote`;return t===`remote`||t===`hybrid`}));let y=r(c.system.mainDir,`remote_dictionaries.cjs`),b=c.build?.require??f(),x=n(y)?b(y):{},S=Object.entries(v),C=S.filter(([e,t])=>{if(!t)return!0;let n=typeof t==`object`?t.updatedAt:t,r=x[e];if(!r)return!0;let i=r?.updatedAt,a=typeof i==`number`?i:i?new Date(i).getTime():void 0;return typeof a==`number`?n>a:!0}).map(([e])=>e),w=S.filter(([e,t])=>{let n=typeof t==`object`?t.updatedAt:t,r=x[e]?.updatedAt,i=typeof r==`number`?r:r?new Date(r).getTime():void 0;return typeof i==`number`&&typeof n==`number`&&i>=n}).map(([e])=>e);if(S.length===0){m(`No dictionaries to fetch`,{level:`error`});return}m(`Fetching dictionaries:`);let T=[...w.map(e=>({dictionaryKey:e,status:`imported`})),...C.map(e=>({dictionaryKey:e,status:`pending`}))],E=new t;E.update(T.map(e=>({dictionaryKey:e.dictionaryKey,status:e.status})));let D=[];await o(T,async e=>{let t=e.status===`imported`||e.status===`up-to-date`;t||(e.status=`fetching`,E.update([{dictionaryKey:e.dictionaryKey,status:`fetching`}]));try{let n;if(t&&(n=x[e.dictionaryKey]),n||=(await h.dictionary.getDictionary(e.dictionaryKey)).data,!n)throw Error(`Dictionary ${e.dictionaryKey} not found on remote`);let r=g[e.dictionaryKey]?.find(e=>e.location===`hybrid`);r&&(n={...n,location:`hybrid`,filePath:r.filePath,localId:r.localId});let{status:a}=await i(n,c,p);e.status=a,E.update([{dictionaryKey:e.dictionaryKey,status:a}]),D.push(n)}catch(t){e.status=`error`,e.error=t,e.errorMessage=`Error fetching dictionary ${e.dictionaryKey}: ${t}`,E.update([{dictionaryKey:e.dictionaryKey,status:`error`}])}},5),E.finish();let O=e=>{switch(e){case`fetched`:case`imported`:case`updated`:case`up-to-date`:case`reimported in JSON`:case`new content file`:return`✔`;case`error`:return`✖`;default:return`⏲`}},k=e=>{switch(e){case`fetched`:case`imported`:case`updated`:case`up-to-date`:return s.GREEN;case`reimported in JSON`:case`new content file`:return s.YELLOW;case`error`:return s.RED;default:return s.BLUE}};for(let e of T){let t=O(e.status),n=k(e.status);m(` - ${e.dictionaryKey} ${s.GREY}[${n}${t} ${e.status}${s.GREY}]${s.RESET}`)}for(let e of T)e.errorMessage&&m(e.errorMessage,{level:`error`})}catch(e){m(e,{level:`error`})}};export{p as pull};
2
2
  //# sourceMappingURL=pull.mjs.map
@@ -1,2 +1,2 @@
1
- import{checkCMSAuth as e}from"../utils/checkAccess.mjs";import{PushLogger as t}from"../pushLog.mjs";import{join as n}from"node:path";import{listGitFiles as r,logConfigDetails as i}from"@intlayer/chokidar/cli";import{ANSIColors as a,colorize as o,colorizeKey as s,getAppLogger as c}from"@intlayer/config/logger";import{getConfiguration as l}from"@intlayer/config/node";import{getUnmergedDictionaries as u}from"@intlayer/unmerged-dictionaries-entry";import{prepareIntlayer as d,writeContentDeclaration as f}from"@intlayer/chokidar/build";import{formatPath as p,parallelize as m}from"@intlayer/chokidar/utils";import{getIntlayerAPIProxy as h}from"@intlayer/api";import*as g from"node:fs/promises";const _={pushed:{icon:`✔`,color:a.GREEN},modified:{icon:`✔`,color:a.GREEN},error:{icon:`✖`,color:a.RED},default:{icon:`⏲`,color:a.BLUE}},v=e=>_[e]??_.default,y=async p=>{let g=l(p?.configOptions);i(p?.configOptions);let _=c(g);p?.build===!0?await d(g,{forceRun:!0}):p?.build===void 0&&await d(g);try{if(!await e(g))return;let i=h(void 0,g),c=u(g),l=Object.values(c).flat(),d=Array.from(new Set(l.map(e=>e.location).filter(e=>e&&![`remote`,`local`,`hybrid`].includes(e)))),y=[];if(d.length>0){let{multiselect:e,confirm:t,isCancel:n}=await import(`@clack/prompts`);if(d.length===1){let e=await t({message:`Do you want to push dictionaries with custom location ${o(d[0],a.BLUE,a.RESET)}?`,initialValue:!1});if(n(e))return;e&&(y=[d[0]])}else{let t=await e({message:`Select custom locations to push:`,options:d.map(e=>({value:e,label:e})),required:!1});if(n(t))return;y=t}}let x=l.filter(e=>{let t=e.location??g.dictionary?.location??`local`;return t===`remote`||t===`hybrid`||y.includes(t)});if(x.length===0){_(`No dictionaries found to push. Only dictionaries with location ${o(`remote`,a.BLUE,a.RESET)}, ${o(`hybrid`,a.BLUE,a.RESET)} or selected custom locations are pushed.`,{level:`warn`}),_(`You can set the location in your dictionary file (e.g. ${o(`{ key: 'my-key', location: 'hybrid', ... }`,a.BLUE,a.RESET)} or globally in your intlayer.config.ts file (e.g. ${o(`{ dictionary: { location: 'hybrid' } }`,a.BLUE,a.RESET)}).`,{level:`info`});return}let S=Object.keys(c);if(p?.dictionaries){let e=p.dictionaries.filter(e=>!S.includes(e));e.length>0&&_(`The following dictionaries do not exist: ${e.join(`, `)} and have been ignored.`,{level:`error`}),x=x.filter(e=>p.dictionaries?.includes(e.key))}if(p?.gitOptions){let e=await r(p.gitOptions);x=x.filter(t=>e.includes(n(g.system.baseDir,t.filePath??``)))}if(x.length===0){_(`No local dictionaries found`,{level:`error`});return}_(`Pushing dictionaries:`);let C=x.map(e=>({dictionary:e,status:`pending`})),w=new t;w.update(C.map(e=>({dictionaryKey:e.dictionary.key,status:`pending`})));let T=[];await m(C,async e=>{e.status=`pushing`,w.update([{dictionaryKey:e.dictionary.key,status:`pushing`}]);try{let t=await i.dictionary.pushDictionaries([e.dictionary]),n=t.data?.updatedDictionaries??[],r=t.data?.newDictionaries??[],a=[...n,...r];for(let e of a){let t=c[e.key]?.find(t=>t.localId===e.localId);t&&await f({...t,id:e.id},g)}n.some(t=>t.key===e.dictionary.key)?(e.status=`modified`,T.push(e.dictionary),w.update([{dictionaryKey:e.dictionary.key,status:`modified`}])):r.some(t=>t.key===e.dictionary.key)?(e.status=`pushed`,T.push(e.dictionary),w.update([{dictionaryKey:e.dictionary.key,status:`pushed`}])):e.status=`unknown`}catch(t){e.status=`error`,e.error=t,e.errorMessage=`Error pushing dictionary ${e.dictionary.key}: ${t}`,w.update([{dictionaryKey:e.dictionary.key,status:`error`}])}},5),w.finish();for(let e of C){let{icon:t,color:n}=v(e.status);_(` - ${s(e.dictionary.key)} ${a.GREY}[${n}${t} ${e.status}${a.GREY}]${a.RESET}`)}for(let e of C)e.errorMessage&&_(e.errorMessage,{level:`error`});let E=p?.deleteLocaleDictionary,D=p?.keepLocaleDictionary;if(E&&D)throw Error(`Cannot specify both --deleteLocaleDictionary and --keepLocaleDictionary options.`);if(E)await b(T,p);else if(!D){let e=T.filter(e=>e.location===`remote`),t=e.map(e=>e.key);if(e.length>0){let{confirm:n,isCancel:r}=await import(`@clack/prompts`),i=await n({message:`Do you want to delete the local dictionaries that were successfully pushed? ${o(`(Dictionaries:`,a.GREY,a.RESET)} ${s(t)}${o(`)`,a.GREY,a.RESET)}`,initialValue:!1});if(r(i))return;i&&await b(e,p)}}}catch(e){_(e,{level:`error`})}},b=async(e,t)=>{let n=c(l(t?.configOptions)),r=new Set;for(let t of e){let{filePath:e}=t;if(!e){n(`Dictionary ${s(t.key)} does not have a file path`,{level:`error`});continue}r.add(e)}for(let e of r)try{let t=await g.lstat(e);t.isFile()?(await g.unlink(e),n(`Deleted file ${p(e)}`,{})):t.isDirectory()?n(`Path is a directory ${p(e)}, skipping.`,{}):n(`Unknown file type for ${p(e)}, skipping.`,{})}catch(t){n(`Error deleting ${p(e)}: ${t}`,{level:`error`})}};export{y as push};
1
+ import{checkCMSAuth as e}from"../utils/checkAccess.mjs";import{PushLogger as t}from"../pushLog.mjs";import{join as n}from"node:path";import{prepareIntlayer as r,writeContentDeclaration as i}from"@intlayer/chokidar/build";import{listGitFiles as a,logConfigDetails as o}from"@intlayer/chokidar/cli";import{formatPath as s,parallelize as c}from"@intlayer/chokidar/utils";import{ANSIColors as l,colorize as u,colorizeKey as d,getAppLogger as f}from"@intlayer/config/logger";import{getConfiguration as p}from"@intlayer/config/node";import{getUnmergedDictionaries as m}from"@intlayer/unmerged-dictionaries-entry";import{getIntlayerAPIProxy as h}from"@intlayer/api";import*as g from"node:fs/promises";const _={pushed:{icon:`✔`,color:l.GREEN},modified:{icon:`✔`,color:l.GREEN},error:{icon:`✖`,color:l.RED},default:{icon:`⏲`,color:l.BLUE}},v=e=>_[e]??_.default,y=async s=>{let g=p(s?.configOptions);o(s?.configOptions);let _=f(g);s?.build===!0?await r(g,{forceRun:!0}):s?.build===void 0&&await r(g);try{if(!await e(g))return;let r=h(void 0,g),o=m(g),f=Object.values(o).flat(),p=Array.from(new Set(f.map(e=>e.location).filter(e=>e&&![`remote`,`local`,`hybrid`].includes(e)))),y=[];if(p.length>0){let{multiselect:e,confirm:t,isCancel:n}=await import(`@clack/prompts`);if(p.length===1){let e=await t({message:`Do you want to push dictionaries with custom location ${u(p[0],l.BLUE,l.RESET)}?`,initialValue:!1});if(n(e))return;e&&(y=[p[0]])}else{let t=await e({message:`Select custom locations to push:`,options:p.map(e=>({value:e,label:e})),required:!1});if(n(t))return;y=t}}let x=f.filter(e=>{let t=e.location??g.dictionary?.location??`local`;return t===`remote`||t===`hybrid`||y.includes(t)});if(x.length===0){_(`No dictionaries found to push. Only dictionaries with location ${u(`remote`,l.BLUE,l.RESET)}, ${u(`hybrid`,l.BLUE,l.RESET)} or selected custom locations are pushed.`,{level:`warn`}),_(`You can set the location in your dictionary file (e.g. ${u(`{ key: 'my-key', location: 'hybrid', ... }`,l.BLUE,l.RESET)} or globally in your intlayer.config.ts file (e.g. ${u(`{ dictionary: { location: 'hybrid' } }`,l.BLUE,l.RESET)}).`,{level:`info`});return}let S=Object.keys(o);if(s?.dictionaries){let e=s.dictionaries.filter(e=>!S.includes(e));e.length>0&&_(`The following dictionaries do not exist: ${e.join(`, `)} and have been ignored.`,{level:`error`}),x=x.filter(e=>s.dictionaries?.includes(e.key))}if(s?.gitOptions){let e=await a(s.gitOptions);x=x.filter(t=>e.includes(n(g.system.baseDir,t.filePath??``)))}if(x.length===0){_(`No local dictionaries found`,{level:`error`});return}_(`Pushing dictionaries:`);let C=x.map(e=>({dictionary:e,status:`pending`})),w=new t;w.update(C.map(e=>({dictionaryKey:e.dictionary.key,status:`pending`})));let T=[];await c(C,async e=>{e.status=`pushing`,w.update([{dictionaryKey:e.dictionary.key,status:`pushing`}]);try{let t=await r.dictionary.pushDictionaries([e.dictionary]),n=t.data?.updatedDictionaries??[],a=t.data?.newDictionaries??[],s=[...n,...a];for(let e of s){let t=o[e.key]?.find(t=>t.localId===e.localId);t&&await i({...t,id:e.id},g)}n.some(t=>t.key===e.dictionary.key)?(e.status=`modified`,T.push(e.dictionary),w.update([{dictionaryKey:e.dictionary.key,status:`modified`}])):a.some(t=>t.key===e.dictionary.key)?(e.status=`pushed`,T.push(e.dictionary),w.update([{dictionaryKey:e.dictionary.key,status:`pushed`}])):e.status=`unknown`}catch(t){e.status=`error`,e.error=t,e.errorMessage=`Error pushing dictionary ${e.dictionary.key}: ${t}`,w.update([{dictionaryKey:e.dictionary.key,status:`error`}])}},5),w.finish();for(let e of C){let{icon:t,color:n}=v(e.status);_(` - ${d(e.dictionary.key)} ${l.GREY}[${n}${t} ${e.status}${l.GREY}]${l.RESET}`)}for(let e of C)e.errorMessage&&_(e.errorMessage,{level:`error`});let E=s?.deleteLocaleDictionary,D=s?.keepLocaleDictionary;if(E&&D)throw Error(`Cannot specify both --deleteLocaleDictionary and --keepLocaleDictionary options.`);if(E)await b(T,s);else if(!D){let e=T.filter(e=>e.location===`remote`),t=e.map(e=>e.key);if(e.length>0){let{confirm:n,isCancel:r}=await import(`@clack/prompts`),i=await n({message:`Do you want to delete the local dictionaries that were successfully pushed? ${u(`(Dictionaries:`,l.GREY,l.RESET)} ${d(t)}${u(`)`,l.GREY,l.RESET)}`,initialValue:!1});if(r(i))return;i&&await b(e,s)}}}catch(e){_(e,{level:`error`})}},b=async(e,t)=>{let n=f(p(t?.configOptions)),r=new Set;for(let t of e){let{filePath:e}=t;if(!e){n(`Dictionary ${d(t.key)} does not have a file path`,{level:`error`});continue}r.add(e)}for(let e of r)try{let t=await g.lstat(e);t.isFile()?(await g.unlink(e),n(`Deleted file ${s(e)}`,{})):t.isDirectory()?n(`Path is a directory ${s(e)}, skipping.`,{}):n(`Unknown file type for ${s(e)}, skipping.`,{})}catch(t){n(`Error deleting ${s(e)}: ${t}`,{level:`error`})}};export{y as push};
2
2
  //# sourceMappingURL=push.mjs.map
@@ -1,2 +1,2 @@
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{reviewFileBlockAware as r}from"./reviewDocBlockAware.mjs";import{existsSync as i}from"node:fs";import{join as a,relative as o}from"node:path";import{listGitFiles as s,listGitLines as c,logConfigDetails as l}from"@intlayer/chokidar/cli";import{ANSIColors as u,colorize as d,colorizeNumber as f,getAppLogger as p}from"@intlayer/config/logger";import{getConfiguration as m}from"@intlayer/config/node";import h from"fast-glob";import{formatLocale as g,formatPath as _,parallelize as v}from"@intlayer/chokidar/utils";const y=async({docPattern:y,locales:b,excludedGlobPattern:x,baseLocale:S,aiOptions:C,nbSimultaneousFileProcessed:w,configOptions:T,customInstructions:E,skipIfModifiedBefore:D,skipIfModifiedAfter:O,skipIfExists:k,gitOptions:A})=>{let j=m(T);l(T);let M=p(j),N=await e(j,C);if(!N?.hasAIAccess)return;let{aiClient:P,aiConfig:F}=N;w&&w>10&&(M(`Warning: nbSimultaneousFileProcessed is set to ${w}, which is greater than 10. Setting it to 10.`),w=10);let I=await h(y,{ignore:x});if(A){let e=await s(A);e&&(I=I.filter(t=>e.some(e=>a(process.cwd(),t)===e)))}M(`Base locale is ${g(S)}`),M(`Reviewing ${f(b.length)} locales: [ ${g(b)} ]`),M(`Reviewing ${f(I.length)} files:`),M(I.map(e=>` - ${_(e)}\n`)),await v(I.flatMap(e=>b.map(s=>async()=>{M(`Reviewing file: ${_(e)} to ${g(s)}`);let l=a(j.system.baseDir,e),f=n(l,s,S);if(k&&i(f)){let e=o(j.system.baseDir,f);M(`${d(`⊘`,u.YELLOW)} File ${_(e)} already exists, skipping.`);return}if(i(f)){let e=t(f,{skipIfModifiedBefore:D,skipIfModifiedAfter:O});if(e.isSkipped){M(e.message);return}}else (D||O)&&M(`${d(`!`,u.YELLOW)} File ${_(f)} does not exist, skipping modification date check.`);let p;if(A){let e=await c(l,A);M(`Git changed lines: ${e.join(`, `)}`),p=e}await r(l,f,s,S,C,T,E,p,P,F)})),e=>e(),w??3)};export{y as reviewDoc};
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{reviewFileBlockAware as r}from"./reviewDocBlockAware.mjs";import{existsSync as i}from"node:fs";import{join as a,relative as o}from"node:path";import{listGitFiles as s,listGitLines as c,logConfigDetails as l}from"@intlayer/chokidar/cli";import{formatLocale as u,formatPath as d,parallelize as f}from"@intlayer/chokidar/utils";import{ANSIColors as p,colorize as m,colorizeNumber as h,getAppLogger as g}from"@intlayer/config/logger";import{getConfiguration as _}from"@intlayer/config/node";import v from"fast-glob";const y=async({docPattern:y,locales:b,excludedGlobPattern:x,baseLocale:S,aiOptions:C,nbSimultaneousFileProcessed:w,configOptions:T,customInstructions:E,skipIfModifiedBefore:D,skipIfModifiedAfter:O,skipIfExists:k,gitOptions:A})=>{let j=_(T);l(T);let M=g(j),N=await e(j,C);if(!N?.hasAIAccess)return;let{aiClient:P,aiConfig:F}=N;w&&w>10&&(M(`Warning: nbSimultaneousFileProcessed is set to ${w}, which is greater than 10. Setting it to 10.`),w=10);let I=await v(y,{ignore:x});if(A){let e=await s(A);e&&(I=I.filter(t=>e.some(e=>a(process.cwd(),t)===e)))}M(`Base locale is ${u(S)}`),M(`Reviewing ${h(b.length)} locales: [ ${u(b)} ]`),M(`Reviewing ${h(I.length)} files:`),M(I.map(e=>` - ${d(e)}\n`)),await f(I.flatMap(e=>b.map(s=>async()=>{M(`Reviewing file: ${d(e)} to ${u(s)}`);let l=a(j.system.baseDir,e),f=n(l,s,S);if(k&&i(f)){let e=o(j.system.baseDir,f);M(`${m(`⊘`,p.YELLOW)} File ${d(e)} already exists, skipping.`);return}if(i(f)){let e=t(f,{skipIfModifiedBefore:D,skipIfModifiedAfter:O});if(e.isSkipped){M(e.message);return}}else (D||O)&&M(`${m(`!`,p.YELLOW)} File ${d(f)} does not exist, skipping modification date check.`);let h;if(A){let e=await c(l,A);M(`Git changed lines: ${e.join(`, `)}`),h=e}await r(l,f,s,S,C,T,E,h,P,F)})),e=>e(),w??3)};export{y as reviewDoc};
2
2
  //# sourceMappingURL=reviewDoc.mjs.map
@@ -1,2 +1,2 @@
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{mkdirSync as s,writeFileSync as c}from"node:fs";import{dirname as l}from"node:path";import{ANSIColors as u,colon as d,colorize as f,colorizeNumber as p,getAppLogger as m}from"@intlayer/config/logger";import{getConfiguration as h}from"@intlayer/config/node";import{formatLocale as g,formatPath as _}from"@intlayer/chokidar/utils";import{retryManager as v}from"@intlayer/config/utils";import{readFile as y}from"node:fs/promises";import{getLocaleName as b}from"@intlayer/core/localization";import*as x from"@intlayer/types/locales";const S=async(S,C,w,T,E,D,O,k,A,j)=>{let M=h(D),N=m(M),P=await y(S,`utf-8`),F=await y(C,`utf-8`).catch(()=>``),I=e(`./prompts/REVIEW_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${g(w,!1)}`).replaceAll(`{{baseLocaleName}}`,`${g(T,!1)}`).replace(`{{applicationContext}}`,E?.applicationContext??`-`).replace(`{{customInstructions}}`,O??`-`),L=[d(`${u.GREY_DARK}[${_(S)}${u.GREY_DARK}] `,{colSize:40}),`→ ${u.RESET}`].join(``),R=[d(`${u.GREY_DARK}[${_(S)}${u.GREY_DARK}][${g(w)}${u.GREY_DARK}] `,{colSize:40}),`→ ${u.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=${p(z.length)}, FR=${p(B.length)}`),N(`${L}Actions: reuse=${p(V.actions.filter(e=>e.kind===`reuse`).length)}, review=${p(V.actions.filter(e=>e.kind===`review`).length)}, new=${p(V.actions.filter(e=>e.kind===`insert_new`).length)}, delete=${p(V.actions.filter(e=>e.kind===`delete`).length)}`),H.length===0){N(`${L}No segments need review, reusing existing translation`),s(l(C),{recursive:!0}),c(C,r(V,B,new Map)),N(`${f(`✔`,u.GREEN)} File ${_(C)} updated successfully (no changes needed).`);return}N(`${L}Segments to review: ${p(H.length)}`);let U=new Map;for(let e of H){let r=H.indexOf(e)+1,i=e.englishBlock,s=()=>`**BLOCK ${r} of ${H.length}** is the base block in ${g(T,!1)} as reference.\n///chunksStart///\n`+i.content+`///chunksEnd///`,c=()=>`**BLOCK ${r} of ${H.length}** is the current block to review in ${g(w,!1)}.\n///chunksStart///\n`+(e.frenchBlockText??``)+`///chunksEnd///`,l=await v(async()=>{let e=await a([{role:`system`,content:I},{role:`system`,content:s()},{role:`system`,content:c()},{role:`system`,content:`The next user message will be the **BLOCK ${p(r)} of ${p(H.length)}** that should be translated in ${b(w,x.ENGLISH)} (${w}).`},{role:`user`,content:i.content}],E,M,A,j);N(`${R}${p(e.tokenUsed)} tokens used - Block ${p(r)} of ${p(H.length)}`);let l=t(e?.fileContent,i.content);if(l=o(l,i.content),!n(i.content,l,N))throw Error(`Validation failed for chunk (structure or length mismatch). Retrying...`);return l})();U.set(e.actionIndex,l)}let W=r(V,B,U);s(l(C),{recursive:!0}),c(C,W),N(`${f(`✔`,u.GREEN)} File ${_(C)} created/updated successfully.`)};export{S as 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{mkdirSync as s,writeFileSync as c}from"node:fs";import{dirname as l}from"node:path";import{formatLocale as u,formatPath as d}from"@intlayer/chokidar/utils";import{ANSIColors as f,colon as p,colorize as m,colorizeNumber as h,getAppLogger as g}from"@intlayer/config/logger";import{getConfiguration as _}from"@intlayer/config/node";import{retryManager as v}from"@intlayer/config/utils";import{readFile as y}from"node:fs/promises";import{getLocaleName as b}from"@intlayer/core/localization";import*as x from"@intlayer/types/locales";const S=async(S,C,w,T,E,D,O,k,A,j)=>{let M=_(D),N=g(M),P=await y(S,`utf-8`),F=await y(C,`utf-8`).catch(()=>``),I=e(`./prompts/REVIEW_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${u(w,!1)}`).replaceAll(`{{baseLocaleName}}`,`${u(T,!1)}`).replace(`{{applicationContext}}`,E?.applicationContext??`-`).replace(`{{customInstructions}}`,O??`-`),L=[p(`${f.GREY_DARK}[${d(S)}${f.GREY_DARK}] `,{colSize:40}),`→ ${f.RESET}`].join(``),R=[p(`${f.GREY_DARK}[${d(S)}${f.GREY_DARK}][${u(w)}${f.GREY_DARK}] `,{colSize:40}),`→ ${f.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=${h(z.length)}, FR=${h(B.length)}`),N(`${L}Actions: reuse=${h(V.actions.filter(e=>e.kind===`reuse`).length)}, review=${h(V.actions.filter(e=>e.kind===`review`).length)}, new=${h(V.actions.filter(e=>e.kind===`insert_new`).length)}, delete=${h(V.actions.filter(e=>e.kind===`delete`).length)}`),H.length===0){N(`${L}No segments need review, reusing existing translation`),s(l(C),{recursive:!0}),c(C,r(V,B,new Map)),N(`${m(`✔`,f.GREEN)} File ${d(C)} updated successfully (no changes needed).`);return}N(`${L}Segments to review: ${h(H.length)}`);let U=new Map;for(let e of H){let r=H.indexOf(e)+1,i=e.englishBlock,s=()=>`**BLOCK ${r} of ${H.length}** is the base block in ${u(T,!1)} as reference.\n///chunksStart///\n`+i.content+`///chunksEnd///`,c=()=>`**BLOCK ${r} of ${H.length}** is the current block to review in ${u(w,!1)}.\n///chunksStart///\n`+(e.frenchBlockText??``)+`///chunksEnd///`,l=await v(async()=>{let e=await a([{role:`system`,content:I},{role:`system`,content:s()},{role:`system`,content:c()},{role:`system`,content:`The next user message will be the **BLOCK ${h(r)} of ${h(H.length)}** that should be translated in ${b(w,x.ENGLISH)} (${w}).`},{role:`user`,content:i.content}],E,M,A,j);N(`${R}${h(e.tokenUsed)} tokens used - Block ${h(r)} of ${h(H.length)}`);let l=t(e?.fileContent,i.content);if(l=o(l,i.content),!n(i.content,l,N))throw Error(`Validation failed for chunk (structure or length mismatch). Retrying...`);return l})();U.set(e.actionIndex,l)}let W=r(V,B,U);s(l(C),{recursive:!0}),c(C,W),N(`${m(`✔`,f.GREEN)} File ${d(C)} created/updated successfully.`)};export{S as reviewFileBlockAware};
2
2
  //# sourceMappingURL=reviewDocBlockAware.mjs.map
@@ -1,2 +1,2 @@
1
- import{listMissingTranslations as e}from"./listMissingTranslations.mjs";import{ANSIColors as t,colon as n,colorize as r,colorizeKey as i,colorizeNumber as a,getAppLogger as o}from"@intlayer/config/logger";import{getConfiguration as s}from"@intlayer/config/node";import{prepareIntlayer as c}from"@intlayer/chokidar/build";import{formatLocale as l,formatPath as u}from"@intlayer/chokidar/utils";const d=async d=>{let f=s(d?.configOptions),{locales:p,requiredLocales:m}=f.internationalization,h=o(f);d?.build===!0?await c(f,{forceRun:!0}):d?.build===void 0&&await c(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=>l(e.locales,!1)).reduce((e,t)=>Math.max(e,t.length),0),y=g.missingTranslations.map(e=>[n(` - ${i(e.key)}`,{colSize:_,maxSize:40}),` - `,n(l(e.locales,t.RED),{colSize:v,maxSize:40}),e.filePath?` - ${u(e.filePath)}`:``,e.id?` - remote`:``].join(``));h(`Missing translations:`,{level:`info`}),y.forEach(e=>{h(e,{level:`info`})}),h(`Locales: ${l(p)}`),h(`Required locales: ${l(m??p)}`),h(`Missing locales: ${g.missingLocales.length===0?r(`-`,t.GREEN):l(g.missingLocales,t.RED)}`),h(`Missing required locales: ${g.missingRequiredLocales.length===0?r(`-`,t.GREEN):l(g.missingRequiredLocales,t.RED)}`),h(`Total missing locales: ${a(g.missingLocales.length,{one:t.RED,other:t.RED,zero:t.GREEN})}`),h(`Total missing required locales: ${a(g.missingRequiredLocales.length,{one:t.RED,other:t.RED,zero:t.GREEN})}`),g.missingRequiredLocales.length>0&&process.exit(1)};export{d as testMissingTranslations};
1
+ import{listMissingTranslations as e}from"./listMissingTranslations.mjs";import{prepareIntlayer as t}from"@intlayer/chokidar/build";import{formatLocale as n,formatPath as r}from"@intlayer/chokidar/utils";import{ANSIColors as i,colon as a,colorize as o,colorizeKey as s,colorizeNumber as c,getAppLogger as l}from"@intlayer/config/logger";import{getConfiguration as u}from"@intlayer/config/node";const d=async d=>{let f=u(d?.configOptions),{locales:p,requiredLocales:m}=f.internationalization,h=l(f);d?.build===!0?await t(f,{forceRun:!0}):d?.build===void 0&&await t(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=>n(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(n(e.locales,i.RED),{colSize:v,maxSize:40}),e.filePath?` - ${r(e.filePath)}`:``,e.id?` - remote`:``].join(``));h(`Missing translations:`,{level:`info`}),y.forEach(e=>{h(e,{level:`info`})}),h(`Locales: ${n(p)}`),h(`Required locales: ${n(m??p)}`),h(`Missing locales: ${g.missingLocales.length===0?o(`-`,i.GREEN):n(g.missingLocales,i.RED)}`),h(`Missing required locales: ${g.missingRequiredLocales.length===0?o(`-`,i.GREEN):n(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};
2
2
  //# sourceMappingURL=test.mjs.map
@@ -1,2 +1,2 @@
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{existsSync as i,mkdirSync as a,writeFileSync as o}from"node:fs";import{dirname as s,join as c}from"node:path";import{listGitFiles as l,logConfigDetails as u}from"@intlayer/chokidar/cli";import{ANSIColors as d,colorize as f,colorizeNumber as p,getAppLogger as m}from"@intlayer/config/logger";import{getConfiguration as h}from"@intlayer/config/node";import g from"fast-glob";import{pLimit as _,parallelize as v}from"@intlayer/chokidar/utils";import{performance as y}from"node:perf_hooks";const b=async({docPattern:b,locales:x,excludedGlobPattern:S,baseLocale:C,aiOptions:w,nbSimultaneousFileProcessed:T=20,configOptions:E,customInstructions:D,skipIfModifiedBefore:O,skipIfModifiedAfter:k,skipIfExists:A,gitOptions:j,flushStrategy:M=`incremental`})=>{let N=h(E);u(E);let P=m(N),F=T,I=_(F),L=await g(b,{ignore:S}),R=await e(N,w);if(!R?.hasAIAccess)return;let{aiClient:z,aiConfig:B}=R;if(j){let e=await l(j);e&&(L=L.filter(t=>e.some(e=>c(process.cwd(),t)===e)))}let V=y.now();P(`Translating ${p(L.length)} files to ${p(x.length)} locales. \nGlobal Concurrency: ${p(F)} chunks in parallel.`);let H={count:0,maxErrors:5,shouldStop:!1};await v(L.flatMap(e=>x.map(l=>async()=>{if(H.shouldStop)return;let u=c(N.system.baseDir,e),d=n(u,l,C);if(A&&i(d))return;M===`incremental`&&!i(d)&&(a(s(d),{recursive:!0}),o(d,``));let f=t(d,{skipIfModifiedBefore:O,skipIfModifiedAfter:k});if(f.isSkipped){P(f.message);return}await r({baseFilePath:u,outputFilePath:d,locale:l,baseLocale:C,configuration:N,errorState:H,aiOptions:w,customInstructions:D,aiClient:z,aiConfig:B,flushStrategy:M,limit:I})})),e=>e(),50);let U=((y.now()-V)/1e3).toFixed(2);H.count>0?P(`Finished with ${H.count} errors in ${U}s.`):P(`${f(`✔`,d.GREEN)} Batch completed successfully in ${p(U)}s.`)};export{b as 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{existsSync as i,mkdirSync as a,writeFileSync as o}from"node:fs";import{dirname as s,join as c}from"node:path";import{listGitFiles as l,logConfigDetails as u}from"@intlayer/chokidar/cli";import{pLimit as d,parallelize as f}from"@intlayer/chokidar/utils";import{ANSIColors as p,colorize as m,colorizeNumber as h,getAppLogger as g}from"@intlayer/config/logger";import{getConfiguration as _}from"@intlayer/config/node";import v from"fast-glob";import{performance as y}from"node:perf_hooks";const b=async({docPattern:b,locales:x,excludedGlobPattern:S,baseLocale:C,aiOptions:w,nbSimultaneousFileProcessed:T=20,configOptions:E,customInstructions:D,skipIfModifiedBefore:O,skipIfModifiedAfter:k,skipIfExists:A,gitOptions:j,flushStrategy:M=`incremental`})=>{let N=_(E);u(E);let P=g(N),F=T,I=d(F),L=await v(b,{ignore:S}),R=await e(N,w);if(!R?.hasAIAccess)return;let{aiClient:z,aiConfig:B}=R;if(j){let e=await l(j);e&&(L=L.filter(t=>e.some(e=>c(process.cwd(),t)===e)))}let V=y.now();P(`Translating ${h(L.length)} files to ${h(x.length)} locales. \nGlobal Concurrency: ${h(F)} chunks in parallel.`);let H={count:0,maxErrors:5,shouldStop:!1};await f(L.flatMap(e=>x.map(l=>async()=>{if(H.shouldStop)return;let u=c(N.system.baseDir,e),d=n(u,l,C);if(A&&i(d))return;M===`incremental`&&!i(d)&&(a(s(d),{recursive:!0}),o(d,``));let f=t(d,{skipIfModifiedBefore:O,skipIfModifiedAfter:k});if(f.isSkipped){P(f.message);return}await r({baseFilePath:u,outputFilePath:d,locale:l,baseLocale:C,configuration:N,errorState:H,aiOptions:w,customInstructions:D,aiClient:z,aiConfig:B,flushStrategy:M,limit:I})})),e=>e(),50);let U=((y.now()-V)/1e3).toFixed(2);H.count>0?P(`Finished with ${H.count} errors in ${U}s.`):P(`${m(`✔`,p.GREEN)} Batch completed successfully in ${h(U)}s.`)};export{b as translateDoc};
2
2
  //# sourceMappingURL=translateDoc.mjs.map
@@ -1,3 +1,3 @@
1
- import{readAsset as e}from"../_virtual/_utils_asset.mjs";import{sanitizeChunk as t,validateTranslation as n}from"./validation.mjs";import{chunkInference as r}from"../utils/chunkInference.mjs";import{fixChunkStartEndChars as i}from"../utils/fixChunkStartEndChars.mjs";import{chunkText as a}from"../utils/calculateChunks.mjs";import{mkdirSync as o,writeFileSync as s}from"node:fs";import{dirname as c,relative as l}from"node:path";import{ANSIColors as u,colon as d,colorize as f,colorizeNumber as p,getAppLogger as m}from"@intlayer/config/logger";import{formatLocale as h,formatPath as g}from"@intlayer/chokidar/utils";import{retryManager as _}from"@intlayer/config/utils";import{readFile as v}from"node:fs/promises";import{performance as y}from"node:perf_hooks";const b=async({baseFilePath:b,outputFilePath:x,locale:S,baseLocale:C,configuration:w,errorState:T,aiOptions:E,customInstructions:D,aiClient:O,aiConfig:k,flushStrategy:A=`incremental`,onChunkReceive:j,limit:M})=>{if(T.shouldStop)return null;let N=m(w,{config:{prefix:``}}),P=y.now();try{let F=a(await v(b,`utf-8`)),I=F.length,L=`${d(`${u.GREY_DARK}[${g(b)}${u.GREY_DARK}] `,{colSize:40})}${u.RESET}`,R=`${d(`${u.GREY_DARK}[${g(b)}${u.GREY_DARK}][${h(S)}${u.GREY_DARK}] `,{colSize:40})}${u.RESET}`;N(`${L}Split into ${p(I)} chunks. Queuing...`);let z=e(`./prompts/TRANSLATE_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${h(S,!1)}`).replaceAll(`{{baseLocaleName}}`,`${h(C,!1)}`).replace(`{{applicationContext}}`,E?.applicationContext??`-`).replace(`{{customInstructions}}`,D??`-`),B=Array(I).fill(``),V=M??(e=>e()),H=F.map((e,a)=>V(async()=>{if(T.shouldStop)return null;let l=m(w,{config:{prefix:`${R} ${u.GREY_DARK}[${a+1}/${I}] ${u.RESET}`}}),d=y.now(),f=a===0,h=e.content,g=()=>">>> CONTEXT: PREVIOUS SOURCE CONTENT <<<\n```\n"+(F[a-1]?.content??``)+"\n```\n>>> END PREVIOUS CONTEXT <<<",v=()=>">>> CONTEXT: NEXT CONTENT <<<\n```\n"+(F[a+1]?.content??``)+"\n```\n>>> END NEXT CONTEXT <<<";l(`Process started`);let{content:b,tokens:S}=await _(async()=>{let e=await r([{role:`system`,content:z},...F[a+1]?[{role:`system`,content:v()}]:[],...f?[]:[{role:`system`,content:g()}],{role:`system`,content:[`You are translating TARGET CHUNK (${a+1}/${I}).`,`Translate ONLY the target chunk. Preserve frontmatter/code exactly.`].join(`
2
- `)},{role:`user`,content:`>>> TARGET CHUNK START <<<\n${h}\n>>> TARGET CHUNK END <<<`}],E,w,O,k),o=t(e?.fileContent,h);if(o=i(o,h),!n(h,o,l))throw Error(`Validation failed for chunk ${a+1}/${I}`);return{content:o,tokens:e.tokenUsed}})(),C=(y.now()-d).toFixed(0);if(B[a]=b,j&&j(b,a,I),A===`incremental`&&B.slice(0,a+1).every(e=>e&&e!==``)){let e=0;for(;e<I&&B[e]&&B[e]!==``;)e++;let t=B.slice(0,e).join(``);o(c(x),{recursive:!0}),s(x,t)}l([`${p(S)} tokens used `,`${u.GREY_DARK}in ${p(C)}ms${u.RESET}`].join(``))}));await Promise.all(H);let U=B.join(``);(A===`end`||A===`incremental`)&&(o(c(x),{recursive:!0}),s(x,U));let W=((y.now()-P)/1e3).toFixed(2),G=l(w.system.baseDir,x);return N(`${f(`✔`,u.GREEN)} File ${g(G)} completed in ${p(W)}s.`),U}catch(e){T.count++;let t=e?.message??JSON.stringify(e);return N(`${f(`✖`,u.RED)} Error: ${t}`),T.count>=T.maxErrors&&(T.shouldStop=!0),null}};export{b as translateFile};
1
+ import{readAsset as e}from"../_virtual/_utils_asset.mjs";import{sanitizeChunk as t,validateTranslation as n}from"./validation.mjs";import{chunkInference as r}from"../utils/chunkInference.mjs";import{fixChunkStartEndChars as i}from"../utils/fixChunkStartEndChars.mjs";import{chunkText as a}from"../utils/calculateChunks.mjs";import{mkdirSync as o,writeFileSync as s}from"node:fs";import{dirname as c,relative as l}from"node:path";import{formatLocale as u,formatPath as d}from"@intlayer/chokidar/utils";import{ANSIColors as f,colon as p,colorize as m,colorizeNumber as h,getAppLogger as g}from"@intlayer/config/logger";import{retryManager as _}from"@intlayer/config/utils";import{readFile as v}from"node:fs/promises";import{performance as y}from"node:perf_hooks";const b=async({baseFilePath:b,outputFilePath:x,locale:S,baseLocale:C,configuration:w,errorState:T,aiOptions:E,customInstructions:D,aiClient:O,aiConfig:k,flushStrategy:A=`incremental`,onChunkReceive:j,limit:M})=>{if(T.shouldStop)return null;let N=g(w,{config:{prefix:``}}),P=y.now();try{let F=a(await v(b,`utf-8`)),I=F.length,L=`${p(`${f.GREY_DARK}[${d(b)}${f.GREY_DARK}] `,{colSize:40})}${f.RESET}`,R=`${p(`${f.GREY_DARK}[${d(b)}${f.GREY_DARK}][${u(S)}${f.GREY_DARK}] `,{colSize:40})}${f.RESET}`;N(`${L}Split into ${h(I)} chunks. Queuing...`);let z=e(`./prompts/TRANSLATE_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${u(S,!1)}`).replaceAll(`{{baseLocaleName}}`,`${u(C,!1)}`).replace(`{{applicationContext}}`,E?.applicationContext??`-`).replace(`{{customInstructions}}`,D??`-`),B=Array(I).fill(``),V=M??(e=>e()),H=F.map((e,a)=>V(async()=>{if(T.shouldStop)return null;let l=g(w,{config:{prefix:`${R} ${f.GREY_DARK}[${a+1}/${I}] ${f.RESET}`}}),u=y.now(),d=a===0,p=e.content,m=()=>">>> CONTEXT: PREVIOUS SOURCE CONTENT <<<\n```\n"+(F[a-1]?.content??``)+"\n```\n>>> END PREVIOUS CONTEXT <<<",v=()=>">>> CONTEXT: NEXT CONTENT <<<\n```\n"+(F[a+1]?.content??``)+"\n```\n>>> END NEXT CONTEXT <<<";l(`Process started`);let{content:b,tokens:S}=await _(async()=>{let e=await r([{role:`system`,content:z},...F[a+1]?[{role:`system`,content:v()}]:[],...d?[]:[{role:`system`,content:m()}],{role:`system`,content:[`You are translating TARGET CHUNK (${a+1}/${I}).`,`Translate ONLY the target chunk. Preserve frontmatter/code exactly.`].join(`
2
+ `)},{role:`user`,content:`>>> TARGET CHUNK START <<<\n${p}\n>>> TARGET CHUNK END <<<`}],E,w,O,k),o=t(e?.fileContent,p);if(o=i(o,p),!n(p,o,l))throw Error(`Validation failed for chunk ${a+1}/${I}`);return{content:o,tokens:e.tokenUsed}})(),C=(y.now()-u).toFixed(0);if(B[a]=b,j&&j(b,a,I),A===`incremental`&&B.slice(0,a+1).every(e=>e&&e!==``)){let e=0;for(;e<I&&B[e]&&B[e]!==``;)e++;let t=B.slice(0,e).join(``);o(c(x),{recursive:!0}),s(x,t)}l([`${h(S)} tokens used `,`${f.GREY_DARK}in ${h(C)}ms${f.RESET}`].join(``))}));await Promise.all(H);let U=B.join(``);(A===`end`||A===`incremental`)&&(o(c(x),{recursive:!0}),s(x,U));let W=((y.now()-P)/1e3).toFixed(2),G=l(w.system.baseDir,x);return N(`${m(`✔`,f.GREEN)} File ${d(G)} completed in ${h(W)}s.`),U}catch(e){T.count++;let t=e?.message??JSON.stringify(e);return N(`${m(`✖`,f.RED)} Error: ${t}`),T.count>=T.maxErrors&&(T.shouldStop=!0),null}};export{b as translateFile};
3
3
  //# sourceMappingURL=translateFile.mjs.map
@@ -1,2 +1,2 @@
1
- import{logConfigDetails as e}from"@intlayer/chokidar/cli";import{getAppLogger as t}from"@intlayer/config/logger";import{getConfiguration as n}from"@intlayer/config/node";import{runParallel as r}from"@intlayer/chokidar/utils";import{watch as i}from"@intlayer/chokidar/watcher";const a=async a=>{let o=n(a?.configOptions);e(a?.configOptions);let s=t(o),c;a?.with&&(c=r(a.with),c.result.catch(()=>{process.exit(1)}));let l=i({persistent:!0,skipPrepare:a?.skipPrepare??!1}),u=async()=>{process.off(`SIGINT`,u),process.off(`SIGTERM`,u),s(`Stopping Intlayer watcher...`);try{await l.close(),c&&`child`in c&&c.child?.kill(`SIGTERM`)}catch(e){console.error(`Error during shutdown:`,e)}finally{process.exit(0)}};process.on(`SIGINT`,u),process.on(`SIGTERM`,u)};export{a as watchContentDeclaration};
1
+ import{logConfigDetails as e}from"@intlayer/chokidar/cli";import{runParallel as t}from"@intlayer/chokidar/utils";import{getAppLogger as n}from"@intlayer/config/logger";import{getConfiguration as r}from"@intlayer/config/node";import{watch as i}from"@intlayer/chokidar/watcher";const a=async a=>{let o=r(a?.configOptions);e(a?.configOptions);let s=n(o),c;a?.with&&(c=t(a.with),c.result.catch(()=>{process.exit(1)}));let l=i({persistent:!0,skipPrepare:a?.skipPrepare??!1}),u=async()=>{process.off(`SIGINT`,u),process.off(`SIGTERM`,u),s(`Stopping Intlayer watcher...`);try{await l.close(),c&&`child`in c&&c.child?.kill(`SIGTERM`)}catch(e){console.error(`Error during shutdown:`,e)}finally{process.exit(0)}};process.on(`SIGINT`,u),process.on(`SIGTERM`,u)};export{a as watchContentDeclaration};
2
2
  //# sourceMappingURL=watch.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extract.d.ts","names":[],"sources":["../../src/extract.ts"],"mappings":";;;;KAmBK,cAAA;EACH,KAAA;EACA,MAAA,GAAS,eAAA;EACT,aAAA,GAAgB,uBAAA;EAChB,QAAA;EACA,eAAA;AAAA;AAAA,cAGW,OAAA,GAAiB,OAAA,EAAS,cAAA,KAAc,OAAA"}
1
+ {"version":3,"file":"extract.d.ts","names":[],"sources":["../../src/extract.ts"],"mappings":";;;;KAyBK,cAAA;EACH,KAAA;EACA,MAAA,GAAS,eAAA;EACT,aAAA,GAAgB,uBAAA;EAChB,QAAA;EACA,eAAA;AAAA;AAAA,cAGW,OAAA,GAAiB,OAAA,EAAS,cAAA,KAAc,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/cli",
3
- "version": "8.3.0-canary.4",
3
+ "version": "8.3.1",
4
4
  "private": false,
5
5
  "description": "Provides uniform command-line interface scripts for Intlayer, used in packages like intlayer-cli and intlayer.",
6
6
  "keywords": [
@@ -67,16 +67,16 @@
67
67
  },
68
68
  "dependencies": {
69
69
  "@clack/prompts": "0.11.0",
70
- "@intlayer/ai": "8.3.0-canary.4",
71
- "@intlayer/api": "8.3.0-canary.4",
72
- "@intlayer/babel": "8.3.0-canary.4",
73
- "@intlayer/chokidar": "8.3.0-canary.4",
74
- "@intlayer/config": "8.3.0-canary.4",
75
- "@intlayer/core": "8.3.0-canary.4",
76
- "@intlayer/dictionaries-entry": "8.3.0-canary.4",
77
- "@intlayer/remote-dictionaries-entry": "8.3.0-canary.4",
78
- "@intlayer/types": "8.3.0-canary.4",
79
- "@intlayer/unmerged-dictionaries-entry": "8.3.0-canary.4",
70
+ "@intlayer/ai": "8.3.1",
71
+ "@intlayer/api": "8.3.1",
72
+ "@intlayer/babel": "8.3.1",
73
+ "@intlayer/chokidar": "8.3.1",
74
+ "@intlayer/config": "8.3.1",
75
+ "@intlayer/core": "8.3.1",
76
+ "@intlayer/dictionaries-entry": "8.3.1",
77
+ "@intlayer/remote-dictionaries-entry": "8.3.1",
78
+ "@intlayer/types": "8.3.1",
79
+ "@intlayer/unmerged-dictionaries-entry": "8.3.1",
80
80
  "commander": "14.0.3",
81
81
  "enquirer": "^2.4.1",
82
82
  "eventsource": "4.1.0",
@@ -93,7 +93,7 @@
93
93
  "vitest": "4.0.18"
94
94
  },
95
95
  "peerDependencies": {
96
- "@intlayer/ai": "8.3.0-canary.4"
96
+ "@intlayer/ai": "8.3.1"
97
97
  },
98
98
  "peerDependenciesMeta": {
99
99
  "@intlayer/ai": {