@intlayer/cli 8.4.0 → 8.4.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 (140) hide show
  1. package/dist/cjs/IntlayerEventListener.cjs +1 -1
  2. package/dist/cjs/IntlayerEventListener.cjs.map +1 -1
  3. package/dist/cjs/_utils_asset-ghp_Cjwk.cjs +2 -0
  4. package/dist/cjs/auth/login.cjs +1 -1
  5. package/dist/cjs/auth/login.cjs.map +1 -1
  6. package/dist/cjs/build.cjs +1 -1
  7. package/dist/cjs/build.cjs.map +1 -1
  8. package/dist/cjs/{_virtual/_rolldown/runtime.cjs → chunk-Bmb41Sf3.cjs} +1 -1
  9. package/dist/cjs/ci.cjs +1 -1
  10. package/dist/cjs/ci.cjs.map +1 -1
  11. package/dist/cjs/cli.cjs +1 -1
  12. package/dist/cjs/cli.cjs.map +1 -1
  13. package/dist/cjs/config.cjs +1 -1
  14. package/dist/cjs/config.cjs.map +1 -1
  15. package/dist/cjs/editor.cjs +1 -1
  16. package/dist/cjs/editor.cjs.map +1 -1
  17. package/dist/cjs/extract.cjs +1 -1
  18. package/dist/cjs/extract.cjs.map +1 -1
  19. package/dist/cjs/fill/fill.cjs +1 -1
  20. package/dist/cjs/fill/fill.cjs.map +1 -1
  21. package/dist/cjs/fill/formatAutoFilledFilePath.cjs +1 -1
  22. package/dist/cjs/fill/formatAutoFilledFilePath.cjs.map +1 -1
  23. package/dist/cjs/fill/formatFillData.cjs +1 -1
  24. package/dist/cjs/fill/formatFillData.cjs.map +1 -1
  25. package/dist/cjs/fill/listTranslationsTasks.cjs +1 -1
  26. package/dist/cjs/fill/listTranslationsTasks.cjs.map +1 -1
  27. package/dist/cjs/fill/translateDictionary.cjs +1 -1
  28. package/dist/cjs/fill/translateDictionary.cjs.map +1 -1
  29. package/dist/cjs/fill/writeFill.cjs +1 -1
  30. package/dist/cjs/fill/writeFill.cjs.map +1 -1
  31. package/dist/cjs/getTargetDictionary.cjs +1 -1
  32. package/dist/cjs/getTargetDictionary.cjs.map +1 -1
  33. package/dist/cjs/init.cjs +1 -1
  34. package/dist/cjs/init.cjs.map +1 -1
  35. package/dist/cjs/initMCP.cjs +1 -1
  36. package/dist/cjs/initMCP.cjs.map +1 -1
  37. package/dist/cjs/initSkills.cjs +1 -1
  38. package/dist/cjs/initSkills.cjs.map +1 -1
  39. package/dist/cjs/listContentDeclaration.cjs +1 -1
  40. package/dist/cjs/listContentDeclaration.cjs.map +1 -1
  41. package/dist/cjs/listProjects.cjs +1 -1
  42. package/dist/cjs/listProjects.cjs.map +1 -1
  43. package/dist/cjs/liveSync.cjs +1 -1
  44. package/dist/cjs/liveSync.cjs.map +1 -1
  45. package/dist/cjs/pull.cjs +1 -1
  46. package/dist/cjs/pull.cjs.map +1 -1
  47. package/dist/cjs/push/pullLog.cjs +1 -1
  48. package/dist/cjs/push/pullLog.cjs.map +1 -1
  49. package/dist/cjs/push/push.cjs +1 -1
  50. package/dist/cjs/push/push.cjs.map +1 -1
  51. package/dist/cjs/pushConfig.cjs +1 -1
  52. package/dist/cjs/pushConfig.cjs.map +1 -1
  53. package/dist/cjs/pushLog.cjs +1 -1
  54. package/dist/cjs/pushLog.cjs.map +1 -1
  55. package/dist/cjs/reviewDoc/reviewDoc.cjs +1 -1
  56. package/dist/cjs/reviewDoc/reviewDoc.cjs.map +1 -1
  57. package/dist/cjs/reviewDoc/reviewDocBlockAware.cjs +1 -1
  58. package/dist/cjs/reviewDoc/reviewDocBlockAware.cjs.map +1 -1
  59. package/dist/cjs/searchDoc.cjs +1 -1
  60. package/dist/cjs/searchDoc.cjs.map +1 -1
  61. package/dist/cjs/test/listMissingTranslations.cjs +1 -1
  62. package/dist/cjs/test/listMissingTranslations.cjs.map +1 -1
  63. package/dist/cjs/test/test.cjs +1 -1
  64. package/dist/cjs/test/test.cjs.map +1 -1
  65. package/dist/cjs/translateDoc/index.cjs +1 -1
  66. package/dist/cjs/translateDoc/translateDoc.cjs +1 -1
  67. package/dist/cjs/translateDoc/translateDoc.cjs.map +1 -1
  68. package/dist/cjs/translateDoc/translateFile.cjs +1 -1
  69. package/dist/cjs/translateDoc/translateFile.cjs.map +1 -1
  70. package/dist/cjs/translation-alignment/fingerprintBlock.cjs +1 -1
  71. package/dist/cjs/translation-alignment/fingerprintBlock.cjs.map +1 -1
  72. package/dist/cjs/utils/calculateChunks.cjs +1 -1
  73. package/dist/cjs/utils/calculateChunks.cjs.map +1 -1
  74. package/dist/cjs/utils/checkAccess.cjs +1 -1
  75. package/dist/cjs/utils/checkAccess.cjs.map +1 -1
  76. package/dist/cjs/utils/checkLastUpdateTime.cjs +1 -1
  77. package/dist/cjs/utils/checkLastUpdateTime.cjs.map +1 -1
  78. package/dist/cjs/utils/chunkInference.cjs +1 -1
  79. package/dist/cjs/utils/chunkInference.cjs.map +1 -1
  80. package/dist/cjs/utils/getIsFileUpdatedRecently.cjs +1 -1
  81. package/dist/cjs/utils/getIsFileUpdatedRecently.cjs.map +1 -1
  82. package/dist/cjs/utils/getParentPackageJSON.cjs +1 -1
  83. package/dist/cjs/utils/getParentPackageJSON.cjs.map +1 -1
  84. package/dist/cjs/utils/mapChunksBetweenFiles.cjs +1 -1
  85. package/dist/cjs/utils/mapChunksBetweenFiles.cjs.map +1 -1
  86. package/dist/cjs/utils/openBrowser.cjs +1 -1
  87. package/dist/cjs/utils/openBrowser.cjs.map +1 -1
  88. package/dist/cjs/utils/setupAI.cjs +1 -1
  89. package/dist/cjs/utils/setupAI.cjs.map +1 -1
  90. package/dist/cjs/watch.cjs +1 -1
  91. package/dist/cjs/watch.cjs.map +1 -1
  92. package/dist/esm/{_virtual/_utils_asset.mjs → _utils_asset-B187VPMw.mjs} +1 -1
  93. package/dist/esm/cli.mjs +1 -1
  94. package/dist/esm/cli.mjs.map +1 -1
  95. package/dist/esm/editor-D8BGlLzF.mjs +2 -0
  96. package/dist/esm/editor-D8BGlLzF.mjs.map +1 -0
  97. package/dist/esm/editor.mjs +1 -2
  98. package/dist/esm/index.mjs +1 -1
  99. package/dist/esm/reviewDoc/reviewDoc.mjs +1 -1
  100. package/dist/esm/reviewDoc/reviewDoc.mjs.map +1 -1
  101. package/dist/esm/reviewDoc/reviewDocBlockAware.mjs +1 -1
  102. package/dist/esm/reviewDoc/reviewDocBlockAware.mjs.map +1 -1
  103. package/dist/esm/translateDoc/index.mjs +1 -1
  104. package/dist/esm/translateDoc/translateDoc.mjs +1 -1
  105. package/dist/esm/translateDoc/translateDoc.mjs.map +1 -1
  106. package/dist/esm/translateDoc/translateFile.mjs +1 -1
  107. package/dist/esm/translateDoc/translateFile.mjs.map +1 -1
  108. package/dist/types/fill/fill.d.ts +1 -1
  109. package/dist/types/fill/translateDictionary.d.ts +1 -1
  110. package/dist/types/getTargetDictionary-RBSRtaQj.d.ts +19 -0
  111. package/dist/types/getTargetDictionary-RBSRtaQj.d.ts.map +1 -0
  112. package/dist/types/getTargetDictionary.d.ts +2 -19
  113. package/dist/types/index.d.ts +2 -2
  114. package/dist/types/listMissingTranslations-DxKw7nqI.d.ts +28 -0
  115. package/dist/types/listMissingTranslations-DxKw7nqI.d.ts.map +1 -0
  116. package/dist/types/reviewDoc/reviewDocBlockAware.d.ts +1 -1
  117. package/dist/types/setupAI-Bosjx7ah.d.ts +21 -0
  118. package/dist/types/setupAI-Bosjx7ah.d.ts.map +1 -0
  119. package/dist/types/test/index.d.ts +2 -2
  120. package/dist/types/test/listMissingTranslations.d.ts +2 -28
  121. package/dist/types/test/test.d.ts +2 -11
  122. package/dist/types/test-DUTiJR5_.d.ts +11 -0
  123. package/dist/types/test-DUTiJR5_.d.ts.map +1 -0
  124. package/dist/types/translateDoc/index.d.ts +1 -1
  125. package/dist/types/translateDoc/translateDoc.d.ts +1 -1
  126. package/dist/types/translateDoc/translateFile.d.ts +1 -1
  127. package/dist/types/translateDoc/types.d.ts +2 -48
  128. package/dist/types/types-BKvc3FmV.d.ts +48 -0
  129. package/dist/types/types-BKvc3FmV.d.ts.map +1 -0
  130. package/dist/types/utils/chunkInference.d.ts +1 -1
  131. package/dist/types/utils/setupAI.d.ts +2 -21
  132. package/package.json +12 -12
  133. package/dist/cjs/_virtual/_utils_asset.cjs +0 -2
  134. package/dist/esm/_virtual/_rolldown/runtime.mjs +0 -1
  135. package/dist/esm/editor.mjs.map +0 -1
  136. package/dist/types/getTargetDictionary.d.ts.map +0 -1
  137. package/dist/types/test/listMissingTranslations.d.ts.map +0 -1
  138. package/dist/types/test/test.d.ts.map +0 -1
  139. package/dist/types/translateDoc/types.d.ts.map +0 -1
  140. package/dist/types/utils/setupAI.d.ts.map +0 -1
