@intlayer/cli 6.1.6 → 7.0.0-canary.0

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 (287) hide show
  1. package/dist/cjs/IntlayerEventListener.cjs +187 -239
  2. package/dist/cjs/IntlayerEventListener.cjs.map +1 -1
  3. package/dist/cjs/_virtual/_utils_asset.cjs +104 -0
  4. package/dist/cjs/_virtual/rolldown_runtime.cjs +25 -0
  5. package/dist/cjs/build.cjs +23 -42
  6. package/dist/cjs/build.cjs.map +1 -1
  7. package/dist/cjs/cli.cjs +370 -431
  8. package/dist/cjs/cli.cjs.map +1 -1
  9. package/dist/cjs/config.cjs +10 -35
  10. package/dist/cjs/config.cjs.map +1 -1
  11. package/dist/cjs/editor.cjs +51 -66
  12. package/dist/cjs/editor.cjs.map +1 -1
  13. package/dist/cjs/fill/fill.cjs +73 -301
  14. package/dist/cjs/fill/fill.cjs.map +1 -1
  15. package/dist/cjs/fill/formatAutoFillData.cjs +48 -106
  16. package/dist/cjs/fill/formatAutoFillData.cjs.map +1 -1
  17. package/dist/cjs/fill/formatAutoFilledFilePath.cjs +27 -43
  18. package/dist/cjs/fill/formatAutoFilledFilePath.cjs.map +1 -1
  19. package/dist/cjs/fill/formatFillData.cjs +50 -0
  20. package/dist/cjs/fill/formatFillData.cjs.map +1 -0
  21. package/dist/cjs/fill/groupLimiter.cjs +42 -0
  22. package/dist/cjs/fill/groupLimiter.cjs.map +1 -0
  23. package/dist/cjs/fill/index.cjs +5 -25
  24. package/dist/cjs/fill/listTranslationsTasks.cjs +77 -0
  25. package/dist/cjs/fill/listTranslationsTasks.cjs.map +1 -0
  26. package/dist/cjs/fill/test-original-case.cjs +10 -0
  27. package/dist/cjs/fill/test-original-case.cjs.map +1 -0
  28. package/dist/cjs/fill/translateDictionary.cjs +148 -0
  29. package/dist/cjs/fill/translateDictionary.cjs.map +1 -0
  30. package/dist/cjs/fill/writeAutoFill.cjs +48 -0
  31. package/dist/cjs/fill/writeAutoFill.cjs.map +1 -0
  32. package/dist/cjs/fill/writeFill.cjs +50 -0
  33. package/dist/cjs/fill/writeFill.cjs.map +1 -0
  34. package/dist/cjs/getTargetDictionary.cjs +36 -76
  35. package/dist/cjs/getTargetDictionary.cjs.map +1 -1
  36. package/dist/cjs/index.cjs +31 -45
  37. package/dist/cjs/listContentDeclaration.cjs +36 -64
  38. package/dist/cjs/listContentDeclaration.cjs.map +1 -1
  39. package/dist/cjs/liveSync.cjs +146 -221
  40. package/dist/cjs/liveSync.cjs.map +1 -1
  41. package/dist/cjs/pull.cjs +132 -195
  42. package/dist/cjs/pull.cjs.map +1 -1
  43. package/dist/cjs/push/pullLog.cjs +101 -144
  44. package/dist/cjs/push/pullLog.cjs.map +1 -1
  45. package/dist/cjs/push/push.cjs +159 -249
  46. package/dist/cjs/push/push.cjs.map +1 -1
  47. package/dist/cjs/pushConfig.cjs +18 -45
  48. package/dist/cjs/pushConfig.cjs.map +1 -1
  49. package/dist/cjs/pushLog.cjs +87 -128
  50. package/dist/cjs/pushLog.cjs.map +1 -1
  51. package/dist/cjs/reviewDoc.cjs +183 -291
  52. package/dist/cjs/reviewDoc.cjs.map +1 -1
  53. package/dist/cjs/test/index.cjs +52 -91
  54. package/dist/cjs/test/index.cjs.map +1 -1
  55. package/dist/cjs/test/listMissingTranslations.cjs +35 -62
  56. package/dist/cjs/test/listMissingTranslations.cjs.map +1 -1
  57. package/dist/cjs/translateDoc.cjs +127 -221
  58. package/dist/cjs/translateDoc.cjs.map +1 -1
  59. package/dist/cjs/utils/calculateChunks.cjs +85 -115
  60. package/dist/cjs/utils/calculateChunks.cjs.map +1 -1
  61. package/dist/cjs/utils/checkAccess.cjs +33 -72
  62. package/dist/cjs/utils/checkAccess.cjs.map +1 -1
  63. package/dist/cjs/utils/checkFileModifiedRange.cjs +75 -91
  64. package/dist/cjs/utils/checkFileModifiedRange.cjs.map +1 -1
  65. package/dist/cjs/utils/checkLastUpdateTime.cjs +17 -30
  66. package/dist/cjs/utils/checkLastUpdateTime.cjs.map +1 -1
  67. package/dist/cjs/utils/chunkInference.cjs +28 -47
  68. package/dist/cjs/utils/chunkInference.cjs.map +1 -1
  69. package/dist/cjs/utils/fixChunkStartEndChars.cjs +23 -42
  70. package/dist/cjs/utils/fixChunkStartEndChars.cjs.map +1 -1
  71. package/dist/cjs/utils/formatTimeDiff.cjs +17 -43
  72. package/dist/cjs/utils/formatTimeDiff.cjs.map +1 -1
  73. package/dist/cjs/utils/getIsFileUpdatedRecently.cjs +13 -32
  74. package/dist/cjs/utils/getIsFileUpdatedRecently.cjs.map +1 -1
  75. package/dist/cjs/utils/getOutputFilePath.cjs +71 -86
  76. package/dist/cjs/utils/getOutputFilePath.cjs.map +1 -1
  77. package/dist/cjs/utils/getParentPackageJSON.cjs +19 -44
  78. package/dist/cjs/utils/getParentPackageJSON.cjs.map +1 -1
  79. package/dist/cjs/utils/listSpecialChars.cjs +49 -73
  80. package/dist/cjs/utils/listSpecialChars.cjs.map +1 -1
  81. package/dist/cjs/utils/mapChunksBetweenFiles.cjs +90 -132
  82. package/dist/cjs/utils/mapChunksBetweenFiles.cjs.map +1 -1
  83. package/dist/cjs/utils/reorderParagraphs.cjs +86 -118
  84. package/dist/cjs/utils/reorderParagraphs.cjs.map +1 -1
  85. package/dist/cjs/watch.cjs +21 -39
  86. package/dist/cjs/watch.cjs.map +1 -1
  87. package/dist/esm/IntlayerEventListener.mjs +178 -201
  88. package/dist/esm/IntlayerEventListener.mjs.map +1 -1
  89. package/dist/esm/_virtual/_utils_asset.mjs +100 -0
  90. package/dist/esm/_virtual/rolldown_runtime.mjs +8 -0
  91. package/dist/esm/build.mjs +20 -23
  92. package/dist/esm/build.mjs.map +1 -1
  93. package/dist/esm/cli.mjs +349 -380
  94. package/dist/esm/cli.mjs.map +1 -1
  95. package/dist/esm/config.mjs +8 -14
  96. package/dist/esm/config.mjs.map +1 -1
  97. package/dist/esm/editor.mjs +47 -41
  98. package/dist/esm/editor.mjs.map +1 -1
  99. package/dist/esm/fill/fill.mjs +68 -300
  100. package/dist/esm/fill/fill.mjs.map +1 -1
  101. package/dist/esm/fill/formatAutoFillData.mjs +47 -81
  102. package/dist/esm/fill/formatAutoFillData.mjs.map +1 -1
  103. package/dist/esm/fill/formatAutoFilledFilePath.mjs +25 -19
  104. package/dist/esm/fill/formatAutoFilledFilePath.mjs.map +1 -1
  105. package/dist/esm/fill/formatFillData.mjs +50 -0
  106. package/dist/esm/fill/formatFillData.mjs.map +1 -0
  107. package/dist/esm/fill/groupLimiter.mjs +40 -0
  108. package/dist/esm/fill/groupLimiter.mjs.map +1 -0
  109. package/dist/esm/fill/index.mjs +4 -3
  110. package/dist/esm/fill/listTranslationsTasks.mjs +70 -0
  111. package/dist/esm/fill/listTranslationsTasks.mjs.map +1 -0
  112. package/dist/esm/fill/test-original-case.mjs +10 -0
  113. package/dist/esm/fill/test-original-case.mjs.map +1 -0
  114. package/dist/esm/fill/translateDictionary.mjs +141 -0
  115. package/dist/esm/fill/translateDictionary.mjs.map +1 -0
  116. package/dist/esm/fill/writeAutoFill.mjs +44 -0
  117. package/dist/esm/fill/writeAutoFill.mjs.map +1 -0
  118. package/dist/esm/fill/writeFill.mjs +45 -0
  119. package/dist/esm/fill/writeFill.mjs.map +1 -0
  120. package/dist/esm/getTargetDictionary.mjs +27 -48
  121. package/dist/esm/getTargetDictionary.mjs.map +1 -1
  122. package/dist/esm/index.mjs +15 -13
  123. package/dist/esm/listContentDeclaration.mjs +28 -43
  124. package/dist/esm/listContentDeclaration.mjs.map +1 -1
  125. package/dist/esm/liveSync.mjs +135 -187
  126. package/dist/esm/liveSync.mjs.map +1 -1
  127. package/dist/esm/pull.mjs +125 -178
  128. package/dist/esm/pull.mjs.map +1 -1
  129. package/dist/esm/push/pullLog.mjs +99 -125
  130. package/dist/esm/push/pullLog.mjs.map +1 -1
  131. package/dist/esm/push/push.mjs +149 -221
  132. package/dist/esm/push/push.mjs.map +1 -1
  133. package/dist/esm/pushConfig.mjs +14 -23
  134. package/dist/esm/pushConfig.mjs.map +1 -1
  135. package/dist/esm/pushLog.mjs +85 -109
  136. package/dist/esm/pushLog.mjs.map +1 -1
  137. package/dist/esm/reviewDoc.mjs +167 -264
  138. package/dist/esm/reviewDoc.mjs.map +1 -1
  139. package/dist/esm/test/index.mjs +47 -73
  140. package/dist/esm/test/index.mjs.map +1 -1
  141. package/dist/esm/test/listMissingTranslations.mjs +30 -41
  142. package/dist/esm/test/listMissingTranslations.mjs.map +1 -1
  143. package/dist/esm/translateDoc.mjs +114 -193
  144. package/dist/esm/translateDoc.mjs.map +1 -1
  145. package/dist/esm/utils/calculateChunks.mjs +83 -91
  146. package/dist/esm/utils/calculateChunks.mjs.map +1 -1
  147. package/dist/esm/utils/checkAccess.mjs +28 -46
  148. package/dist/esm/utils/checkAccess.mjs.map +1 -1
  149. package/dist/esm/utils/checkFileModifiedRange.mjs +73 -65
  150. package/dist/esm/utils/checkFileModifiedRange.mjs.map +1 -1
  151. package/dist/esm/utils/checkLastUpdateTime.mjs +15 -6
  152. package/dist/esm/utils/checkLastUpdateTime.mjs.map +1 -1
  153. package/dist/esm/utils/chunkInference.mjs +24 -24
  154. package/dist/esm/utils/chunkInference.mjs.map +1 -1
  155. package/dist/esm/utils/fixChunkStartEndChars.mjs +22 -18
  156. package/dist/esm/utils/fixChunkStartEndChars.mjs.map +1 -1
  157. package/dist/esm/utils/formatTimeDiff.mjs +16 -19
  158. package/dist/esm/utils/formatTimeDiff.mjs.map +1 -1
  159. package/dist/esm/utils/getIsFileUpdatedRecently.mjs +11 -8
  160. package/dist/esm/utils/getIsFileUpdatedRecently.mjs.map +1 -1
  161. package/dist/esm/utils/getOutputFilePath.mjs +70 -62
  162. package/dist/esm/utils/getOutputFilePath.mjs.map +1 -1
  163. package/dist/esm/utils/getParentPackageJSON.mjs +16 -20
  164. package/dist/esm/utils/getParentPackageJSON.mjs.map +1 -1
  165. package/dist/esm/utils/listSpecialChars.mjs +48 -49
  166. package/dist/esm/utils/listSpecialChars.mjs.map +1 -1
  167. package/dist/esm/utils/mapChunksBetweenFiles.mjs +87 -107
  168. package/dist/esm/utils/mapChunksBetweenFiles.mjs.map +1 -1
  169. package/dist/esm/utils/reorderParagraphs.mjs +85 -93
  170. package/dist/esm/utils/reorderParagraphs.mjs.map +1 -1
  171. package/dist/esm/watch.mjs +17 -17
  172. package/dist/esm/watch.mjs.map +1 -1
  173. package/dist/types/IntlayerEventListener.d.ts +63 -59
  174. package/dist/types/IntlayerEventListener.d.ts.map +1 -1
  175. package/dist/types/build.d.ts +10 -7
  176. package/dist/types/build.d.ts.map +1 -1
  177. package/dist/types/cli.d.ts +13 -10
  178. package/dist/types/cli.d.ts.map +1 -1
  179. package/dist/types/config.d.ts +7 -4
  180. package/dist/types/config.d.ts.map +1 -1
  181. package/dist/types/editor.d.ts +6 -4
  182. package/dist/types/editor.d.ts.map +1 -1
  183. package/dist/types/fill/fill.d.ts +20 -14
  184. package/dist/types/fill/fill.d.ts.map +1 -1
  185. package/dist/types/fill/formatAutoFillData.d.ts +10 -7
  186. package/dist/types/fill/formatAutoFillData.d.ts.map +1 -1
  187. package/dist/types/fill/formatAutoFilledFilePath.d.ts +6 -2
  188. package/dist/types/fill/formatAutoFilledFilePath.d.ts.map +1 -1
  189. package/dist/types/fill/formatFillData.d.ts +12 -0
  190. package/dist/types/fill/formatFillData.d.ts.map +1 -0
  191. package/dist/types/fill/groupLimiter.d.ts +15 -0
  192. package/dist/types/fill/groupLimiter.d.ts.map +1 -0
  193. package/dist/types/fill/index.d.ts +3 -3
  194. package/dist/types/fill/listTranslationsTasks.d.ts +15 -0
  195. package/dist/types/fill/listTranslationsTasks.d.ts.map +1 -0
  196. package/dist/types/fill/test-original-case.d.ts +1 -0
  197. package/dist/types/fill/translateDictionary.d.ts +19 -0
  198. package/dist/types/fill/translateDictionary.d.ts.map +1 -0
  199. package/dist/types/fill/writeAutoFill.d.ts +7 -0
  200. package/dist/types/fill/writeAutoFill.d.ts.map +1 -0
  201. package/dist/types/fill/writeFill.d.ts +7 -0
  202. package/dist/types/fill/writeFill.d.ts.map +1 -0
  203. package/dist/types/getTargetDictionary.d.ts +17 -13
  204. package/dist/types/getTargetDictionary.d.ts.map +1 -1
  205. package/dist/types/index.d.ts +15 -14
  206. package/dist/types/listContentDeclaration.d.ts +10 -7
  207. package/dist/types/listContentDeclaration.d.ts.map +1 -1
  208. package/dist/types/liveSync.d.ts +8 -3
  209. package/dist/types/liveSync.d.ts.map +1 -1
  210. package/dist/types/pull.d.ts +9 -6
  211. package/dist/types/pull.d.ts.map +1 -1
  212. package/dist/types/push/pullLog.d.ts +25 -21
  213. package/dist/types/push/pullLog.d.ts.map +1 -1
  214. package/dist/types/push/push.d.ts +13 -9
  215. package/dist/types/push/push.d.ts.map +1 -1
  216. package/dist/types/pushConfig.d.ts +7 -4
  217. package/dist/types/pushConfig.d.ts.map +1 -1
  218. package/dist/types/pushLog.d.ts +23 -20
  219. package/dist/types/pushLog.d.ts.map +1 -1
  220. package/dist/types/reviewDoc.d.ts +34 -17
  221. package/dist/types/reviewDoc.d.ts.map +1 -1
  222. package/dist/types/test/index.d.ts +9 -5
  223. package/dist/types/test/index.d.ts.map +1 -1
  224. package/dist/types/test/listMissingTranslations.d.ts +14 -10
  225. package/dist/types/test/listMissingTranslations.d.ts.map +1 -1
  226. package/dist/types/translateDoc.d.ts +34 -17
  227. package/dist/types/translateDoc.d.ts.map +1 -1
  228. package/dist/types/utils/calculateChunks.d.ts +10 -7
  229. package/dist/types/utils/calculateChunks.d.ts.map +1 -1
  230. package/dist/types/utils/checkAccess.d.ts +8 -4
  231. package/dist/types/utils/checkAccess.d.ts.map +1 -1
  232. package/dist/types/utils/checkFileModifiedRange.d.ts +8 -6
  233. package/dist/types/utils/checkFileModifiedRange.d.ts.map +1 -1
  234. package/dist/types/utils/checkLastUpdateTime.d.ts +4 -1
  235. package/dist/types/utils/checkLastUpdateTime.d.ts.map +1 -1
  236. package/dist/types/utils/chunkInference.d.ts +9 -6
  237. package/dist/types/utils/chunkInference.d.ts.map +1 -1
  238. package/dist/types/utils/fixChunkStartEndChars.d.ts +4 -1
  239. package/dist/types/utils/fixChunkStartEndChars.d.ts.map +1 -1
  240. package/dist/types/utils/formatTimeDiff.d.ts +4 -1
  241. package/dist/types/utils/formatTimeDiff.d.ts.map +1 -1
  242. package/dist/types/utils/getIsFileUpdatedRecently.d.ts +4 -1
  243. package/dist/types/utils/getIsFileUpdatedRecently.d.ts.map +1 -1
  244. package/dist/types/utils/getOutputFilePath.d.ts +7 -2
  245. package/dist/types/utils/getOutputFilePath.d.ts.map +1 -1
  246. package/dist/types/utils/getParentPackageJSON.d.ts +30 -28
  247. package/dist/types/utils/getParentPackageJSON.d.ts.map +1 -1
  248. package/dist/types/utils/listSpecialChars.d.ts +9 -7
  249. package/dist/types/utils/listSpecialChars.d.ts.map +1 -1
  250. package/dist/types/utils/mapChunksBetweenFiles.d.ts +10 -6
  251. package/dist/types/utils/mapChunksBetweenFiles.d.ts.map +1 -1
  252. package/dist/types/utils/reorderParagraphs.d.ts +4 -1
  253. package/dist/types/utils/reorderParagraphs.d.ts.map +1 -1
  254. package/dist/types/watch.d.ts +9 -6
  255. package/dist/types/watch.d.ts.map +1 -1
  256. package/package.json +42 -47
  257. package/LICENSE +0 -202
  258. package/dist/cjs/fill/autoFill.cjs +0 -105
  259. package/dist/cjs/fill/autoFill.cjs.map +0 -1
  260. package/dist/cjs/fill/index.cjs.map +0 -1
  261. package/dist/cjs/index.cjs.map +0 -1
  262. package/dist/cjs/utils/getChunk.cjs +0 -77
  263. package/dist/cjs/utils/getChunk.cjs.map +0 -1
  264. package/dist/cjs/utils/splitTextByLine.cjs +0 -35
  265. package/dist/cjs/utils/splitTextByLine.cjs.map +0 -1
  266. package/dist/esm/fill/autoFill.mjs +0 -92
  267. package/dist/esm/fill/autoFill.mjs.map +0 -1
  268. package/dist/esm/fill/index.mjs.map +0 -1
  269. package/dist/esm/index.mjs.map +0 -1
  270. package/dist/esm/prompts/REVIEW_PROMPT.md +0 -37
  271. package/dist/esm/prompts/TRANSLATE_PROMPT.md +0 -38
  272. package/dist/esm/utils/calculrateChunkTest.md +0 -9
  273. package/dist/esm/utils/getChunk.mjs +0 -53
  274. package/dist/esm/utils/getChunk.mjs.map +0 -1
  275. package/dist/esm/utils/splitTextByLine.mjs +0 -11
  276. package/dist/esm/utils/splitTextByLine.mjs.map +0 -1
  277. package/dist/types/fill/autoFill.d.ts +0 -4
  278. package/dist/types/fill/autoFill.d.ts.map +0 -1
  279. package/dist/types/fill/index.d.ts.map +0 -1
  280. package/dist/types/index.d.ts.map +0 -1
  281. package/dist/types/utils/getChunk.d.ts +0 -9
  282. package/dist/types/utils/getChunk.d.ts.map +0 -1
  283. package/dist/types/utils/splitTextByLine.d.ts +0 -2
  284. package/dist/types/utils/splitTextByLine.d.ts.map +0 -1
  285. /package/dist/{cjs → assets}/prompts/REVIEW_PROMPT.md +0 -0
  286. /package/dist/{cjs → assets}/prompts/TRANSLATE_PROMPT.md +0 -0
  287. /package/dist/{cjs/utils/calculrateChunkTest.md → assets/utils/_calculateChunkTest.md} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/fill/formatAutoFilledFilePath.ts"],"sourcesContent":["import { Locales } from '@intlayer/config';\nimport { basename, dirname, join } from 'path';\n\nconst transformUriToAbsolutePath = (\n uri: string,\n filePath: string,\n baseDir: string\n) => {\n if (uri.startsWith('/')) {\n return join(baseDir, uri);\n }\n\n if (uri.startsWith('./')) {\n return join(dirname(filePath), uri);\n }\n\n return filePath;\n};\n\nexport const formatAutoFilledFilePath = (\n autoFillField: string,\n dictionaryKey: string,\n dictionaryFilePath: string,\n baseDir: string,\n locale?: Locales\n) => {\n // transform `/src/components/home/index.content.json` to `index`\n // transform `./test.content.tsx` to `test`\n const fileName = basename(dictionaryFilePath)\n .split('.')\n .slice(0, -2) // Remove last 2 extensions (.content.tsx)\n .join('.');\n\n let result: string = autoFillField\n .replace('{{key}}', dictionaryKey)\n .replace('{{fileName}}', fileName);\n\n if (locale) {\n result = result.replace('{{locale}}', locale);\n }\n\n return transformUriToAbsolutePath(result, dictionaryFilePath, baseDir);\n};\n"],"mappings":"AACA,SAAS,UAAU,SAAS,YAAY;AAExC,MAAM,6BAA6B,CACjC,KACA,UACA,YACG;AACH,MAAI,IAAI,WAAW,GAAG,GAAG;AACvB,WAAO,KAAK,SAAS,GAAG;AAAA,EAC1B;AAEA,MAAI,IAAI,WAAW,IAAI,GAAG;AACxB,WAAO,KAAK,QAAQ,QAAQ,GAAG,GAAG;AAAA,EACpC;AAEA,SAAO;AACT;AAEO,MAAM,2BAA2B,CACtC,eACA,eACA,oBACA,SACA,WACG;AAGH,QAAM,WAAW,SAAS,kBAAkB,EACzC,MAAM,GAAG,EACT,MAAM,GAAG,EAAE,EACX,KAAK,GAAG;AAEX,MAAI,SAAiB,cAClB,QAAQ,WAAW,aAAa,EAChC,QAAQ,gBAAgB,QAAQ;AAEnC,MAAI,QAAQ;AACV,aAAS,OAAO,QAAQ,cAAc,MAAM;AAAA,EAC9C;AAEA,SAAO,2BAA2B,QAAQ,oBAAoB,OAAO;AACvE;","names":[]}
1
+ {"version":3,"file":"formatAutoFilledFilePath.mjs","names":["result: string"],"sources":["../../../src/fill/formatAutoFilledFilePath.ts"],"sourcesContent":["import {\n basename,\n dirname,\n isAbsolute,\n normalize,\n relative,\n resolve,\n} from 'node:path';\nimport type { LocalesValues } from '@intlayer/types';\n\nexport const formatAutoFilledFilePath = (\n autoFillField: string,\n dictionaryKey: string,\n dictionaryFilePath: string,\n baseDir: string,\n locale?: LocalesValues\n): string => {\n // Validate inputs\n if (!autoFillField || typeof autoFillField !== 'string') {\n throw new Error('autoFillField must be a non-empty string');\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 let result: string = autoFillField\n .replace(/\\{\\{key\\}\\}/g, originalFileName) // Use original filename, not dictionaryKey\n .replace(/\\{\\{fileName\\}\\}/g, originalFileName);\n\n if (locale) {\n result = result.replace(/\\{\\{locale\\}\\}/g, 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":";;;AAUA,MAAa,4BACX,eACA,eACA,oBACA,SACA,WACW;AAEX,KAAI,CAAC,iBAAiB,OAAO,kBAAkB,SAC7C,OAAM,IAAI,MAAM,2CAA2C;AAE7D,KAAI,CAAC,iBAAiB,OAAO,kBAAkB,SAC7C,OAAM,IAAI,MAAM,2CAA2C;AAE7D,KAAI,CAAC,sBAAsB,OAAO,uBAAuB,SACvD,OAAM,IAAI,MAAM,gDAAgD;AAElE,KAAI,CAAC,WAAW,OAAO,YAAY,SACjC,OAAM,IAAI,MAAM,qCAAqC;CAIvD,MAAM,mBAAmB,SAAS,mBAAmB,CAClD,MAAM,IAAI,CACV,MAAM,GAAG,GAAG,CACZ,KAAK,IAAI;CAGZ,IAAIA,SAAiB,cAClB,QAAQ,gBAAgB,iBAAiB,CACzC,QAAQ,qBAAqB,iBAAiB;AAEjD,KAAI,OACF,UAAS,OAAO,QAAQ,mBAAmB,OAAO;CAIpD,MAAM,yBAAyB,WAAW,mBAAmB,GACzD,qBACA,QAAQ,SAAS,mBAAmB;AAGxC,KAAI,OAAO,WAAW,KAAK,IAAI,OAAO,WAAW,MAAM,CAIrD,QAFqB,QADL,QAAQ,uBAAuB,EACT,OAAO;AAM/C,KAAI,WAAW,OAAO,EAAE;EACtB,MAAM,mBAAmB,UAAU,OAAO;EAC1C,MAAM,oBAAoB,UAAU,QAAQ;AAI5C,MACE,OAAO,WAAW,IAAI,IACtB,CAAC,iBAAiB,WAAW,kBAAkB,EAC/C;GAEA,MAAM,iBAAiB,QAAQ,SAAS,OAAO,UAAU,EAAE,CAAC;AAG5D,OACE,CAAC,OAAO,WAAW,QAAQ,IAC3B,CAAC,OAAO,WAAW,QAAQ,IAC3B,CAAC,OAAO,WAAW,QAAQ,IAC3B,CAAC,OAAO,WAAW,SAAS,IAC5B,CAAC,OAAO,WAAW,UAAU,CAE7B,QAAO;;AAKX,SAAO;;AAIT,QAAO,UAAU,OAAO"}
@@ -0,0 +1,50 @@
1
+ import { formatAutoFilledFilePath } from "./formatAutoFilledFilePath.mjs";
2
+
3
+ //#region src/fill/formatFillData.ts
4
+ const formatFillData = (autoFillField, localeList, filePath, dictionaryKey, configuration) => {
5
+ const outputContentDeclarationFile = [];
6
+ const baseDir = configuration.content.baseDir;
7
+ if (!autoFillField) return outputContentDeclarationFile;
8
+ if (typeof autoFillField === "string") {
9
+ if (autoFillField.includes("{{locale}}")) {
10
+ const output = localeList.map((locale) => {
11
+ const formattedFilePath = formatAutoFilledFilePath(autoFillField, dictionaryKey, filePath, baseDir, locale);
12
+ return {
13
+ localeList: [locale],
14
+ filePath: formattedFilePath,
15
+ isPerLocale: true
16
+ };
17
+ });
18
+ outputContentDeclarationFile.push(...output);
19
+ } else {
20
+ const formattedFilePath = formatAutoFilledFilePath(autoFillField, dictionaryKey, filePath, baseDir);
21
+ outputContentDeclarationFile.push({
22
+ localeList,
23
+ filePath: formattedFilePath,
24
+ isPerLocale: false
25
+ });
26
+ }
27
+ return outputContentDeclarationFile;
28
+ }
29
+ if (typeof autoFillField === "object") {
30
+ const groupedByFilePath = Object.keys(autoFillField).filter((locale) => typeof autoFillField[locale] === "string").filter((locale) => Boolean(autoFillField[locale])).map((locale) => {
31
+ const formattedFilePath = formatAutoFilledFilePath(autoFillField[locale], dictionaryKey, filePath, baseDir, locale);
32
+ return {
33
+ localeList: [locale],
34
+ filePath: formattedFilePath,
35
+ isPerLocale: true
36
+ };
37
+ }).reduce((acc, curr) => {
38
+ const existing = acc.find((item) => item.filePath === curr.filePath);
39
+ if (existing) existing.localeList.push(...curr.localeList);
40
+ else acc.push(curr);
41
+ return acc;
42
+ }, []);
43
+ outputContentDeclarationFile.push(...groupedByFilePath);
44
+ }
45
+ return outputContentDeclarationFile;
46
+ };
47
+
48
+ //#endregion
49
+ export { formatFillData };
50
+ //# sourceMappingURL=formatFillData.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatFillData.mjs","names":["outputContentDeclarationFile: FillData[]"],"sources":["../../../src/fill/formatFillData.ts"],"sourcesContent":["import type { Fill, IntlayerConfig, LocalesValues } from '@intlayer/types';\nimport { formatAutoFilledFilePath } from './formatAutoFilledFilePath';\n\nexport type FillData = {\n localeList: LocalesValues[];\n filePath: string;\n isPerLocale: boolean;\n};\n\nexport const formatFillData = (\n autoFillField: Fill,\n localeList: LocalesValues[],\n filePath: string,\n dictionaryKey: string,\n configuration: IntlayerConfig\n): FillData[] => {\n const outputContentDeclarationFile: FillData[] = [];\n\n const baseDir = configuration.content.baseDir;\n\n if (!autoFillField) return outputContentDeclarationFile;\n\n if (typeof autoFillField === 'string') {\n if (autoFillField.includes('{{locale}}')) {\n const output = localeList.map((locale) => {\n const formattedFilePath = formatAutoFilledFilePath(\n autoFillField,\n dictionaryKey,\n filePath,\n baseDir,\n locale\n );\n\n return {\n localeList: [locale],\n filePath: formattedFilePath,\n isPerLocale: true,\n };\n });\n\n outputContentDeclarationFile.push(...output);\n } else {\n const formattedFilePath = formatAutoFilledFilePath(\n autoFillField,\n dictionaryKey,\n filePath,\n baseDir\n );\n\n outputContentDeclarationFile.push({\n localeList,\n filePath: formattedFilePath,\n isPerLocale: false,\n });\n }\n\n return outputContentDeclarationFile;\n }\n\n if (typeof autoFillField === 'object') {\n const localeList = Object.keys(autoFillField).filter(\n (locale) =>\n typeof autoFillField[locale as keyof typeof autoFillField] === 'string'\n ) as LocalesValues[];\n\n const output: FillData[] = localeList\n .filter((locale) =>\n Boolean(autoFillField[locale as keyof typeof autoFillField])\n )\n .map((locale) => {\n const formattedFilePath = formatAutoFilledFilePath(\n autoFillField[locale as keyof typeof autoFillField] as string,\n dictionaryKey,\n filePath,\n baseDir,\n locale\n );\n\n return {\n localeList: [locale],\n filePath: formattedFilePath,\n isPerLocale: true,\n };\n });\n\n // Group by filePath and merge localeList\n const groupedByFilePath = output.reduce((acc, curr) => {\n const existing = acc.find((item) => item.filePath === curr.filePath);\n if (existing) {\n existing.localeList.push(...curr.localeList);\n } else {\n acc.push(curr);\n }\n return acc;\n }, [] as FillData[]);\n\n outputContentDeclarationFile.push(...groupedByFilePath);\n }\n\n return outputContentDeclarationFile;\n};\n"],"mappings":";;;AASA,MAAa,kBACX,eACA,YACA,UACA,eACA,kBACe;CACf,MAAMA,+BAA2C,EAAE;CAEnD,MAAM,UAAU,cAAc,QAAQ;AAEtC,KAAI,CAAC,cAAe,QAAO;AAE3B,KAAI,OAAO,kBAAkB,UAAU;AACrC,MAAI,cAAc,SAAS,aAAa,EAAE;GACxC,MAAM,SAAS,WAAW,KAAK,WAAW;IACxC,MAAM,oBAAoB,yBACxB,eACA,eACA,UACA,SACA,OACD;AAED,WAAO;KACL,YAAY,CAAC,OAAO;KACpB,UAAU;KACV,aAAa;KACd;KACD;AAEF,gCAA6B,KAAK,GAAG,OAAO;SACvC;GACL,MAAM,oBAAoB,yBACxB,eACA,eACA,UACA,QACD;AAED,gCAA6B,KAAK;IAChC;IACA,UAAU;IACV,aAAa;IACd,CAAC;;AAGJ,SAAO;;AAGT,KAAI,OAAO,kBAAkB,UAAU;EA2BrC,MAAM,oBA1Ba,OAAO,KAAK,cAAc,CAAC,QAC3C,WACC,OAAO,cAAc,YAA0C,SAClE,CAGE,QAAQ,WACP,QAAQ,cAAc,QAAsC,CAC7D,CACA,KAAK,WAAW;GACf,MAAM,oBAAoB,yBACxB,cAAc,SACd,eACA,UACA,SACA,OACD;AAED,UAAO;IACL,YAAY,CAAC,OAAO;IACpB,UAAU;IACV,aAAa;IACd;IACD,CAG6B,QAAQ,KAAK,SAAS;GACrD,MAAM,WAAW,IAAI,MAAM,SAAS,KAAK,aAAa,KAAK,SAAS;AACpE,OAAI,SACF,UAAS,WAAW,KAAK,GAAG,KAAK,WAAW;OAE5C,KAAI,KAAK,KAAK;AAEhB,UAAO;KACN,EAAE,CAAe;AAEpB,+BAA6B,KAAK,GAAG,kBAAkB;;AAGzD,QAAO"}
@@ -0,0 +1,40 @@
1
+ import { pLimit } from "@intlayer/chokidar";
2
+
3
+ //#region src/fill/groupLimiter.ts
4
+ /**
5
+ * Creates a group limiter that controls concurrency and provides a sync point
6
+ * to wait for all scheduled tasks to complete.
7
+ */
8
+ const makeGroupLimiter = (concurrency) => {
9
+ const limit = pLimit(concurrency);
10
+ let inflight = 0;
11
+ let resolveDone;
12
+ const donePromise = new Promise((r) => {
13
+ resolveDone = r;
14
+ });
15
+ let doneResolved = false;
16
+ const schedule = (fn) => {
17
+ inflight++;
18
+ limit(async () => {
19
+ await fn();
20
+ inflight--;
21
+ if (inflight === 0 && !doneResolved && limit.pendingCount === 0 && limit.activeCount === 0) {
22
+ doneResolved = true;
23
+ resolveDone();
24
+ }
25
+ });
26
+ };
27
+ const done = () => donePromise;
28
+ const activeCount = () => limit.activeCount;
29
+ const pendingCount = () => limit.pendingCount;
30
+ return {
31
+ schedule,
32
+ done,
33
+ activeCount,
34
+ pendingCount
35
+ };
36
+ };
37
+
38
+ //#endregion
39
+ export { makeGroupLimiter };
40
+ //# sourceMappingURL=groupLimiter.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groupLimiter.mjs","names":["resolveDone!: () => void"],"sources":["../../../src/fill/groupLimiter.ts"],"sourcesContent":["import { pLimit } from '@intlayer/chokidar';\n\nexport type GroupLimiter = {\n schedule: <T>(fn: () => Promise<T>) => void;\n done: () => Promise<void>;\n activeCount: () => number;\n pendingCount: () => number;\n};\n\ntype PLimitFunction = {\n (...args: any[]): Promise<any>;\n activeCount: number;\n pendingCount: number;\n clearQueue: () => void;\n concurrency: number;\n};\n\n/**\n * Creates a group limiter that controls concurrency and provides a sync point\n * to wait for all scheduled tasks to complete.\n */\nexport const makeGroupLimiter = (concurrency: number): GroupLimiter => {\n const limit = pLimit(concurrency) as PLimitFunction;\n let inflight = 0;\n let resolveDone!: () => void;\n const donePromise = new Promise<void>((r) => {\n resolveDone = r;\n });\n let doneResolved = false;\n\n const schedule = <T>(fn: () => Promise<T>): void => {\n inflight++;\n limit(async () => {\n await fn();\n\n inflight--;\n if (\n inflight === 0 &&\n !doneResolved &&\n limit.pendingCount === 0 &&\n limit.activeCount === 0\n ) {\n doneResolved = true;\n resolveDone();\n }\n });\n };\n\n const done = (): Promise<void> => donePromise;\n\n const activeCount = (): number => limit.activeCount;\n const pendingCount = (): number => limit.pendingCount;\n\n return { schedule, done, activeCount, pendingCount };\n};\n"],"mappings":";;;;;;;AAqBA,MAAa,oBAAoB,gBAAsC;CACrE,MAAM,QAAQ,OAAO,YAAY;CACjC,IAAI,WAAW;CACf,IAAIA;CACJ,MAAM,cAAc,IAAI,SAAe,MAAM;AAC3C,gBAAc;GACd;CACF,IAAI,eAAe;CAEnB,MAAM,YAAe,OAA+B;AAClD;AACA,QAAM,YAAY;AAChB,SAAM,IAAI;AAEV;AACA,OACE,aAAa,KACb,CAAC,gBACD,MAAM,iBAAiB,KACvB,MAAM,gBAAgB,GACtB;AACA,mBAAe;AACf,iBAAa;;IAEf;;CAGJ,MAAM,aAA4B;CAElC,MAAM,oBAA4B,MAAM;CACxC,MAAM,qBAA6B,MAAM;AAEzC,QAAO;EAAE;EAAU;EAAM;EAAa;EAAc"}
@@ -1,3 +1,4 @@
1
- export * from "./autoFill.mjs";
2
- export * from "./fill.mjs";
3
- //# sourceMappingURL=index.mjs.map
1
+ import { writeFill } from "./writeFill.mjs";
2
+ import { fill } from "./fill.mjs";
3
+
4
+ export { fill, writeFill };
@@ -0,0 +1,70 @@
1
+ import { formatLocale } from "@intlayer/chokidar";
2
+ import { ANSIColors, colon, colorize, colorizeKey, colorizePath, getAppLogger } from "@intlayer/config";
3
+ import { basename } from "node:path";
4
+ import { getUnmergedDictionaries } from "@intlayer/unmerged-dictionaries-entry";
5
+ import { getFilterTranslationsOnlyDictionary, getMissingLocalesContent } from "@intlayer/core";
6
+ import { getDictionaries } from "@intlayer/dictionaries-entry";
7
+
8
+ //#region src/fill/listTranslationsTasks.ts
9
+ const listTranslationsTasks = (localIds, outputLocales, mode, baseLocale, configuration) => {
10
+ const appLogger = getAppLogger(configuration);
11
+ const mergedDictionariesRecord = getDictionaries(configuration);
12
+ const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);
13
+ const dictionariesToProcess = Object.values(unmergedDictionariesRecord).flat().filter((dictionary) => localIds.includes(dictionary.localId));
14
+ const maxKeyLength = Math.max(...dictionariesToProcess.map((dict) => dict.key.length));
15
+ const translationTasks = [];
16
+ for (const targetUnmergedDictionary of dictionariesToProcess) {
17
+ const dictionaryPreset = colon([
18
+ " - ",
19
+ colorize("[", ANSIColors.GREY_DARK),
20
+ colorizeKey(targetUnmergedDictionary.key),
21
+ colorize("]", ANSIColors.GREY_DARK)
22
+ ].join(""), { colSize: maxKeyLength + 6 });
23
+ const dictionaryKey = targetUnmergedDictionary.key;
24
+ const dictionaryLocalId = targetUnmergedDictionary.localId;
25
+ const mainDictionaryToProcess = mergedDictionariesRecord[dictionaryKey];
26
+ if ((targetUnmergedDictionary.fill ?? configuration.content.fill) === false) continue;
27
+ const sourceLocale = targetUnmergedDictionary.locale ?? baseLocale;
28
+ if (!mainDictionaryToProcess) {
29
+ appLogger(`${dictionaryPreset} Dictionary not found in dictionariesRecord. Skipping.`, { level: "warn" });
30
+ continue;
31
+ }
32
+ if (!targetUnmergedDictionary.filePath) {
33
+ appLogger(`${dictionaryPreset} Dictionary has no file path. Skipping.`, { level: "warn" });
34
+ continue;
35
+ }
36
+ const sourceLocaleContent = getFilterTranslationsOnlyDictionary(mainDictionaryToProcess, sourceLocale);
37
+ if (Object.keys(sourceLocaleContent).length === 0) {
38
+ appLogger(`${dictionaryPreset} No content found for dictionary in source locale ${formatLocale(sourceLocale)}. Skipping translation for this dictionary.`, { level: "warn" });
39
+ continue;
40
+ }
41
+ /**
42
+ * In 'complete' mode, filter only the missing locales to translate
43
+ *
44
+ * Skip the dictionary if there are no missing locales to translate
45
+ */
46
+ let outputLocalesList = outputLocales;
47
+ if (mode === "complete") outputLocalesList = getMissingLocalesContent(targetUnmergedDictionary, outputLocales, {
48
+ dictionaryKey: targetUnmergedDictionary.key,
49
+ keyPath: [],
50
+ plugins: []
51
+ });
52
+ if (outputLocalesList.length === 0) {
53
+ appLogger(`${dictionaryPreset} No locales to fill, Skipping ${colorizePath(basename(targetUnmergedDictionary.filePath))}`, { level: "warn" });
54
+ continue;
55
+ }
56
+ translationTasks.push({
57
+ dictionaryKey,
58
+ dictionaryLocalId,
59
+ sourceLocale,
60
+ targetLocales: outputLocalesList,
61
+ dictionaryPreset,
62
+ dictionaryFilePath: targetUnmergedDictionary.filePath
63
+ });
64
+ }
65
+ return translationTasks;
66
+ };
67
+
68
+ //#endregion
69
+ export { listTranslationsTasks };
70
+ //# sourceMappingURL=listTranslationsTasks.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listTranslationsTasks.mjs","names":["translationTasks: TranslationTask[]","mainDictionaryToProcess: Dictionary","sourceLocale: Locale","outputLocalesList: Locale[]"],"sources":["../../../src/fill/listTranslationsTasks.ts"],"sourcesContent":["import { basename } from 'node:path';\nimport { formatLocale } from '@intlayer/chokidar';\nimport {\n ANSIColors,\n colon,\n colorize,\n colorizeKey,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config';\nimport {\n getFilterTranslationsOnlyDictionary,\n getMissingLocalesContent,\n} from '@intlayer/core';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type {\n ContentNode,\n Dictionary,\n IntlayerConfig,\n LocalDictionaryId,\n Locale,\n} from '@intlayer/types';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\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 maxKeyLength = Math.max(\n ...dictionariesToProcess.map((dict) => dict.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 dictionaryFill =\n targetUnmergedDictionary.fill ?? configuration.content.fill;\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 const missingLocales = getMissingLocalesContent(\n targetUnmergedDictionary as unknown as ContentNode,\n outputLocales,\n {\n dictionaryKey: targetUnmergedDictionary.key,\n keyPath: [],\n plugins: [],\n }\n );\n\n outputLocalesList = missingLocales;\n }\n\n if (outputLocalesList.length === 0) {\n appLogger(\n `${dictionaryPreset} No locales to fill, Skipping ${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 translationTasks;\n};\n"],"mappings":";;;;;;;;AAiCA,MAAa,yBACX,UACA,eACA,MACA,YACA,kBACsB;CACtB,MAAM,YAAY,aAAa,cAAc;CAE7C,MAAM,2BAA2B,gBAAgB,cAAc;CAC/D,MAAM,6BAA6B,wBAAwB,cAAc;CAGzE,MAAM,wBADsB,OAAO,OAAO,2BAA2B,CAAC,MAAM,CAC1B,QAAQ,eACxD,SAAS,SAAS,WAAW,QAAS,CACvC;CAED,MAAM,eAAe,KAAK,IACxB,GAAG,sBAAsB,KAAK,SAAS,KAAK,IAAI,OAAO,CACxD;CAED,MAAMA,mBAAsC,EAAE;AAE9C,MAAK,MAAM,4BAA4B,uBAAuB;EAC5D,MAAM,mBAAmB,MACvB;GACE;GACA,SAAS,KAAK,WAAW,UAAU;GACnC,YAAY,yBAAyB,IAAI;GACzC,SAAS,KAAK,WAAW,UAAU;GACpC,CAAC,KAAK,GAAG,EACV,EAAE,SAAS,eAAe,GAAG,CAC9B;EAED,MAAM,gBAAgB,yBAAyB;EAC/C,MAAM,oBAAoB,yBAAyB;EACnD,MAAMC,0BACJ,yBAAyB;AAI3B,OAFE,yBAAyB,QAAQ,cAAc,QAAQ,UAElC,MAAO;EAE9B,MAAMC,eAAwB,yBAAyB,UACrD;AAEF,MAAI,CAAC,yBAAyB;AAC5B,aACE,GAAG,iBAAiB,yDACpB,EACE,OAAO,QACR,CACF;AACD;;AAGF,MAAI,CAAC,yBAAyB,UAAU;AACtC,aAAU,GAAG,iBAAiB,0CAA0C,EACtE,OAAO,QACR,CAAC;AACF;;EAGF,MAAM,sBAAsB,oCAC1B,yBACA,aACD;AAED,MACE,OAAO,KAAK,oBAA+C,CAAC,WAAW,GACvE;AACA,aACE,GAAG,iBAAiB,oDAAoD,aAAa,aAAa,CAAC,8CACnG,EACE,OAAO,QACR,CACF;AACD;;;;;;;EAQF,IAAIC,oBAA8B;AAElC,MAAI,SAAS,WAWX,qBAVuB,yBACrB,0BACA,eACA;GACE,eAAe,yBAAyB;GACxC,SAAS,EAAE;GACX,SAAS,EAAE;GACZ,CACF;AAKH,MAAI,kBAAkB,WAAW,GAAG;AAClC,aACE,GAAG,iBAAiB,gCAAgC,aAAa,SAAS,yBAAyB,SAAS,CAAC,IAC7G,EACE,OAAO,QACR,CACF;AACD;;AAGF,mBAAiB,KAAK;GACpB;GACA;GACA;GACA,eAAe;GACf;GACA,oBAAoB,yBAAyB;GAC9C,CAAC;;AAGJ,QAAO"}
@@ -0,0 +1,10 @@
1
+ import { formatAutoFilledFilePath } from "./formatAutoFilledFilePath.mjs";
2
+
3
+ //#region src/fill/test-original-case.ts
4
+ const result = formatAutoFilledFilePath("./{{key}}.content.json", "dictionary-field-editor", "../../packages/@intlayer/design-system/src/components/DictionaryFieldEditor/dictionaryFieldEditor.content.ts", "/Users/aymericpineau/Documents/intlayer/apps/website");
5
+ console.log("Result:", result);
6
+ console.log("Expected: ../../packages/@intlayer/design-system/src/components/DictionaryFieldEditor/dictionaryFieldEditor.content.json");
7
+ console.log("Match:", result === "../../packages/@intlayer/design-system/src/components/DictionaryFieldEditor/dictionaryFieldEditor.content.json");
8
+
9
+ //#endregion
10
+ //# sourceMappingURL=test-original-case.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-original-case.mjs","names":[],"sources":["../../../src/fill/test-original-case.ts"],"sourcesContent":["import { formatAutoFilledFilePath } from './formatAutoFilledFilePath';\n\n// Original use case from the user\nconst result = formatAutoFilledFilePath(\n './{{key}}.content.json',\n 'dictionary-field-editor',\n '../../packages/@intlayer/design-system/src/components/DictionaryFieldEditor/dictionaryFieldEditor.content.ts',\n '/Users/aymericpineau/Documents/intlayer/apps/website'\n);\n\nconsole.log('Result:', result);\nconsole.log('Expected: ../../packages/@intlayer/design-system/src/components/DictionaryFieldEditor/dictionaryFieldEditor.content.json');\nconsole.log('Match:', result === '../../packages/@intlayer/design-system/src/components/DictionaryFieldEditor/dictionaryFieldEditor.content.json');\n\n"],"mappings":";;;AAGA,MAAM,SAAS,yBACb,0BACA,2BACA,gHACA,uDACD;AAED,QAAQ,IAAI,WAAW,OAAO;AAC9B,QAAQ,IAAI,2HAA2H;AACvI,QAAQ,IAAI,UAAU,WAAW,iHAAiH"}
@@ -0,0 +1,141 @@
1
+ import { getIntlayerAPIProxy } from "@intlayer/api";
2
+ import { chunkJSON, formatLocale, reconstructFromSingleChunk, reduceObjectFormat, verifyIdenticObjectFormat } from "@intlayer/chokidar";
3
+ import { ANSIColors, colon, colorize, colorizeNumber, colorizePath, getAppLogger, retryManager } from "@intlayer/config";
4
+ import { basename } from "node:path";
5
+ import { getUnmergedDictionaries } from "@intlayer/unmerged-dictionaries-entry";
6
+ import { getFilterMissingTranslationsDictionary, getPerLocaleDictionary, insertContentInDictionary, mergeDictionaries } from "@intlayer/core";
7
+
8
+ //#region src/fill/translateDictionary.ts
9
+ const hasMissingMetadata = (dictionary) => !dictionary.description || !dictionary.title || !dictionary.tags;
10
+ const CHUNK_SIZE = 7e3;
11
+ const GLOBAL_MAX_RETRY = 2;
12
+ const MAX_RETRY = 3;
13
+ const RETRY_DELAY = 1e3 * 10;
14
+ const translateDictionary = async (task, configuration, options) => {
15
+ const appLogger = getAppLogger(configuration);
16
+ const intlayerAPI = getIntlayerAPIProxy(void 0, configuration);
17
+ const { mode, aiOptions, fillMetadata } = {
18
+ mode: "complete",
19
+ fillMetadata: true,
20
+ ...options
21
+ };
22
+ return await retryManager(async () => {
23
+ const baseUnmergedDictionary = getUnmergedDictionaries(configuration)[task.dictionaryKey].find((dict) => dict.localId === task.dictionaryLocalId);
24
+ if (!baseUnmergedDictionary) {
25
+ appLogger(`${task.dictionaryPreset}Dictionary not found in unmergedDictionariesRecord. Skipping.`, { level: "warn" });
26
+ return {
27
+ ...task,
28
+ dictionaryOutput: null
29
+ };
30
+ }
31
+ let metadata;
32
+ if (fillMetadata && (hasMissingMetadata(baseUnmergedDictionary) || mode === "review")) {
33
+ const defaultLocaleDictionary = getPerLocaleDictionary(baseUnmergedDictionary, configuration.internationalization.defaultLocale);
34
+ appLogger(`${task.dictionaryPreset} Filling missing metadata for ${colorizePath(basename(baseUnmergedDictionary.filePath))}`, { level: "info" });
35
+ const runAudit = async () => await intlayerAPI.ai.auditContentDeclarationMetadata({
36
+ fileContent: JSON.stringify(defaultLocaleDictionary),
37
+ aiOptions
38
+ });
39
+ metadata = (options?.onHandle ? await options.onHandle(runAudit) : await runAudit()).data?.fileContent;
40
+ }
41
+ let dictionaryToProcess = baseUnmergedDictionary;
42
+ const translatedContent = {};
43
+ for await (const targetLocale of task.targetLocales) {
44
+ /**
45
+ * In complete mode, for large dictionaries, we want to filter all content that is already translated
46
+ *
47
+ * targetLocale: fr
48
+ *
49
+ * { test1: t({ ar: 'Hello', en: 'Hello', fr: 'Bonjour' } }) -> {}
50
+ * { test2: t({ ar: 'Hello', en: 'Hello' }) } -> { test2: t({ ar: 'Hello', en: 'Hello' }) }
51
+ *
52
+ */
53
+ if (mode === "complete") dictionaryToProcess = getFilterMissingTranslationsDictionary(dictionaryToProcess, targetLocale);
54
+ dictionaryToProcess = getPerLocaleDictionary(dictionaryToProcess, task.sourceLocale);
55
+ const targetLocaleDictionary = getPerLocaleDictionary(baseUnmergedDictionary, targetLocale);
56
+ const localePreset = colon([
57
+ colorize("[", ANSIColors.GREY_DARK),
58
+ formatLocale(targetLocale),
59
+ colorize("]", ANSIColors.GREY_DARK)
60
+ ].join(""), { colSize: 10 });
61
+ const createChunkPreset = (chunkIndex, totalChunks) => {
62
+ if (totalChunks <= 1) return "";
63
+ return colon([
64
+ colorize("[", ANSIColors.GREY_DARK),
65
+ colorizeNumber(chunkIndex + 1),
66
+ colorize(`/${totalChunks}`, ANSIColors.GREY_DARK),
67
+ colorize("]", ANSIColors.GREY_DARK)
68
+ ].join(""), { colSize: 5 });
69
+ };
70
+ appLogger(`${task.dictionaryPreset}${localePreset} Preparing ${colorizePath(basename(targetLocaleDictionary.filePath))}`, { level: "info" });
71
+ const chunkedJsonContent = chunkJSON(dictionaryToProcess.content, CHUNK_SIZE);
72
+ const nbOfChunks = chunkedJsonContent.length;
73
+ if (nbOfChunks > 1) appLogger(`${task.dictionaryPreset}${localePreset} Split into ${colorizeNumber(nbOfChunks)} chunks for translation`, { level: "info" });
74
+ const chunkResult = [];
75
+ const chunkPromises = chunkedJsonContent.map((chunk) => {
76
+ const chunkPreset = createChunkPreset(chunk.index, chunk.total);
77
+ if (nbOfChunks > 1) appLogger(`${task.dictionaryPreset}${localePreset}${chunkPreset} Translating chunk`, { level: "info" });
78
+ const chunkContent = reconstructFromSingleChunk(chunk);
79
+ const presetOutputContent = reduceObjectFormat(targetLocaleDictionary.content, chunkContent);
80
+ const executeTranslation = async () => {
81
+ return await retryManager(async () => {
82
+ const translationResult = await intlayerAPI.ai.translateJSON({
83
+ entryFileContent: chunkContent,
84
+ presetOutputContent,
85
+ dictionaryDescription: dictionaryToProcess.description ?? metadata?.description ?? "",
86
+ entryLocale: task.sourceLocale,
87
+ outputLocale: targetLocale,
88
+ mode,
89
+ aiOptions
90
+ });
91
+ if (!translationResult.data?.fileContent) throw new Error("No content result");
92
+ const { isIdentic } = verifyIdenticObjectFormat(translationResult.data.fileContent, chunkContent);
93
+ if (!isIdentic) throw new Error("Translation result does not match expected format");
94
+ return translationResult.data.fileContent;
95
+ }, {
96
+ maxRetry: MAX_RETRY,
97
+ delay: RETRY_DELAY,
98
+ onError: ({ error, attempt, maxRetry }) => {
99
+ const chunkPreset$1 = createChunkPreset(chunk.index, chunk.total);
100
+ appLogger(`${task.dictionaryPreset}${localePreset}${chunkPreset$1} ${colorize("Error filling:", ANSIColors.RED)} ${colorize(error, ANSIColors.GREY_DARK)} - Attempt ${colorizeNumber(attempt + 1)} of ${colorizeNumber(maxRetry)}`, { level: "error" });
101
+ }
102
+ })();
103
+ };
104
+ return (options?.onHandle ? options.onHandle(executeTranslation) : executeTranslation()).then((result) => ({
105
+ chunk,
106
+ result
107
+ }));
108
+ });
109
+ (await Promise.all(chunkPromises)).sort((a, b) => a.chunk.index - b.chunk.index).forEach(({ result }) => {
110
+ chunkResult.push(result);
111
+ });
112
+ translatedContent[targetLocale] = mergeDictionaries(chunkResult.map((chunk) => ({
113
+ ...dictionaryToProcess,
114
+ content: chunk
115
+ }))).content;
116
+ }
117
+ let dictionaryOutput = {
118
+ ...baseUnmergedDictionary,
119
+ ...metadata
120
+ };
121
+ for (const targetLocale of task.targetLocales) if (translatedContent[targetLocale]) dictionaryOutput = insertContentInDictionary(dictionaryOutput, translatedContent[targetLocale], targetLocale);
122
+ appLogger(`${task.dictionaryPreset} ${colorize("Translation completed successfully", ANSIColors.GREEN)} for ${colorizePath(basename(dictionaryOutput.filePath))}`, { level: "info" });
123
+ return {
124
+ ...task,
125
+ dictionaryOutput
126
+ };
127
+ }, {
128
+ maxRetry: GLOBAL_MAX_RETRY,
129
+ delay: RETRY_DELAY,
130
+ onError: ({ error, attempt, maxRetry }) => {
131
+ appLogger(`${task.dictionaryPreset} ${colorize("Error fill command:", ANSIColors.RED)} ${colorize(error, ANSIColors.GREY_DARK)} - Attempt ${colorizeNumber(attempt + 1)} of ${colorizeNumber(maxRetry)}`, { level: "error" });
132
+ },
133
+ onMaxTryReached: ({ error }) => {
134
+ appLogger(`${task.dictionaryPreset} ${colorize("Maximum number of retries reached:", ANSIColors.RED)} ${colorize(error, ANSIColors.GREY_DARK)}`, { level: "error" });
135
+ }
136
+ })();
137
+ };
138
+
139
+ //#endregion
140
+ export { translateDictionary };
141
+ //# sourceMappingURL=translateDictionary.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translateDictionary.mjs","names":["baseUnmergedDictionary: Dictionary | undefined","metadata:\n | Pick<Dictionary, 'description' | 'title' | 'tags'>\n | undefined","translatedContent: Partial<Record<Locale, Dictionary['content']>>","chunkedJsonContent: JsonChunk[]","chunkResult: JsonChunk[]","chunkPreset","dictionaryOutput: Dictionary"],"sources":["../../../src/fill/translateDictionary.ts"],"sourcesContent":["import { basename } from 'node:path';\nimport { type AIOptions, getIntlayerAPIProxy } from '@intlayer/api';\nimport {\n chunkJSON,\n formatLocale,\n type JsonChunk,\n reconstructFromSingleChunk,\n reduceObjectFormat,\n verifyIdenticObjectFormat,\n} from '@intlayer/chokidar';\nimport {\n ANSIColors,\n colon,\n colorize,\n colorizeNumber,\n colorizePath,\n getAppLogger,\n retryManager,\n} from '@intlayer/config';\nimport {\n getFilterMissingTranslationsDictionary,\n getPerLocaleDictionary,\n insertContentInDictionary,\n mergeDictionaries,\n} from '@intlayer/core';\nimport type { Dictionary, IntlayerConfig, Locale } from '@intlayer/types';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\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<typeof import('@intlayer/chokidar').getGlobalLimiter>;\n};\n\nconst hasMissingMetadata = (dictionary: Dictionary) =>\n !dictionary.description || !dictionary.title || !dictionary.tags;\n\nconst CHUNK_SIZE = 7000; // GPT-5 Mini safe input size\nconst GLOBAL_MAX_RETRY = 2;\nconst MAX_RETRY = 3;\nconst RETRY_DELAY = 1000 * 10; // 10 seconds\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 } = {\n mode: 'complete',\n fillMetadata: true,\n ...options,\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 await intlayerAPI.ai.auditContentDeclarationMetadata({\n fileContent: JSON.stringify(defaultLocaleDictionary),\n aiOptions,\n });\n\n const metadataResult = options?.onHandle\n ? await options.onHandle(runAudit)\n : await runAudit();\n\n metadata = metadataResult.data?.fileContent;\n }\n\n let dictionaryToProcess = baseUnmergedDictionary;\n\n const translatedContent: Partial<Record<Locale, Dictionary['content']>> =\n {};\n\n for await (const targetLocale of task.targetLocales) {\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 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 const targetLocaleDictionary = getPerLocaleDictionary(\n baseUnmergedDictionary,\n targetLocale\n );\n\n const localePreset = colon(\n [\n colorize('[', ANSIColors.GREY_DARK),\n formatLocale(targetLocale),\n colorize(']', ANSIColors.GREY_DARK),\n ].join(''),\n { colSize: 10 }\n );\n\n const createChunkPreset = (chunkIndex: number, totalChunks: number) => {\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 chunkedJsonContent: JsonChunk[] = chunkJSON(\n dictionaryToProcess.content,\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 targetLocaleDictionary.content,\n chunkContent\n );\n\n const executeTranslation = async () => {\n return await retryManager(\n async () => {\n const translationResult = await intlayerAPI.ai.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\n if (!translationResult.data?.fileContent) {\n throw new Error('No content result');\n }\n\n const { isIdentic } = verifyIdenticObjectFormat(\n translationResult.data.fileContent,\n chunkContent\n );\n if (!isIdentic) {\n throw new Error(\n 'Translation result does not match expected format'\n );\n }\n\n return translationResult.data.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(error, ANSIColors.GREY_DARK)} - Attempt ${colorizeNumber(attempt + 1)} of ${colorizeNumber(maxRetry)}`,\n {\n level: 'error',\n }\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((a, b) => a.chunk.index - b.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 const merged = mergeDictionaries(\n chunkResult.map((chunk) => ({\n ...dictionaryToProcess,\n content: chunk,\n }))\n );\n\n translatedContent[targetLocale] =\n merged.content as Dictionary['content'];\n }\n\n let dictionaryOutput: Dictionary = {\n ...baseUnmergedDictionary,\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 return {\n ...task,\n dictionaryOutput,\n };\n },\n {\n maxRetry: GLOBAL_MAX_RETRY,\n delay: RETRY_DELAY,\n onError: ({ error, attempt, maxRetry }) => {\n appLogger(\n `${task.dictionaryPreset} ${colorize('Error fill command:', ANSIColors.RED)} ${colorize(error, ANSIColors.GREY_DARK)} - Attempt ${colorizeNumber(attempt + 1)} of ${colorizeNumber(maxRetry)}`,\n {\n level: 'error',\n }\n );\n },\n onMaxTryReached: ({ error }) => {\n appLogger(\n `${task.dictionaryPreset} ${colorize('Maximum number of retries reached:', ANSIColors.RED)} ${colorize(error, ANSIColors.GREY_DARK)}`,\n {\n level: 'error',\n }\n );\n },\n }\n )();\n\n return result as TranslateDictionaryResult;\n};\n"],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { formatFillData } from "./formatFillData.mjs";
2
+ import { formatLocale, formatPath, reduceDictionaryContent, writeContentDeclaration } from "@intlayer/chokidar";
3
+ import { colorizeKey, getAppLogger } from "@intlayer/config";
4
+ import { getDictionaries } from "@intlayer/dictionaries-entry";
5
+
6
+ //#region src/fill/writeAutoFill.ts
7
+ const writeFill = async (contentDeclarationFile, outputLocales, parentLocales, configuration) => {
8
+ const appLogger = getAppLogger(configuration);
9
+ const fullDictionary = getDictionaries(configuration)[contentDeclarationFile.key];
10
+ const filePath = contentDeclarationFile.filePath;
11
+ if (!filePath) {
12
+ appLogger("No file path found for dictionary", { level: "error" });
13
+ return;
14
+ }
15
+ const autoFillOptions = fullDictionary.fill ?? configuration.content.fill;
16
+ if (typeof autoFillOptions === "boolean" && autoFillOptions === false) {
17
+ appLogger(`Auto fill is disabled for '${colorizeKey(fullDictionary.key)}'`, { level: "info" });
18
+ return;
19
+ }
20
+ const autoFillData = formatFillData(autoFillOptions, (outputLocales ?? configuration.internationalization.locales).filter((locale) => !parentLocales?.includes(locale)), filePath, fullDictionary.key, configuration);
21
+ for await (const output of autoFillData) {
22
+ if (!output.filePath) {
23
+ appLogger(`No file path found for auto filled content declaration for '${colorizeKey(fullDictionary.key)}'`, { level: "error" });
24
+ continue;
25
+ }
26
+ const reducedDictionaryContent = reduceDictionaryContent(fullDictionary, contentDeclarationFile);
27
+ await writeContentDeclaration({
28
+ ...fullDictionary,
29
+ fill: void 0,
30
+ filled: true,
31
+ locale: output.isPerLocale ? output.localeList[0] : void 0,
32
+ content: reducedDictionaryContent.content,
33
+ filePath: output.filePath
34
+ }, configuration);
35
+ if (output.isPerLocale) {
36
+ const sourceLocale = output.localeList[0];
37
+ appLogger(`Auto filled per-locale content declaration for '${colorizeKey(fullDictionary.key)}' written to ${formatPath(output.filePath)} for locale ${formatLocale(sourceLocale)}`, { level: "info" });
38
+ } else appLogger(`Auto filled content declaration for '${colorizeKey(fullDictionary.key)}' written to ${formatPath(output.filePath)}`, { level: "info" });
39
+ }
40
+ };
41
+
42
+ //#endregion
43
+ export { writeFill };
44
+ //# sourceMappingURL=writeAutoFill.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeAutoFill.mjs","names":["autoFillData: FillData[]"],"sources":["../../../src/fill/writeAutoFill.ts"],"sourcesContent":["import {\n formatLocale,\n formatPath,\n reduceDictionaryContent,\n writeContentDeclaration,\n} from '@intlayer/chokidar';\nimport { colorizeKey, getAppLogger } from '@intlayer/config';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type { Dictionary, Fill, IntlayerConfig, Locale } from '@intlayer/types';\nimport { type FillData, formatFillData } from './formatFillData';\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.filePath;\n\n if (!filePath) {\n appLogger('No file path found for dictionary', {\n level: 'error',\n });\n return;\n }\n\n const autoFillOptions = fullDictionary.fill ?? configuration.content.fill;\n\n if (\n typeof autoFillOptions === 'boolean' &&\n (autoFillOptions as boolean) === false\n ) {\n appLogger(\n `Auto fill is disabled for '${colorizeKey(fullDictionary.key)}'`,\n {\n level: 'info',\n }\n );\n return;\n }\n\n const localeList: Locale[] = (\n outputLocales ?? configuration.internationalization.locales\n ).filter((locale) => !parentLocales?.includes(locale));\n\n const autoFillData: FillData[] = formatFillData(\n autoFillOptions as Fill,\n localeList,\n filePath,\n fullDictionary.key,\n configuration\n );\n\n for await (const output of autoFillData) {\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 reducedDictionaryContent = reduceDictionaryContent(\n fullDictionary,\n contentDeclarationFile\n );\n\n // write file\n await writeContentDeclaration(\n {\n ...fullDictionary,\n fill: undefined,\n filled: true,\n locale: output.isPerLocale ? output.localeList[0] : undefined,\n content: reducedDictionaryContent.content,\n filePath: output.filePath,\n },\n configuration\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":";;;;;;AAWA,MAAa,YAAY,OACvB,wBACA,eACA,eACA,kBACG;CACH,MAAM,YAAY,aAAa,cAAc;CAG7C,MAAM,iBAFe,gBAAgB,cAAc,CAEf,uBAAuB;CAE3D,MAAM,WAAW,uBAAuB;AAExC,KAAI,CAAC,UAAU;AACb,YAAU,qCAAqC,EAC7C,OAAO,SACR,CAAC;AACF;;CAGF,MAAM,kBAAkB,eAAe,QAAQ,cAAc,QAAQ;AAErE,KACE,OAAO,oBAAoB,aAC1B,oBAAgC,OACjC;AACA,YACE,8BAA8B,YAAY,eAAe,IAAI,CAAC,IAC9D,EACE,OAAO,QACR,CACF;AACD;;CAOF,MAAMA,eAA2B,eAC/B,kBAJA,iBAAiB,cAAc,qBAAqB,SACpD,QAAQ,WAAW,CAAC,eAAe,SAAS,OAAO,CAAC,EAKpD,UACA,eAAe,KACf,cACD;AAED,YAAW,MAAM,UAAU,cAAc;AACvC,MAAI,CAAC,OAAO,UAAU;AACpB,aACE,+DAA+D,YAAY,eAAe,IAAI,CAAC,IAC/F,EACE,OAAO,SACR,CACF;AACD;;EAGF,MAAM,2BAA2B,wBAC/B,gBACA,uBACD;AAGD,QAAM,wBACJ;GACE,GAAG;GACH,MAAM;GACN,QAAQ;GACR,QAAQ,OAAO,cAAc,OAAO,WAAW,KAAK;GACpD,SAAS,yBAAyB;GAClC,UAAU,OAAO;GAClB,EACD,cACD;AAED,MAAI,OAAO,aAAa;GACtB,MAAM,eAAe,OAAO,WAAW;AAEvC,aACE,mDAAmD,YAAY,eAAe,IAAI,CAAC,eAAe,WAAW,OAAO,SAAS,CAAC,cAAc,aAAa,aAAa,IACtK,EACE,OAAO,QACR,CACF;QAED,WACE,wCAAwC,YAAY,eAAe,IAAI,CAAC,eAAe,WAAW,OAAO,SAAS,IAClH,EACE,OAAO,QACR,CACF"}
@@ -0,0 +1,45 @@
1
+ import { formatFillData } from "./formatFillData.mjs";
2
+ import { formatLocale, formatPath, writeContentDeclaration } from "@intlayer/chokidar";
3
+ import { colorizeKey, getAppLogger } from "@intlayer/config";
4
+ import { relative } from "node:path";
5
+ import { getDictionaries } from "@intlayer/dictionaries-entry";
6
+
7
+ //#region src/fill/writeFill.ts
8
+ const writeFill = async (contentDeclarationFile, outputLocales, parentLocales, configuration) => {
9
+ const appLogger = getAppLogger(configuration);
10
+ const fullDictionary = getDictionaries(configuration)[contentDeclarationFile.key];
11
+ const { filePath } = contentDeclarationFile;
12
+ if (!filePath) {
13
+ appLogger("No file path found for dictionary", { level: "error" });
14
+ return;
15
+ }
16
+ const autoFillOptions = contentDeclarationFile.fill ?? configuration.content.fill;
17
+ if (typeof autoFillOptions === "boolean" && autoFillOptions === false) {
18
+ appLogger(`Auto fill is disabled for '${colorizeKey(fullDictionary.key)}'`, { level: "info" });
19
+ return;
20
+ }
21
+ const autoFillData = formatFillData(autoFillOptions, (outputLocales ?? configuration.internationalization.locales).filter((locale) => !parentLocales?.includes(locale)), filePath, fullDictionary.key, configuration);
22
+ for await (const output of autoFillData) {
23
+ if (!output.filePath) {
24
+ appLogger(`No file path found for auto filled content declaration for '${colorizeKey(fullDictionary.key)}'`, { level: "error" });
25
+ continue;
26
+ }
27
+ const { fill,...rest } = contentDeclarationFile;
28
+ const relativeFilePath = relative(configuration.content.baseDir, output.filePath);
29
+ await writeContentDeclaration({
30
+ ...rest,
31
+ filled: true,
32
+ locale: output.isPerLocale ? output.localeList[0] : void 0,
33
+ localId: `${contentDeclarationFile.key}::local::${relativeFilePath}`,
34
+ filePath: relativeFilePath
35
+ }, configuration, { localeList: output.localeList });
36
+ if (output.isPerLocale) {
37
+ const sourceLocale = output.localeList[0];
38
+ appLogger(`Auto filled per-locale content declaration for '${colorizeKey(fullDictionary.key)}' written to ${formatPath(output.filePath)} for locale ${formatLocale(sourceLocale)}`, { level: "info" });
39
+ } else appLogger(`Auto filled content declaration for '${colorizeKey(fullDictionary.key)}' written to ${formatPath(output.filePath)}`, { level: "info" });
40
+ }
41
+ };
42
+
43
+ //#endregion
44
+ export { writeFill };
45
+ //# sourceMappingURL=writeFill.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeFill.mjs","names":["autoFillData: FillData[]"],"sources":["../../../src/fill/writeFill.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport {\n formatLocale,\n formatPath,\n writeContentDeclaration,\n} from '@intlayer/chokidar';\nimport { colorizeKey, getAppLogger } from '@intlayer/config';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type { Dictionary, Fill, IntlayerConfig, Locale } from '@intlayer/types';\nimport { type FillData, formatFillData } from './formatFillData';\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 autoFillOptions =\n contentDeclarationFile.fill ?? configuration.content.fill;\n\n if (\n typeof autoFillOptions === 'boolean' &&\n (autoFillOptions as boolean) === false\n ) {\n appLogger(\n `Auto fill is disabled for '${colorizeKey(fullDictionary.key)}'`,\n {\n level: 'info',\n }\n );\n return;\n }\n\n const localeList: Locale[] = (\n outputLocales ?? configuration.internationalization.locales\n ).filter((locale) => !parentLocales?.includes(locale));\n\n const autoFillData: FillData[] = formatFillData(\n autoFillOptions as Fill,\n localeList,\n filePath,\n fullDictionary.key,\n configuration\n );\n\n for await (const output of autoFillData) {\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 // biome-ignore lint/correctness/noUnusedVariables: Just filtering out the fill property\n const { fill, ...rest } = contentDeclarationFile;\n\n const relativeFilePath = relative(\n configuration.content.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":";;;;;;;AAWA,MAAa,YAAY,OACvB,wBACA,eACA,eACA,kBACG;CACH,MAAM,YAAY,aAAa,cAAc;CAG7C,MAAM,iBAFe,gBAAgB,cAAc,CAEf,uBAAuB;CAE3D,MAAM,EAAE,aAAa;AAErB,KAAI,CAAC,UAAU;AACb,YAAU,qCAAqC,EAC7C,OAAO,SACR,CAAC;AACF;;CAGF,MAAM,kBACJ,uBAAuB,QAAQ,cAAc,QAAQ;AAEvD,KACE,OAAO,oBAAoB,aAC1B,oBAAgC,OACjC;AACA,YACE,8BAA8B,YAAY,eAAe,IAAI,CAAC,IAC9D,EACE,OAAO,QACR,CACF;AACD;;CAOF,MAAMA,eAA2B,eAC/B,kBAJA,iBAAiB,cAAc,qBAAqB,SACpD,QAAQ,WAAW,CAAC,eAAe,SAAS,OAAO,CAAC,EAKpD,UACA,eAAe,KACf,cACD;AAED,YAAW,MAAM,UAAU,cAAc;AACvC,MAAI,CAAC,OAAO,UAAU;AACpB,aACE,+DAA+D,YAAY,eAAe,IAAI,CAAC,IAC/F,EACE,OAAO,SACR,CACF;AACD;;EAIF,MAAM,EAAE,KAAM,GAAG,SAAS;EAE1B,MAAM,mBAAmB,SACvB,cAAc,QAAQ,SACtB,OAAO,SACR;AAGD,QAAM,wBACJ;GACE,GAAG;GACH,QAAQ;GACR,QAAQ,OAAO,cAAc,OAAO,WAAW,KAAK;GACpD,SAAS,GAAG,uBAAuB,IAAI,WAAW;GAClD,UAAU;GACX,EACD,eACA,EACE,YAAY,OAAO,YACpB,CACF;AAED,MAAI,OAAO,aAAa;GACtB,MAAM,eAAe,OAAO,WAAW;AAEvC,aACE,mDAAmD,YAAY,eAAe,IAAI,CAAC,eAAe,WAAW,OAAO,SAAS,CAAC,cAAc,aAAa,aAAa,IACtK,EACE,OAAO,QACR,CACF;QAED,WACE,wCAAwC,YAAY,eAAe,IAAI,CAAC,eAAe,WAAW,OAAO,SAAS,IAClH,EACE,OAAO,QACR,CACF"}
@@ -1,55 +1,34 @@
1
1
  import { listGitFiles } from "@intlayer/chokidar";
2
2
  import { getConfiguration } from "@intlayer/config";
3
+ import { join, relative } from "node:path";
3
4
  import { getUnmergedDictionaries } from "@intlayer/unmerged-dictionaries-entry";
4
- import { join, relative } from "path";
5
+
6
+ //#region src/getTargetDictionary.ts
5
7
  const ensureArray = (value) => [value].flat();
6
8
  const getTargetUnmergedDictionaries = async (options) => {
7
- const configuration = getConfiguration(options.configOptions);
8
- const { baseDir } = configuration.content;
9
- const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);
10
- let result = Object.values(unmergedDictionariesRecord).flat();
11
- if (typeof options.file !== "undefined") {
12
- const fileArray = ensureArray(options.file);
13
- const relativeFilePaths = fileArray.map(
14
- (file) => file.startsWith("/") ? relative(baseDir, file) : join("./", file)
15
- );
16
- result = result.filter(
17
- (dict) => dict.filePath && // Check for absolute path
18
- relativeFilePaths.includes(dict.filePath)
19
- );
20
- }
21
- if (typeof options.keys !== "undefined") {
22
- result = result.filter(
23
- (dict) => ensureArray(options.keys)?.includes(dict.key)
24
- );
25
- }
26
- if (typeof options.excludedKeys !== "undefined") {
27
- result = result.filter(
28
- (dict) => !ensureArray(options.excludedKeys)?.includes(dict.key)
29
- );
30
- }
31
- if (typeof options.pathFilter !== "undefined") {
32
- result = result.filter(
33
- (dict) => ensureArray(options.pathFilter)?.includes(dict.filePath ?? "")
34
- );
35
- }
36
- if (typeof options.filter !== "undefined") {
37
- result = result.filter(options.filter);
38
- }
39
- const gitOptions = options.gitOptions;
40
- if (gitOptions) {
41
- const gitChangedFiles = await listGitFiles(gitOptions);
42
- if (gitChangedFiles) {
43
- result = result.filter((dict) => {
44
- if (!dict.filePath) return false;
45
- return gitChangedFiles.some((gitFile) => dict.filePath === gitFile);
46
- });
47
- }
48
- }
49
- return result.filter((dict) => !dict.autoFilled);
50
- };
51
- export {
52
- ensureArray,
53
- getTargetUnmergedDictionaries
9
+ const configuration = getConfiguration(options?.configOptions);
10
+ const { baseDir } = configuration.content;
11
+ const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);
12
+ let result = Object.values(unmergedDictionariesRecord).flat();
13
+ if (typeof options?.file !== "undefined") {
14
+ const relativeFilePaths = ensureArray(options?.file).map((file) => file.startsWith("/") ? relative(baseDir, file) : join("./", file));
15
+ result = result.filter((dict) => dict.filePath && relativeFilePaths.includes(dict.filePath));
16
+ }
17
+ if (typeof options?.keys !== "undefined") result = result.filter((dict) => ensureArray(options?.keys)?.includes(dict.key));
18
+ if (typeof options?.excludedKeys !== "undefined") result = result.filter((dict) => !ensureArray(options?.excludedKeys)?.includes(dict.key));
19
+ if (typeof options?.pathFilter !== "undefined") result = result.filter((dict) => ensureArray(options?.pathFilter)?.includes(dict.filePath ?? ""));
20
+ if (typeof options?.filter !== "undefined") result = result.filter(options?.filter);
21
+ const gitOptions = options?.gitOptions;
22
+ if (gitOptions) {
23
+ const gitChangedFiles = await listGitFiles(gitOptions);
24
+ if (gitChangedFiles) result = result.filter((dict) => {
25
+ if (!dict.filePath) return false;
26
+ return gitChangedFiles.some((gitFile) => dict.filePath === gitFile);
27
+ });
28
+ }
29
+ return result.filter((dict) => !dict.filled);
54
30
  };
31
+
32
+ //#endregion
33
+ export { ensureArray, getTargetUnmergedDictionaries };
55
34
  //# sourceMappingURL=getTargetDictionary.mjs.map