@@ -1 +1 @@
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
+ {"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":"kcAiCA,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/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;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-Bmb41Sf3.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":"fill.cjs","names":["ensureArray","setupAI","getTargetUnmergedDictionaries","ANSIColors","listTranslationsTasks","translateDictionary","writeFill"],"sources":["../../../src/fill/fill.ts"],"sourcesContent":["import { basename, relative } from 'node:path';\nimport type { AIOptions } from '@intlayer/api';\nimport {\n prepareIntlayer,\n writeContentDeclaration,\n} from '@intlayer/chokidar/build';\nimport {\n type ListGitFilesOptions,\n logConfigDetails,\n} from '@intlayer/chokidar/cli';\nimport {\n formatPath,\n getGlobalLimiter,\n getTaskLimiter,\n} from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizeKey,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport {\n ensureArray,\n type GetTargetDictionaryOptions,\n getTargetUnmergedDictionaries,\n} from '../getTargetDictionary';\nimport { setupAI } from '../utils/setupAI';\nimport {\n listTranslationsTasks,\n type TranslationTask,\n} from './listTranslationsTasks';\nimport { translateDictionary } from './translateDictionary';\nimport { writeFill } from './writeFill';\n\nconst NB_CONCURRENT_TRANSLATIONS = 7;\n\n// Arguments for the fill function\nexport type FillOptions = {\n sourceLocale?: Locale;\n outputLocales?: Locale | Locale[];\n mode?: 'complete' | 'review';\n gitOptions?: ListGitFilesOptions;\n aiOptions?: AIOptions; // Added aiOptions to be passed to translateJSON\n verbose?: boolean;\n nbConcurrentTranslations?: number;\n nbConcurrentTasks?: number; // NEW: number of tasks that may run at once\n build?: boolean;\n skipMetadata?: boolean;\n} & GetTargetDictionaryOptions;\n\n/**\n * Fill translations based on the provided options.\n */\nexport const fill = async (options?: FillOptions): Promise<void> => {\n const configuration = getConfiguration(options?.configOptions);\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(configuration);\n\n if (options?.build === true) {\n await prepareIntlayer(configuration, { forceRun: true });\n } else if (typeof options?.build === 'undefined') {\n await prepareIntlayer(configuration);\n }\n\n const { defaultLocale, locales } = configuration.internationalization;\n const mode = options?.mode ?? 'complete';\n const baseLocale = options?.sourceLocale ?? defaultLocale;\n\n const outputLocales = options?.outputLocales\n ? ensureArray(options.outputLocales)\n : locales;\n\n const aiResult = await setupAI(configuration, options?.aiOptions);\n\n if (!aiResult?.hasAIAccess) return;\n\n const { aiClient, aiConfig } = aiResult;\n\n const targetUnmergedDictionaries =\n await getTargetUnmergedDictionaries(options);\n\n const affectedDictionaryKeys = new Set<string>();\n targetUnmergedDictionaries.forEach((dict) => {\n affectedDictionaryKeys.add(dict.key);\n });\n\n const keysToProcess = Array.from(affectedDictionaryKeys);\n\n appLogger([\n 'Affected dictionary keys for processing:',\n keysToProcess.length > 0\n ? keysToProcess.map((key) => colorizeKey(key)).join(', ')\n : colorize('No keys found', ANSIColors.YELLOW),\n ]);\n\n if (keysToProcess.length === 0) return;\n\n /**\n * List the translations tasks\n *\n * Create a list of per-locale dictionaries to translate\n *\n * In 'complete' mode, filter only the missing locales to translate\n */\n const translationTasks: TranslationTask[] = listTranslationsTasks(\n targetUnmergedDictionaries.map((dictionary) => dictionary.localId!),\n outputLocales,\n mode,\n baseLocale,\n configuration\n );\n\n // AI calls in flight at once (translateJSON + metadata audit)\n const nbConcurrentTranslations =\n options?.nbConcurrentTranslations ?? NB_CONCURRENT_TRANSLATIONS;\n const globalLimiter = getGlobalLimiter(nbConcurrentTranslations);\n\n // NEW: number of *tasks* that may run at once (start/prepare/log/write)\n const nbConcurrentTasks = Math.max(\n 1,\n Math.min(\n options?.nbConcurrentTasks ?? nbConcurrentTranslations,\n translationTasks.length\n )\n );\n\n const taskLimiter = getTaskLimiter(nbConcurrentTasks);\n\n const runners = translationTasks.map((task) =>\n taskLimiter(async () => {\n const relativePath = relative(\n configuration?.content?.baseDir ?? process.cwd(),\n task?.dictionaryFilePath ?? ''\n );\n\n // log AFTER acquiring a task slot\n appLogger(\n `${task.dictionaryPreset} Processing ${colorizePath(basename(relativePath))}`,\n { level: 'info' }\n );\n\n const translationTaskResult = await translateDictionary(\n task,\n configuration,\n {\n mode,\n aiOptions: options?.aiOptions,\n fillMetadata: !options?.skipMetadata,\n onHandle: globalLimiter, // <= AI calls go through here\n aiClient,\n aiConfig,\n }\n );\n\n if (!translationTaskResult?.dictionaryOutput) return;\n\n const { dictionaryOutput, sourceLocale } = translationTaskResult;\n\n // Determine if we should write to separate files\n // - If dictionary has explicit fill setting (string or object), use it\n // - If dictionary is per-locale AND has no explicit fill=false, use global fill config\n // - If dictionary is multilingual (no locale property), always write to same file\n const hasDictionaryLevelFill =\n typeof dictionaryOutput.fill === 'string' ||\n typeof dictionaryOutput.fill === 'object';\n\n const isPerLocale = typeof dictionaryOutput.locale === 'string';\n\n const effectiveFill = hasDictionaryLevelFill\n ? dictionaryOutput.fill\n : isPerLocale\n ? (configuration.dictionary?.fill ?? true)\n : false; // Multilingual dictionaries don't use fill by default\n\n const isFillOtherFile =\n typeof effectiveFill === 'string' || typeof effectiveFill === 'object';\n\n if (isFillOtherFile) {\n await writeFill(\n {\n ...dictionaryOutput,\n // Ensure fill is set on the dictionary for writeFill to use\n fill: effectiveFill,\n },\n outputLocales,\n [sourceLocale],\n configuration\n );\n } else {\n await writeContentDeclaration(dictionaryOutput, configuration);\n\n if (dictionaryOutput.filePath) {\n appLogger(\n `${task.dictionaryPreset} Content declaration written to ${formatPath(basename(dictionaryOutput.filePath))}`,\n { level: 'info' }\n );\n }\n }\n })\n );\n\n await Promise.all(runners);\n await (globalLimiter as any).onIdle();\n};\n"],"mappings":"ggBAqCA,MAmBa,EAAO,KAAO,IAAyC,CAClE,IAAM,GAAA,EAAA,EAAA,kBAAiC,GAAS,cAAc,EAC9D,EAAA,EAAA,kBAAiB,GAAS,cAAc,CAExC,IAAM,GAAA,EAAA,EAAA,cAAyB,EAAc,CAEzC,GAAS,QAAU,GACrB,MAAA,EAAA,EAAA,iBAAsB,EAAe,CAAE,SAAU,GAAM,CAAC,CACxC,GAAS,QAAU,QACnC,MAAA,EAAA,EAAA,iBAAsB,EAAc,CAGtC,GAAM,CAAE,gBAAe,WAAY,EAAc,qBAC3C,EAAO,GAAS,MAAQ,WACxB,EAAa,GAAS,cAAgB,EAEtC,EAAgB,GAAS,cAC3BA,EAAAA,YAAY,EAAQ,cAAc,CAClC,EAEE,EAAW,MAAMC,EAAAA,QAAQ,EAAe,GAAS,UAAU,CAEjE,GAAI,CAAC,GAAU,YAAa,OAE5B,GAAM,CAAE,WAAU,YAAa,EAEzB,EACJ,MAAMC,EAAAA,8BAA8B,EAAQ,CAExC,EAAyB,IAAI,IACnC,EAA2B,QAAS,GAAS,CAC3C,EAAuB,IAAI,EAAK,IAAI,EACpC,CAEF,IAAM,EAAgB,MAAM,KAAK,EAAuB,CASxD,GAPA,EAAU,CACR,2CACA,EAAc,OAAS,EACnB,EAAc,IAAK,IAAA,EAAA,EAAA,aAAoB,EAAI,CAAC,CAAC,KAAK,KAAK,EAAA,EAAA,EAAA,UAC9C,gBAAiBC,EAAAA,WAAW,OAAO,CACjD,CAAC,CAEE,EAAc,SAAW,EAAG,OAShC,IAAM,EAAsCC,EAAAA,sBAC1C,EAA2B,IAAK,GAAe,EAAW,QAAS,CACnE,EACA,EACA,EACA,EACD,CAGK,EACJ,GAAS,0BAA4B,EACjC,GAAA,EAAA,EAAA,kBAAiC,EAAyB,CAW1D,GAAA,EAAA,EAAA,gBARoB,KAAK,IAC7B,EACA,KAAK,IACH,GAAS,mBAAqB,EAC9B,EAAiB,OAClB,CACF,CAEoD,CAE/C,EAAU,EAAiB,IAAK,GACpC,EAAY,SAAY,CACtB,IAAM,GAAA,EAAA,EAAA,UACJ,GAAe,SAAS,SAAW,QAAQ,KAAK,CAChD,GAAM,oBAAsB,GAC7B,CAGD,EACE,GAAG,EAAK,iBAAiB,eAAA,EAAA,EAAA,eAAA,EAAA,EAAA,UAAoC,EAAa,CAAC,GAC3E,CAAE,MAAO,OAAQ,CAClB,CAED,IAAM,EAAwB,MAAMC,EAAAA,oBAClC,EACA,EACA,CACE,OACA,UAAW,GAAS,UACpB,aAAc,CAAC,GAAS,aACxB,SAAU,EACV,WACA,WACD,CACF,CAED,GAAI,CAAC,GAAuB,iBAAkB,OAE9C,GAAM,CAAE,mBAAkB,gBAAiB,EAMrC,EACJ,OAAO,EAAiB,MAAS,UACjC,OAAO,EAAiB,MAAS,SAE7B,EAAc,OAAO,EAAiB,QAAW,SAEjD,EAAgB,EAClB,EAAiB,KACjB,EACG,EAAc,YAAY,MAAQ,GACnC,GAGJ,OAAO,GAAkB,UAAY,OAAO,GAAkB,SAG9D,MAAMC,EAAAA,UACJ,CACE,GAAG,EAEH,KAAM,EACP,CACD,EACA,CAAC,EAAa,CACd,EACD,EAED,MAAA,EAAA,EAAA,yBAA8B,EAAkB,EAAc,CAE1D,EAAiB,UACnB,EACE,GAAG,EAAK,iBAAiB,mCAAA,EAAA,EAAA,aAAA,EAAA,EAAA,UAAsD,EAAiB,SAAS,CAAC,GAC1G,CAAE,MAAO,OAAQ,CAClB,GAGL,CACH,CAED,MAAM,QAAQ,IAAI,EAAQ,CAC1B,MAAO,EAAsB,QAAQ"}
1
+ {"version":3,"file":"fill.cjs","names":["ensureArray","setupAI","getTargetUnmergedDictionaries","ANSIColors","listTranslationsTasks","translateDictionary","writeFill"],"sources":["../../../src/fill/fill.ts"],"sourcesContent":["import { basename, relative } from 'node:path';\nimport type { AIOptions } from '@intlayer/api';\nimport {\n prepareIntlayer,\n writeContentDeclaration,\n} from '@intlayer/chokidar/build';\nimport {\n type ListGitFilesOptions,\n logConfigDetails,\n} from '@intlayer/chokidar/cli';\nimport {\n formatPath,\n getGlobalLimiter,\n getTaskLimiter,\n} from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizeKey,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport {\n ensureArray,\n type GetTargetDictionaryOptions,\n getTargetUnmergedDictionaries,\n} from '../getTargetDictionary';\nimport { setupAI } from '../utils/setupAI';\nimport {\n listTranslationsTasks,\n type TranslationTask,\n} from './listTranslationsTasks';\nimport { translateDictionary } from './translateDictionary';\nimport { writeFill } from './writeFill';\n\nconst NB_CONCURRENT_TRANSLATIONS = 7;\n\n// Arguments for the fill function\nexport type FillOptions = {\n sourceLocale?: Locale;\n outputLocales?: Locale | Locale[];\n mode?: 'complete' | 'review';\n gitOptions?: ListGitFilesOptions;\n aiOptions?: AIOptions; // Added aiOptions to be passed to translateJSON\n verbose?: boolean;\n nbConcurrentTranslations?: number;\n nbConcurrentTasks?: number; // NEW: number of tasks that may run at once\n build?: boolean;\n skipMetadata?: boolean;\n} & GetTargetDictionaryOptions;\n\n/**\n * Fill translations based on the provided options.\n */\nexport const fill = async (options?: FillOptions): Promise<void> => {\n const configuration = getConfiguration(options?.configOptions);\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(configuration);\n\n if (options?.build === true) {\n await prepareIntlayer(configuration, { forceRun: true });\n } else if (typeof options?.build === 'undefined') {\n await prepareIntlayer(configuration);\n }\n\n const { defaultLocale, locales } = configuration.internationalization;\n const mode = options?.mode ?? 'complete';\n const baseLocale = options?.sourceLocale ?? defaultLocale;\n\n const outputLocales = options?.outputLocales\n ? ensureArray(options.outputLocales)\n : locales;\n\n const aiResult = await setupAI(configuration, options?.aiOptions);\n\n if (!aiResult?.hasAIAccess) return;\n\n const { aiClient, aiConfig } = aiResult;\n\n const targetUnmergedDictionaries =\n await getTargetUnmergedDictionaries(options);\n\n const affectedDictionaryKeys = new Set<string>();\n targetUnmergedDictionaries.forEach((dict) => {\n affectedDictionaryKeys.add(dict.key);\n });\n\n const keysToProcess = Array.from(affectedDictionaryKeys);\n\n appLogger([\n 'Affected dictionary keys for processing:',\n keysToProcess.length > 0\n ? keysToProcess.map((key) => colorizeKey(key)).join(', ')\n : colorize('No keys found', ANSIColors.YELLOW),\n ]);\n\n if (keysToProcess.length === 0) return;\n\n /**\n * List the translations tasks\n *\n * Create a list of per-locale dictionaries to translate\n *\n * In 'complete' mode, filter only the missing locales to translate\n */\n const translationTasks: TranslationTask[] = listTranslationsTasks(\n targetUnmergedDictionaries.map((dictionary) => dictionary.localId!),\n outputLocales,\n mode,\n baseLocale,\n configuration\n );\n\n // AI calls in flight at once (translateJSON + metadata audit)\n const nbConcurrentTranslations =\n options?.nbConcurrentTranslations ?? NB_CONCURRENT_TRANSLATIONS;\n const globalLimiter = getGlobalLimiter(nbConcurrentTranslations);\n\n // NEW: number of *tasks* that may run at once (start/prepare/log/write)\n const nbConcurrentTasks = Math.max(\n 1,\n Math.min(\n options?.nbConcurrentTasks ?? nbConcurrentTranslations,\n translationTasks.length\n )\n );\n\n const taskLimiter = getTaskLimiter(nbConcurrentTasks);\n\n const runners = translationTasks.map((task) =>\n taskLimiter(async () => {\n const relativePath = relative(\n configuration?.content?.baseDir ?? process.cwd(),\n task?.dictionaryFilePath ?? ''\n );\n\n // log AFTER acquiring a task slot\n appLogger(\n `${task.dictionaryPreset} Processing ${colorizePath(basename(relativePath))}`,\n { level: 'info' }\n );\n\n const translationTaskResult = await translateDictionary(\n task,\n configuration,\n {\n mode,\n aiOptions: options?.aiOptions,\n fillMetadata: !options?.skipMetadata,\n onHandle: globalLimiter, // <= AI calls go through here\n aiClient,\n aiConfig,\n }\n );\n\n if (!translationTaskResult?.dictionaryOutput) return;\n\n const { dictionaryOutput, sourceLocale } = translationTaskResult;\n\n // Determine if we should write to separate files\n // - If dictionary has explicit fill setting (string or object), use it\n // - If dictionary is per-locale AND has no explicit fill=false, use global fill config\n // - If dictionary is multilingual (no locale property), always write to same file\n const hasDictionaryLevelFill =\n typeof dictionaryOutput.fill === 'string' ||\n typeof dictionaryOutput.fill === 'object';\n\n const isPerLocale = typeof dictionaryOutput.locale === 'string';\n\n const effectiveFill = hasDictionaryLevelFill\n ? dictionaryOutput.fill\n : isPerLocale\n ? (configuration.dictionary?.fill ?? true)\n : false; // Multilingual dictionaries don't use fill by default\n\n const isFillOtherFile =\n typeof effectiveFill === 'string' || typeof effectiveFill === 'object';\n\n if (isFillOtherFile) {\n await writeFill(\n {\n ...dictionaryOutput,\n // Ensure fill is set on the dictionary for writeFill to use\n fill: effectiveFill,\n },\n outputLocales,\n [sourceLocale],\n configuration\n );\n } else {\n await writeContentDeclaration(dictionaryOutput, configuration);\n\n if (dictionaryOutput.filePath) {\n appLogger(\n `${task.dictionaryPreset} Content declaration written to ${formatPath(basename(dictionaryOutput.filePath))}`,\n { level: 'info' }\n );\n }\n }\n })\n );\n\n await Promise.all(runners);\n await (globalLimiter as any).onIdle();\n};\n"],"mappings":"ofAqCA,MAmBa,EAAO,KAAO,IAAyC,CAClE,IAAM,GAAA,EAAA,EAAA,kBAAiC,GAAS,cAAc,EAC9D,EAAA,EAAA,kBAAiB,GAAS,cAAc,CAExC,IAAM,GAAA,EAAA,EAAA,cAAyB,EAAc,CAEzC,GAAS,QAAU,GACrB,MAAA,EAAA,EAAA,iBAAsB,EAAe,CAAE,SAAU,GAAM,CAAC,CACxC,GAAS,QAAU,QACnC,MAAA,EAAA,EAAA,iBAAsB,EAAc,CAGtC,GAAM,CAAE,gBAAe,WAAY,EAAc,qBAC3C,EAAO,GAAS,MAAQ,WACxB,EAAa,GAAS,cAAgB,EAEtC,EAAgB,GAAS,cAC3BA,EAAAA,YAAY,EAAQ,cAAc,CAClC,EAEE,EAAW,MAAMC,EAAAA,QAAQ,EAAe,GAAS,UAAU,CAEjE,GAAI,CAAC,GAAU,YAAa,OAE5B,GAAM,CAAE,WAAU,YAAa,EAEzB,EACJ,MAAMC,EAAAA,8BAA8B,EAAQ,CAExC,EAAyB,IAAI,IACnC,EAA2B,QAAS,GAAS,CAC3C,EAAuB,IAAI,EAAK,IAAI,EACpC,CAEF,IAAM,EAAgB,MAAM,KAAK,EAAuB,CASxD,GAPA,EAAU,CACR,2CACA,EAAc,OAAS,EACnB,EAAc,IAAK,IAAA,EAAA,EAAA,aAAoB,EAAI,CAAC,CAAC,KAAK,KAAK,EAAA,EAAA,EAAA,UAC9C,gBAAiBC,EAAAA,WAAW,OAAO,CACjD,CAAC,CAEE,EAAc,SAAW,EAAG,OAShC,IAAM,EAAsCC,EAAAA,sBAC1C,EAA2B,IAAK,GAAe,EAAW,QAAS,CACnE,EACA,EACA,EACA,EACD,CAGK,EACJ,GAAS,0BAA4B,EACjC,GAAA,EAAA,EAAA,kBAAiC,EAAyB,CAW1D,GAAA,EAAA,EAAA,gBARoB,KAAK,IAC7B,EACA,KAAK,IACH,GAAS,mBAAqB,EAC9B,EAAiB,OAClB,CACF,CAEoD,CAE/C,EAAU,EAAiB,IAAK,GACpC,EAAY,SAAY,CACtB,IAAM,GAAA,EAAA,EAAA,UACJ,GAAe,SAAS,SAAW,QAAQ,KAAK,CAChD,GAAM,oBAAsB,GAC7B,CAGD,EACE,GAAG,EAAK,iBAAiB,eAAA,EAAA,EAAA,eAAA,EAAA,EAAA,UAAoC,EAAa,CAAC,GAC3E,CAAE,MAAO,OAAQ,CAClB,CAED,IAAM,EAAwB,MAAMC,EAAAA,oBAClC,EACA,EACA,CACE,OACA,UAAW,GAAS,UACpB,aAAc,CAAC,GAAS,aACxB,SAAU,EACV,WACA,WACD,CACF,CAED,GAAI,CAAC,GAAuB,iBAAkB,OAE9C,GAAM,CAAE,mBAAkB,gBAAiB,EAMrC,EACJ,OAAO,EAAiB,MAAS,UACjC,OAAO,EAAiB,MAAS,SAE7B,EAAc,OAAO,EAAiB,QAAW,SAEjD,EAAgB,EAClB,EAAiB,KACjB,EACG,EAAc,YAAY,MAAQ,GACnC,GAGJ,OAAO,GAAkB,UAAY,OAAO,GAAkB,SAG9D,MAAMC,EAAAA,UACJ,CACE,GAAG,EAEH,KAAM,EACP,CACD,EACA,CAAC,EAAa,CACd,EACD,EAED,MAAA,EAAA,EAAA,yBAA8B,EAAkB,EAAc,CAE1D,EAAiB,UACnB,EACE,GAAG,EAAK,iBAAiB,mCAAA,EAAA,EAAA,aAAA,EAAA,EAAA,UAAsD,EAAiB,SAAS,CAAC,GAC1G,CAAE,MAAO,OAAQ,CAClB,GAGL,CACH,CAED,MAAM,QAAQ,IAAI,EAAQ,CAC1B,MAAO,EAAsB,QAAQ"}
@@ -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/utils`);const n=async(n,r,i,a,o)=>{if(!n)throw Error(`autoFillField must be provided`);if(!r||typeof r!=`string`)throw Error(`dictionaryKey must be a non-empty string`);if(!i||typeof i!=`string`)throw Error(`dictionaryFilePath must be a non-empty string`);if(!a||typeof a!=`string`)throw Error(`baseDir must be a non-empty string`);let s=await(0,t.parseFilePathPattern)(n,{key:r,fileName:(0,e.basename)(i).split(`.`).slice(0,-2).join(`.`),locale:o}),c=(0,e.isAbsolute)(i)?i:(0,e.resolve)(a,i);if(s.startsWith(`./`)||s.startsWith(`../`))return(0,e.resolve)((0,e.dirname)(c),s);if((0,e.isAbsolute)(s)){let t=(0,e.normalize)(s),n=(0,e.normalize)(a);if(s.startsWith(`/`)&&!t.startsWith(n)){let t=(0,e.resolve)(a,s.substring(1));if(!s.startsWith(`/usr/`)&&!s.startsWith(`/etc/`)&&!s.startsWith(`/var/`)&&!s.startsWith(`/home/`)&&!s.startsWith(`/Users/`))return t}return t}return(0,e.normalize)(s)};exports.formatAutoFilledFilePath=n;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-Bmb41Sf3.cjs`);let e=require(`node:path`),t=require(`@intlayer/config/utils`);const n=async(n,r,i,a,o)=>{if(!n)throw Error(`autoFillField must be provided`);if(!r||typeof r!=`string`)throw Error(`dictionaryKey must be a non-empty string`);if(!i||typeof i!=`string`)throw Error(`dictionaryFilePath must be a non-empty string`);if(!a||typeof a!=`string`)throw Error(`baseDir must be a non-empty string`);let s=await(0,t.parseFilePathPattern)(n,{key:r,fileName:(0,e.basename)(i).split(`.`).slice(0,-2).join(`.`),locale:o}),c=(0,e.isAbsolute)(i)?i:(0,e.resolve)(a,i);if(s.startsWith(`./`)||s.startsWith(`../`))return(0,e.resolve)((0,e.dirname)(c),s);if((0,e.isAbsolute)(s)){let t=(0,e.normalize)(s),n=(0,e.normalize)(a);if(s.startsWith(`/`)&&!t.startsWith(n)){let t=(0,e.resolve)(a,s.substring(1));if(!s.startsWith(`/usr/`)&&!s.startsWith(`/etc/`)&&!s.startsWith(`/var/`)&&!s.startsWith(`/home/`)&&!s.startsWith(`/Users/`))return t}return t}return(0,e.normalize)(s)};exports.formatAutoFilledFilePath=n;
2
2
  //# sourceMappingURL=formatAutoFilledFilePath.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatAutoFilledFilePath.cjs","names":[],"sources":["../../../src/fill/formatAutoFilledFilePath.ts"],"sourcesContent":["import { basename, dirname, isAbsolute, normalize, resolve } from 'node:path';\nimport { parseFilePathPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { FilePathPattern } from '@intlayer/types/filePathPattern';\n\nexport const formatAutoFilledFilePath = async (\n autoFillField: FilePathPattern,\n dictionaryKey: string,\n dictionaryFilePath: string,\n baseDir: string,\n locale?: Locale\n): Promise<string> => {\n // Validate inputs\n if (!autoFillField) {\n throw new Error('autoFillField must be provided');\n }\n if (!dictionaryKey || typeof dictionaryKey !== 'string') {\n throw new Error('dictionaryKey must be a non-empty string');\n }\n if (!dictionaryFilePath || typeof dictionaryFilePath !== 'string') {\n throw new Error('dictionaryFilePath must be a non-empty string');\n }\n if (!baseDir || typeof baseDir !== 'string') {\n throw new Error('baseDir must be a non-empty string');\n }\n\n // Extract the original filename without extensions (.content.ts -> dictionaryFieldEditor)\n const originalFileName = basename(dictionaryFilePath)\n .split('.')\n .slice(0, -2) // Remove last 2 extensions (.content.tsx)\n .join('.');\n\n // Replace placeholders in autoFillField\n const result: string = await parseFilePathPattern(autoFillField, {\n key: dictionaryKey,\n fileName: originalFileName,\n locale,\n });\n\n // Normalize the dictionary file path - if it's relative, make it absolute relative to baseDir\n const absoluteDictionaryPath = isAbsolute(dictionaryFilePath)\n ? dictionaryFilePath\n : resolve(baseDir, dictionaryFilePath);\n\n // Handle relative paths (starting with ./ or ../)\n if (result.startsWith('./') || result.startsWith('../')) {\n const fileDir = dirname(absoluteDictionaryPath);\n const resolvedPath = resolve(fileDir, result);\n\n return resolvedPath;\n }\n\n // Handle absolute paths\n if (isAbsolute(result)) {\n const normalizedResult = normalize(result);\n const normalizedBaseDir = normalize(baseDir);\n\n // Check if it's relative to baseDir (starts with /)\n // but not a system path (like /usr/local)\n if (\n result.startsWith('/') &&\n !normalizedResult.startsWith(normalizedBaseDir)\n ) {\n // Try to resolve it relative to baseDir first\n const relativeToBase = resolve(baseDir, result.substring(1));\n\n // If the path doesn't exist in common system directories, treat as relative to baseDir\n if (\n !result.startsWith('/usr/') &&\n !result.startsWith('/etc/') &&\n !result.startsWith('/var/') &&\n !result.startsWith('/home/') &&\n !result.startsWith('/Users/')\n ) {\n return relativeToBase;\n }\n }\n\n // It's a true system absolute path\n return normalizedResult;\n }\n\n // Default case: treat as relative to baseDir\n return normalize(result);\n};\n"],"mappings":"+KAKA,MAAa,EAA2B,MACtC,EACA,EACA,EACA,EACA,IACoB,CAEpB,GAAI,CAAC,EACH,MAAU,MAAM,iCAAiC,CAEnD,GAAI,CAAC,GAAiB,OAAO,GAAkB,SAC7C,MAAU,MAAM,2CAA2C,CAE7D,GAAI,CAAC,GAAsB,OAAO,GAAuB,SACvD,MAAU,MAAM,gDAAgD,CAElE,GAAI,CAAC,GAAW,OAAO,GAAY,SACjC,MAAU,MAAM,qCAAqC,CAUvD,IAAM,EAAiB,MAAA,EAAA,EAAA,sBAA2B,EAAe,CAC/D,IAAK,EACL,UAAA,EAAA,EAAA,UARgC,EAAmB,CAClD,MAAM,IAAI,CACV,MAAM,EAAG,GAAG,CACZ,KAAK,IAAI,CAMV,SACD,CAAC,CAGI,GAAA,EAAA,EAAA,YAAoC,EAAmB,CACzD,GAAA,EAAA,EAAA,SACQ,EAAS,EAAmB,CAGxC,GAAI,EAAO,WAAW,KAAK,EAAI,EAAO,WAAW,MAAM,CAIrD,OAAA,EAAA,EAAA,UAAA,EAAA,EAAA,SAHwB,EAAuB,CACT,EAAO,CAM/C,IAAA,EAAA,EAAA,YAAe,EAAO,CAAE,CACtB,IAAM,GAAA,EAAA,EAAA,WAA6B,EAAO,CACpC,GAAA,EAAA,EAAA,WAA8B,EAAQ,CAI5C,GACE,EAAO,WAAW,IAAI,EACtB,CAAC,EAAiB,WAAW,EAAkB,CAC/C,CAEA,IAAM,GAAA,EAAA,EAAA,SAAyB,EAAS,EAAO,UAAU,EAAE,CAAC,CAG5D,GACE,CAAC,EAAO,WAAW,QAAQ,EAC3B,CAAC,EAAO,WAAW,QAAQ,EAC3B,CAAC,EAAO,WAAW,QAAQ,EAC3B,CAAC,EAAO,WAAW,SAAS,EAC5B,CAAC,EAAO,WAAW,UAAU,CAE7B,OAAO,EAKX,OAAO,EAIT,OAAA,EAAA,EAAA,WAAiB,EAAO"}
1
+ {"version":3,"file":"formatAutoFilledFilePath.cjs","names":[],"sources":["../../../src/fill/formatAutoFilledFilePath.ts"],"sourcesContent":["import { basename, dirname, isAbsolute, normalize, resolve } from 'node:path';\nimport { parseFilePathPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { FilePathPattern } from '@intlayer/types/filePathPattern';\n\nexport const formatAutoFilledFilePath = async (\n autoFillField: FilePathPattern,\n dictionaryKey: string,\n dictionaryFilePath: string,\n baseDir: string,\n locale?: Locale\n): Promise<string> => {\n // Validate inputs\n if (!autoFillField) {\n throw new Error('autoFillField must be provided');\n }\n if (!dictionaryKey || typeof dictionaryKey !== 'string') {\n throw new Error('dictionaryKey must be a non-empty string');\n }\n if (!dictionaryFilePath || typeof dictionaryFilePath !== 'string') {\n throw new Error('dictionaryFilePath must be a non-empty string');\n }\n if (!baseDir || typeof baseDir !== 'string') {\n throw new Error('baseDir must be a non-empty string');\n }\n\n // Extract the original filename without extensions (.content.ts -> dictionaryFieldEditor)\n const originalFileName = basename(dictionaryFilePath)\n .split('.')\n .slice(0, -2) // Remove last 2 extensions (.content.tsx)\n .join('.');\n\n // Replace placeholders in autoFillField\n const result: string = await parseFilePathPattern(autoFillField, {\n key: dictionaryKey,\n fileName: originalFileName,\n locale,\n });\n\n // Normalize the dictionary file path - if it's relative, make it absolute relative to baseDir\n const absoluteDictionaryPath = isAbsolute(dictionaryFilePath)\n ? dictionaryFilePath\n : resolve(baseDir, dictionaryFilePath);\n\n // Handle relative paths (starting with ./ or ../)\n if (result.startsWith('./') || result.startsWith('../')) {\n const fileDir = dirname(absoluteDictionaryPath);\n const resolvedPath = resolve(fileDir, result);\n\n return resolvedPath;\n }\n\n // Handle absolute paths\n if (isAbsolute(result)) {\n const normalizedResult = normalize(result);\n const normalizedBaseDir = normalize(baseDir);\n\n // Check if it's relative to baseDir (starts with /)\n // but not a system path (like /usr/local)\n if (\n result.startsWith('/') &&\n !normalizedResult.startsWith(normalizedBaseDir)\n ) {\n // Try to resolve it relative to baseDir first\n const relativeToBase = resolve(baseDir, result.substring(1));\n\n // If the path doesn't exist in common system directories, treat as relative to baseDir\n if (\n !result.startsWith('/usr/') &&\n !result.startsWith('/etc/') &&\n !result.startsWith('/var/') &&\n !result.startsWith('/home/') &&\n !result.startsWith('/Users/')\n ) {\n return relativeToBase;\n }\n }\n\n // It's a true system absolute path\n return normalizedResult;\n }\n\n // Default case: treat as relative to baseDir\n return normalize(result);\n};\n"],"mappings":"mKAKA,MAAa,EAA2B,MACtC,EACA,EACA,EACA,EACA,IACoB,CAEpB,GAAI,CAAC,EACH,MAAU,MAAM,iCAAiC,CAEnD,GAAI,CAAC,GAAiB,OAAO,GAAkB,SAC7C,MAAU,MAAM,2CAA2C,CAE7D,GAAI,CAAC,GAAsB,OAAO,GAAuB,SACvD,MAAU,MAAM,gDAAgD,CAElE,GAAI,CAAC,GAAW,OAAO,GAAY,SACjC,MAAU,MAAM,qCAAqC,CAUvD,IAAM,EAAiB,MAAA,EAAA,EAAA,sBAA2B,EAAe,CAC/D,IAAK,EACL,UAAA,EAAA,EAAA,UARgC,EAAmB,CAClD,MAAM,IAAI,CACV,MAAM,EAAG,GAAG,CACZ,KAAK,IAAI,CAMV,SACD,CAAC,CAGI,GAAA,EAAA,EAAA,YAAoC,EAAmB,CACzD,GAAA,EAAA,EAAA,SACQ,EAAS,EAAmB,CAGxC,GAAI,EAAO,WAAW,KAAK,EAAI,EAAO,WAAW,MAAM,CAIrD,OAAA,EAAA,EAAA,UAAA,EAAA,EAAA,SAHwB,EAAuB,CACT,EAAO,CAM/C,IAAA,EAAA,EAAA,YAAe,EAAO,CAAE,CACtB,IAAM,GAAA,EAAA,EAAA,WAA6B,EAAO,CACpC,GAAA,EAAA,EAAA,WAA8B,EAAQ,CAI5C,GACE,EAAO,WAAW,IAAI,EACtB,CAAC,EAAiB,WAAW,EAAkB,CAC/C,CAEA,IAAM,GAAA,EAAA,EAAA,SAAyB,EAAS,EAAO,UAAU,EAAE,CAAC,CAG5D,GACE,CAAC,EAAO,WAAW,QAAQ,EAC3B,CAAC,EAAO,WAAW,QAAQ,EAC3B,CAAC,EAAO,WAAW,QAAQ,EAC3B,CAAC,EAAO,WAAW,SAAS,EAC5B,CAAC,EAAO,WAAW,UAAU,CAE7B,OAAO,EAKX,OAAO,EAIT,OAAA,EAAA,EAAA,WAAiB,EAAO"}
@@ -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/chokidar/utils`),n=require(`@intlayer/config/utils`);const r=async(r,i,a,o,s)=>{if(!r||typeof r==`boolean`)return[];let{baseDir:c}=s.system,{defaultLocale:l}=s.internationalization,u=(0,e.extname)(a),d=(0,e.basename)(a),f=d.includes(`.content.`)?d.split(`.content.`)[0]:d.split(`.`)[0],p=f.charAt(0).toLowerCase()+f.slice(1),m=(0,t.getFormatFromExtension)(u),h=(n,r)=>{let i=`json`;if(typeof r==`string`){let n=(0,t.getFormatFromExtension)((0,e.extname)(r));n&&(i=n)}return{key:o,componentDirPath:(0,e.relative)(c,(0,e.dirname)(a)),componentFileName:f,fileName:p,componentFormat:m,componentExtension:u,format:i,locale:n,extension:s.content.fileExtensions[0]}},g=async(e,r)=>{let i=`###########locale###########`,o=!1;if(typeof e==`string`?o=e.includes(`{{locale}}`):typeof e==`function`&&(o=(await e(h(i,e))).includes(i)),o){let i=[];for(let o of r){let r=(0,t.resolveRelativePath)(typeof e==`string`?(0,n.parseStringPattern)(e,h(o,e)):await e(h(o,e)),a,c);i.push({filePath:r,localeList:[o],isPerLocale:!0})}return i.reduce((e,t)=>{let n=e.find(e=>e.filePath===t.filePath);return n?(n.localeList.includes(t.localeList[0])||n.localeList.push(...t.localeList),n.isPerLocale=!1):e.push(t),e},[])}else return[{filePath:(0,t.resolveRelativePath)(typeof e==`string`?(0,n.parseStringPattern)(e,h(l,e)):await e(h(l,e)),a,c),localeList:r,isPerLocale:!1}]};if(typeof r==`object`&&r){let e=[];for(let t of i){let n=r[t];if(n&&typeof n!=`boolean`){let r=await g(n,[t]);e.push(...r)}}return e.reduce((e,t)=>{let n=e.find(e=>e.filePath===t.filePath);if(n){for(let e of t.localeList)n.localeList.includes(e)||n.localeList.push(e);n.isPerLocale=!1}else e.push(t);return e},[])}return typeof r==`string`||typeof r==`function`?g(r,i):[]};exports.formatFillData=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-Bmb41Sf3.cjs`);let e=require(`node:path`),t=require(`@intlayer/chokidar/utils`),n=require(`@intlayer/config/utils`);const r=async(r,i,a,o,s)=>{if(!r||typeof r==`boolean`)return[];let{baseDir:c}=s.system,{defaultLocale:l}=s.internationalization,u=(0,e.extname)(a),d=(0,e.basename)(a),f=d.includes(`.content.`)?d.split(`.content.`)[0]:d.split(`.`)[0],p=f.charAt(0).toLowerCase()+f.slice(1),m=(0,t.getFormatFromExtension)(u),h=(n,r)=>{let i=`json`;if(typeof r==`string`){let n=(0,t.getFormatFromExtension)((0,e.extname)(r));n&&(i=n)}return{key:o,componentDirPath:(0,e.relative)(c,(0,e.dirname)(a)),componentFileName:f,fileName:p,componentFormat:m,componentExtension:u,format:i,locale:n,extension:s.content.fileExtensions[0]}},g=async(e,r)=>{let i=`###########locale###########`,o=!1;if(typeof e==`string`?o=e.includes(`{{locale}}`):typeof e==`function`&&(o=(await e(h(i,e))).includes(i)),o){let i=[];for(let o of r){let r=(0,t.resolveRelativePath)(typeof e==`string`?(0,n.parseStringPattern)(e,h(o,e)):await e(h(o,e)),a,c);i.push({filePath:r,localeList:[o],isPerLocale:!0})}return i.reduce((e,t)=>{let n=e.find(e=>e.filePath===t.filePath);return n?(n.localeList.includes(t.localeList[0])||n.localeList.push(...t.localeList),n.isPerLocale=!1):e.push(t),e},[])}else return[{filePath:(0,t.resolveRelativePath)(typeof e==`string`?(0,n.parseStringPattern)(e,h(l,e)):await e(h(l,e)),a,c),localeList:r,isPerLocale:!1}]};if(typeof r==`object`&&r){let e=[];for(let t of i){let n=r[t];if(n&&typeof n!=`boolean`){let r=await g(n,[t]);e.push(...r)}}return e.reduce((e,t)=>{let n=e.find(e=>e.filePath===t.filePath);if(n){for(let e of t.localeList)n.localeList.includes(e)||n.localeList.push(e);n.isPerLocale=!1}else e.push(t);return e},[])}return typeof r==`string`||typeof r==`function`?g(r,i):[]};exports.formatFillData=r;
2
2
  //# sourceMappingURL=formatFillData.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);\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":"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"}
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":"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"}
@@ -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/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;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-Bmb41Sf3.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 +1 @@
1
- {"version":3,"file":"listTranslationsTasks.cjs","names":["listMissingTranslationsWithConfig","ANSIColors"],"sources":["../../../src/fill/listTranslationsTasks.ts"],"sourcesContent":["import { basename } from 'node:path';\nimport { formatLocale } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colon,\n colorize,\n colorizeKey,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport { getFilterTranslationsOnlyDictionary } from '@intlayer/core/plugins';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type { Dictionary, LocalDictionaryId } from '@intlayer/types/dictionary';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { listMissingTranslationsWithConfig } from '../test';\n\nexport type TranslationTask = {\n dictionaryKey: string;\n dictionaryLocalId: LocalDictionaryId;\n sourceLocale: Locale;\n targetLocales: Locale[];\n dictionaryPreset: string;\n dictionaryFilePath: string;\n};\n\nexport const listTranslationsTasks = (\n localIds: LocalDictionaryId[],\n outputLocales: Locale[],\n mode: 'complete' | 'review',\n baseLocale: Locale,\n configuration: IntlayerConfig\n): TranslationTask[] => {\n const appLogger = getAppLogger(configuration);\n\n const mergedDictionariesRecord = getDictionaries(configuration);\n const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);\n\n const allFlatDictionaries = Object.values(unmergedDictionariesRecord).flat();\n const dictionariesToProcess = allFlatDictionaries.filter((dictionary) =>\n localIds.includes(dictionary.localId!)\n );\n\n const { missingTranslations } =\n listMissingTranslationsWithConfig(configuration);\n\n const maxKeyLength = Math.max(\n ...dictionariesToProcess.map((dictionary) => dictionary.key.length)\n );\n\n const translationTasks: TranslationTask[] = [];\n\n for (const targetUnmergedDictionary of dictionariesToProcess) {\n const dictionaryPreset = colon(\n [\n ' - ',\n colorize('[', ANSIColors.GREY_DARK),\n colorizeKey(targetUnmergedDictionary.key),\n colorize(']', ANSIColors.GREY_DARK),\n ].join(''),\n { colSize: maxKeyLength + 6 }\n );\n\n const dictionaryKey = targetUnmergedDictionary.key;\n const dictionaryLocalId = targetUnmergedDictionary.localId!;\n const mainDictionaryToProcess: Dictionary =\n mergedDictionariesRecord[dictionaryKey];\n const dictionaryFilled = targetUnmergedDictionary.filled ?? false;\n\n if (dictionaryFilled === true) {\n continue;\n }\n\n const dictionaryFill =\n targetUnmergedDictionary.fill ?? configuration.dictionary?.fill ?? false;\n\n if (dictionaryFill === false) continue;\n\n const sourceLocale: Locale = (targetUnmergedDictionary.locale ??\n baseLocale) as Locale;\n\n if (!mainDictionaryToProcess) {\n appLogger(\n `${dictionaryPreset} Dictionary not found in dictionariesRecord. Skipping.`,\n {\n level: 'warn',\n }\n );\n continue;\n }\n\n if (!targetUnmergedDictionary.filePath) {\n appLogger(`${dictionaryPreset} Dictionary has no file path. Skipping.`, {\n level: 'warn',\n });\n continue;\n }\n\n const sourceLocaleContent = getFilterTranslationsOnlyDictionary(\n mainDictionaryToProcess,\n sourceLocale\n );\n\n if (\n Object.keys(sourceLocaleContent as Record<string, unknown>).length === 0\n ) {\n appLogger(\n `${dictionaryPreset} No content found for dictionary in source locale ${formatLocale(sourceLocale)}. Skipping translation for this dictionary.`,\n {\n level: 'warn',\n }\n );\n continue;\n }\n\n /**\n * In 'complete' mode, filter only the missing locales to translate\n *\n * Skip the dictionary if there are no missing locales to translate\n */\n let outputLocalesList: Locale[] = outputLocales as Locale[];\n\n if (mode === 'complete') {\n outputLocalesList =\n missingTranslations\n .find(\n (missingTranslation) => missingTranslation.key === dictionaryKey\n )\n ?.locales.filter((locale) => outputLocales.includes(locale)) ?? [];\n }\n\n if (outputLocalesList.length === 0) {\n appLogger(\n `${dictionaryPreset} ${colorize('No locales to fill, Skipping', ANSIColors.GREY_DARK)} ${colorizePath(basename(targetUnmergedDictionary.filePath))}`,\n {\n level: 'warn',\n }\n );\n continue;\n }\n\n translationTasks.push({\n dictionaryKey,\n dictionaryLocalId,\n sourceLocale,\n targetLocales: outputLocalesList,\n dictionaryPreset,\n dictionaryFilePath: targetUnmergedDictionary.filePath,\n });\n }\n\n // Return the list of tasks to execute\n return translationTasks;\n};\n"],"mappings":"8YA2BA,MAAa,GACX,EACA,EACA,EACA,EACA,IACsB,CACtB,IAAM,GAAA,EAAA,EAAA,cAAyB,EAAc,CAEvC,GAAA,EAAA,EAAA,iBAA2C,EAAc,CACzD,GAAA,EAAA,EAAA,yBAAqD,EAAc,CAGnE,EADsB,OAAO,OAAO,EAA2B,CAAC,MAAM,CAC1B,OAAQ,GACxD,EAAS,SAAS,EAAW,QAAS,CACvC,CAEK,CAAE,uBACNA,EAAAA,kCAAkC,EAAc,CAE5C,EAAe,KAAK,IACxB,GAAG,EAAsB,IAAK,GAAe,EAAW,IAAI,OAAO,CACpE,CAEK,EAAsC,EAAE,CAE9C,IAAK,IAAM,KAA4B,EAAuB,CAC5D,IAAM,GAAA,EAAA,EAAA,OACJ,CACE,qBACS,IAAKC,EAAAA,WAAW,UAAU,mBACvB,EAAyB,IAAI,gBAChC,IAAKA,EAAAA,WAAW,UAAU,CACpC,CAAC,KAAK,GAAG,CACV,CAAE,QAAS,EAAe,EAAG,CAC9B,CAEK,EAAgB,EAAyB,IACzC,EAAoB,EAAyB,QAC7C,EACJ,EAAyB,GAU3B,IATyB,EAAyB,QAAU,MAEnC,KAKvB,EAAyB,MAAQ,EAAc,YAAY,MAAQ,MAE9C,GAAO,SAE9B,IAAM,EAAwB,EAAyB,QACrD,EAEF,GAAI,CAAC,EAAyB,CAC5B,EACE,GAAG,EAAiB,wDACpB,CACE,MAAO,OACR,CACF,CACD,SAGF,GAAI,CAAC,EAAyB,SAAU,CACtC,EAAU,GAAG,EAAiB,yCAA0C,CACtE,MAAO,OACR,CAAC,CACF,SAGF,IAAM,GAAA,EAAA,EAAA,qCACJ,EACA,EACD,CAED,GACE,OAAO,KAAK,EAA+C,CAAC,SAAW,EACvE,CACA,EACE,GAAG,EAAiB,qDAAA,EAAA,EAAA,cAAiE,EAAa,CAAC,6CACnG,CACE,MAAO,OACR,CACF,CACD,SAQF,IAAI,EAA8B,EAWlC,GATI,IAAS,aACX,EACE,EACG,KACE,GAAuB,EAAmB,MAAQ,EACpD,EACC,QAAQ,OAAQ,GAAW,EAAc,SAAS,EAAO,CAAC,EAAI,EAAE,EAGpE,EAAkB,SAAW,EAAG,CAClC,EACE,GAAG,EAAiB,IAAA,EAAA,EAAA,UAAY,+BAAgCA,EAAAA,WAAW,UAAU,CAAC,IAAA,EAAA,EAAA,eAAA,EAAA,EAAA,UAAyB,EAAyB,SAAS,CAAC,GAClJ,CACE,MAAO,OACR,CACF,CACD,SAGF,EAAiB,KAAK,CACpB,gBACA,oBACA,eACA,cAAe,EACf,mBACA,mBAAoB,EAAyB,SAC9C,CAAC,CAIJ,OAAO"}
1
+ {"version":3,"file":"listTranslationsTasks.cjs","names":["listMissingTranslationsWithConfig","ANSIColors"],"sources":["../../../src/fill/listTranslationsTasks.ts"],"sourcesContent":["import { basename } from 'node:path';\nimport { formatLocale } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colon,\n colorize,\n colorizeKey,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport { getFilterTranslationsOnlyDictionary } from '@intlayer/core/plugins';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type { Dictionary, LocalDictionaryId } from '@intlayer/types/dictionary';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { listMissingTranslationsWithConfig } from '../test';\n\nexport type TranslationTask = {\n dictionaryKey: string;\n dictionaryLocalId: LocalDictionaryId;\n sourceLocale: Locale;\n targetLocales: Locale[];\n dictionaryPreset: string;\n dictionaryFilePath: string;\n};\n\nexport const listTranslationsTasks = (\n localIds: LocalDictionaryId[],\n outputLocales: Locale[],\n mode: 'complete' | 'review',\n baseLocale: Locale,\n configuration: IntlayerConfig\n): TranslationTask[] => {\n const appLogger = getAppLogger(configuration);\n\n const mergedDictionariesRecord = getDictionaries(configuration);\n const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);\n\n const allFlatDictionaries = Object.values(unmergedDictionariesRecord).flat();\n const dictionariesToProcess = allFlatDictionaries.filter((dictionary) =>\n localIds.includes(dictionary.localId!)\n );\n\n const { missingTranslations } =\n listMissingTranslationsWithConfig(configuration);\n\n const maxKeyLength = Math.max(\n ...dictionariesToProcess.map((dictionary) => dictionary.key.length)\n );\n\n const translationTasks: TranslationTask[] = [];\n\n for (const targetUnmergedDictionary of dictionariesToProcess) {\n const dictionaryPreset = colon(\n [\n ' - ',\n colorize('[', ANSIColors.GREY_DARK),\n colorizeKey(targetUnmergedDictionary.key),\n colorize(']', ANSIColors.GREY_DARK),\n ].join(''),\n { colSize: maxKeyLength + 6 }\n );\n\n const dictionaryKey = targetUnmergedDictionary.key;\n const dictionaryLocalId = targetUnmergedDictionary.localId!;\n const mainDictionaryToProcess: Dictionary =\n mergedDictionariesRecord[dictionaryKey];\n const dictionaryFilled = targetUnmergedDictionary.filled ?? false;\n\n if (dictionaryFilled === true) {\n continue;\n }\n\n const dictionaryFill =\n targetUnmergedDictionary.fill ?? configuration.dictionary?.fill ?? false;\n\n if (dictionaryFill === false) continue;\n\n const sourceLocale: Locale = (targetUnmergedDictionary.locale ??\n baseLocale) as Locale;\n\n if (!mainDictionaryToProcess) {\n appLogger(\n `${dictionaryPreset} Dictionary not found in dictionariesRecord. Skipping.`,\n {\n level: 'warn',\n }\n );\n continue;\n }\n\n if (!targetUnmergedDictionary.filePath) {\n appLogger(`${dictionaryPreset} Dictionary has no file path. Skipping.`, {\n level: 'warn',\n });\n continue;\n }\n\n const sourceLocaleContent = getFilterTranslationsOnlyDictionary(\n mainDictionaryToProcess,\n sourceLocale\n );\n\n if (\n Object.keys(sourceLocaleContent as Record<string, unknown>).length === 0\n ) {\n appLogger(\n `${dictionaryPreset} No content found for dictionary in source locale ${formatLocale(sourceLocale)}. Skipping translation for this dictionary.`,\n {\n level: 'warn',\n }\n );\n continue;\n }\n\n /**\n * In 'complete' mode, filter only the missing locales to translate\n *\n * Skip the dictionary if there are no missing locales to translate\n */\n let outputLocalesList: Locale[] = outputLocales as Locale[];\n\n if (mode === 'complete') {\n outputLocalesList =\n missingTranslations\n .find(\n (missingTranslation) => missingTranslation.key === dictionaryKey\n )\n ?.locales.filter((locale) => outputLocales.includes(locale)) ?? [];\n }\n\n if (outputLocalesList.length === 0) {\n appLogger(\n `${dictionaryPreset} ${colorize('No locales to fill, Skipping', ANSIColors.GREY_DARK)} ${colorizePath(basename(targetUnmergedDictionary.filePath))}`,\n {\n level: 'warn',\n }\n );\n continue;\n }\n\n translationTasks.push({\n dictionaryKey,\n dictionaryLocalId,\n sourceLocale,\n targetLocales: outputLocalesList,\n dictionaryPreset,\n dictionaryFilePath: targetUnmergedDictionary.filePath,\n });\n }\n\n // Return the list of tasks to execute\n return translationTasks;\n};\n"],"mappings":"kYA2BA,MAAa,GACX,EACA,EACA,EACA,EACA,IACsB,CACtB,IAAM,GAAA,EAAA,EAAA,cAAyB,EAAc,CAEvC,GAAA,EAAA,EAAA,iBAA2C,EAAc,CACzD,GAAA,EAAA,EAAA,yBAAqD,EAAc,CAGnE,EADsB,OAAO,OAAO,EAA2B,CAAC,MAAM,CAC1B,OAAQ,GACxD,EAAS,SAAS,EAAW,QAAS,CACvC,CAEK,CAAE,uBACNA,EAAAA,kCAAkC,EAAc,CAE5C,EAAe,KAAK,IACxB,GAAG,EAAsB,IAAK,GAAe,EAAW,IAAI,OAAO,CACpE,CAEK,EAAsC,EAAE,CAE9C,IAAK,IAAM,KAA4B,EAAuB,CAC5D,IAAM,GAAA,EAAA,EAAA,OACJ,CACE,qBACS,IAAKC,EAAAA,WAAW,UAAU,mBACvB,EAAyB,IAAI,gBAChC,IAAKA,EAAAA,WAAW,UAAU,CACpC,CAAC,KAAK,GAAG,CACV,CAAE,QAAS,EAAe,EAAG,CAC9B,CAEK,EAAgB,EAAyB,IACzC,EAAoB,EAAyB,QAC7C,EACJ,EAAyB,GAU3B,IATyB,EAAyB,QAAU,MAEnC,KAKvB,EAAyB,MAAQ,EAAc,YAAY,MAAQ,MAE9C,GAAO,SAE9B,IAAM,EAAwB,EAAyB,QACrD,EAEF,GAAI,CAAC,EAAyB,CAC5B,EACE,GAAG,EAAiB,wDACpB,CACE,MAAO,OACR,CACF,CACD,SAGF,GAAI,CAAC,EAAyB,SAAU,CACtC,EAAU,GAAG,EAAiB,yCAA0C,CACtE,MAAO,OACR,CAAC,CACF,SAGF,IAAM,GAAA,EAAA,EAAA,qCACJ,EACA,EACD,CAED,GACE,OAAO,KAAK,EAA+C,CAAC,SAAW,EACvE,CACA,EACE,GAAG,EAAiB,qDAAA,EAAA,EAAA,cAAiE,EAAa,CAAC,6CACnG,CACE,MAAO,OACR,CACF,CACD,SAQF,IAAI,EAA8B,EAWlC,GATI,IAAS,aACX,EACE,EACG,KACE,GAAuB,EAAmB,MAAQ,EACpD,EACC,QAAQ,OAAQ,GAAW,EAAc,SAAS,EAAO,CAAC,EAAI,EAAE,EAGpE,EAAkB,SAAW,EAAG,CAClC,EACE,GAAG,EAAiB,IAAA,EAAA,EAAA,UAAY,+BAAgCA,EAAAA,WAAW,UAAU,CAAC,IAAA,EAAA,EAAA,eAAA,EAAA,EAAA,UAAyB,EAAyB,SAAS,CAAC,GAClJ,CACE,MAAO,OACR,CACF,CACD,SAGF,EAAiB,KAAK,CACpB,gBACA,oBACA,eACA,cAAe,EACf,mBACA,mBAAoB,EAAyB,SAC9C,CAAC,CAIJ,OAAO"}
@@ -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/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;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-Bmb41Sf3.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 +1 @@
1
- {"version":3,"file":"translateDictionary.cjs","names":["getFilterMissingContentPerLocale","ANSIColors","deepMergeContent"],"sources":["../../../src/fill/translateDictionary.ts"],"sourcesContent":["import { basename } from 'node:path';\nimport type { AIConfig } from '@intlayer/ai';\nimport { type AIOptions, getIntlayerAPIProxy } from '@intlayer/api';\nimport {\n chunkJSON,\n formatLocale,\n type JsonChunk,\n mergeChunks,\n reconstructFromSingleChunk,\n reduceObjectFormat,\n verifyIdenticObjectFormat,\n} from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colon,\n colorize,\n colorizeNumber,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport { retryManager } from '@intlayer/config/utils';\nimport {\n getFilterMissingTranslationsDictionary,\n getMultilingualDictionary,\n getPerLocaleDictionary,\n insertContentInDictionary,\n} from '@intlayer/core/plugins';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport type { AIClient } from '../utils/setupAI';\nimport { deepMergeContent } from './deepMergeContent';\nimport { getFilterMissingContentPerLocale } from './getFilterMissingContentPerLocale';\nimport type { TranslationTask } from './listTranslationsTasks';\n\ntype TranslateDictionaryResult = TranslationTask & {\n dictionaryOutput: Dictionary | null;\n};\n\ntype TranslateDictionaryOptions = {\n mode: 'complete' | 'review';\n aiOptions?: AIOptions;\n fillMetadata?: boolean;\n onHandle?: ReturnType<\n typeof import('@intlayer/chokidar/utils').getGlobalLimiter\n >;\n onSuccess?: () => void;\n onError?: (error: unknown) => void;\n getAbortError?: () => Error | null;\n aiClient?: AIClient;\n aiConfig?: AIConfig;\n};\n\nconst hasMissingMetadata = (dictionary: Dictionary) =>\n !dictionary.description || !dictionary.title || !dictionary.tags;\n\n/**\n * Recursively strips null values from an object, returning the cleaned content\n * and a separate object containing only the null-valued paths so they can be\n * re-injected after AI translation (nulls don't need translation).\n */\nconst stripNullValues = (\n obj: any\n): { content: any; nulls: any; hasNulls: boolean } => {\n if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {\n return { content: obj, nulls: undefined, hasNulls: false };\n }\n\n const content: any = {};\n const nulls: any = {};\n let hasNulls = false;\n\n for (const [key, value] of Object.entries(obj)) {\n if (value === null) {\n nulls[key] = null;\n hasNulls = true;\n } else {\n const child = stripNullValues(value);\n content[key] = child.content;\n if (child.hasNulls) {\n nulls[key] = child.nulls;\n hasNulls = true;\n }\n }\n }\n\n return { content, nulls: hasNulls ? nulls : undefined, hasNulls };\n};\n\nconst CHUNK_SIZE = 7000; // GPT-5 Mini safe input size\nconst GROUP_MAX_RETRY = 2;\nconst MAX_RETRY = 3;\nconst RETRY_DELAY = 1000 * 10; // 10 seconds\n\nconst MAX_FOLLOWING_ERRORS = 10; // 10 errors in a row, hard exit the process\nlet followingErrors = 0;\n\nexport const translateDictionary = async (\n task: TranslationTask,\n configuration: IntlayerConfig,\n options?: TranslateDictionaryOptions\n): Promise<TranslateDictionaryResult> => {\n const appLogger = getAppLogger(configuration);\n const intlayerAPI = getIntlayerAPIProxy(undefined, configuration);\n\n const { mode, aiOptions, fillMetadata, aiClient, aiConfig } = {\n mode: 'complete',\n fillMetadata: true,\n ...options,\n } as const;\n\n const notifySuccess = () => {\n followingErrors = 0;\n options?.onSuccess?.();\n };\n\n const result = await retryManager(\n async () => {\n const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);\n\n const baseUnmergedDictionary: Dictionary | undefined =\n unmergedDictionariesRecord[task.dictionaryKey].find(\n (dict) => dict.localId === task.dictionaryLocalId\n );\n\n if (!baseUnmergedDictionary) {\n appLogger(\n `${task.dictionaryPreset}Dictionary not found in unmergedDictionariesRecord. Skipping.`,\n {\n level: 'warn',\n }\n );\n return { ...task, dictionaryOutput: null };\n }\n\n let metadata:\n | Pick<Dictionary, 'description' | 'title' | 'tags'>\n | undefined;\n\n if (\n fillMetadata &&\n (hasMissingMetadata(baseUnmergedDictionary) || mode === 'review')\n ) {\n const defaultLocaleDictionary = getPerLocaleDictionary(\n baseUnmergedDictionary,\n configuration.internationalization.defaultLocale\n );\n\n appLogger(\n `${task.dictionaryPreset} Filling missing metadata for ${colorizePath(basename(baseUnmergedDictionary.filePath!))}`,\n {\n level: 'info',\n }\n );\n\n const runAudit = async () => {\n if (aiClient && aiConfig) {\n const result = await aiClient.auditDictionaryMetadata({\n fileContent: JSON.stringify(defaultLocaleDictionary),\n aiConfig,\n });\n\n return {\n data: result,\n };\n }\n\n return await intlayerAPI.ai.auditContentDeclarationMetadata({\n fileContent: JSON.stringify(defaultLocaleDictionary),\n aiOptions,\n });\n };\n\n const metadataResult = options?.onHandle\n ? await options.onHandle(runAudit)\n : await runAudit();\n\n metadata = metadataResult.data?.fileContent;\n }\n\n const translatedContentResults = await Promise.all(\n task.targetLocales.map(async (targetLocale) => {\n /**\n * In complete mode, for large dictionaries, we want to filter all content that is already translated\n *\n * targetLocale: fr\n *\n * { test1: t({ ar: 'Hello', en: 'Hello', fr: 'Bonjour' } }) -> {}\n * { test2: t({ ar: 'Hello', en: 'Hello' }) } -> { test2: t({ ar: 'Hello', en: 'Hello' }) }\n *\n */\n // Reset to base dictionary for each locale to ensure we filter from the original\n let dictionaryToProcess = structuredClone(baseUnmergedDictionary);\n\n let targetLocaleDictionary: Dictionary;\n\n if (typeof baseUnmergedDictionary.locale === 'string') {\n // For per-locale files, the content is already in simple JSON format (not translation nodes)\n // The base dictionary is already the source locale content\n\n // Load the existing target locale dictionary\n const targetLocaleFilePath =\n baseUnmergedDictionary.filePath?.replace(\n new RegExp(`/${task.sourceLocale}/`, 'g'),\n `/${targetLocale}/`\n );\n\n // Find the target locale dictionary in unmerged dictionaries\n const targetUnmergedDictionary = targetLocaleFilePath\n ? unmergedDictionariesRecord[task.dictionaryKey]?.find(\n (dict) =>\n dict.filePath === targetLocaleFilePath &&\n dict.locale === targetLocale\n )\n : undefined;\n\n targetLocaleDictionary = targetUnmergedDictionary ?? {\n key: baseUnmergedDictionary.key,\n content: {},\n filePath: targetLocaleFilePath,\n locale: targetLocale,\n };\n\n // In complete mode, filter out already translated content\n if (mode === 'complete') {\n dictionaryToProcess = getFilterMissingContentPerLocale(\n dictionaryToProcess,\n targetUnmergedDictionary\n );\n }\n } else {\n // For multilingual dictionaries\n if (mode === 'complete') {\n // Remove all nodes that don't have any content to translate\n dictionaryToProcess = getFilterMissingTranslationsDictionary(\n dictionaryToProcess,\n targetLocale\n );\n }\n\n dictionaryToProcess = getPerLocaleDictionary(\n dictionaryToProcess,\n task.sourceLocale\n );\n\n targetLocaleDictionary = getPerLocaleDictionary(\n baseUnmergedDictionary,\n targetLocale\n );\n }\n\n const localePreset = colon(\n [\n colorize('[', ANSIColors.GREY_DARK),\n formatLocale(targetLocale),\n colorize(']', ANSIColors.GREY_DARK),\n ].join(''),\n { colSize: 18 }\n );\n\n const createChunkPreset = (\n chunkIndex: number,\n totalChunks: number\n ) => {\n if (totalChunks <= 1) return '';\n return colon(\n [\n colorize('[', ANSIColors.GREY_DARK),\n colorizeNumber(chunkIndex + 1),\n colorize(`/${totalChunks}`, ANSIColors.GREY_DARK),\n colorize(']', ANSIColors.GREY_DARK),\n ].join(''),\n { colSize: 5 }\n );\n };\n\n appLogger(\n `${task.dictionaryPreset}${localePreset} Preparing ${colorizePath(basename(targetLocaleDictionary.filePath!))}`,\n {\n level: 'info',\n }\n );\n\n const isContentStructured =\n (typeof dictionaryToProcess.content === 'object' &&\n dictionaryToProcess.content !== null) ||\n Array.isArray(dictionaryToProcess.content);\n\n const rawContentToProcess = isContentStructured\n ? dictionaryToProcess.content\n : {\n __INTLAYER_ROOT_PRIMITIVE_CONTENT__:\n dictionaryToProcess.content,\n };\n\n // Strip null values before sending to AI — nulls need no translation\n // and confuse the model. They will be re-injected after merging.\n const { content: contentToProcess, nulls: strippedNullValues } =\n stripNullValues(rawContentToProcess);\n\n const chunkedJsonContent: JsonChunk[] = chunkJSON(\n contentToProcess as unknown as Record<string, any>,\n CHUNK_SIZE\n );\n\n const nbOfChunks = chunkedJsonContent.length;\n\n if (nbOfChunks > 1) {\n appLogger(\n `${task.dictionaryPreset}${localePreset} Split into ${colorizeNumber(nbOfChunks)} chunks for translation`,\n {\n level: 'info',\n }\n );\n }\n\n const chunkResult: JsonChunk[] = [];\n\n // Process chunks in parallel (globally throttled) to allow concurrent translation\n const chunkPromises = chunkedJsonContent.map((chunk) => {\n const chunkPreset = createChunkPreset(chunk.index, chunk.total);\n\n if (nbOfChunks > 1) {\n appLogger(\n `${task.dictionaryPreset}${localePreset}${chunkPreset} Translating chunk`,\n {\n level: 'info',\n }\n );\n }\n\n // Reconstruct partial JSON content from this chunk's patches\n const chunkContent = reconstructFromSingleChunk(chunk);\n const presetOutputContent = reduceObjectFormat(\n isContentStructured\n ? targetLocaleDictionary.content\n : {\n __INTLAYER_ROOT_PRIMITIVE_CONTENT__:\n targetLocaleDictionary.content,\n },\n chunkContent\n ) as unknown as JSON;\n\n const executeTranslation = async () => {\n return await retryManager(\n async () => {\n let translationResult: any;\n\n if (aiClient && aiConfig) {\n translationResult = await aiClient.translateJSON({\n entryFileContent: chunkContent as unknown as JSON,\n presetOutputContent,\n dictionaryDescription:\n dictionaryToProcess.description ??\n metadata?.description ??\n '',\n entryLocale: task.sourceLocale,\n outputLocale: targetLocale,\n mode,\n aiConfig,\n });\n } else {\n translationResult = await intlayerAPI.ai\n .translateJSON({\n entryFileContent: chunkContent as unknown as JSON,\n presetOutputContent,\n dictionaryDescription:\n dictionaryToProcess.description ??\n metadata?.description ??\n '',\n entryLocale: task.sourceLocale,\n outputLocale: targetLocale,\n mode,\n aiOptions,\n })\n .then((result) => result.data);\n }\n\n if (!translationResult?.fileContent) {\n throw new Error('No content result');\n }\n\n const { isIdentic } = verifyIdenticObjectFormat(\n translationResult.fileContent,\n chunkContent\n );\n\n if (!isIdentic) {\n throw new Error(\n 'Translation result does not match expected format'\n );\n }\n\n notifySuccess();\n return translationResult.fileContent;\n },\n {\n maxRetry: MAX_RETRY,\n delay: RETRY_DELAY,\n onError: ({ error, attempt, maxRetry }) => {\n const chunkPreset = createChunkPreset(\n chunk.index,\n chunk.total\n );\n appLogger(\n `${task.dictionaryPreset}${localePreset}${chunkPreset} ${colorize('Error filling:', ANSIColors.RED)} ${colorize(typeof error === 'string' ? error : JSON.stringify(error), ANSIColors.GREY_DARK)} - Attempt ${colorizeNumber(attempt + 1)} of ${colorizeNumber(maxRetry)}`,\n {\n level: 'error',\n }\n );\n\n followingErrors += 1;\n\n if (followingErrors >= MAX_FOLLOWING_ERRORS) {\n appLogger(`There is something wrong.`, {\n level: 'error',\n });\n process.exit(1); // 1 for error\n }\n },\n }\n )();\n };\n\n const wrapped = options?.onHandle\n ? options.onHandle(executeTranslation) // queued in global limiter\n : executeTranslation(); // no global limiter\n\n return wrapped.then((result) => ({ chunk, result }));\n });\n\n // Wait for all chunks for this locale in parallel (still capped by global limiter)\n const chunkResults = await Promise.all(chunkPromises);\n\n // Maintain order\n chunkResults\n .sort((chunkA, chunkB) => chunkA.chunk.index - chunkB.chunk.index)\n .forEach(({ result }) => {\n chunkResult.push(result);\n });\n\n // Merge partial JSON objects produced from each chunk into a single object\n let mergedContent = mergeChunks(chunkResult);\n\n // Re-inject null values that were stripped before AI translation\n if (strippedNullValues) {\n mergedContent = deepMergeContent(mergedContent, strippedNullValues);\n }\n\n const merged = {\n ...dictionaryToProcess,\n content: mergedContent,\n };\n\n // For per-locale files, merge the newly translated content with existing target content\n let finalContent = merged.content;\n\n if (!isContentStructured) {\n finalContent = (finalContent as any)\n ?.__INTLAYER_ROOT_PRIMITIVE_CONTENT__;\n }\n\n if (typeof baseUnmergedDictionary.locale === 'string') {\n // Deep merge: existing content + newly translated content\n finalContent = deepMergeContent(\n targetLocaleDictionary.content ?? {},\n finalContent\n );\n }\n\n return [targetLocale, finalContent] as const;\n })\n );\n\n const translatedContent: Partial<Record<Locale, Dictionary['content']>> =\n Object.fromEntries(translatedContentResults);\n\n const baseDictionary = baseUnmergedDictionary.locale\n ? {\n ...baseUnmergedDictionary,\n key: baseUnmergedDictionary.key!,\n content: {},\n }\n : baseUnmergedDictionary;\n\n let dictionaryOutput: Dictionary = {\n ...getMultilingualDictionary(baseDictionary),\n locale: undefined, // Ensure the dictionary is multilingual\n ...metadata,\n };\n\n for (const targetLocale of task.targetLocales) {\n if (translatedContent[targetLocale]) {\n dictionaryOutput = insertContentInDictionary(\n dictionaryOutput,\n translatedContent[targetLocale],\n targetLocale\n );\n }\n }\n\n appLogger(\n `${task.dictionaryPreset} ${colorize('Translation completed successfully', ANSIColors.GREEN)} for ${colorizePath(basename(dictionaryOutput.filePath!))}`,\n {\n level: 'info',\n }\n );\n\n if (\n baseUnmergedDictionary.locale &&\n (baseUnmergedDictionary.fill === true ||\n baseUnmergedDictionary.fill === undefined) &&\n baseUnmergedDictionary.location === 'local'\n ) {\n const dictionaryFilePath = baseUnmergedDictionary\n .filePath!.split('.')\n .slice(0, -1);\n\n const contentIndex = dictionaryFilePath[dictionaryFilePath.length - 1];\n\n return JSON.parse(\n JSON.stringify({\n ...task,\n dictionaryOutput: {\n ...dictionaryOutput,\n fill: undefined,\n filled: true,\n },\n }).replaceAll(\n new RegExp(`\\\\.${contentIndex}\\\\.[a-zA-Z0-9]+`, 'g'),\n `.filled.${contentIndex}.json`\n )\n );\n }\n\n return {\n ...task,\n dictionaryOutput,\n };\n },\n {\n maxRetry: GROUP_MAX_RETRY,\n delay: RETRY_DELAY,\n onError: ({ error, attempt, maxRetry }) =>\n appLogger(\n `${task.dictionaryPreset} ${colorize('Error:', ANSIColors.RED)} ${colorize(typeof error === 'string' ? error : JSON.stringify(error), ANSIColors.GREY_DARK)} - Attempt ${colorizeNumber(attempt + 1)} of ${colorizeNumber(maxRetry)}`,\n {\n level: 'error',\n }\n ),\n onMaxTryReached: ({ error }) =>\n appLogger(\n `${task.dictionaryPreset} ${colorize('Maximum number of retries reached:', ANSIColors.RED)} ${colorize(typeof error === 'string' ? error : JSON.stringify(error), ANSIColors.GREY_DARK)}`,\n {\n level: 'error',\n }\n ),\n }\n )();\n\n return result as TranslateDictionaryResult;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"translateDictionary.cjs","names":["getFilterMissingContentPerLocale","ANSIColors","deepMergeContent"],"sources":["../../../src/fill/translateDictionary.ts"],"sourcesContent":["import { basename } from 'node:path';\nimport type { AIConfig } from '@intlayer/ai';\nimport { type AIOptions, getIntlayerAPIProxy } from '@intlayer/api';\nimport {\n chunkJSON,\n formatLocale,\n type JsonChunk,\n mergeChunks,\n reconstructFromSingleChunk,\n reduceObjectFormat,\n verifyIdenticObjectFormat,\n} from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colon,\n colorize,\n colorizeNumber,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport { retryManager } from '@intlayer/config/utils';\nimport {\n getFilterMissingTranslationsDictionary,\n getMultilingualDictionary,\n getPerLocaleDictionary,\n insertContentInDictionary,\n} from '@intlayer/core/plugins';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport type { AIClient } from '../utils/setupAI';\nimport { deepMergeContent } from './deepMergeContent';\nimport { getFilterMissingContentPerLocale } from './getFilterMissingContentPerLocale';\nimport type { TranslationTask } from './listTranslationsTasks';\n\ntype TranslateDictionaryResult = TranslationTask & {\n dictionaryOutput: Dictionary | null;\n};\n\ntype TranslateDictionaryOptions = {\n mode: 'complete' | 'review';\n aiOptions?: AIOptions;\n fillMetadata?: boolean;\n onHandle?: ReturnType<\n typeof import('@intlayer/chokidar/utils').getGlobalLimiter\n >;\n onSuccess?: () => void;\n onError?: (error: unknown) => void;\n getAbortError?: () => Error | null;\n aiClient?: AIClient;\n aiConfig?: AIConfig;\n};\n\nconst hasMissingMetadata = (dictionary: Dictionary) =>\n !dictionary.description || !dictionary.title || !dictionary.tags;\n\n/**\n * Recursively strips null values from an object, returning the cleaned content\n * and a separate object containing only the null-valued paths so they can be\n * re-injected after AI translation (nulls don't need translation).\n */\nconst stripNullValues = (\n obj: any\n): { content: any; nulls: any; hasNulls: boolean } => {\n if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {\n return { content: obj, nulls: undefined, hasNulls: false };\n }\n\n const content: any = {};\n const nulls: any = {};\n let hasNulls = false;\n\n for (const [key, value] of Object.entries(obj)) {\n if (value === null) {\n nulls[key] = null;\n hasNulls = true;\n } else {\n const child = stripNullValues(value);\n content[key] = child.content;\n if (child.hasNulls) {\n nulls[key] = child.nulls;\n hasNulls = true;\n }\n }\n }\n\n return { content, nulls: hasNulls ? nulls : undefined, hasNulls };\n};\n\nconst CHUNK_SIZE = 7000; // GPT-5 Mini safe input size\nconst GROUP_MAX_RETRY = 2;\nconst MAX_RETRY = 3;\nconst RETRY_DELAY = 1000 * 10; // 10 seconds\n\nconst MAX_FOLLOWING_ERRORS = 10; // 10 errors in a row, hard exit the process\nlet followingErrors = 0;\n\nexport const translateDictionary = async (\n task: TranslationTask,\n configuration: IntlayerConfig,\n options?: TranslateDictionaryOptions\n): Promise<TranslateDictionaryResult> => {\n const appLogger = getAppLogger(configuration);\n const intlayerAPI = getIntlayerAPIProxy(undefined, configuration);\n\n const { mode, aiOptions, fillMetadata, aiClient, aiConfig } = {\n mode: 'complete',\n fillMetadata: true,\n ...options,\n } as const;\n\n const notifySuccess = () => {\n followingErrors = 0;\n options?.onSuccess?.();\n };\n\n const result = await retryManager(\n async () => {\n const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);\n\n const baseUnmergedDictionary: Dictionary | undefined =\n unmergedDictionariesRecord[task.dictionaryKey].find(\n (dict) => dict.localId === task.dictionaryLocalId\n );\n\n if (!baseUnmergedDictionary) {\n appLogger(\n `${task.dictionaryPreset}Dictionary not found in unmergedDictionariesRecord. Skipping.`,\n {\n level: 'warn',\n }\n );\n return { ...task, dictionaryOutput: null };\n }\n\n let metadata:\n | Pick<Dictionary, 'description' | 'title' | 'tags'>\n | undefined;\n\n if (\n fillMetadata &&\n (hasMissingMetadata(baseUnmergedDictionary) || mode === 'review')\n ) {\n const defaultLocaleDictionary = getPerLocaleDictionary(\n baseUnmergedDictionary,\n configuration.internationalization.defaultLocale\n );\n\n appLogger(\n `${task.dictionaryPreset} Filling missing metadata for ${colorizePath(basename(baseUnmergedDictionary.filePath!))}`,\n {\n level: 'info',\n }\n );\n\n const runAudit = async () => {\n if (aiClient && aiConfig) {\n const result = await aiClient.auditDictionaryMetadata({\n fileContent: JSON.stringify(defaultLocaleDictionary),\n aiConfig,\n });\n\n return {\n data: result,\n };\n }\n\n return await intlayerAPI.ai.auditContentDeclarationMetadata({\n fileContent: JSON.stringify(defaultLocaleDictionary),\n aiOptions,\n });\n };\n\n const metadataResult = options?.onHandle\n ? await options.onHandle(runAudit)\n : await runAudit();\n\n metadata = metadataResult.data?.fileContent;\n }\n\n const translatedContentResults = await Promise.all(\n task.targetLocales.map(async (targetLocale) => {\n /**\n * In complete mode, for large dictionaries, we want to filter all content that is already translated\n *\n * targetLocale: fr\n *\n * { test1: t({ ar: 'Hello', en: 'Hello', fr: 'Bonjour' } }) -> {}\n * { test2: t({ ar: 'Hello', en: 'Hello' }) } -> { test2: t({ ar: 'Hello', en: 'Hello' }) }\n *\n */\n // Reset to base dictionary for each locale to ensure we filter from the original\n let dictionaryToProcess = structuredClone(baseUnmergedDictionary);\n\n let targetLocaleDictionary: Dictionary;\n\n if (typeof baseUnmergedDictionary.locale === 'string') {\n // For per-locale files, the content is already in simple JSON format (not translation nodes)\n // The base dictionary is already the source locale content\n\n // Load the existing target locale dictionary\n const targetLocaleFilePath =\n baseUnmergedDictionary.filePath?.replace(\n new RegExp(`/${task.sourceLocale}/`, 'g'),\n `/${targetLocale}/`\n );\n\n // Find the target locale dictionary in unmerged dictionaries\n const targetUnmergedDictionary = targetLocaleFilePath\n ? unmergedDictionariesRecord[task.dictionaryKey]?.find(\n (dict) =>\n dict.filePath === targetLocaleFilePath &&\n dict.locale === targetLocale\n )\n : undefined;\n\n targetLocaleDictionary = targetUnmergedDictionary ?? {\n key: baseUnmergedDictionary.key,\n content: {},\n filePath: targetLocaleFilePath,\n locale: targetLocale,\n };\n\n // In complete mode, filter out already translated content\n if (mode === 'complete') {\n dictionaryToProcess = getFilterMissingContentPerLocale(\n dictionaryToProcess,\n targetUnmergedDictionary\n );\n }\n } else {\n // For multilingual dictionaries\n if (mode === 'complete') {\n // Remove all nodes that don't have any content to translate\n dictionaryToProcess = getFilterMissingTranslationsDictionary(\n dictionaryToProcess,\n targetLocale\n );\n }\n\n dictionaryToProcess = getPerLocaleDictionary(\n dictionaryToProcess,\n task.sourceLocale\n );\n\n targetLocaleDictionary = getPerLocaleDictionary(\n baseUnmergedDictionary,\n targetLocale\n );\n }\n\n const localePreset = colon(\n [\n colorize('[', ANSIColors.GREY_DARK),\n formatLocale(targetLocale),\n colorize(']', ANSIColors.GREY_DARK),\n ].join(''),\n { colSize: 18 }\n );\n\n const createChunkPreset = (\n chunkIndex: number,\n totalChunks: number\n ) => {\n if (totalChunks <= 1) return '';\n return colon(\n [\n colorize('[', ANSIColors.GREY_DARK),\n colorizeNumber(chunkIndex + 1),\n colorize(`/${totalChunks}`, ANSIColors.GREY_DARK),\n colorize(']', ANSIColors.GREY_DARK),\n ].join(''),\n { colSize: 5 }\n );\n };\n\n appLogger(\n `${task.dictionaryPreset}${localePreset} Preparing ${colorizePath(basename(targetLocaleDictionary.filePath!))}`,\n {\n level: 'info',\n }\n );\n\n const isContentStructured =\n (typeof dictionaryToProcess.content === 'object' &&\n dictionaryToProcess.content !== null) ||\n Array.isArray(dictionaryToProcess.content);\n\n const rawContentToProcess = isContentStructured\n ? dictionaryToProcess.content\n : {\n __INTLAYER_ROOT_PRIMITIVE_CONTENT__:\n dictionaryToProcess.content,\n };\n\n // Strip null values before sending to AI — nulls need no translation\n // and confuse the model. They will be re-injected after merging.\n const { content: contentToProcess, nulls: strippedNullValues } =\n stripNullValues(rawContentToProcess);\n\n const chunkedJsonContent: JsonChunk[] = chunkJSON(\n contentToProcess as unknown as Record<string, any>,\n CHUNK_SIZE\n );\n\n const nbOfChunks = chunkedJsonContent.length;\n\n if (nbOfChunks > 1) {\n appLogger(\n `${task.dictionaryPreset}${localePreset} Split into ${colorizeNumber(nbOfChunks)} chunks for translation`,\n {\n level: 'info',\n }\n );\n }\n\n const chunkResult: JsonChunk[] = [];\n\n // Process chunks in parallel (globally throttled) to allow concurrent translation\n const chunkPromises = chunkedJsonContent.map((chunk) => {\n const chunkPreset = createChunkPreset(chunk.index, chunk.total);\n\n if (nbOfChunks > 1) {\n appLogger(\n `${task.dictionaryPreset}${localePreset}${chunkPreset} Translating chunk`,\n {\n level: 'info',\n }\n );\n }\n\n // Reconstruct partial JSON content from this chunk's patches\n const chunkContent = reconstructFromSingleChunk(chunk);\n const presetOutputContent = reduceObjectFormat(\n isContentStructured\n ? targetLocaleDictionary.content\n : {\n __INTLAYER_ROOT_PRIMITIVE_CONTENT__:\n targetLocaleDictionary.content,\n },\n chunkContent\n ) as unknown as JSON;\n\n const executeTranslation = async () => {\n return await retryManager(\n async () => {\n let translationResult: any;\n\n if (aiClient && aiConfig) {\n translationResult = await aiClient.translateJSON({\n entryFileContent: chunkContent as unknown as JSON,\n presetOutputContent,\n dictionaryDescription:\n dictionaryToProcess.description ??\n metadata?.description ??\n '',\n entryLocale: task.sourceLocale,\n outputLocale: targetLocale,\n mode,\n aiConfig,\n });\n } else {\n translationResult = await intlayerAPI.ai\n .translateJSON({\n entryFileContent: chunkContent as unknown as JSON,\n presetOutputContent,\n dictionaryDescription:\n dictionaryToProcess.description ??\n metadata?.description ??\n '',\n entryLocale: task.sourceLocale,\n outputLocale: targetLocale,\n mode,\n aiOptions,\n })\n .then((result) => result.data);\n }\n\n if (!translationResult?.fileContent) {\n throw new Error('No content result');\n }\n\n const { isIdentic } = verifyIdenticObjectFormat(\n translationResult.fileContent,\n chunkContent\n );\n\n if (!isIdentic) {\n throw new Error(\n 'Translation result does not match expected format'\n );\n }\n\n notifySuccess();\n return translationResult.fileContent;\n },\n {\n maxRetry: MAX_RETRY,\n delay: RETRY_DELAY,\n onError: ({ error, attempt, maxRetry }) => {\n const chunkPreset = createChunkPreset(\n chunk.index,\n chunk.total\n );\n appLogger(\n `${task.dictionaryPreset}${localePreset}${chunkPreset} ${colorize('Error filling:', ANSIColors.RED)} ${colorize(typeof error === 'string' ? error : JSON.stringify(error), ANSIColors.GREY_DARK)} - Attempt ${colorizeNumber(attempt + 1)} of ${colorizeNumber(maxRetry)}`,\n {\n level: 'error',\n }\n );\n\n followingErrors += 1;\n\n if (followingErrors >= MAX_FOLLOWING_ERRORS) {\n appLogger(`There is something wrong.`, {\n level: 'error',\n });\n process.exit(1); // 1 for error\n }\n },\n }\n )();\n };\n\n const wrapped = options?.onHandle\n ? options.onHandle(executeTranslation) // queued in global limiter\n : executeTranslation(); // no global limiter\n\n return wrapped.then((result) => ({ chunk, result }));\n });\n\n // Wait for all chunks for this locale in parallel (still capped by global limiter)\n const chunkResults = await Promise.all(chunkPromises);\n\n // Maintain order\n chunkResults\n .sort((chunkA, chunkB) => chunkA.chunk.index - chunkB.chunk.index)\n .forEach(({ result }) => {\n chunkResult.push(result);\n });\n\n // Merge partial JSON objects produced from each chunk into a single object\n let mergedContent = mergeChunks(chunkResult);\n\n // Re-inject null values that were stripped before AI translation\n if (strippedNullValues) {\n mergedContent = deepMergeContent(mergedContent, strippedNullValues);\n }\n\n const merged = {\n ...dictionaryToProcess,\n content: mergedContent,\n };\n\n // For per-locale files, merge the newly translated content with existing target content\n let finalContent = merged.content;\n\n if (!isContentStructured) {\n finalContent = (finalContent as any)\n ?.__INTLAYER_ROOT_PRIMITIVE_CONTENT__;\n }\n\n if (typeof baseUnmergedDictionary.locale === 'string') {\n // Deep merge: existing content + newly translated content\n finalContent = deepMergeContent(\n targetLocaleDictionary.content ?? {},\n finalContent\n );\n }\n\n return [targetLocale, finalContent] as const;\n })\n );\n\n const translatedContent: Partial<Record<Locale, Dictionary['content']>> =\n Object.fromEntries(translatedContentResults);\n\n const baseDictionary = baseUnmergedDictionary.locale\n ? {\n ...baseUnmergedDictionary,\n key: baseUnmergedDictionary.key!,\n content: {},\n }\n : baseUnmergedDictionary;\n\n let dictionaryOutput: Dictionary = {\n ...getMultilingualDictionary(baseDictionary),\n locale: undefined, // Ensure the dictionary is multilingual\n ...metadata,\n };\n\n for (const targetLocale of task.targetLocales) {\n if (translatedContent[targetLocale]) {\n dictionaryOutput = insertContentInDictionary(\n dictionaryOutput,\n translatedContent[targetLocale],\n targetLocale\n );\n }\n }\n\n appLogger(\n `${task.dictionaryPreset} ${colorize('Translation completed successfully', ANSIColors.GREEN)} for ${colorizePath(basename(dictionaryOutput.filePath!))}`,\n {\n level: 'info',\n }\n );\n\n if (\n baseUnmergedDictionary.locale &&\n (baseUnmergedDictionary.fill === true ||\n baseUnmergedDictionary.fill === undefined) &&\n baseUnmergedDictionary.location === 'local'\n ) {\n const dictionaryFilePath = baseUnmergedDictionary\n .filePath!.split('.')\n .slice(0, -1);\n\n const contentIndex = dictionaryFilePath[dictionaryFilePath.length - 1];\n\n return JSON.parse(\n JSON.stringify({\n ...task,\n dictionaryOutput: {\n ...dictionaryOutput,\n fill: undefined,\n filled: true,\n },\n }).replaceAll(\n new RegExp(`\\\\.${contentIndex}\\\\.[a-zA-Z0-9]+`, 'g'),\n `.filled.${contentIndex}.json`\n )\n );\n }\n\n return {\n ...task,\n dictionaryOutput,\n };\n },\n {\n maxRetry: GROUP_MAX_RETRY,\n delay: RETRY_DELAY,\n onError: ({ error, attempt, maxRetry }) =>\n appLogger(\n `${task.dictionaryPreset} ${colorize('Error:', ANSIColors.RED)} ${colorize(typeof error === 'string' ? error : JSON.stringify(error), ANSIColors.GREY_DARK)} - Attempt ${colorizeNumber(attempt + 1)} of ${colorizeNumber(maxRetry)}`,\n {\n level: 'error',\n }\n ),\n onMaxTryReached: ({ error }) =>\n appLogger(\n `${task.dictionaryPreset} ${colorize('Maximum number of retries reached:', ANSIColors.RED)} ${colorize(typeof error === 'string' ? error : JSON.stringify(error), ANSIColors.GREY_DARK)}`,\n {\n level: 'error',\n }\n ),\n }\n )();\n\n return result as TranslateDictionaryResult;\n};\n"],"mappings":"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"}
@@ -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/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;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-Bmb41Sf3.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 +1 @@
1
- {"version":3,"file":"writeFill.cjs","names":["getAvailableLocalesInDictionary","formatFillData"],"sources":["../../../src/fill/writeFill.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport { writeContentDeclaration } from '@intlayer/chokidar/build';\nimport { formatLocale, formatPath } from '@intlayer/chokidar/utils';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary, Fill } from '@intlayer/types/dictionary';\nimport { type FillData, formatFillData } from './formatFillData';\nimport { getAvailableLocalesInDictionary } from './getAvailableLocalesInDictionary';\n\nexport const writeFill = async (\n contentDeclarationFile: Dictionary,\n outputLocales: Locale[],\n parentLocales: Locale[],\n configuration: IntlayerConfig\n) => {\n const appLogger = getAppLogger(configuration);\n const dictionaries = getDictionaries(configuration);\n\n const fullDictionary = dictionaries[contentDeclarationFile.key];\n\n const { filePath } = contentDeclarationFile;\n\n if (!filePath) {\n appLogger('No file path found for dictionary', {\n level: 'error',\n });\n return;\n }\n\n const fillOptions: Fill | undefined =\n contentDeclarationFile.fill ?? configuration.dictionary?.fill ?? true;\n\n if ((fillOptions as boolean) === false) {\n appLogger(\n `Auto fill is disabled for '${colorizeKey(fullDictionary.key)}'`,\n {\n level: 'info',\n }\n );\n return;\n }\n\n const requestedLocales: Locale[] = (\n outputLocales ?? configuration.internationalization.locales\n ).filter((locale) => !parentLocales?.includes(locale));\n\n // Get locales that actually have translations in the content\n const availableLocales = getAvailableLocalesInDictionary(\n contentDeclarationFile\n );\n\n // Only write files for locales that have actual translations\n const localeList = requestedLocales.filter((locale) =>\n availableLocales.includes(locale)\n );\n\n if (localeList.length === 0) {\n appLogger(\n `No translations available for dictionary '${colorizeKey(fullDictionary.key)}'`,\n {\n level: 'info',\n }\n );\n return;\n }\n\n const fillData: FillData[] = await formatFillData(\n fillOptions as Fill,\n localeList,\n filePath,\n fullDictionary.key,\n configuration\n );\n\n for await (const output of fillData) {\n if (!output.filePath) {\n appLogger(\n `No file path found for auto filled content declaration for '${colorizeKey(fullDictionary.key)}'`,\n {\n level: 'error',\n }\n );\n continue;\n }\n\n const { fill, ...rest } = contentDeclarationFile;\n\n const relativeFilePath = relative(\n configuration.system.baseDir,\n output.filePath\n );\n\n // write file\n await writeContentDeclaration(\n {\n ...rest,\n filled: true,\n locale: output.isPerLocale ? output.localeList[0] : undefined,\n localId: `${contentDeclarationFile.key}::local::${relativeFilePath}`,\n filePath: relativeFilePath,\n },\n configuration,\n {\n localeList: output.localeList,\n }\n );\n\n if (output.isPerLocale) {\n const sourceLocale = output.localeList[0];\n\n appLogger(\n `Auto filled per-locale content declaration for '${colorizeKey(fullDictionary.key)}' written to ${formatPath(output.filePath)} for locale ${formatLocale(sourceLocale)}`,\n {\n level: 'info',\n }\n );\n } else {\n appLogger(\n `Auto filled content declaration for '${colorizeKey(fullDictionary.key)}' written to ${formatPath(output.filePath)}`,\n {\n level: 'info',\n }\n );\n }\n }\n};\n"],"mappings":"iYAWA,MAAa,EAAY,MACvB,EACA,EACA,EACA,IACG,CACH,IAAM,GAAA,EAAA,EAAA,cAAyB,EAAc,CAGvC,GAAA,EAAA,EAAA,iBAF+B,EAAc,CAEf,EAAuB,KAErD,CAAE,YAAa,EAErB,GAAI,CAAC,EAAU,CACb,EAAU,oCAAqC,CAC7C,MAAO,QACR,CAAC,CACF,OAGF,IAAM,EACJ,EAAuB,MAAQ,EAAc,YAAY,MAAQ,GAEnE,GAAK,IAA4B,GAAO,CACtC,EACE,+BAAA,EAAA,EAAA,aAA0C,EAAe,IAAI,CAAC,GAC9D,CACE,MAAO,OACR,CACF,CACD,OAGF,IAAM,GACJ,GAAiB,EAAc,qBAAqB,SACpD,OAAQ,GAAW,CAAC,GAAe,SAAS,EAAO,CAAC,CAGhD,EAAmBA,EAAAA,gCACvB,EACD,CAGK,EAAa,EAAiB,OAAQ,GAC1C,EAAiB,SAAS,EAAO,CAClC,CAED,GAAI,EAAW,SAAW,EAAG,CAC3B,EACE,8CAAA,EAAA,EAAA,aAAyD,EAAe,IAAI,CAAC,GAC7E,CACE,MAAO,OACR,CACF,CACD,OAGF,IAAM,EAAuB,MAAMC,EAAAA,eACjC,EACA,EACA,EACA,EAAe,IACf,EACD,CAED,UAAW,IAAM,KAAU,EAAU,CACnC,GAAI,CAAC,EAAO,SAAU,CACpB,EACE,gEAAA,EAAA,EAAA,aAA2E,EAAe,IAAI,CAAC,GAC/F,CACE,MAAO,QACR,CACF,CACD,SAGF,GAAM,CAAE,OAAM,GAAG,GAAS,EAEpB,GAAA,EAAA,EAAA,UACJ,EAAc,OAAO,QACrB,EAAO,SACR,CAiBD,GAdA,MAAA,EAAA,EAAA,yBACE,CACE,GAAG,EACH,OAAQ,GACR,OAAQ,EAAO,YAAc,EAAO,WAAW,GAAK,IAAA,GACpD,QAAS,GAAG,EAAuB,IAAI,WAAW,IAClD,SAAU,EACX,CACD,EACA,CACE,WAAY,EAAO,WACpB,CACF,CAEG,EAAO,YAAa,CACtB,IAAM,EAAe,EAAO,WAAW,GAEvC,EACE,oDAAA,EAAA,EAAA,aAA+D,EAAe,IAAI,CAAC,gBAAA,EAAA,EAAA,YAA0B,EAAO,SAAS,CAAC,eAAA,EAAA,EAAA,cAA2B,EAAa,GACtK,CACE,MAAO,OACR,CACF,MAED,EACE,yCAAA,EAAA,EAAA,aAAoD,EAAe,IAAI,CAAC,gBAAA,EAAA,EAAA,YAA0B,EAAO,SAAS,GAClH,CACE,MAAO,OACR,CACF"}
1
+ {"version":3,"file":"writeFill.cjs","names":["getAvailableLocalesInDictionary","formatFillData"],"sources":["../../../src/fill/writeFill.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport { writeContentDeclaration } from '@intlayer/chokidar/build';\nimport { formatLocale, formatPath } from '@intlayer/chokidar/utils';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary, Fill } from '@intlayer/types/dictionary';\nimport { type FillData, formatFillData } from './formatFillData';\nimport { getAvailableLocalesInDictionary } from './getAvailableLocalesInDictionary';\n\nexport const writeFill = async (\n contentDeclarationFile: Dictionary,\n outputLocales: Locale[],\n parentLocales: Locale[],\n configuration: IntlayerConfig\n) => {\n const appLogger = getAppLogger(configuration);\n const dictionaries = getDictionaries(configuration);\n\n const fullDictionary = dictionaries[contentDeclarationFile.key];\n\n const { filePath } = contentDeclarationFile;\n\n if (!filePath) {\n appLogger('No file path found for dictionary', {\n level: 'error',\n });\n return;\n }\n\n const fillOptions: Fill | undefined =\n contentDeclarationFile.fill ?? configuration.dictionary?.fill ?? true;\n\n if ((fillOptions as boolean) === false) {\n appLogger(\n `Auto fill is disabled for '${colorizeKey(fullDictionary.key)}'`,\n {\n level: 'info',\n }\n );\n return;\n }\n\n const requestedLocales: Locale[] = (\n outputLocales ?? configuration.internationalization.locales\n ).filter((locale) => !parentLocales?.includes(locale));\n\n // Get locales that actually have translations in the content\n const availableLocales = getAvailableLocalesInDictionary(\n contentDeclarationFile\n );\n\n // Only write files for locales that have actual translations\n const localeList = requestedLocales.filter((locale) =>\n availableLocales.includes(locale)\n );\n\n if (localeList.length === 0) {\n appLogger(\n `No translations available for dictionary '${colorizeKey(fullDictionary.key)}'`,\n {\n level: 'info',\n }\n );\n return;\n }\n\n const fillData: FillData[] = await formatFillData(\n fillOptions as Fill,\n localeList,\n filePath,\n fullDictionary.key,\n configuration\n );\n\n for await (const output of fillData) {\n if (!output.filePath) {\n appLogger(\n `No file path found for auto filled content declaration for '${colorizeKey(fullDictionary.key)}'`,\n {\n level: 'error',\n }\n );\n continue;\n }\n\n const { fill, ...rest } = contentDeclarationFile;\n\n const relativeFilePath = relative(\n configuration.system.baseDir,\n output.filePath\n );\n\n // write file\n await writeContentDeclaration(\n {\n ...rest,\n filled: true,\n locale: output.isPerLocale ? output.localeList[0] : undefined,\n localId: `${contentDeclarationFile.key}::local::${relativeFilePath}`,\n filePath: relativeFilePath,\n },\n configuration,\n {\n localeList: output.localeList,\n }\n );\n\n if (output.isPerLocale) {\n const sourceLocale = output.localeList[0];\n\n appLogger(\n `Auto filled per-locale content declaration for '${colorizeKey(fullDictionary.key)}' written to ${formatPath(output.filePath)} for locale ${formatLocale(sourceLocale)}`,\n {\n level: 'info',\n }\n );\n } else {\n appLogger(\n `Auto filled content declaration for '${colorizeKey(fullDictionary.key)}' written to ${formatPath(output.filePath)}`,\n {\n level: 'info',\n }\n );\n }\n }\n};\n"],"mappings":"qXAWA,MAAa,EAAY,MACvB,EACA,EACA,EACA,IACG,CACH,IAAM,GAAA,EAAA,EAAA,cAAyB,EAAc,CAGvC,GAAA,EAAA,EAAA,iBAF+B,EAAc,CAEf,EAAuB,KAErD,CAAE,YAAa,EAErB,GAAI,CAAC,EAAU,CACb,EAAU,oCAAqC,CAC7C,MAAO,QACR,CAAC,CACF,OAGF,IAAM,EACJ,EAAuB,MAAQ,EAAc,YAAY,MAAQ,GAEnE,GAAK,IAA4B,GAAO,CACtC,EACE,+BAAA,EAAA,EAAA,aAA0C,EAAe,IAAI,CAAC,GAC9D,CACE,MAAO,OACR,CACF,CACD,OAGF,IAAM,GACJ,GAAiB,EAAc,qBAAqB,SACpD,OAAQ,GAAW,CAAC,GAAe,SAAS,EAAO,CAAC,CAGhD,EAAmBA,EAAAA,gCACvB,EACD,CAGK,EAAa,EAAiB,OAAQ,GAC1C,EAAiB,SAAS,EAAO,CAClC,CAED,GAAI,EAAW,SAAW,EAAG,CAC3B,EACE,8CAAA,EAAA,EAAA,aAAyD,EAAe,IAAI,CAAC,GAC7E,CACE,MAAO,OACR,CACF,CACD,OAGF,IAAM,EAAuB,MAAMC,EAAAA,eACjC,EACA,EACA,EACA,EAAe,IACf,EACD,CAED,UAAW,IAAM,KAAU,EAAU,CACnC,GAAI,CAAC,EAAO,SAAU,CACpB,EACE,gEAAA,EAAA,EAAA,aAA2E,EAAe,IAAI,CAAC,GAC/F,CACE,MAAO,QACR,CACF,CACD,SAGF,GAAM,CAAE,OAAM,GAAG,GAAS,EAEpB,GAAA,EAAA,EAAA,UACJ,EAAc,OAAO,QACrB,EAAO,SACR,CAiBD,GAdA,MAAA,EAAA,EAAA,yBACE,CACE,GAAG,EACH,OAAQ,GACR,OAAQ,EAAO,YAAc,EAAO,WAAW,GAAK,IAAA,GACpD,QAAS,GAAG,EAAuB,IAAI,WAAW,IAClD,SAAU,EACX,CACD,EACA,CACE,WAAY,EAAO,WACpB,CACF,CAEG,EAAO,YAAa,CACtB,IAAM,EAAe,EAAO,WAAW,GAEvC,EACE,oDAAA,EAAA,EAAA,aAA+D,EAAe,IAAI,CAAC,gBAAA,EAAA,EAAA,YAA0B,EAAO,SAAS,CAAC,eAAA,EAAA,EAAA,cAA2B,EAAa,GACtK,CACE,MAAO,OACR,CACF,MAED,EACE,yCAAA,EAAA,EAAA,aAAoD,EAAe,IAAI,CAAC,gBAAA,EAAA,EAAA,YAA0B,EAAO,SAAS,GAClH,CACE,MAAO,OACR,CACF"}
@@ -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/chokidar/cli`),n=require(`@intlayer/config/node`),r=require(`@intlayer/unmerged-dictionaries-entry`);const i=e=>[e].flat(),a=async a=>{let o=(0,n.getConfiguration)(a?.configOptions),{baseDir:s}=o.system,c=(0,r.getUnmergedDictionaries)(o),l=Object.values(c).flat();if(a?.file!==void 0){let t=i(a?.file).map(t=>t.startsWith(`/`)?(0,e.relative)(s,t):(0,e.join)(`./`,t));l=l.filter(e=>e.filePath&&t.includes(e.filePath))}a?.keys!==void 0&&(l=l.filter(e=>i(a?.keys)?.includes(e.key))),a?.excludedKeys!==void 0&&(l=l.filter(e=>!i(a?.excludedKeys)?.includes(e.key))),a?.pathFilter!==void 0&&(l=l.filter(e=>i(a?.pathFilter)?.includes(e.filePath??``))),a?.filter!==void 0&&(l=l.filter(a?.filter));let u=a?.gitOptions;if(u){let e=await(0,t.listGitFiles)(u);e&&(l=l.filter(t=>t.filePath?e.some(e=>t.filePath===e):!1))}return l};exports.ensureArray=i,exports.getTargetUnmergedDictionaries=a;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-Bmb41Sf3.cjs`);let e=require(`node:path`),t=require(`@intlayer/chokidar/cli`),n=require(`@intlayer/config/node`),r=require(`@intlayer/unmerged-dictionaries-entry`);const i=e=>[e].flat(),a=async a=>{let o=(0,n.getConfiguration)(a?.configOptions),{baseDir:s}=o.system,c=(0,r.getUnmergedDictionaries)(o),l=Object.values(c).flat();if(a?.file!==void 0){let t=i(a?.file).map(t=>t.startsWith(`/`)?(0,e.relative)(s,t):(0,e.join)(`./`,t));l=l.filter(e=>e.filePath&&t.includes(e.filePath))}a?.keys!==void 0&&(l=l.filter(e=>i(a?.keys)?.includes(e.key))),a?.excludedKeys!==void 0&&(l=l.filter(e=>!i(a?.excludedKeys)?.includes(e.key))),a?.pathFilter!==void 0&&(l=l.filter(e=>i(a?.pathFilter)?.includes(e.filePath??``))),a?.filter!==void 0&&(l=l.filter(a?.filter));let u=a?.gitOptions;if(u){let e=await(0,t.listGitFiles)(u);e&&(l=l.filter(t=>t.filePath?e.some(e=>t.filePath===e):!1))}return l};exports.ensureArray=i,exports.getTargetUnmergedDictionaries=a;
2
2
  //# sourceMappingURL=getTargetDictionary.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"getTargetDictionary.cjs","names":[],"sources":["../../src/getTargetDictionary.ts"],"sourcesContent":["import { join, relative } from 'node:path';\nimport { type ListGitFilesOptions, listGitFiles } from '@intlayer/chokidar/cli';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\n\nexport const ensureArray = <T>(value: T | T[]): T[] => [value].flat() as T[];\n\n// Arguments for the fill function\nexport type GetTargetDictionaryOptions = {\n file?: string | string[];\n keys?: string | string[];\n excludedKeys?: string | string[];\n filter?: (entry: Dictionary) => boolean; // DictionaryEntry needs to be defined\n pathFilter?: string | string[];\n gitOptions?: ListGitFilesOptions;\n configOptions?: GetConfigurationOptions;\n};\n\nexport const getTargetUnmergedDictionaries = async (\n options?: GetTargetDictionaryOptions\n): Promise<Dictionary[]> => {\n const configuration = getConfiguration(options?.configOptions);\n\n const { baseDir } = configuration.system;\n\n const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);\n let result = Object.values(unmergedDictionariesRecord).flat();\n\n // 1. if filePath not defined, list all content declaration files based on unmerged dictionaries list\n if (typeof options?.file !== 'undefined') {\n const fileArray = ensureArray(options?.file);\n const relativeFilePaths = fileArray.map((file) =>\n file.startsWith('/') ? relative(baseDir, file) : join('./', file)\n );\n\n result = result.filter(\n (dict) =>\n dict.filePath &&\n // Check for absolute path\n relativeFilePaths.includes(dict.filePath)\n );\n }\n\n if (typeof options?.keys !== 'undefined') {\n result = result.filter((dict) =>\n ensureArray(options?.keys)?.includes(dict.key)\n );\n }\n\n if (typeof options?.excludedKeys !== 'undefined') {\n result = result.filter(\n (dict) => !ensureArray(options?.excludedKeys)?.includes(dict.key)\n );\n }\n\n if (typeof options?.pathFilter !== 'undefined') {\n result = result.filter((dict) =>\n ensureArray(options?.pathFilter)?.includes(dict.filePath ?? '')\n );\n }\n\n if (typeof options?.filter !== 'undefined') {\n result = result.filter(options?.filter);\n }\n\n const gitOptions = options?.gitOptions;\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 result = result.filter((dict) => {\n if (!dict.filePath) return false;\n\n return gitChangedFiles.some((gitFile) => dict.filePath === gitFile);\n });\n }\n }\n\n return result;\n};\n"],"mappings":"oQASA,MAAa,EAAkB,GAAwB,CAAC,EAAM,CAAC,MAAM,CAaxD,EAAgC,KAC3C,IAC0B,CAC1B,IAAM,GAAA,EAAA,EAAA,kBAAiC,GAAS,cAAc,CAExD,CAAE,WAAY,EAAc,OAE5B,GAAA,EAAA,EAAA,yBAAqD,EAAc,CACrE,EAAS,OAAO,OAAO,EAA2B,CAAC,MAAM,CAG7D,GAAW,GAAS,OAAS,OAAa,CAExC,IAAM,EADY,EAAY,GAAS,KAAK,CACR,IAAK,GACvC,EAAK,WAAW,IAAI,EAAA,EAAA,EAAA,UAAY,EAAS,EAAK,EAAA,EAAA,EAAA,MAAQ,KAAM,EAAK,CAClE,CAED,EAAS,EAAO,OACb,GACC,EAAK,UAEL,EAAkB,SAAS,EAAK,SAAS,CAC5C,CAGQ,GAAS,OAAS,SAC3B,EAAS,EAAO,OAAQ,GACtB,EAAY,GAAS,KAAK,EAAE,SAAS,EAAK,IAAI,CAC/C,EAGQ,GAAS,eAAiB,SACnC,EAAS,EAAO,OACb,GAAS,CAAC,EAAY,GAAS,aAAa,EAAE,SAAS,EAAK,IAAI,CAClE,EAGQ,GAAS,aAAe,SACjC,EAAS,EAAO,OAAQ,GACtB,EAAY,GAAS,WAAW,EAAE,SAAS,EAAK,UAAY,GAAG,CAChE,EAGQ,GAAS,SAAW,SAC7B,EAAS,EAAO,OAAO,GAAS,OAAO,EAGzC,IAAM,EAAa,GAAS,WAC5B,GAAI,EAAY,CACd,IAAM,EAAkB,MAAA,EAAA,EAAA,cAAmB,EAAW,CAElD,IAIF,EAAS,EAAO,OAAQ,GACjB,EAAK,SAEH,EAAgB,KAAM,GAAY,EAAK,WAAa,EAAQ,CAFxC,GAG3B,EAIN,OAAO"}
1
+ {"version":3,"file":"getTargetDictionary.cjs","names":[],"sources":["../../src/getTargetDictionary.ts"],"sourcesContent":["import { join, relative } from 'node:path';\nimport { type ListGitFilesOptions, listGitFiles } from '@intlayer/chokidar/cli';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\n\nexport const ensureArray = <T>(value: T | T[]): T[] => [value].flat() as T[];\n\n// Arguments for the fill function\nexport type GetTargetDictionaryOptions = {\n file?: string | string[];\n keys?: string | string[];\n excludedKeys?: string | string[];\n filter?: (entry: Dictionary) => boolean; // DictionaryEntry needs to be defined\n pathFilter?: string | string[];\n gitOptions?: ListGitFilesOptions;\n configOptions?: GetConfigurationOptions;\n};\n\nexport const getTargetUnmergedDictionaries = async (\n options?: GetTargetDictionaryOptions\n): Promise<Dictionary[]> => {\n const configuration = getConfiguration(options?.configOptions);\n\n const { baseDir } = configuration.system;\n\n const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);\n let result = Object.values(unmergedDictionariesRecord).flat();\n\n // 1. if filePath not defined, list all content declaration files based on unmerged dictionaries list\n if (typeof options?.file !== 'undefined') {\n const fileArray = ensureArray(options?.file);\n const relativeFilePaths = fileArray.map((file) =>\n file.startsWith('/') ? relative(baseDir, file) : join('./', file)\n );\n\n result = result.filter(\n (dict) =>\n dict.filePath &&\n // Check for absolute path\n relativeFilePaths.includes(dict.filePath)\n );\n }\n\n if (typeof options?.keys !== 'undefined') {\n result = result.filter((dict) =>\n ensureArray(options?.keys)?.includes(dict.key)\n );\n }\n\n if (typeof options?.excludedKeys !== 'undefined') {\n result = result.filter(\n (dict) => !ensureArray(options?.excludedKeys)?.includes(dict.key)\n );\n }\n\n if (typeof options?.pathFilter !== 'undefined') {\n result = result.filter((dict) =>\n ensureArray(options?.pathFilter)?.includes(dict.filePath ?? '')\n );\n }\n\n if (typeof options?.filter !== 'undefined') {\n result = result.filter(options?.filter);\n }\n\n const gitOptions = options?.gitOptions;\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 result = result.filter((dict) => {\n if (!dict.filePath) return false;\n\n return gitChangedFiles.some((gitFile) => dict.filePath === gitFile);\n });\n }\n }\n\n return result;\n};\n"],"mappings":"wPASA,MAAa,EAAkB,GAAwB,CAAC,EAAM,CAAC,MAAM,CAaxD,EAAgC,KAC3C,IAC0B,CAC1B,IAAM,GAAA,EAAA,EAAA,kBAAiC,GAAS,cAAc,CAExD,CAAE,WAAY,EAAc,OAE5B,GAAA,EAAA,EAAA,yBAAqD,EAAc,CACrE,EAAS,OAAO,OAAO,EAA2B,CAAC,MAAM,CAG7D,GAAW,GAAS,OAAS,OAAa,CAExC,IAAM,EADY,EAAY,GAAS,KAAK,CACR,IAAK,GACvC,EAAK,WAAW,IAAI,EAAA,EAAA,EAAA,UAAY,EAAS,EAAK,EAAA,EAAA,EAAA,MAAQ,KAAM,EAAK,CAClE,CAED,EAAS,EAAO,OACb,GACC,EAAK,UAEL,EAAkB,SAAS,EAAK,SAAS,CAC5C,CAGQ,GAAS,OAAS,SAC3B,EAAS,EAAO,OAAQ,GACtB,EAAY,GAAS,KAAK,EAAE,SAAS,EAAK,IAAI,CAC/C,EAGQ,GAAS,eAAiB,SACnC,EAAS,EAAO,OACb,GAAS,CAAC,EAAY,GAAS,aAAa,EAAE,SAAS,EAAK,IAAI,CAClE,EAGQ,GAAS,aAAe,SACjC,EAAS,EAAO,OAAQ,GACtB,EAAY,GAAS,WAAW,EAAE,SAAS,EAAK,UAAY,GAAG,CAChE,EAGQ,GAAS,SAAW,SAC7B,EAAS,EAAO,OAAO,GAAS,OAAO,EAGzC,IAAM,EAAa,GAAS,WAC5B,GAAI,EAAY,CACd,IAAM,EAAkB,MAAA,EAAA,EAAA,cAAmB,EAAW,CAElD,IAIF,EAAS,EAAO,OAAQ,GACjB,EAAK,SAEH,EAAgB,KAAM,GAAY,EAAK,WAAa,EAAQ,CAFxC,GAG3B,EAIN,OAAO"}
package/dist/cjs/init.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`node:fs`),t=require(`node:path`),n=require(`@intlayer/chokidar/cli`);const r=n=>{let r=n;for(;r!==(0,t.resolve)(r,`..`);){if((0,e.existsSync)((0,t.join)(r,`package.json`)))return r;r=(0,t.resolve)(r,`..`)}return n},i=async e=>{await(0,n.initIntlayer)(r(e?(0,t.resolve)(e):process.cwd()))};exports.findProjectRoot=r,exports.init=i;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-Bmb41Sf3.cjs`);let e=require(`node:fs`),t=require(`node:path`),n=require(`@intlayer/chokidar/cli`);const r=n=>{let r=n;for(;r!==(0,t.resolve)(r,`..`);){if((0,e.existsSync)((0,t.join)(r,`package.json`)))return r;r=(0,t.resolve)(r,`..`)}return n},i=async e=>{await(0,n.initIntlayer)(r(e?(0,t.resolve)(e):process.cwd()))};exports.findProjectRoot=r,exports.init=i;
2
2
  //# sourceMappingURL=init.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.cjs","names":[],"sources":["../../src/init.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { initIntlayer } from '@intlayer/chokidar/cli';\n\nexport const findProjectRoot = (startDir: string) => {\n let currentDir = startDir;\n\n while (currentDir !== resolve(currentDir, '..')) {\n if (existsSync(join(currentDir, 'package.json'))) {\n return currentDir;\n }\n currentDir = resolve(currentDir, '..');\n }\n\n // If no package.json is found, return the start directory.\n // The initIntlayer function will handle the missing package.json error.\n return startDir;\n};\n\nexport const init = async (projectRoot?: string) => {\n const root = projectRoot\n ? findProjectRoot(resolve(projectRoot))\n : findProjectRoot(process.cwd());\n\n await initIntlayer(root);\n};\n"],"mappings":"mMAIA,MAAa,EAAmB,GAAqB,CACnD,IAAI,EAAa,EAEjB,KAAO,KAAA,EAAA,EAAA,SAAuB,EAAY,KAAK,EAAE,CAC/C,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,MAAoB,EAAY,eAAe,CAAC,CAC9C,OAAO,EAET,GAAA,EAAA,EAAA,SAAqB,EAAY,KAAK,CAKxC,OAAO,GAGI,EAAO,KAAO,IAAyB,CAKlD,MAAA,EAAA,EAAA,cAHI,EADS,GACT,EAAA,EAAA,SAAwB,EAAY,CACpB,QAAQ,KAAK,CAAC,CAEV"}
1
+ {"version":3,"file":"init.cjs","names":[],"sources":["../../src/init.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { initIntlayer } from '@intlayer/chokidar/cli';\n\nexport const findProjectRoot = (startDir: string) => {\n let currentDir = startDir;\n\n while (currentDir !== resolve(currentDir, '..')) {\n if (existsSync(join(currentDir, 'package.json'))) {\n return currentDir;\n }\n currentDir = resolve(currentDir, '..');\n }\n\n // If no package.json is found, return the start directory.\n // The initIntlayer function will handle the missing package.json error.\n return startDir;\n};\n\nexport const init = async (projectRoot?: string) => {\n const root = projectRoot\n ? findProjectRoot(resolve(projectRoot))\n : findProjectRoot(process.cwd());\n\n await initIntlayer(root);\n};\n"],"mappings":"uLAIA,MAAa,EAAmB,GAAqB,CACnD,IAAI,EAAa,EAEjB,KAAO,KAAA,EAAA,EAAA,SAAuB,EAAY,KAAK,EAAE,CAC/C,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,MAAoB,EAAY,eAAe,CAAC,CAC9C,OAAO,EAET,GAAA,EAAA,EAAA,SAAqB,EAAY,KAAK,CAKxC,OAAO,GAGI,EAAO,KAAO,IAAyB,CAKlD,MAAA,EAAA,EAAA,cAHI,EADS,GACT,EAAA,EAAA,SAAwB,EAAY,CACpB,QAAQ,KAAK,CAAC,CAEV"}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./_virtual/_rolldown/runtime.cjs`),t=require(`./init.cjs`),n=require(`./initSkills.cjs`);let r=require(`node:path`),i=require(`@intlayer/chokidar/cli`),a=require(`enquirer`);a=e.__toESM(a);let o=require(`@clack/prompts`);o=e.__toESM(o);const s=async e=>{let s=t.findProjectRoot(e?(0,r.resolve)(e):process.cwd());o.intro(`Initializing Intlayer MCP Server`);let c=n.getDetectedPlatform(),l;try{l=(await a.default.prompt({type:`autocomplete`,name:`platforms`,message:`Which platform are you using? (Type to search)`,multiple:!1,initial:c?i.PLATFORMS.indexOf(c):void 0,choices:n.PLATFORM_OPTIONS.map(e=>({name:e.value,message:e.label,hint:e.hint}))})).platforms}catch{o.cancel(`Operation cancelled.`);return}if(!l){o.cancel(`Operation cancelled. No platform selected.`);return}let u=await o.select({message:`Which transport method do you want to use?`,options:[{value:`stdio`,label:`Local server (stdio)`,hint:`Recommended. Integrates all features including CLI tools.`},{value:`sse`,label:`Remote server (SSE)`,hint:`Hosted by Intlayer. Documentation only.`}]});if(o.isCancel(u)||!u){o.cancel(`Operation cancelled.`);return}let d=o.spinner();d.start(`Configuring MCP Server...`);try{let e=await(0,i.installMCP)(s,l,u);d.stop(`MCP Server configured successfully`),o.note(e,`Success`)}catch(e){d.stop(`Failed to configure MCP Server`),o.log.error(e instanceof Error?e.message:String(e))}o.outro(`Intlayer MCP Server initialization complete`)};exports.initMCP=s;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunk-Bmb41Sf3.cjs`),t=require(`./init.cjs`),n=require(`./initSkills.cjs`);let r=require(`node:path`),i=require(`@intlayer/chokidar/cli`),a=require(`enquirer`);a=e.t(a);let o=require(`@clack/prompts`);o=e.t(o);const s=async e=>{let s=t.findProjectRoot(e?(0,r.resolve)(e):process.cwd());o.intro(`Initializing Intlayer MCP Server`);let c=n.getDetectedPlatform(),l;try{l=(await a.default.prompt({type:`autocomplete`,name:`platforms`,message:`Which platform are you using? (Type to search)`,multiple:!1,initial:c?i.PLATFORMS.indexOf(c):void 0,choices:n.PLATFORM_OPTIONS.map(e=>({name:e.value,message:e.label,hint:e.hint}))})).platforms}catch{o.cancel(`Operation cancelled.`);return}if(!l){o.cancel(`Operation cancelled. No platform selected.`);return}let u=await o.select({message:`Which transport method do you want to use?`,options:[{value:`stdio`,label:`Local server (stdio)`,hint:`Recommended. Integrates all features including CLI tools.`},{value:`sse`,label:`Remote server (SSE)`,hint:`Hosted by Intlayer. Documentation only.`}]});if(o.isCancel(u)||!u){o.cancel(`Operation cancelled.`);return}let d=o.spinner();d.start(`Configuring MCP Server...`);try{let e=await(0,i.installMCP)(s,l,u);d.stop(`MCP Server configured successfully`),o.note(e,`Success`)}catch(e){d.stop(`Failed to configure MCP Server`),o.log.error(e instanceof Error?e.message:String(e))}o.outro(`Intlayer MCP Server initialization complete`)};exports.initMCP=s;
2
2
  //# sourceMappingURL=initMCP.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"initMCP.cjs","names":["findProjectRoot","getDetectedPlatform","PLATFORMS","PLATFORM_OPTIONS","p"],"sources":["../../src/initMCP.ts"],"sourcesContent":["import { resolve } from 'node:path';\nimport * as p from '@clack/prompts';\nimport {\n installMCP,\n type MCPTransport,\n PLATFORMS,\n} from '@intlayer/chokidar/cli';\nimport enquirer from 'enquirer';\nimport { findProjectRoot } from './init';\nimport { getDetectedPlatform, PLATFORM_OPTIONS } from './initSkills';\n\nexport const initMCP = async (projectRoot?: string) => {\n const root = findProjectRoot(\n projectRoot ? resolve(projectRoot) : process.cwd()\n );\n\n p.intro('Initializing Intlayer MCP Server');\n\n const detectedPlatform = getDetectedPlatform();\n\n let platform: any;\n try {\n const response = await enquirer.prompt<{ platforms: any }>({\n type: 'autocomplete',\n name: 'platforms',\n message: 'Which platform are you using? (Type to search)',\n multiple: false,\n initial: detectedPlatform\n ? PLATFORMS.indexOf(detectedPlatform)\n : undefined,\n choices: PLATFORM_OPTIONS.map((opt) => ({\n name: opt.value,\n message: opt.label,\n hint: opt.hint,\n })),\n });\n platform = response.platforms;\n } catch {\n p.cancel('Operation cancelled.');\n return;\n }\n\n if (!platform) {\n p.cancel('Operation cancelled. No platform selected.');\n return;\n }\n\n const transport = (await p.select({\n message: 'Which transport method do you want to use?',\n options: [\n {\n value: 'stdio',\n label: 'Local server (stdio)',\n hint: 'Recommended. Integrates all features including CLI tools.',\n },\n {\n value: 'sse',\n label: 'Remote server (SSE)',\n hint: 'Hosted by Intlayer. Documentation only.',\n },\n ],\n })) as MCPTransport;\n\n if (p.isCancel(transport) || !transport) {\n p.cancel('Operation cancelled.');\n return;\n }\n\n const s = p.spinner();\n s.start('Configuring MCP Server...');\n\n try {\n const result = await installMCP(root, platform, transport);\n\n s.stop('MCP Server configured successfully');\n\n p.note(result, 'Success');\n } catch (error) {\n s.stop('Failed to configure MCP Server');\n p.log.error(error instanceof Error ? error.message : String(error));\n }\n\n p.outro('Intlayer MCP Server initialization complete');\n};\n"],"mappings":"gUAWA,MAAa,EAAU,KAAO,IAAyB,CACrD,IAAM,EAAOA,EAAAA,gBACX,GAAA,EAAA,EAAA,SAAsB,EAAY,CAAG,QAAQ,KAAK,CACnD,CAED,EAAE,MAAM,mCAAmC,CAE3C,IAAM,EAAmBC,EAAAA,qBAAqB,CAE1C,EACJ,GAAI,CAeF,GAdiB,MAAM,EAAA,QAAS,OAA2B,CACzD,KAAM,eACN,KAAM,YACN,QAAS,iDACT,SAAU,GACV,QAAS,EACLC,EAAAA,UAAU,QAAQ,EAAiB,CACnC,IAAA,GACJ,QAASC,EAAAA,iBAAiB,IAAK,IAAS,CACtC,KAAM,EAAI,MACV,QAAS,EAAI,MACb,KAAM,EAAI,KACX,EAAE,CACJ,CAAC,EACkB,eACd,CACN,EAAE,OAAO,uBAAuB,CAChC,OAGF,GAAI,CAAC,EAAU,CACb,EAAE,OAAO,6CAA6C,CACtD,OAGF,IAAM,EAAa,MAAMC,EAAE,OAAO,CAChC,QAAS,6CACT,QAAS,CACP,CACE,MAAO,QACP,MAAO,uBACP,KAAM,4DACP,CACD,CACE,MAAO,MACP,MAAO,sBACP,KAAM,0CACP,CACF,CACF,CAAC,CAEF,GAAIA,EAAE,SAAS,EAAU,EAAI,CAAC,EAAW,CACvC,EAAE,OAAO,uBAAuB,CAChC,OAGF,IAAM,EAAIA,EAAE,SAAS,CACrB,EAAE,MAAM,4BAA4B,CAEpC,GAAI,CACF,IAAM,EAAS,MAAA,EAAA,EAAA,YAAiB,EAAM,EAAU,EAAU,CAE1D,EAAE,KAAK,qCAAqC,CAE5C,EAAE,KAAK,EAAQ,UAAU,OAClB,EAAO,CACd,EAAE,KAAK,iCAAiC,CACxC,EAAE,IAAI,MAAM,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAAC,CAGrE,EAAE,MAAM,8CAA8C"}
1
+ {"version":3,"file":"initMCP.cjs","names":["findProjectRoot","getDetectedPlatform","PLATFORMS","PLATFORM_OPTIONS","p"],"sources":["../../src/initMCP.ts"],"sourcesContent":["import { resolve } from 'node:path';\nimport * as p from '@clack/prompts';\nimport {\n installMCP,\n type MCPTransport,\n PLATFORMS,\n} from '@intlayer/chokidar/cli';\nimport enquirer from 'enquirer';\nimport { findProjectRoot } from './init';\nimport { getDetectedPlatform, PLATFORM_OPTIONS } from './initSkills';\n\nexport const initMCP = async (projectRoot?: string) => {\n const root = findProjectRoot(\n projectRoot ? resolve(projectRoot) : process.cwd()\n );\n\n p.intro('Initializing Intlayer MCP Server');\n\n const detectedPlatform = getDetectedPlatform();\n\n let platform: any;\n try {\n const response = await enquirer.prompt<{ platforms: any }>({\n type: 'autocomplete',\n name: 'platforms',\n message: 'Which platform are you using? (Type to search)',\n multiple: false,\n initial: detectedPlatform\n ? PLATFORMS.indexOf(detectedPlatform)\n : undefined,\n choices: PLATFORM_OPTIONS.map((opt) => ({\n name: opt.value,\n message: opt.label,\n hint: opt.hint,\n })),\n });\n platform = response.platforms;\n } catch {\n p.cancel('Operation cancelled.');\n return;\n }\n\n if (!platform) {\n p.cancel('Operation cancelled. No platform selected.');\n return;\n }\n\n const transport = (await p.select({\n message: 'Which transport method do you want to use?',\n options: [\n {\n value: 'stdio',\n label: 'Local server (stdio)',\n hint: 'Recommended. Integrates all features including CLI tools.',\n },\n {\n value: 'sse',\n label: 'Remote server (SSE)',\n hint: 'Hosted by Intlayer. Documentation only.',\n },\n ],\n })) as MCPTransport;\n\n if (p.isCancel(transport) || !transport) {\n p.cancel('Operation cancelled.');\n return;\n }\n\n const s = p.spinner();\n s.start('Configuring MCP Server...');\n\n try {\n const result = await installMCP(root, platform, transport);\n\n s.stop('MCP Server configured successfully');\n\n p.note(result, 'Success');\n } catch (error) {\n s.stop('Failed to configure MCP Server');\n p.log.error(error instanceof Error ? error.message : String(error));\n }\n\n p.outro('Intlayer MCP Server initialization complete');\n};\n"],"mappings":"wSAWA,MAAa,EAAU,KAAO,IAAyB,CACrD,IAAM,EAAOA,EAAAA,gBACX,GAAA,EAAA,EAAA,SAAsB,EAAY,CAAG,QAAQ,KAAK,CACnD,CAED,EAAE,MAAM,mCAAmC,CAE3C,IAAM,EAAmBC,EAAAA,qBAAqB,CAE1C,EACJ,GAAI,CAeF,GAdiB,MAAM,EAAA,QAAS,OAA2B,CACzD,KAAM,eACN,KAAM,YACN,QAAS,iDACT,SAAU,GACV,QAAS,EACLC,EAAAA,UAAU,QAAQ,EAAiB,CACnC,IAAA,GACJ,QAASC,EAAAA,iBAAiB,IAAK,IAAS,CACtC,KAAM,EAAI,MACV,QAAS,EAAI,MACb,KAAM,EAAI,KACX,EAAE,CACJ,CAAC,EACkB,eACd,CACN,EAAE,OAAO,uBAAuB,CAChC,OAGF,GAAI,CAAC,EAAU,CACb,EAAE,OAAO,6CAA6C,CACtD,OAGF,IAAM,EAAa,MAAMC,EAAE,OAAO,CAChC,QAAS,6CACT,QAAS,CACP,CACE,MAAO,QACP,MAAO,uBACP,KAAM,4DACP,CACD,CACE,MAAO,MACP,MAAO,sBACP,KAAM,0CACP,CACF,CACF,CAAC,CAEF,GAAIA,EAAE,SAAS,EAAU,EAAI,CAAC,EAAW,CACvC,EAAE,OAAO,uBAAuB,CAChC,OAGF,IAAM,EAAIA,EAAE,SAAS,CACrB,EAAE,MAAM,4BAA4B,CAEpC,GAAI,CACF,IAAM,EAAS,MAAA,EAAA,EAAA,YAAiB,EAAM,EAAU,EAAU,CAE1D,EAAE,KAAK,qCAAqC,CAE5C,EAAE,KAAK,EAAQ,UAAU,OAClB,EAAO,CACd,EAAE,KAAK,iCAAiC,CACxC,EAAE,IAAI,MAAM,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAAC,CAGrE,EAAE,MAAM,8CAA8C"}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./_virtual/_rolldown/runtime.cjs`),t=require(`./init.cjs`);let n=require(`node:fs`),r=require(`node:path`),i=require(`@intlayer/chokidar/cli`),a=require(`enquirer`);a=e.__toESM(a);let o=require(`@clack/prompts`);o=e.__toESM(o);const s=i.PLATFORMS.filter(e=>i.PLATFORMS_METADATA[e].check).map(e=>({check:i.PLATFORMS_METADATA[e].check??(()=>!1),platform:e})),c=i.PLATFORMS.map(e=>({value:e,label:i.PLATFORMS_METADATA[e].label,hint:`(${i.PLATFORMS_METADATA[e].dir})`})),l=()=>s.find(({check:e})=>e())?.platform,u=e=>{try{let t=(0,r.join)(e,`package.json`);if(!(0,n.existsSync)(t))return{};let{dependencies:i={},devDependencies:a={}}=JSON.parse((0,n.readFileSync)(t,`utf-8`));return{...i,...a}}catch{return{}}},d=async e=>{let n=t.findProjectRoot(e?(0,r.resolve)(e):process.cwd());o.intro(`Initializing Intlayer skills`);let s=l(),d;try{d=(await a.default.prompt({type:`autocomplete`,name:`platforms`,message:`Which platforms are you using? (Type to search)`,multiple:!1,initial:s?i.PLATFORMS.indexOf(s):void 0,choices:c.map(e=>({name:e.value,message:e.label,hint:e.hint}))})).platforms}catch{o.cancel(`Operation cancelled.`);return}if(!d){o.log.warn(`No platform selected. Nothing to install.`);return}let f=(0,i.getInitialSkills)(u(n)),p=await o.multiselect({message:`Select the documentation skills to provide to your AI:`,initialValues:f,options:i.SKILLS.map(e=>({value:e,label:e,hint:i.SKILLS_METADATA[e]})),required:!1});if(o.isCancel(p)||!p||p.length===0){o.cancel(`Operation cancelled. No skills selected.`);return}let m=o.spinner();m.start(`Installing skills...`);try{let e=await(0,i.installSkills)(n,d,p);m.stop(`Skills installed successfully`),o.note(e,`Success`)}catch(e){m.stop(`Failed to install skills`),o.log.error(e instanceof Error?e.message:String(e))}o.outro(`Intlayer skills initialization complete`)};exports.PLATFORM_OPTIONS=c,exports.getDetectedPlatform=l,exports.initSkills=d;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunk-Bmb41Sf3.cjs`),t=require(`./init.cjs`);let n=require(`node:fs`),r=require(`node:path`),i=require(`@intlayer/chokidar/cli`),a=require(`enquirer`);a=e.t(a);let o=require(`@clack/prompts`);o=e.t(o);const s=i.PLATFORMS.filter(e=>i.PLATFORMS_METADATA[e].check).map(e=>({check:i.PLATFORMS_METADATA[e].check??(()=>!1),platform:e})),c=i.PLATFORMS.map(e=>({value:e,label:i.PLATFORMS_METADATA[e].label,hint:`(${i.PLATFORMS_METADATA[e].dir})`})),l=()=>s.find(({check:e})=>e())?.platform,u=e=>{try{let t=(0,r.join)(e,`package.json`);if(!(0,n.existsSync)(t))return{};let{dependencies:i={},devDependencies:a={}}=JSON.parse((0,n.readFileSync)(t,`utf-8`));return{...i,...a}}catch{return{}}},d=async e=>{let n=t.findProjectRoot(e?(0,r.resolve)(e):process.cwd());o.intro(`Initializing Intlayer skills`);let s=l(),d;try{d=(await a.default.prompt({type:`autocomplete`,name:`platforms`,message:`Which platforms are you using? (Type to search)`,multiple:!1,initial:s?i.PLATFORMS.indexOf(s):void 0,choices:c.map(e=>({name:e.value,message:e.label,hint:e.hint}))})).platforms}catch{o.cancel(`Operation cancelled.`);return}if(!d){o.log.warn(`No platform selected. Nothing to install.`);return}let f=(0,i.getInitialSkills)(u(n)),p=await o.multiselect({message:`Select the documentation skills to provide to your AI:`,initialValues:f,options:i.SKILLS.map(e=>({value:e,label:e,hint:i.SKILLS_METADATA[e]})),required:!1});if(o.isCancel(p)||!p||p.length===0){o.cancel(`Operation cancelled. No skills selected.`);return}let m=o.spinner();m.start(`Installing skills...`);try{let e=await(0,i.installSkills)(n,d,p);m.stop(`Skills installed successfully`),o.note(e,`Success`)}catch(e){m.stop(`Failed to install skills`),o.log.error(e instanceof Error?e.message:String(e))}o.outro(`Intlayer skills initialization complete`)};exports.PLATFORM_OPTIONS=c,exports.getDetectedPlatform=l,exports.initSkills=d;
2
2
  //# sourceMappingURL=initSkills.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"initSkills.cjs","names":["PLATFORMS","PLATFORMS_METADATA","findProjectRoot","p","SKILLS","SKILLS_METADATA"],"sources":["../../src/initSkills.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport * as p from '@clack/prompts';\nimport {\n getInitialSkills,\n installSkills,\n PLATFORMS,\n PLATFORMS_METADATA,\n type Platform,\n SKILLS,\n SKILLS_METADATA,\n} from '@intlayer/chokidar/cli';\nimport enquirer from 'enquirer';\nimport { findProjectRoot } from './init';\n\nconst PLATFORM_CHECKS: Array<{ check: () => boolean; platform: Platform }> =\n PLATFORMS.filter((platform) => PLATFORMS_METADATA[platform].check).map(\n (platform) => ({\n check: PLATFORMS_METADATA[platform].check ?? (() => false),\n platform,\n })\n );\n\nexport const PLATFORM_OPTIONS: Array<{\n value: Platform;\n label: string;\n hint: string;\n}> = PLATFORMS.map((platform) => ({\n value: platform,\n label: PLATFORMS_METADATA[platform].label,\n hint: `(${PLATFORMS_METADATA[platform].dir})`,\n}));\n\nexport const getDetectedPlatform = (): Platform | undefined =>\n PLATFORM_CHECKS.find(({ check }) => check())?.platform;\n\nconst getDependencies = (root: string): Record<string, string> => {\n try {\n const packageJsonPath = join(root, 'package.json');\n if (!existsSync(packageJsonPath)) return {};\n\n const { dependencies = {}, devDependencies = {} } = JSON.parse(\n readFileSync(packageJsonPath, 'utf-8')\n );\n return { ...dependencies, ...devDependencies };\n } catch {\n return {};\n }\n};\n\nexport const initSkills = async (projectRoot?: string) => {\n const root = findProjectRoot(\n projectRoot ? resolve(projectRoot) : process.cwd()\n );\n\n p.intro('Initializing Intlayer skills');\n\n const detectedPlatform = getDetectedPlatform();\n\n let platform: Platform;\n try {\n const response = await enquirer.prompt<{ platforms: Platform }>({\n type: 'autocomplete',\n name: 'platforms',\n message: 'Which platforms are you using? (Type to search)',\n multiple: false,\n initial: detectedPlatform\n ? PLATFORMS.indexOf(detectedPlatform)\n : undefined,\n choices: PLATFORM_OPTIONS.map((opt) => ({\n name: opt.value,\n message: opt.label,\n hint: opt.hint,\n })),\n });\n platform = response.platforms;\n } catch {\n p.cancel('Operation cancelled.');\n return;\n }\n\n if (!platform) {\n p.log.warn('No platform selected. Nothing to install.');\n return;\n }\n\n const dependencies = getDependencies(root);\n const initialValues = getInitialSkills(dependencies);\n\n const selectedSkills = await p.multiselect({\n message: 'Select the documentation skills to provide to your AI:',\n initialValues,\n options: SKILLS.map((skill) => ({\n value: skill,\n label: skill,\n hint: SKILLS_METADATA[skill],\n })),\n required: false,\n });\n\n if (\n p.isCancel(selectedSkills) ||\n !selectedSkills ||\n (selectedSkills as string[]).length === 0\n ) {\n p.cancel('Operation cancelled. No skills selected.');\n return;\n }\n\n const s = p.spinner();\n s.start('Installing skills...');\n\n try {\n const result = await installSkills(root, platform, selectedSkills);\n\n s.stop('Skills installed successfully');\n\n p.note(result, 'Success');\n } catch (error) {\n s.stop('Failed to install skills');\n p.log.error(error instanceof Error ? error.message : String(error));\n }\n\n p.outro('Intlayer skills initialization complete');\n};\n"],"mappings":"uTAeA,MAAM,EACJA,EAAAA,UAAU,OAAQ,GAAaC,EAAAA,mBAAmB,GAAU,MAAM,CAAC,IAChE,IAAc,CACb,MAAOA,EAAAA,mBAAmB,GAAU,YAAgB,IACpD,WACD,EACF,CAEU,EAIRD,EAAAA,UAAU,IAAK,IAAc,CAChC,MAAO,EACP,MAAOC,EAAAA,mBAAmB,GAAU,MACpC,KAAM,IAAIA,EAAAA,mBAAmB,GAAU,IAAI,GAC5C,EAAE,CAEU,MACX,EAAgB,MAAM,CAAE,WAAY,GAAO,CAAC,EAAE,SAE1C,EAAmB,GAAyC,CAChE,GAAI,CACF,IAAM,GAAA,EAAA,EAAA,MAAuB,EAAM,eAAe,CAClD,GAAI,EAAA,EAAA,EAAA,YAAY,EAAgB,CAAE,MAAO,EAAE,CAE3C,GAAM,CAAE,eAAe,EAAE,CAAE,kBAAkB,EAAE,EAAK,KAAK,OAAA,EAAA,EAAA,cAC1C,EAAiB,QAAQ,CACvC,CACD,MAAO,CAAE,GAAG,EAAc,GAAG,EAAiB,MACxC,CACN,MAAO,EAAE,GAIA,EAAa,KAAO,IAAyB,CACxD,IAAM,EAAOC,EAAAA,gBACX,GAAA,EAAA,EAAA,SAAsB,EAAY,CAAG,QAAQ,KAAK,CACnD,CAED,EAAE,MAAM,+BAA+B,CAEvC,IAAM,EAAmB,GAAqB,CAE1C,EACJ,GAAI,CAeF,GAdiB,MAAM,EAAA,QAAS,OAAgC,CAC9D,KAAM,eACN,KAAM,YACN,QAAS,kDACT,SAAU,GACV,QAAS,EACLF,EAAAA,UAAU,QAAQ,EAAiB,CACnC,IAAA,GACJ,QAAS,EAAiB,IAAK,IAAS,CACtC,KAAM,EAAI,MACV,QAAS,EAAI,MACb,KAAM,EAAI,KACX,EAAE,CACJ,CAAC,EACkB,eACd,CACN,EAAE,OAAO,uBAAuB,CAChC,OAGF,GAAI,CAAC,EAAU,CACb,EAAE,IAAI,KAAK,4CAA4C,CACvD,OAIF,IAAM,GAAA,EAAA,EAAA,kBADe,EAAgB,EAAK,CACU,CAE9C,EAAiB,MAAMG,EAAE,YAAY,CACzC,QAAS,yDACT,gBACA,QAASC,EAAAA,OAAO,IAAK,IAAW,CAC9B,MAAO,EACP,MAAO,EACP,KAAMC,EAAAA,gBAAgB,GACvB,EAAE,CACH,SAAU,GACX,CAAC,CAEF,GACEF,EAAE,SAAS,EAAe,EAC1B,CAAC,GACA,EAA4B,SAAW,EACxC,CACA,EAAE,OAAO,2CAA2C,CACpD,OAGF,IAAM,EAAIA,EAAE,SAAS,CACrB,EAAE,MAAM,uBAAuB,CAE/B,GAAI,CACF,IAAM,EAAS,MAAA,EAAA,EAAA,eAAoB,EAAM,EAAU,EAAe,CAElE,EAAE,KAAK,gCAAgC,CAEvC,EAAE,KAAK,EAAQ,UAAU,OAClB,EAAO,CACd,EAAE,KAAK,2BAA2B,CAClC,EAAE,IAAI,MAAM,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAAC,CAGrE,EAAE,MAAM,0CAA0C"}
1
+ {"version":3,"file":"initSkills.cjs","names":["PLATFORMS","PLATFORMS_METADATA","findProjectRoot","p","SKILLS","SKILLS_METADATA"],"sources":["../../src/initSkills.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport * as p from '@clack/prompts';\nimport {\n getInitialSkills,\n installSkills,\n PLATFORMS,\n PLATFORMS_METADATA,\n type Platform,\n SKILLS,\n SKILLS_METADATA,\n} from '@intlayer/chokidar/cli';\nimport enquirer from 'enquirer';\nimport { findProjectRoot } from './init';\n\nconst PLATFORM_CHECKS: Array<{ check: () => boolean; platform: Platform }> =\n PLATFORMS.filter((platform) => PLATFORMS_METADATA[platform].check).map(\n (platform) => ({\n check: PLATFORMS_METADATA[platform].check ?? (() => false),\n platform,\n })\n );\n\nexport const PLATFORM_OPTIONS: Array<{\n value: Platform;\n label: string;\n hint: string;\n}> = PLATFORMS.map((platform) => ({\n value: platform,\n label: PLATFORMS_METADATA[platform].label,\n hint: `(${PLATFORMS_METADATA[platform].dir})`,\n}));\n\nexport const getDetectedPlatform = (): Platform | undefined =>\n PLATFORM_CHECKS.find(({ check }) => check())?.platform;\n\nconst getDependencies = (root: string): Record<string, string> => {\n try {\n const packageJsonPath = join(root, 'package.json');\n if (!existsSync(packageJsonPath)) return {};\n\n const { dependencies = {}, devDependencies = {} } = JSON.parse(\n readFileSync(packageJsonPath, 'utf-8')\n );\n return { ...dependencies, ...devDependencies };\n } catch {\n return {};\n }\n};\n\nexport const initSkills = async (projectRoot?: string) => {\n const root = findProjectRoot(\n projectRoot ? resolve(projectRoot) : process.cwd()\n );\n\n p.intro('Initializing Intlayer skills');\n\n const detectedPlatform = getDetectedPlatform();\n\n let platform: Platform;\n try {\n const response = await enquirer.prompt<{ platforms: Platform }>({\n type: 'autocomplete',\n name: 'platforms',\n message: 'Which platforms are you using? (Type to search)',\n multiple: false,\n initial: detectedPlatform\n ? PLATFORMS.indexOf(detectedPlatform)\n : undefined,\n choices: PLATFORM_OPTIONS.map((opt) => ({\n name: opt.value,\n message: opt.label,\n hint: opt.hint,\n })),\n });\n platform = response.platforms;\n } catch {\n p.cancel('Operation cancelled.');\n return;\n }\n\n if (!platform) {\n p.log.warn('No platform selected. Nothing to install.');\n return;\n }\n\n const dependencies = getDependencies(root);\n const initialValues = getInitialSkills(dependencies);\n\n const selectedSkills = await p.multiselect({\n message: 'Select the documentation skills to provide to your AI:',\n initialValues,\n options: SKILLS.map((skill) => ({\n value: skill,\n label: skill,\n hint: SKILLS_METADATA[skill],\n })),\n required: false,\n });\n\n if (\n p.isCancel(selectedSkills) ||\n !selectedSkills ||\n (selectedSkills as string[]).length === 0\n ) {\n p.cancel('Operation cancelled. No skills selected.');\n return;\n }\n\n const s = p.spinner();\n s.start('Installing skills...');\n\n try {\n const result = await installSkills(root, platform, selectedSkills);\n\n s.stop('Skills installed successfully');\n\n p.note(result, 'Success');\n } catch (error) {\n s.stop('Failed to install skills');\n p.log.error(error instanceof Error ? error.message : String(error));\n }\n\n p.outro('Intlayer skills initialization complete');\n};\n"],"mappings":"+RAeA,MAAM,EACJA,EAAAA,UAAU,OAAQ,GAAaC,EAAAA,mBAAmB,GAAU,MAAM,CAAC,IAChE,IAAc,CACb,MAAOA,EAAAA,mBAAmB,GAAU,YAAgB,IACpD,WACD,EACF,CAEU,EAIRD,EAAAA,UAAU,IAAK,IAAc,CAChC,MAAO,EACP,MAAOC,EAAAA,mBAAmB,GAAU,MACpC,KAAM,IAAIA,EAAAA,mBAAmB,GAAU,IAAI,GAC5C,EAAE,CAEU,MACX,EAAgB,MAAM,CAAE,WAAY,GAAO,CAAC,EAAE,SAE1C,EAAmB,GAAyC,CAChE,GAAI,CACF,IAAM,GAAA,EAAA,EAAA,MAAuB,EAAM,eAAe,CAClD,GAAI,EAAA,EAAA,EAAA,YAAY,EAAgB,CAAE,MAAO,EAAE,CAE3C,GAAM,CAAE,eAAe,EAAE,CAAE,kBAAkB,EAAE,EAAK,KAAK,OAAA,EAAA,EAAA,cAC1C,EAAiB,QAAQ,CACvC,CACD,MAAO,CAAE,GAAG,EAAc,GAAG,EAAiB,MACxC,CACN,MAAO,EAAE,GAIA,EAAa,KAAO,IAAyB,CACxD,IAAM,EAAOC,EAAAA,gBACX,GAAA,EAAA,EAAA,SAAsB,EAAY,CAAG,QAAQ,KAAK,CACnD,CAED,EAAE,MAAM,+BAA+B,CAEvC,IAAM,EAAmB,GAAqB,CAE1C,EACJ,GAAI,CAeF,GAdiB,MAAM,EAAA,QAAS,OAAgC,CAC9D,KAAM,eACN,KAAM,YACN,QAAS,kDACT,SAAU,GACV,QAAS,EACLF,EAAAA,UAAU,QAAQ,EAAiB,CACnC,IAAA,GACJ,QAAS,EAAiB,IAAK,IAAS,CACtC,KAAM,EAAI,MACV,QAAS,EAAI,MACb,KAAM,EAAI,KACX,EAAE,CACJ,CAAC,EACkB,eACd,CACN,EAAE,OAAO,uBAAuB,CAChC,OAGF,GAAI,CAAC,EAAU,CACb,EAAE,IAAI,KAAK,4CAA4C,CACvD,OAIF,IAAM,GAAA,EAAA,EAAA,kBADe,EAAgB,EAAK,CACU,CAE9C,EAAiB,MAAMG,EAAE,YAAY,CACzC,QAAS,yDACT,gBACA,QAASC,EAAAA,OAAO,IAAK,IAAW,CAC9B,MAAO,EACP,MAAO,EACP,KAAMC,EAAAA,gBAAgB,GACvB,EAAE,CACH,SAAU,GACX,CAAC,CAEF,GACEF,EAAE,SAAS,EAAe,EAC1B,CAAC,GACA,EAA4B,SAAW,EACxC,CACA,EAAE,OAAO,2CAA2C,CACpD,OAGF,IAAM,EAAIA,EAAE,SAAS,CACrB,EAAE,MAAM,uBAAuB,CAE/B,GAAI,CACF,IAAM,EAAS,MAAA,EAAA,EAAA,eAAoB,EAAM,EAAU,EAAe,CAElE,EAAE,KAAK,gCAAgC,CAEvC,EAAE,KAAK,EAAQ,UAAU,OAClB,EAAO,CACd,EAAE,KAAK,2BAA2B,CAClC,EAAE,IAAI,MAAM,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAAC,CAGrE,EAAE,MAAM,0CAA0C"}