@intlayer/babel 9.0.0-canary.16 → 9.0.0-canary.18

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 (122) hide show
  1. package/dist/cjs/babel-plugin-intlayer-extract.cjs.map +1 -1
  2. package/dist/cjs/babel-plugin-intlayer-field-rename.cjs +79 -26
  3. package/dist/cjs/babel-plugin-intlayer-field-rename.cjs.map +1 -1
  4. package/dist/cjs/babel-plugin-intlayer-minify.cjs.map +1 -1
  5. package/dist/cjs/babel-plugin-intlayer-optimize.cjs +2 -2
  6. package/dist/cjs/babel-plugin-intlayer-optimize.cjs.map +1 -1
  7. package/dist/cjs/babel-plugin-intlayer-purge.cjs +3 -4
  8. package/dist/cjs/babel-plugin-intlayer-purge.cjs.map +1 -1
  9. package/dist/cjs/babel-plugin-intlayer-usage-analyzer.cjs +103 -35
  10. package/dist/cjs/babel-plugin-intlayer-usage-analyzer.cjs.map +1 -1
  11. package/dist/cjs/extractContent/babelProcessor.cjs +3 -3
  12. package/dist/cjs/extractContent/babelProcessor.cjs.map +1 -1
  13. package/dist/cjs/extractContent/contentWriter.cjs.map +1 -1
  14. package/dist/cjs/extractContent/extractContent.cjs.map +1 -1
  15. package/dist/cjs/extractContent/processTsxFile.cjs.map +1 -1
  16. package/dist/cjs/extractContent/utils/constants.cjs +1 -1
  17. package/dist/cjs/extractContent/utils/constants.cjs.map +1 -1
  18. package/dist/cjs/extractContent/utils/detectPackageName.cjs +0 -1
  19. package/dist/cjs/extractContent/utils/detectPackageName.cjs.map +1 -1
  20. package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs.map +1 -1
  21. package/dist/cjs/extractContent/utils/extractDictionaryKey.cjs +0 -1
  22. package/dist/cjs/extractContent/utils/extractDictionaryKey.cjs.map +1 -1
  23. package/dist/cjs/extractContent/utils/generateKey.cjs.map +1 -1
  24. package/dist/cjs/extractContent/utils/getComponentName.cjs.map +1 -1
  25. package/dist/cjs/extractContent/utils/getExistingIntlayerInfo.cjs.map +1 -1
  26. package/dist/cjs/extractContent/utils/getOrGenerateKey.cjs.map +1 -1
  27. package/dist/cjs/extractContent/utils/resolveDictionaryKey.cjs +0 -1
  28. package/dist/cjs/extractContent/utils/resolveDictionaryKey.cjs.map +1 -1
  29. package/dist/cjs/extractContent/utils/shouldExtract.cjs.map +1 -1
  30. package/dist/cjs/extractScriptBlocks.cjs +0 -1
  31. package/dist/cjs/extractScriptBlocks.cjs.map +1 -1
  32. package/dist/cjs/getExtractPluginOptions.cjs.map +1 -1
  33. package/dist/cjs/getOptimizePluginOptions.cjs +0 -1
  34. package/dist/cjs/getOptimizePluginOptions.cjs.map +1 -1
  35. package/dist/cjs/getPurgePluginOptions.cjs +0 -1
  36. package/dist/cjs/getPurgePluginOptions.cjs.map +1 -1
  37. package/dist/cjs/index.cjs +1 -0
  38. package/dist/cjs/normalizedFilesList.cjs +0 -1
  39. package/dist/cjs/normalizedFilesList.cjs.map +1 -1
  40. package/dist/cjs/transformers.cjs +0 -1
  41. package/dist/cjs/transformers.cjs.map +1 -1
  42. package/dist/esm/babel-plugin-intlayer-extract.mjs.map +1 -1
  43. package/dist/esm/babel-plugin-intlayer-field-rename.mjs +79 -27
  44. package/dist/esm/babel-plugin-intlayer-field-rename.mjs.map +1 -1
  45. package/dist/esm/babel-plugin-intlayer-minify.mjs.map +1 -1
  46. package/dist/esm/babel-plugin-intlayer-optimize.mjs +2 -1
  47. package/dist/esm/babel-plugin-intlayer-optimize.mjs.map +1 -1
  48. package/dist/esm/babel-plugin-intlayer-purge.mjs +4 -4
  49. package/dist/esm/babel-plugin-intlayer-purge.mjs.map +1 -1
  50. package/dist/esm/babel-plugin-intlayer-usage-analyzer.mjs +103 -35
  51. package/dist/esm/babel-plugin-intlayer-usage-analyzer.mjs.map +1 -1
  52. package/dist/esm/extractContent/babelProcessor.mjs +3 -3
  53. package/dist/esm/extractContent/babelProcessor.mjs.map +1 -1
  54. package/dist/esm/extractContent/contentWriter.mjs.map +1 -1
  55. package/dist/esm/extractContent/extractContent.mjs.map +1 -1
  56. package/dist/esm/extractContent/processTsxFile.mjs.map +1 -1
  57. package/dist/esm/extractContent/utils/constants.mjs +1 -1
  58. package/dist/esm/extractContent/utils/constants.mjs.map +1 -1
  59. package/dist/esm/extractContent/utils/detectPackageName.mjs.map +1 -1
  60. package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs.map +1 -1
  61. package/dist/esm/extractContent/utils/extractDictionaryKey.mjs.map +1 -1
  62. package/dist/esm/extractContent/utils/generateKey.mjs.map +1 -1
  63. package/dist/esm/extractContent/utils/getComponentName.mjs.map +1 -1
  64. package/dist/esm/extractContent/utils/getExistingIntlayerInfo.mjs.map +1 -1
  65. package/dist/esm/extractContent/utils/getOrGenerateKey.mjs.map +1 -1
  66. package/dist/esm/extractContent/utils/resolveDictionaryKey.mjs.map +1 -1
  67. package/dist/esm/extractContent/utils/shouldExtract.mjs.map +1 -1
  68. package/dist/esm/extractScriptBlocks.mjs.map +1 -1
  69. package/dist/esm/getExtractPluginOptions.mjs.map +1 -1
  70. package/dist/esm/getOptimizePluginOptions.mjs.map +1 -1
  71. package/dist/esm/getPurgePluginOptions.mjs.map +1 -1
  72. package/dist/esm/index.mjs +2 -2
  73. package/dist/esm/normalizedFilesList.mjs.map +1 -1
  74. package/dist/esm/transformers.mjs.map +1 -1
  75. package/dist/types/babel-plugin-intlayer-extract.d.ts +0 -1
  76. package/dist/types/babel-plugin-intlayer-extract.d.ts.map +1 -1
  77. package/dist/types/babel-plugin-intlayer-field-rename.d.ts +15 -6
  78. package/dist/types/babel-plugin-intlayer-field-rename.d.ts.map +1 -1
  79. package/dist/types/babel-plugin-intlayer-minify.d.ts +0 -1
  80. package/dist/types/babel-plugin-intlayer-minify.d.ts.map +1 -1
  81. package/dist/types/babel-plugin-intlayer-optimize.d.ts +17 -10
  82. package/dist/types/babel-plugin-intlayer-optimize.d.ts.map +1 -1
  83. package/dist/types/babel-plugin-intlayer-purge.d.ts +0 -1
  84. package/dist/types/babel-plugin-intlayer-purge.d.ts.map +1 -1
  85. package/dist/types/babel-plugin-intlayer-usage-analyzer.d.ts +28 -12
  86. package/dist/types/babel-plugin-intlayer-usage-analyzer.d.ts.map +1 -1
  87. package/dist/types/extractContent/babelProcessor.d.ts +3 -2
  88. package/dist/types/extractContent/babelProcessor.d.ts.map +1 -1
  89. package/dist/types/extractContent/contentWriter.d.ts +0 -1
  90. package/dist/types/extractContent/contentWriter.d.ts.map +1 -1
  91. package/dist/types/extractContent/extractContent.d.ts +1 -1
  92. package/dist/types/extractContent/extractContent.d.ts.map +1 -1
  93. package/dist/types/extractContent/processTsxFile.d.ts +1 -1
  94. package/dist/types/extractContent/processTsxFile.d.ts.map +1 -1
  95. package/dist/types/extractContent/utils/constants.d.ts +2 -2
  96. package/dist/types/extractContent/utils/constants.d.ts.map +1 -1
  97. package/dist/types/extractContent/utils/detectPackageName.d.ts +0 -1
  98. package/dist/types/extractContent/utils/detectPackageName.d.ts.map +1 -1
  99. package/dist/types/extractContent/utils/extractDictionaryInfo.d.ts +0 -1
  100. package/dist/types/extractContent/utils/extractDictionaryInfo.d.ts.map +1 -1
  101. package/dist/types/extractContent/utils/extractDictionaryKey.d.ts.map +1 -1
  102. package/dist/types/extractContent/utils/generateKey.d.ts.map +1 -1
  103. package/dist/types/extractContent/utils/getComponentName.d.ts +0 -1
  104. package/dist/types/extractContent/utils/getComponentName.d.ts.map +1 -1
  105. package/dist/types/extractContent/utils/getExistingIntlayerInfo.d.ts +8 -5
  106. package/dist/types/extractContent/utils/getExistingIntlayerInfo.d.ts.map +1 -1
  107. package/dist/types/extractContent/utils/getOrGenerateKey.d.ts.map +1 -1
  108. package/dist/types/extractContent/utils/resolveDictionaryKey.d.ts +0 -1
  109. package/dist/types/extractContent/utils/resolveDictionaryKey.d.ts.map +1 -1
  110. package/dist/types/extractContent/utils/shouldExtract.d.ts.map +1 -1
  111. package/dist/types/extractScriptBlocks.d.ts.map +1 -1
  112. package/dist/types/getExtractPluginOptions.d.ts +0 -1
  113. package/dist/types/getExtractPluginOptions.d.ts.map +1 -1
  114. package/dist/types/getOptimizePluginOptions.d.ts +0 -1
  115. package/dist/types/getOptimizePluginOptions.d.ts.map +1 -1
  116. package/dist/types/getPurgePluginOptions.d.ts +0 -1
  117. package/dist/types/getPurgePluginOptions.d.ts.map +1 -1
  118. package/dist/types/index.d.ts +4 -3
  119. package/dist/types/normalizedFilesList.d.ts.map +1 -1
  120. package/dist/types/transformers.d.ts +0 -1
  121. package/dist/types/transformers.d.ts.map +1 -1
  122. package/package.json +23 -15
@@ -1 +1 @@
1
- {"version":3,"file":"getExistingIntlayerInfo.mjs","names":[],"sources":["../../../../src/extractContent/utils/getExistingIntlayerInfo.ts"],"sourcesContent":["import type { NodePath } from '@babel/traverse';\nimport * as t from '@babel/types';\n\nexport type ExistingIntlayerInfo = {\n key: string;\n hook: 'useIntlayer' | 'getIntlayer';\n /** The variable name used to store the call result (e.g. `t` in `const t = useIntlayer(...)`) */\n variableName: string;\n /** True when the call result is destructured: `const { a, b } = getIntlayer(...)` */\n isDestructured: boolean;\n /** Keys already present in the destructuring pattern (empty when not destructured) */\n existingDestructuredKeys: string[];\n /** The ObjectPattern AST node, present only when `isDestructured` is true */\n objectPatternNode?: t.ObjectPattern;\n};\n\n/**\n * Searches for an existing useIntlayer or getIntlayer call in the function body.\n */\nexport const getExistingIntlayerInfo = (\n path: NodePath\n): ExistingIntlayerInfo | undefined => {\n let result: ExistingIntlayerInfo | undefined;\n\n // We only check the direct body of the function, not nested functions\n path.traverse({\n CallExpression(childPath) {\n const callee = childPath.node.callee;\n\n if (\n t.isIdentifier(callee) &&\n (callee.name === 'useIntlayer' || callee.name === 'getIntlayer')\n ) {\n const arg = childPath.node.arguments[0];\n\n if (t.isStringLiteral(arg)) {\n const parentNode = childPath.parent;\n let isDestructured = false;\n let existingDestructuredKeys: string[] = [];\n let objectPatternNode: t.ObjectPattern | undefined;\n let variableName = 'content';\n\n if (t.isVariableDeclarator(parentNode)) {\n if (t.isObjectPattern(parentNode.id)) {\n isDestructured = true;\n objectPatternNode = parentNode.id;\n existingDestructuredKeys = parentNode.id.properties\n .filter(\n (p): p is t.ObjectProperty =>\n t.isObjectProperty(p) && t.isIdentifier(p.key)\n )\n .map((p) => (p.key as t.Identifier).name);\n } else if (t.isIdentifier(parentNode.id)) {\n variableName = parentNode.id.name;\n }\n }\n\n result = {\n key: arg.value,\n hook: callee.name as 'useIntlayer' | 'getIntlayer',\n variableName,\n isDestructured,\n existingDestructuredKeys,\n objectPatternNode,\n };\n childPath.stop();\n }\n }\n },\n Function(childPath) {\n childPath.skip(); // Don't look inside nested functions\n },\n });\n\n return result;\n};\n"],"mappings":";;;;;;AAmBA,MAAa,2BACX,SACqC;CACrC,IAAI;AAGJ,MAAK,SAAS;EACZ,eAAe,WAAW;GACxB,MAAM,SAAS,UAAU,KAAK;AAE9B,OACE,EAAE,aAAa,OAAO,KACrB,OAAO,SAAS,iBAAiB,OAAO,SAAS,gBAClD;IACA,MAAM,MAAM,UAAU,KAAK,UAAU;AAErC,QAAI,EAAE,gBAAgB,IAAI,EAAE;KAC1B,MAAM,aAAa,UAAU;KAC7B,IAAI,iBAAiB;KACrB,IAAI,2BAAqC,EAAE;KAC3C,IAAI;KACJ,IAAI,eAAe;AAEnB,SAAI,EAAE,qBAAqB,WAAW,EACpC;UAAI,EAAE,gBAAgB,WAAW,GAAG,EAAE;AACpC,wBAAiB;AACjB,2BAAoB,WAAW;AAC/B,kCAA2B,WAAW,GAAG,WACtC,QACE,MACC,EAAE,iBAAiB,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,CACjD,CACA,KAAK,MAAO,EAAE,IAAqB,KAAK;iBAClC,EAAE,aAAa,WAAW,GAAG,CACtC,gBAAe,WAAW,GAAG;;AAIjC,cAAS;MACP,KAAK,IAAI;MACT,MAAM,OAAO;MACb;MACA;MACA;MACA;MACD;AACD,eAAU,MAAM;;;;EAItB,SAAS,WAAW;AAClB,aAAU,MAAM;;EAEnB,CAAC;AAEF,QAAO"}
1
+ {"version":3,"file":"getExistingIntlayerInfo.mjs","names":[],"sources":["../../../../src/extractContent/utils/getExistingIntlayerInfo.ts"],"sourcesContent":["import type { NodePath } from '@babel/traverse';\nimport * as t from '@babel/types';\n\nexport type ExistingIntlayerInfo = {\n key: string;\n hook: 'useIntlayer' | 'getIntlayer';\n /** The variable name used to store the call result (e.g. `t` in `const t = useIntlayer(...)`) */\n variableName: string;\n /** True when the call result is destructured: `const { a, b } = getIntlayer(...)` */\n isDestructured: boolean;\n /** Keys already present in the destructuring pattern (empty when not destructured) */\n existingDestructuredKeys: string[];\n /** The ObjectPattern AST node, present only when `isDestructured` is true */\n objectPatternNode?: t.ObjectPattern;\n};\n\n/**\n * Searches for an existing useIntlayer or getIntlayer call in the function body.\n */\nexport const getExistingIntlayerInfo = (\n path: NodePath\n): ExistingIntlayerInfo | undefined => {\n let result: ExistingIntlayerInfo | undefined;\n\n // We only check the direct body of the function, not nested functions\n path.traverse({\n CallExpression(childPath) {\n const callee = childPath.node.callee;\n\n if (\n t.isIdentifier(callee) &&\n (callee.name === 'useIntlayer' || callee.name === 'getIntlayer')\n ) {\n const arg = childPath.node.arguments[0];\n\n if (t.isStringLiteral(arg)) {\n const parentNode = childPath.parent;\n let isDestructured = false;\n let existingDestructuredKeys: string[] = [];\n let objectPatternNode: t.ObjectPattern | undefined;\n let variableName = 'content';\n\n if (t.isVariableDeclarator(parentNode)) {\n if (t.isObjectPattern(parentNode.id)) {\n isDestructured = true;\n objectPatternNode = parentNode.id;\n existingDestructuredKeys = parentNode.id.properties\n .filter(\n (p): p is t.ObjectProperty =>\n t.isObjectProperty(p) && t.isIdentifier(p.key)\n )\n .map((p) => (p.key as t.Identifier).name);\n } else if (t.isIdentifier(parentNode.id)) {\n variableName = parentNode.id.name;\n }\n }\n\n result = {\n key: arg.value,\n hook: callee.name as 'useIntlayer' | 'getIntlayer',\n variableName,\n isDestructured,\n existingDestructuredKeys,\n objectPatternNode,\n };\n childPath.stop();\n }\n }\n },\n Function(childPath) {\n childPath.skip(); // Don't look inside nested functions\n },\n });\n\n return result;\n};\n"],"mappings":";;;;;;AAmBA,MAAa,2BACX,SACqC;CACrC,IAAI;CAGJ,KAAK,SAAS;EACZ,eAAe,WAAW;GACxB,MAAM,SAAS,UAAU,KAAK;GAE9B,IACE,EAAE,aAAa,MAAM,MACpB,OAAO,SAAS,iBAAiB,OAAO,SAAS,gBAClD;IACA,MAAM,MAAM,UAAU,KAAK,UAAU;IAErC,IAAI,EAAE,gBAAgB,GAAG,GAAG;KAC1B,MAAM,aAAa,UAAU;KAC7B,IAAI,iBAAiB;KACrB,IAAI,2BAAqC,CAAC;KAC1C,IAAI;KACJ,IAAI,eAAe;KAEnB,IAAI,EAAE,qBAAqB,UAAU,GACnC;UAAI,EAAE,gBAAgB,WAAW,EAAE,GAAG;OACpC,iBAAiB;OACjB,oBAAoB,WAAW;OAC/B,2BAA2B,WAAW,GAAG,WACtC,QACE,MACC,EAAE,iBAAiB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,CACjD,CAAC,CACA,KAAK,MAAO,EAAE,IAAqB,IAAI;MAC5C,OAAO,IAAI,EAAE,aAAa,WAAW,EAAE,GACrC,eAAe,WAAW,GAAG;KAC/B;KAGF,SAAS;MACP,KAAK,IAAI;MACT,MAAM,OAAO;MACb;MACA;MACA;MACA;KACF;KACA,UAAU,KAAK;IACjB;GACF;EACF;EACA,SAAS,WAAW;GAClB,UAAU,KAAK;EACjB;CACF,CAAC;CAED,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"getOrGenerateKey.mjs","names":[],"sources":["../../../../src/extractContent/utils/getOrGenerateKey.ts"],"sourcesContent":["import { generateKey } from './generateKey';\n\n/**\n * Gets an existing key for a given text or generates a new one.\n */\nexport const getOrGenerateKey = (\n text: string,\n componentKey: string,\n existingKeys: Set<string>,\n extractedContent: Record<string, Record<string, string>>\n): string => {\n if (!extractedContent[componentKey]) {\n extractedContent[componentKey] = {};\n }\n const existingEntry = Object.entries(extractedContent[componentKey]).find(\n ([_, value]) => value === text\n );\n\n if (existingEntry) {\n return existingEntry[0];\n }\n const key = generateKey(text, existingKeys);\n\n existingKeys.add(key);\n extractedContent[componentKey][key] = text;\n return key;\n};\n"],"mappings":";;;;;;AAKA,MAAa,oBACX,MACA,cACA,cACA,qBACW;AACX,KAAI,CAAC,iBAAiB,cACpB,kBAAiB,gBAAgB,EAAE;CAErC,MAAM,gBAAgB,OAAO,QAAQ,iBAAiB,cAAc,CAAC,MAClE,CAAC,GAAG,WAAW,UAAU,KAC3B;AAED,KAAI,cACF,QAAO,cAAc;CAEvB,MAAM,MAAM,YAAY,MAAM,aAAa;AAE3C,cAAa,IAAI,IAAI;AACrB,kBAAiB,cAAc,OAAO;AACtC,QAAO"}
1
+ {"version":3,"file":"getOrGenerateKey.mjs","names":[],"sources":["../../../../src/extractContent/utils/getOrGenerateKey.ts"],"sourcesContent":["import { generateKey } from './generateKey';\n\n/**\n * Gets an existing key for a given text or generates a new one.\n */\nexport const getOrGenerateKey = (\n text: string,\n componentKey: string,\n existingKeys: Set<string>,\n extractedContent: Record<string, Record<string, string>>\n): string => {\n if (!extractedContent[componentKey]) {\n extractedContent[componentKey] = {};\n }\n const existingEntry = Object.entries(extractedContent[componentKey]).find(\n ([_, value]) => value === text\n );\n\n if (existingEntry) {\n return existingEntry[0];\n }\n const key = generateKey(text, existingKeys);\n\n existingKeys.add(key);\n extractedContent[componentKey][key] = text;\n return key;\n};\n"],"mappings":";;;;;;AAKA,MAAa,oBACX,MACA,cACA,cACA,qBACW;CACX,IAAI,CAAC,iBAAiB,eACpB,iBAAiB,gBAAgB,CAAC;CAEpC,MAAM,gBAAgB,OAAO,QAAQ,iBAAiB,aAAa,CAAC,CAAC,MAClE,CAAC,GAAG,WAAW,UAAU,IAC5B;CAEA,IAAI,eACF,OAAO,cAAc;CAEvB,MAAM,MAAM,YAAY,MAAM,YAAY;CAE1C,aAAa,IAAI,GAAG;CACpB,iBAAiB,aAAa,CAAC,OAAO;CACtC,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolveDictionaryKey.mjs","names":[],"sources":["../../../../src/extractContent/utils/resolveDictionaryKey.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { assertPathWithin } from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\n\n/**\n * Resolves a unique dictionary key, checking for existing dictionaries and files.\n * Note: this chokidar-specific variant fetches unmergedDictionaries internally\n * from the configuration (unlike the `@intlayer/babel` version which takes it as a parameter).\n */\nexport const resolveDictionaryKey = (\n initialKey: string,\n filePath: string,\n configuration: IntlayerConfig,\n unmergedDictionaries?: Record<string, unknown>,\n usedKeys: Set<string> = new Set()\n): string => {\n const dicts =\n unmergedDictionaries ?? getUnmergedDictionaries(configuration) ?? {};\n\n const { fileExtensions } = configuration.content;\n\n const dirName = dirname(filePath);\n const firstExtension = fileExtensions[0] ?? '.ts';\n const extension = firstExtension.startsWith('.')\n ? firstExtension\n : `.${firstExtension}`;\n\n let index = 0;\n\n while (index < 100) {\n const keyToTest = index === 0 ? initialKey : `${initialKey}${index}`;\n const dictionaries = dicts[keyToTest] as Dictionary[] | undefined;\n const contentFilePath = join(dirName, `${keyToTest}${extension}`);\n\n assertPathWithin(resolve(contentFilePath), dirName);\n\n const isKeyUsed = usedKeys.has(keyToTest);\n const hasDictionaries = dictionaries && dictionaries.length > 0;\n const fileExists = existsSync(contentFilePath);\n\n if (!isKeyUsed && !hasDictionaries && !fileExists) {\n return keyToTest;\n }\n index++;\n }\n\n return initialKey;\n};\n"],"mappings":";;;;;;;;;;;AAYA,MAAa,wBACX,YACA,UACA,eACA,sBACA,2BAAwB,IAAI,KAAK,KACtB;CACX,MAAM,QACJ,wBAAwB,wBAAwB,cAAc,IAAI,EAAE;CAEtE,MAAM,EAAE,mBAAmB,cAAc;CAEzC,MAAM,UAAU,QAAQ,SAAS;CACjC,MAAM,iBAAiB,eAAe,MAAM;CAC5C,MAAM,YAAY,eAAe,WAAW,IAAI,GAC5C,iBACA,IAAI;CAER,IAAI,QAAQ;AAEZ,QAAO,QAAQ,KAAK;EAClB,MAAM,YAAY,UAAU,IAAI,aAAa,GAAG,aAAa;EAC7D,MAAM,eAAe,MAAM;EAC3B,MAAM,kBAAkB,KAAK,SAAS,GAAG,YAAY,YAAY;AAEjE,mBAAiB,QAAQ,gBAAgB,EAAE,QAAQ;EAEnD,MAAM,YAAY,SAAS,IAAI,UAAU;EACzC,MAAM,kBAAkB,gBAAgB,aAAa,SAAS;EAC9D,MAAM,aAAa,WAAW,gBAAgB;AAE9C,MAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,WACrC,QAAO;AAET;;AAGF,QAAO"}
1
+ {"version":3,"file":"resolveDictionaryKey.mjs","names":[],"sources":["../../../../src/extractContent/utils/resolveDictionaryKey.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { assertPathWithin } from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\n\n/**\n * Resolves a unique dictionary key, checking for existing dictionaries and files.\n * Note: this chokidar-specific variant fetches unmergedDictionaries internally\n * from the configuration (unlike the `@intlayer/babel` version which takes it as a parameter).\n */\nexport const resolveDictionaryKey = (\n initialKey: string,\n filePath: string,\n configuration: IntlayerConfig,\n unmergedDictionaries?: Record<string, unknown>,\n usedKeys: Set<string> = new Set()\n): string => {\n const dicts =\n unmergedDictionaries ?? getUnmergedDictionaries(configuration) ?? {};\n\n const { fileExtensions } = configuration.content;\n\n const dirName = dirname(filePath);\n const firstExtension = fileExtensions[0] ?? '.ts';\n const extension = firstExtension.startsWith('.')\n ? firstExtension\n : `.${firstExtension}`;\n\n let index = 0;\n\n while (index < 100) {\n const keyToTest = index === 0 ? initialKey : `${initialKey}${index}`;\n const dictionaries = dicts[keyToTest] as Dictionary[] | undefined;\n const contentFilePath = join(dirName, `${keyToTest}${extension}`);\n\n assertPathWithin(resolve(contentFilePath), dirName);\n\n const isKeyUsed = usedKeys.has(keyToTest);\n const hasDictionaries = dictionaries && dictionaries.length > 0;\n const fileExists = existsSync(contentFilePath);\n\n if (!isKeyUsed && !hasDictionaries && !fileExists) {\n return keyToTest;\n }\n index++;\n }\n\n return initialKey;\n};\n"],"mappings":";;;;;;;;;;;AAYA,MAAa,wBACX,YACA,UACA,eACA,sBACA,2BAAwB,IAAI,IAAI,MACrB;CACX,MAAM,QACJ,wBAAwB,wBAAwB,aAAa,KAAK,CAAC;CAErE,MAAM,EAAE,mBAAmB,cAAc;CAEzC,MAAM,UAAU,QAAQ,QAAQ;CAChC,MAAM,iBAAiB,eAAe,MAAM;CAC5C,MAAM,YAAY,eAAe,WAAW,GAAG,IAC3C,iBACA,IAAI;CAER,IAAI,QAAQ;CAEZ,OAAO,QAAQ,KAAK;EAClB,MAAM,YAAY,UAAU,IAAI,aAAa,GAAG,aAAa;EAC7D,MAAM,eAAe,MAAM;EAC3B,MAAM,kBAAkB,KAAK,SAAS,GAAG,YAAY,WAAW;EAEhE,iBAAiB,QAAQ,eAAe,GAAG,OAAO;EAElD,MAAM,YAAY,SAAS,IAAI,SAAS;EACxC,MAAM,kBAAkB,gBAAgB,aAAa,SAAS;EAC9D,MAAM,aAAa,WAAW,eAAe;EAE7C,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,YACrC,OAAO;EAET;CACF;CAEA,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"shouldExtract.mjs","names":[],"sources":["../../../../src/extractContent/utils/shouldExtract.ts"],"sourcesContent":["/**\n * Checks whether the given text should be extracted as a translatable string.\n *\n * Filters out:\n * - Empty strings\n * - Emails\n * - Single capitalized words (likely brand/proper nouns, e.g. \"Intlayer\")\n * - Uncapitalized strings of 2 words or fewer (likely technical terms)\n * - Dynamic content patterns like Vue bindings (`v-`) or object patterns (`{`)\n */\nexport const shouldExtract = (text: string): boolean => {\n const trimmed = text.trim();\n\n if (!trimmed) return false;\n\n // Ignore emails\n if (/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(trimmed)) return false;\n\n // Ignore dynamic content patterns, but allow {{placeholder}} which is intlayer's insertion format\n if (\n (trimmed.startsWith('{') && !trimmed.startsWith('{{')) ||\n trimmed.startsWith('v-')\n )\n return false;\n\n // Ignore explicit code patterns (markers)\n if (\n trimmed.includes('=>') ||\n trimmed.includes(');') ||\n trimmed.includes('(){') ||\n trimmed.includes('==') ||\n trimmed.includes('window.') ||\n trimmed.startsWith('(function') ||\n trimmed.startsWith('function(')\n ) {\n return false;\n }\n\n // Heuristic: check for characters that are common in code but rare in natural text.\n // Whitelist: letters, numbers, spaces, and frequent text symbols (including punctuation, braces, and technical symbols)\n const nonTextualRegex =\n /[^\\p{L}\\p{N}\\s.,!?;:'\"()[\\]{}–—/«»„“\\p{Sc}%&*+#@^_+=<>/~]/gu;\n const nonTextualMatches = trimmed.match(nonTextualRegex) || [];\n\n // If a string contains a high density of truly exceptional symbols (like |, \\, etc.),\n // it is highly likely to be code or complex technical data.\n if (nonTextualMatches.length > 5) return false;\n\n const wordCount = trimmed.split(/\\s+/).length;\n\n // Ignore CSS/Tailwind utility class strings. A string whose tokens all look\n // like CSS utility classes (lowercase, optional responsive/state prefix like\n // \"sm:\" or \"hover:\", optional hyphenated suffix like \"-4\" or \"-full\") and\n // where at least one token contains a hyphen is almost certainly a className\n // value, not translatable text.\n const cssClassTokenRegex =\n /^!?([a-z][a-z0-9-]*:)*[a-z][a-z0-9]*(-[a-z0-9[\\].,%#/]+)*(\\/[a-z0-9]+)?$/;\n if (wordCount > 1) {\n const tokens = trimmed.split(/\\s+/);\n if (\n tokens.every((token) => cssClassTokenRegex.test(token)) &&\n tokens.some((token) => token.includes('-'))\n ) {\n return false;\n }\n }\n\n // Check if starts with a capital letter (including after an opening parenthesis/quote)\n const isCapitalized = /^['\"([]*\\p{Lu}/u.test(trimmed);\n\n // Ignore single capitalized words (e.g. brand or proper nouns like \"Intlayer\").\n // A lone word starting with a capital is almost always a name/identifier rather\n // than a translatable sentence or label.\n if (wordCount === 1 && isCapitalized) return false;\n\n // Ignore technical identifiers (one word strings with camelCase, kebab-case, snake_case etc.)\n if (wordCount === 1) {\n // CamelCase or internal capitals (like camelCaseProperty or CamelCaseProperty)\n if (/[a-z]\\p{Lu}/u.test(trimmed)) return false;\n // kebab-case or snake_case\n if (trimmed.includes('-') || trimmed.includes('_')) return false;\n }\n\n // We usually want to extract full sentences or labels, not single/short technical words.\n // Extract if capitalized, or if it contains more than 2 words.\n if (!isCapitalized && wordCount <= 2) return false;\n\n return true;\n};\n"],"mappings":";;;;;;;;;;;AAUA,MAAa,iBAAiB,SAA0B;CACtD,MAAM,UAAU,KAAK,MAAM;AAE3B,KAAI,CAAC,QAAS,QAAO;AAGrB,KAAI,6BAA6B,KAAK,QAAQ,CAAE,QAAO;AAGvD,KACG,QAAQ,WAAW,IAAI,IAAI,CAAC,QAAQ,WAAW,KAAK,IACrD,QAAQ,WAAW,KAAK,CAExB,QAAO;AAGT,KACE,QAAQ,SAAS,KAAK,IACtB,QAAQ,SAAS,KAAK,IACtB,QAAQ,SAAS,MAAM,IACvB,QAAQ,SAAS,KAAK,IACtB,QAAQ,SAAS,UAAU,IAC3B,QAAQ,WAAW,YAAY,IAC/B,QAAQ,WAAW,YAAY,CAE/B,QAAO;AAWT,MAJ0B,QAAQ,MAAM,8DAAgB,IAAI,EAAE,EAIxC,SAAS,EAAG,QAAO;CAEzC,MAAM,YAAY,QAAQ,MAAM,MAAM,CAAC;CAOvC,MAAM,qBACJ;AACF,KAAI,YAAY,GAAG;EACjB,MAAM,SAAS,QAAQ,MAAM,MAAM;AACnC,MACE,OAAO,OAAO,UAAU,mBAAmB,KAAK,MAAM,CAAC,IACvD,OAAO,MAAM,UAAU,MAAM,SAAS,IAAI,CAAC,CAE3C,QAAO;;CAKX,MAAM,gBAAgB,kBAAkB,KAAK,QAAQ;AAKrD,KAAI,cAAc,KAAK,cAAe,QAAO;AAG7C,KAAI,cAAc,GAAG;AAEnB,MAAI,eAAe,KAAK,QAAQ,CAAE,QAAO;AAEzC,MAAI,QAAQ,SAAS,IAAI,IAAI,QAAQ,SAAS,IAAI,CAAE,QAAO;;AAK7D,KAAI,CAAC,iBAAiB,aAAa,EAAG,QAAO;AAE7C,QAAO"}
1
+ {"version":3,"file":"shouldExtract.mjs","names":[],"sources":["../../../../src/extractContent/utils/shouldExtract.ts"],"sourcesContent":["/**\n * Checks whether the given text should be extracted as a translatable string.\n *\n * Filters out:\n * - Empty strings\n * - Emails\n * - Single capitalized words (likely brand/proper nouns, e.g. \"Intlayer\")\n * - Uncapitalized strings of 2 words or fewer (likely technical terms)\n * - Dynamic content patterns like Vue bindings (`v-`) or object patterns (`{`)\n */\nexport const shouldExtract = (text: string): boolean => {\n const trimmed = text.trim();\n\n if (!trimmed) return false;\n\n // Ignore emails\n if (/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(trimmed)) return false;\n\n // Ignore dynamic content patterns, but allow {{placeholder}} which is intlayer's insertion format\n if (\n (trimmed.startsWith('{') && !trimmed.startsWith('{{')) ||\n trimmed.startsWith('v-')\n )\n return false;\n\n // Ignore explicit code patterns (markers)\n if (\n trimmed.includes('=>') ||\n trimmed.includes(');') ||\n trimmed.includes('(){') ||\n trimmed.includes('==') ||\n trimmed.includes('window.') ||\n trimmed.startsWith('(function') ||\n trimmed.startsWith('function(')\n ) {\n return false;\n }\n\n // Heuristic: check for characters that are common in code but rare in natural text.\n // Whitelist: letters, numbers, spaces, and frequent text symbols (including punctuation, braces, and technical symbols)\n const nonTextualRegex =\n /[^\\p{L}\\p{N}\\s.,!?;:'\"()[\\]{}–—/«»„“\\p{Sc}%&*+#@^_+=<>/~]/gu;\n const nonTextualMatches = trimmed.match(nonTextualRegex) || [];\n\n // If a string contains a high density of truly exceptional symbols (like |, \\, etc.),\n // it is highly likely to be code or complex technical data.\n if (nonTextualMatches.length > 5) return false;\n\n const wordCount = trimmed.split(/\\s+/).length;\n\n // Ignore CSS/Tailwind utility class strings. A string whose tokens all look\n // like CSS utility classes (lowercase, optional responsive/state prefix like\n // \"sm:\" or \"hover:\", optional hyphenated suffix like \"-4\" or \"-full\") and\n // where at least one token contains a hyphen is almost certainly a className\n // value, not translatable text.\n const cssClassTokenRegex =\n /^!?([a-z][a-z0-9-]*:)*[a-z][a-z0-9]*(-[a-z0-9[\\].,%#/]+)*(\\/[a-z0-9]+)?$/;\n if (wordCount > 1) {\n const tokens = trimmed.split(/\\s+/);\n if (\n tokens.every((token) => cssClassTokenRegex.test(token)) &&\n tokens.some((token) => token.includes('-'))\n ) {\n return false;\n }\n }\n\n // Check if starts with a capital letter (including after an opening parenthesis/quote)\n const isCapitalized = /^['\"([]*\\p{Lu}/u.test(trimmed);\n\n // Ignore single capitalized words (e.g. brand or proper nouns like \"Intlayer\").\n // A lone word starting with a capital is almost always a name/identifier rather\n // than a translatable sentence or label.\n if (wordCount === 1 && isCapitalized) return false;\n\n // Ignore technical identifiers (one word strings with camelCase, kebab-case, snake_case etc.)\n if (wordCount === 1) {\n // CamelCase or internal capitals (like camelCaseProperty or CamelCaseProperty)\n if (/[a-z]\\p{Lu}/u.test(trimmed)) return false;\n // kebab-case or snake_case\n if (trimmed.includes('-') || trimmed.includes('_')) return false;\n }\n\n // We usually want to extract full sentences or labels, not single/short technical words.\n // Extract if capitalized, or if it contains more than 2 words.\n if (!isCapitalized && wordCount <= 2) return false;\n\n return true;\n};\n"],"mappings":";;;;;;;;;;;AAUA,MAAa,iBAAiB,SAA0B;CACtD,MAAM,UAAU,KAAK,KAAK;CAE1B,IAAI,CAAC,SAAS,OAAO;CAGrB,IAAI,6BAA6B,KAAK,OAAO,GAAG,OAAO;CAGvD,IACG,QAAQ,WAAW,GAAG,KAAK,CAAC,QAAQ,WAAW,IAAI,KACpD,QAAQ,WAAW,IAAI,GAEvB,OAAO;CAGT,IACE,QAAQ,SAAS,IAAI,KACrB,QAAQ,SAAS,IAAI,KACrB,QAAQ,SAAS,KAAK,KACtB,QAAQ,SAAS,IAAI,KACrB,QAAQ,SAAS,SAAS,KAC1B,QAAQ,WAAW,WAAW,KAC9B,QAAQ,WAAW,WAAW,GAE9B,OAAO;CAWT,KAJ0B,QAAQ,MAAM,6DAAe,KAAK,CAAC,EAIxC,CAAC,SAAS,GAAG,OAAO;CAEzC,MAAM,YAAY,QAAQ,MAAM,KAAK,CAAC,CAAC;CAOvC,MAAM,qBACJ;CACF,IAAI,YAAY,GAAG;EACjB,MAAM,SAAS,QAAQ,MAAM,KAAK;EAClC,IACE,OAAO,OAAO,UAAU,mBAAmB,KAAK,KAAK,CAAC,KACtD,OAAO,MAAM,UAAU,MAAM,SAAS,GAAG,CAAC,GAE1C,OAAO;CAEX;CAGA,MAAM,gBAAgB,kBAAkB,KAAK,OAAO;CAKpD,IAAI,cAAc,KAAK,eAAe,OAAO;CAG7C,IAAI,cAAc,GAAG;EAEnB,IAAI,eAAe,KAAK,OAAO,GAAG,OAAO;EAEzC,IAAI,QAAQ,SAAS,GAAG,KAAK,QAAQ,SAAS,GAAG,GAAG,OAAO;CAC7D;CAIA,IAAI,CAAC,iBAAiB,aAAa,GAAG,OAAO;CAE7C,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"extractScriptBlocks.mjs","names":[],"sources":["../../src/extractScriptBlocks.ts"],"sourcesContent":["import { extname } from 'node:path';\n\n/**\n * A script block extracted from an SFC (Vue or Svelte) source file.\n *\n * `content` – The raw JS/TS text between the opening and closing\n * `<script>` tags (does NOT include the tags).\n * `contentStartOffset` – Byte offset of `content[0]` in the full source string.\n * `contentEndOffset` – Byte offset one past the last byte of `content` in the\n * full source string (i.e. `source.slice(start, end) === content`).\n */\nexport type ScriptBlock = {\n content: string;\n contentStartOffset: number;\n contentEndOffset: number;\n};\n\n// ── SFC script extraction ─────────────────────────────────────────────────────\n\n/**\n * Regex that matches every `<script …>…</script>` block in an SFC (Vue or\n * Svelte). Works for both instance scripts and module/setup scripts.\n *\n * Limitations (shared with `@intlayer/svelte-compiler`'s own approach):\n * - A literal `</script>` inside a string or comment inside the script block\n * would prematurely close the match. This is an accepted trade-off for the\n * vast majority of real-world files.\n */\nconst SFC_SCRIPT_RE = /<script([^>]*)>([\\s\\S]*?)<\\/script>/g;\n\n/**\n * Matches an Astro frontmatter block: the JS/TS code between the opening `---`\n * and closing `---` at the top of an `.astro` file.\n *\n * Group 1 captures the raw script content (without the fence markers).\n */\nconst ASTRO_FRONTMATTER_RE = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/;\n\n/**\n * Extracts the frontmatter script block from a raw `.astro` source file.\n * Returns an empty array when no frontmatter fence is present (static pages).\n */\nconst extractAstroFrontmatter = (code: string): ScriptBlock[] => {\n const match = ASTRO_FRONTMATTER_RE.exec(code);\n if (!match) return [];\n\n const openingFence = match[0].slice(0, match[0].indexOf('\\n') + 1); // \"---\\n\" or \"---\\r\\n\"\n const contentStartOffset = openingFence.length;\n const content = match[1] ?? '';\n\n return [\n {\n content,\n contentStartOffset,\n contentEndOffset: contentStartOffset + content.length,\n },\n ];\n};\n\n/**\n * Extracts all `<script>` blocks from a Vue SFC or Svelte source string,\n * returning each block's text content together with its start/end byte offsets\n * in the original source.\n *\n * Uses the same regex strategy as `@intlayer/svelte-compiler` internally.\n */\nconst extractSFCScriptBlocks = (code: string): ScriptBlock[] => {\n const blocks: ScriptBlock[] = [];\n SFC_SCRIPT_RE.lastIndex = 0;\n\n for (\n let match = SFC_SCRIPT_RE.exec(code);\n match !== null;\n match = SFC_SCRIPT_RE.exec(code)\n ) {\n // match[0]: full `<script ATTRS>CONTENT</script>`\n // match[1]: the attribute string (may be empty)\n // match[2]: the script content\n const attrs = match[1] ?? '';\n const openingTagLength = '<script'.length + attrs.length + '>'.length;\n const contentStart = match.index + openingTagLength;\n const content = match[2] ?? '';\n blocks.push({\n content,\n contentStartOffset: contentStart,\n contentEndOffset: contentStart + content.length,\n });\n }\n\n return blocks;\n};\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Extracts the script block(s) from a source file, dispatching by extension:\n *\n * - `.vue` / `.svelte` → searches for `<script>` blocks using a regex.\n * Returns an **empty array** when no `<script>` tag is found, which\n * happens both for template-only SFCs and for already-compiled JS that\n * Vite passes to `enforce:'post'` transform hooks.\n * - `.astro` → extracts the frontmatter block between the opening and closing\n * `---` fences. Returns an empty array when called on already-compiled JS\n * (no fences present), which is the case inside the `enforce:'post'`\n * transform hook where Astro has already compiled the file.\n * - everything else → treats the whole file as a single script block and\n * returns it wrapped in a single-element array.\n */\nexport const extractScriptBlocks = (\n filePath: string,\n code: string\n): ScriptBlock[] => {\n const ext = extname(filePath);\n\n if (ext === '.vue' || ext === '.svelte') {\n return extractSFCScriptBlocks(code);\n }\n\n if (ext === '.astro') {\n return extractAstroFrontmatter(code);\n }\n\n // Plain JS / TS / JSX / TSX / MJS / CJS – the whole file is the script.\n return [\n {\n content: code,\n contentStartOffset: 0,\n contentEndOffset: code.length,\n },\n ];\n};\n\n/**\n * Applies modified script block content back into the original source string.\n *\n * Each entry in `modifications` pairs an original `ScriptBlock` (as returned\n * by `extractScriptBlocks`) with the replacement text for its content.\n * Replacements are applied in reverse offset order so that earlier offsets\n * remain valid while later replacements are being processed.\n *\n * Returns `originalCode` unchanged when `modifications` is empty.\n */\nexport const injectScriptBlocks = (\n originalCode: string,\n modifications: ReadonlyArray<{\n block: ScriptBlock;\n modifiedContent: string;\n }>\n): string => {\n if (modifications.length === 0) return originalCode;\n\n const sorted = [...modifications].sort(\n (a, b) => b.block.contentStartOffset - a.block.contentStartOffset\n );\n\n let result = originalCode;\n for (const { block, modifiedContent } of sorted) {\n result =\n result.slice(0, block.contentStartOffset) +\n modifiedContent +\n result.slice(block.contentEndOffset);\n }\n\n return result;\n};\n"],"mappings":";;;;;;;;;;;;AA4BA,MAAM,gBAAgB;;;;;;;AAQtB,MAAM,uBAAuB;;;;;AAM7B,MAAM,2BAA2B,SAAgC;CAC/D,MAAM,QAAQ,qBAAqB,KAAK,KAAK;AAC7C,KAAI,CAAC,MAAO,QAAO,EAAE;CAGrB,MAAM,qBADe,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,KAAK,GAAG,EACzB,CAAC;CACxC,MAAM,UAAU,MAAM,MAAM;AAE5B,QAAO,CACL;EACE;EACA;EACA,kBAAkB,qBAAqB,QAAQ;EAChD,CACF;;;;;;;;;AAUH,MAAM,0BAA0B,SAAgC;CAC9D,MAAM,SAAwB,EAAE;AAChC,eAAc,YAAY;AAE1B,MACE,IAAI,QAAQ,cAAc,KAAK,KAAK,EACpC,UAAU,MACV,QAAQ,cAAc,KAAK,KAAK,EAChC;EAKA,MAAM,mBAAmB,KADX,MAAM,MAAM,IACwB,SAAS;EAC3D,MAAM,eAAe,MAAM,QAAQ;EACnC,MAAM,UAAU,MAAM,MAAM;AAC5B,SAAO,KAAK;GACV;GACA,oBAAoB;GACpB,kBAAkB,eAAe,QAAQ;GAC1C,CAAC;;AAGJ,QAAO;;;;;;;;;;;;;;;;AAmBT,MAAa,uBACX,UACA,SACkB;CAClB,MAAM,MAAM,QAAQ,SAAS;AAE7B,KAAI,QAAQ,UAAU,QAAQ,UAC5B,QAAO,uBAAuB,KAAK;AAGrC,KAAI,QAAQ,SACV,QAAO,wBAAwB,KAAK;AAItC,QAAO,CACL;EACE,SAAS;EACT,oBAAoB;EACpB,kBAAkB,KAAK;EACxB,CACF;;;;;;;;;;;;AAaH,MAAa,sBACX,cACA,kBAIW;AACX,KAAI,cAAc,WAAW,EAAG,QAAO;CAEvC,MAAM,SAAS,CAAC,GAAG,cAAc,CAAC,MAC/B,GAAG,MAAM,EAAE,MAAM,qBAAqB,EAAE,MAAM,mBAChD;CAED,IAAI,SAAS;AACb,MAAK,MAAM,EAAE,OAAO,qBAAqB,OACvC,UACE,OAAO,MAAM,GAAG,MAAM,mBAAmB,GACzC,kBACA,OAAO,MAAM,MAAM,iBAAiB;AAGxC,QAAO"}
1
+ {"version":3,"file":"extractScriptBlocks.mjs","names":[],"sources":["../../src/extractScriptBlocks.ts"],"sourcesContent":["import { extname } from 'node:path';\n\n/**\n * A script block extracted from an SFC (Vue or Svelte) source file.\n *\n * `content` – The raw JS/TS text between the opening and closing\n * `<script>` tags (does NOT include the tags).\n * `contentStartOffset` – Byte offset of `content[0]` in the full source string.\n * `contentEndOffset` – Byte offset one past the last byte of `content` in the\n * full source string (i.e. `source.slice(start, end) === content`).\n */\nexport type ScriptBlock = {\n content: string;\n contentStartOffset: number;\n contentEndOffset: number;\n};\n\n// ── SFC script extraction ─────────────────────────────────────────────────────\n\n/**\n * Regex that matches every `<script …>…</script>` block in an SFC (Vue or\n * Svelte). Works for both instance scripts and module/setup scripts.\n *\n * Limitations (shared with `@intlayer/svelte-compiler`'s own approach):\n * - A literal `</script>` inside a string or comment inside the script block\n * would prematurely close the match. This is an accepted trade-off for the\n * vast majority of real-world files.\n */\nconst SFC_SCRIPT_RE = /<script([^>]*)>([\\s\\S]*?)<\\/script>/g;\n\n/**\n * Matches an Astro frontmatter block: the JS/TS code between the opening `---`\n * and closing `---` at the top of an `.astro` file.\n *\n * Group 1 captures the raw script content (without the fence markers).\n */\nconst ASTRO_FRONTMATTER_RE = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/;\n\n/**\n * Extracts the frontmatter script block from a raw `.astro` source file.\n * Returns an empty array when no frontmatter fence is present (static pages).\n */\nconst extractAstroFrontmatter = (code: string): ScriptBlock[] => {\n const match = ASTRO_FRONTMATTER_RE.exec(code);\n if (!match) return [];\n\n const openingFence = match[0].slice(0, match[0].indexOf('\\n') + 1); // \"---\\n\" or \"---\\r\\n\"\n const contentStartOffset = openingFence.length;\n const content = match[1] ?? '';\n\n return [\n {\n content,\n contentStartOffset,\n contentEndOffset: contentStartOffset + content.length,\n },\n ];\n};\n\n/**\n * Extracts all `<script>` blocks from a Vue SFC or Svelte source string,\n * returning each block's text content together with its start/end byte offsets\n * in the original source.\n *\n * Uses the same regex strategy as `@intlayer/svelte-compiler` internally.\n */\nconst extractSFCScriptBlocks = (code: string): ScriptBlock[] => {\n const blocks: ScriptBlock[] = [];\n SFC_SCRIPT_RE.lastIndex = 0;\n\n for (\n let match = SFC_SCRIPT_RE.exec(code);\n match !== null;\n match = SFC_SCRIPT_RE.exec(code)\n ) {\n // match[0]: full `<script ATTRS>CONTENT</script>`\n // match[1]: the attribute string (may be empty)\n // match[2]: the script content\n const attrs = match[1] ?? '';\n const openingTagLength = '<script'.length + attrs.length + '>'.length;\n const contentStart = match.index + openingTagLength;\n const content = match[2] ?? '';\n blocks.push({\n content,\n contentStartOffset: contentStart,\n contentEndOffset: contentStart + content.length,\n });\n }\n\n return blocks;\n};\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Extracts the script block(s) from a source file, dispatching by extension:\n *\n * - `.vue` / `.svelte` → searches for `<script>` blocks using a regex.\n * Returns an **empty array** when no `<script>` tag is found, which\n * happens both for template-only SFCs and for already-compiled JS that\n * Vite passes to `enforce:'post'` transform hooks.\n * - `.astro` → extracts the frontmatter block between the opening and closing\n * `---` fences. Returns an empty array when called on already-compiled JS\n * (no fences present), which is the case inside the `enforce:'post'`\n * transform hook where Astro has already compiled the file.\n * - everything else → treats the whole file as a single script block and\n * returns it wrapped in a single-element array.\n */\nexport const extractScriptBlocks = (\n filePath: string,\n code: string\n): ScriptBlock[] => {\n const ext = extname(filePath);\n\n if (ext === '.vue' || ext === '.svelte') {\n return extractSFCScriptBlocks(code);\n }\n\n if (ext === '.astro') {\n return extractAstroFrontmatter(code);\n }\n\n // Plain JS / TS / JSX / TSX / MJS / CJS – the whole file is the script.\n return [\n {\n content: code,\n contentStartOffset: 0,\n contentEndOffset: code.length,\n },\n ];\n};\n\n/**\n * Applies modified script block content back into the original source string.\n *\n * Each entry in `modifications` pairs an original `ScriptBlock` (as returned\n * by `extractScriptBlocks`) with the replacement text for its content.\n * Replacements are applied in reverse offset order so that earlier offsets\n * remain valid while later replacements are being processed.\n *\n * Returns `originalCode` unchanged when `modifications` is empty.\n */\nexport const injectScriptBlocks = (\n originalCode: string,\n modifications: ReadonlyArray<{\n block: ScriptBlock;\n modifiedContent: string;\n }>\n): string => {\n if (modifications.length === 0) return originalCode;\n\n const sorted = [...modifications].sort(\n (a, b) => b.block.contentStartOffset - a.block.contentStartOffset\n );\n\n let result = originalCode;\n for (const { block, modifiedContent } of sorted) {\n result =\n result.slice(0, block.contentStartOffset) +\n modifiedContent +\n result.slice(block.contentEndOffset);\n }\n\n return result;\n};\n"],"mappings":";;;;;;;;;;;;AA4BA,MAAM,gBAAgB;;;;;;;AAQtB,MAAM,uBAAuB;;;;;AAM7B,MAAM,2BAA2B,SAAgC;CAC/D,MAAM,QAAQ,qBAAqB,KAAK,IAAI;CAC5C,IAAI,CAAC,OAAO,OAAO,CAAC;CAGpB,MAAM,qBADe,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,IAAI,IAAI,CAC1B,CAAC,CAAC;CACxC,MAAM,UAAU,MAAM,MAAM;CAE5B,OAAO,CACL;EACE;EACA;EACA,kBAAkB,qBAAqB,QAAQ;CACjD,CACF;AACF;;;;;;;;AASA,MAAM,0BAA0B,SAAgC;CAC9D,MAAM,SAAwB,CAAC;CAC/B,cAAc,YAAY;CAE1B,KACE,IAAI,QAAQ,cAAc,KAAK,IAAI,GACnC,UAAU,MACV,QAAQ,cAAc,KAAK,IAAI,GAC/B;EAKA,MAAM,mBAAmB,KADX,MAAM,MAAM,GACuB,CAAC,SAAS;EAC3D,MAAM,eAAe,MAAM,QAAQ;EACnC,MAAM,UAAU,MAAM,MAAM;EAC5B,OAAO,KAAK;GACV;GACA,oBAAoB;GACpB,kBAAkB,eAAe,QAAQ;EAC3C,CAAC;CACH;CAEA,OAAO;AACT;;;;;;;;;;;;;;;AAkBA,MAAa,uBACX,UACA,SACkB;CAClB,MAAM,MAAM,QAAQ,QAAQ;CAE5B,IAAI,QAAQ,UAAU,QAAQ,WAC5B,OAAO,uBAAuB,IAAI;CAGpC,IAAI,QAAQ,UACV,OAAO,wBAAwB,IAAI;CAIrC,OAAO,CACL;EACE,SAAS;EACT,oBAAoB;EACpB,kBAAkB,KAAK;CACzB,CACF;AACF;;;;;;;;;;;AAYA,MAAa,sBACX,cACA,kBAIW;CACX,IAAI,cAAc,WAAW,GAAG,OAAO;CAEvC,MAAM,SAAS,CAAC,GAAG,aAAa,CAAC,CAAC,MAC/B,GAAG,MAAM,EAAE,MAAM,qBAAqB,EAAE,MAAM,kBACjD;CAEA,IAAI,SAAS;CACb,KAAK,MAAM,EAAE,OAAO,qBAAqB,QACvC,SACE,OAAO,MAAM,GAAG,MAAM,kBAAkB,IACxC,kBACA,OAAO,MAAM,MAAM,gBAAgB;CAGvC,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"getExtractPluginOptions.mjs","names":[],"sources":["../../src/getExtractPluginOptions.ts"],"sourcesContent":["import * as ANSIColors from '@intlayer/config/colors';\nimport { COMPILER_ENABLED } from '@intlayer/config/defaultValues';\nimport { colorize, colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { buildComponentFilesList } from '@intlayer/engine/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { ExtractPluginOptions } from './babel-plugin-intlayer-extract';\nimport { writeContentHelper } from './extractContent/contentWriter';\n\n/**\n * Mode of the compiler\n * - 'dev': Development mode with HMR support\n * - 'build': Production build mode\n */\nexport type CompilerMode = 'dev' | 'build';\n\n/**\n * Get the options for the Intlayer Babel extraction plugin\n * This function loads the Intlayer configuration and sets up the onExtract callback\n * to write dictionaries to the filesystem.\n */\nexport const getExtractPluginOptions = (\n configuration: IntlayerConfig = getConfiguration(),\n isDev: CompilerMode | string | undefined = process.env.INTLAYER_IS_DEV_COMMAND\n): ExtractPluginOptions => {\n // Accept 'dev'/'serve' (Vite), boolean true, or the string 'true' (env var)\n const isDevBoolean = isDev === 'dev' || isDev === 'serve' || isDev === 'true';\n\n const compilerMode: CompilerMode = isDevBoolean ? 'dev' : 'build';\n\n const logger = getAppLogger(configuration);\n\n if (configuration.compiler?.enabled === 'build-only' && isDevBoolean) {\n logger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} i18n function is not inserted in the code in dev mode to optimize build time. (to test i18n in dev mode set compiler.enabled to true)`\n );\n }\n\n let enabled = configuration.compiler?.enabled ?? COMPILER_ENABLED;\n\n if (enabled === 'build-only') {\n if (compilerMode) {\n enabled = compilerMode === 'build';\n } else {\n // Fallback if mode isn't explicitly provided (e.g. pure babel plugin context)\n enabled = process.env.NODE_ENV === 'production';\n }\n }\n\n const filesList = buildComponentFilesList(configuration);\n\n return {\n enabled,\n configuration,\n filesList,\n onExtract: async ({ dictionaryKey, content, filePath }) => {\n try {\n await writeContentHelper(\n content,\n dictionaryKey,\n filePath,\n configuration\n );\n } catch (error) {\n logger(\n [\n `Failed to process extracted content for ${colorizeKey(dictionaryKey)}:`,\n error,\n ],\n { level: 'error' }\n );\n }\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;AAqBA,MAAa,2BACX,gBAAgC,kBAAkB,EAClD,QAA2C,QAAQ,IAAI,4BAC9B;CAEzB,MAAM,eAAe,UAAU,SAAS,UAAU,WAAW,UAAU;CAEvE,MAAM,eAA6B,eAAe,QAAQ;CAE1D,MAAM,SAAS,aAAa,cAAc;AAE1C,KAAI,cAAc,UAAU,YAAY,gBAAgB,aACtD,QACE,GAAG,SAAS,aAAa,WAAW,UAAU,CAAC,wIAChD;CAGH,IAAI,UAAU,cAAc,UAAU,WAAW;AAEjD,KAAI,YAAY,aACd,KAAI,aACF,WAAU,iBAAiB;KAG3B,WAAU;CAId,MAAM,YAAY,wBAAwB,cAAc;AAExD,QAAO;EACL;EACA;EACA;EACA,WAAW,OAAO,EAAE,eAAe,SAAS,eAAe;AACzD,OAAI;AACF,UAAM,mBACJ,SACA,eACA,UACA,cACD;YACM,OAAO;AACd,WACE,CACE,2CAA2C,YAAY,cAAc,CAAC,IACtE,MACD,EACD,EAAE,OAAO,SAAS,CACnB;;;EAGN"}
1
+ {"version":3,"file":"getExtractPluginOptions.mjs","names":[],"sources":["../../src/getExtractPluginOptions.ts"],"sourcesContent":["import * as ANSIColors from '@intlayer/config/colors';\nimport { COMPILER_ENABLED } from '@intlayer/config/defaultValues';\nimport { colorize, colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { buildComponentFilesList } from '@intlayer/engine/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { ExtractPluginOptions } from './babel-plugin-intlayer-extract';\nimport { writeContentHelper } from './extractContent/contentWriter';\n\n/**\n * Mode of the compiler\n * - 'dev': Development mode with HMR support\n * - 'build': Production build mode\n */\nexport type CompilerMode = 'dev' | 'build';\n\n/**\n * Get the options for the Intlayer Babel extraction plugin\n * This function loads the Intlayer configuration and sets up the onExtract callback\n * to write dictionaries to the filesystem.\n */\nexport const getExtractPluginOptions = (\n configuration: IntlayerConfig = getConfiguration(),\n isDev: CompilerMode | string | undefined = process.env.INTLAYER_IS_DEV_COMMAND\n): ExtractPluginOptions => {\n // Accept 'dev'/'serve' (Vite), boolean true, or the string 'true' (env var)\n const isDevBoolean = isDev === 'dev' || isDev === 'serve' || isDev === 'true';\n\n const compilerMode: CompilerMode = isDevBoolean ? 'dev' : 'build';\n\n const logger = getAppLogger(configuration);\n\n if (configuration.compiler?.enabled === 'build-only' && isDevBoolean) {\n logger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} i18n function is not inserted in the code in dev mode to optimize build time. (to test i18n in dev mode set compiler.enabled to true)`\n );\n }\n\n let enabled = configuration.compiler?.enabled ?? COMPILER_ENABLED;\n\n if (enabled === 'build-only') {\n if (compilerMode) {\n enabled = compilerMode === 'build';\n } else {\n // Fallback if mode isn't explicitly provided (e.g. pure babel plugin context)\n enabled = process.env.NODE_ENV === 'production';\n }\n }\n\n const filesList = buildComponentFilesList(configuration);\n\n return {\n enabled,\n configuration,\n filesList,\n onExtract: async ({ dictionaryKey, content, filePath }) => {\n try {\n await writeContentHelper(\n content,\n dictionaryKey,\n filePath,\n configuration\n );\n } catch (error) {\n logger(\n [\n `Failed to process extracted content for ${colorizeKey(dictionaryKey)}:`,\n error,\n ],\n { level: 'error' }\n );\n }\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;AAqBA,MAAa,2BACX,gBAAgC,iBAAiB,GACjD,QAA2C,QAAQ,IAAI,4BAC9B;CAEzB,MAAM,eAAe,UAAU,SAAS,UAAU,WAAW,UAAU;CAEvE,MAAM,eAA6B,eAAe,QAAQ;CAE1D,MAAM,SAAS,aAAa,aAAa;CAEzC,IAAI,cAAc,UAAU,YAAY,gBAAgB,cACtD,OACE,GAAG,SAAS,aAAa,WAAW,SAAS,EAAE,uIACjD;CAGF,IAAI,UAAU,cAAc,UAAU,WAAW;CAEjD,IAAI,YAAY,cACd,IAAI,cACF,UAAU,iBAAiB;MAG3B,UAAU;CAId,MAAM,YAAY,wBAAwB,aAAa;CAEvD,OAAO;EACL;EACA;EACA;EACA,WAAW,OAAO,EAAE,eAAe,SAAS,eAAe;GACzD,IAAI;IACF,MAAM,mBACJ,SACA,eACA,UACA,aACF;GACF,SAAS,OAAO;IACd,OACE,CACE,2CAA2C,YAAY,aAAa,EAAE,IACtE,KACF,GACA,EAAE,OAAO,QAAQ,CACnB;GACF;EACF;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"getOptimizePluginOptions.mjs","names":[],"sources":["../../src/getOptimizePluginOptions.ts"],"sourcesContent":["import { join } from 'node:path';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { buildComponentFilesList } from '@intlayer/engine/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { OptimizePluginOptions } from './babel-plugin-intlayer-optimize';\n\ntype GetOptimizePluginOptionsParams = {\n /**\n * Configuration options for loading intlayer config\n */\n configOptions?: GetConfigurationOptions;\n /**\n * Pre-loaded dictionaries (optional - will be loaded if not provided)\n */\n dictionaries?: Dictionary[];\n /**\n * Whether the current transform is for an SSR bundle. When using Babel\n * directly (e.g. in `babel.config.js`), forward the bundler's server flag\n * here so SSR-specific static dictionary transforms apply.\n */\n isServer?: boolean;\n /**\n * Override specific options\n */\n overrides?: Partial<OptimizePluginOptions>;\n};\n\n/**\n * Load dictionaries from the dictionaries-entry package\n */\nconst loadDictionaries = (config: IntlayerConfig): Dictionary[] => {\n try {\n // Dynamic require to avoid build-time dependency issues\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { getDictionaries } = require('@intlayer/dictionaries-entry');\n const dictionariesRecord = getDictionaries(config);\n\n return Object.values(dictionariesRecord);\n } catch {\n // If dictionaries-entry is not available, return empty array\n return [];\n }\n};\n\n/**\n * Get the options for the Intlayer Babel optimization plugin\n * This function loads the Intlayer configuration and returns the paths\n * needed for dictionary optimization and import rewriting.\n */\nexport const getOptimizePluginOptions = (\n params?: GetOptimizePluginOptionsParams\n): OptimizePluginOptions => {\n const {\n configOptions,\n dictionaries: providedDictionaries,\n isServer,\n overrides,\n } = params ?? {};\n\n const config = getConfiguration(configOptions);\n const {\n mainDir,\n dictionariesDir,\n unmergedDictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n } = config.system;\n const importMode = config.build.importMode ?? config.dictionary?.importMode;\n const optimize = config.build.optimize;\n\n const dictionariesEntryPath = join(mainDir, 'dictionaries.mjs');\n const unmergedDictionariesEntryPath = join(\n mainDir,\n 'unmerged_dictionaries.mjs'\n );\n const dynamicDictionariesEntryPath = join(\n mainDir,\n 'dynamic_dictionaries.mjs'\n );\n const fetchDictionariesEntryPath = join(mainDir, 'fetch_dictionaries.mjs');\n\n const filesListPattern = buildComponentFilesList(config);\n\n const filesList = [\n ...filesListPattern,\n dictionariesEntryPath, // should add dictionariesEntryPath to replace it by an empty object if import made dynamic\n unmergedDictionariesEntryPath, // should add dictionariesEntryPath to replace it by an empty object if import made dynamic\n ];\n\n // Load dictionaries if not provided\n const dictionaries = providedDictionaries ?? loadDictionaries(config);\n\n const dictionaryModeMap: Record<\n string,\n 'static' | 'dynamic' | 'fetch' | undefined\n > = {};\n\n dictionaries.forEach((dictionary) => {\n dictionaryModeMap[dictionary.key] = dictionary.importMode ?? importMode;\n });\n\n return {\n optimize,\n dictionariesDir,\n dictionariesEntryPath,\n unmergedDictionariesDir,\n unmergedDictionariesEntryPath,\n dynamicDictionariesDir,\n dynamicDictionariesEntryPath,\n fetchDictionariesDir,\n fetchDictionariesEntryPath,\n replaceDictionaryEntry: true,\n importMode,\n dictionaryModeMap,\n filesList,\n isServer,\n ...overrides,\n };\n};\n"],"mappings":";;;;;;;;;AAkCA,MAAM,oBAAoB,WAAyC;AACjE,KAAI;EAGF,MAAM,EAAE,8BAA4B,+BAA+B;EACnE,MAAM,qBAAqB,gBAAgB,OAAO;AAElD,SAAO,OAAO,OAAO,mBAAmB;SAClC;AAEN,SAAO,EAAE;;;;;;;;AASb,MAAa,4BACX,WAC0B;CAC1B,MAAM,EACJ,eACA,cAAc,sBACd,UACA,cACE,UAAU,EAAE;CAEhB,MAAM,SAAS,iBAAiB,cAAc;CAC9C,MAAM,EACJ,SACA,iBACA,yBACA,wBACA,yBACE,OAAO;CACX,MAAM,aAAa,OAAO,MAAM,cAAc,OAAO,YAAY;CACjE,MAAM,WAAW,OAAO,MAAM;CAE9B,MAAM,wBAAwB,KAAK,SAAS,mBAAmB;CAC/D,MAAM,gCAAgC,KACpC,SACA,4BACD;CACD,MAAM,+BAA+B,KACnC,SACA,2BACD;CACD,MAAM,6BAA6B,KAAK,SAAS,yBAAyB;CAI1E,MAAM,YAAY;EAChB,GAHuB,wBAAwB,OAG5B;EACnB;EACA;EACD;CAGD,MAAM,eAAe,wBAAwB,iBAAiB,OAAO;CAErE,MAAM,oBAGF,EAAE;AAEN,cAAa,SAAS,eAAe;AACnC,oBAAkB,WAAW,OAAO,WAAW,cAAc;GAC7D;AAEF,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,wBAAwB;EACxB;EACA;EACA;EACA;EACA,GAAG;EACJ"}
1
+ {"version":3,"file":"getOptimizePluginOptions.mjs","names":[],"sources":["../../src/getOptimizePluginOptions.ts"],"sourcesContent":["import { join } from 'node:path';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { buildComponentFilesList } from '@intlayer/engine/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { OptimizePluginOptions } from './babel-plugin-intlayer-optimize';\n\ntype GetOptimizePluginOptionsParams = {\n /**\n * Configuration options for loading intlayer config\n */\n configOptions?: GetConfigurationOptions;\n /**\n * Pre-loaded dictionaries (optional - will be loaded if not provided)\n */\n dictionaries?: Dictionary[];\n /**\n * Whether the current transform is for an SSR bundle. When using Babel\n * directly (e.g. in `babel.config.js`), forward the bundler's server flag\n * here so SSR-specific static dictionary transforms apply.\n */\n isServer?: boolean;\n /**\n * Override specific options\n */\n overrides?: Partial<OptimizePluginOptions>;\n};\n\n/**\n * Load dictionaries from the dictionaries-entry package\n */\nconst loadDictionaries = (config: IntlayerConfig): Dictionary[] => {\n try {\n // Dynamic require to avoid build-time dependency issues\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { getDictionaries } = require('@intlayer/dictionaries-entry');\n const dictionariesRecord = getDictionaries(config);\n\n return Object.values(dictionariesRecord);\n } catch {\n // If dictionaries-entry is not available, return empty array\n return [];\n }\n};\n\n/**\n * Get the options for the Intlayer Babel optimization plugin\n * This function loads the Intlayer configuration and returns the paths\n * needed for dictionary optimization and import rewriting.\n */\nexport const getOptimizePluginOptions = (\n params?: GetOptimizePluginOptionsParams\n): OptimizePluginOptions => {\n const {\n configOptions,\n dictionaries: providedDictionaries,\n isServer,\n overrides,\n } = params ?? {};\n\n const config = getConfiguration(configOptions);\n const {\n mainDir,\n dictionariesDir,\n unmergedDictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n } = config.system;\n const importMode = config.build.importMode ?? config.dictionary?.importMode;\n const optimize = config.build.optimize;\n\n const dictionariesEntryPath = join(mainDir, 'dictionaries.mjs');\n const unmergedDictionariesEntryPath = join(\n mainDir,\n 'unmerged_dictionaries.mjs'\n );\n const dynamicDictionariesEntryPath = join(\n mainDir,\n 'dynamic_dictionaries.mjs'\n );\n const fetchDictionariesEntryPath = join(mainDir, 'fetch_dictionaries.mjs');\n\n const filesListPattern = buildComponentFilesList(config);\n\n const filesList = [\n ...filesListPattern,\n dictionariesEntryPath, // should add dictionariesEntryPath to replace it by an empty object if import made dynamic\n unmergedDictionariesEntryPath, // should add dictionariesEntryPath to replace it by an empty object if import made dynamic\n ];\n\n // Load dictionaries if not provided\n const dictionaries = providedDictionaries ?? loadDictionaries(config);\n\n const dictionaryModeMap: Record<\n string,\n 'static' | 'dynamic' | 'fetch' | undefined\n > = {};\n\n dictionaries.forEach((dictionary) => {\n dictionaryModeMap[dictionary.key] = dictionary.importMode ?? importMode;\n });\n\n return {\n optimize,\n dictionariesDir,\n dictionariesEntryPath,\n unmergedDictionariesDir,\n unmergedDictionariesEntryPath,\n dynamicDictionariesDir,\n dynamicDictionariesEntryPath,\n fetchDictionariesDir,\n fetchDictionariesEntryPath,\n replaceDictionaryEntry: true,\n importMode,\n dictionaryModeMap,\n filesList,\n isServer,\n ...overrides,\n };\n};\n"],"mappings":";;;;;;;;;AAkCA,MAAM,oBAAoB,WAAyC;CACjE,IAAI;EAGF,MAAM,EAAE,8BAA4B,8BAA8B;EAClE,MAAM,qBAAqB,gBAAgB,MAAM;EAEjD,OAAO,OAAO,OAAO,kBAAkB;CACzC,QAAQ;EAEN,OAAO,CAAC;CACV;AACF;;;;;;AAOA,MAAa,4BACX,WAC0B;CAC1B,MAAM,EACJ,eACA,cAAc,sBACd,UACA,cACE,UAAU,CAAC;CAEf,MAAM,SAAS,iBAAiB,aAAa;CAC7C,MAAM,EACJ,SACA,iBACA,yBACA,wBACA,yBACE,OAAO;CACX,MAAM,aAAa,OAAO,MAAM,cAAc,OAAO,YAAY;CACjE,MAAM,WAAW,OAAO,MAAM;CAE9B,MAAM,wBAAwB,KAAK,SAAS,kBAAkB;CAC9D,MAAM,gCAAgC,KACpC,SACA,2BACF;CACA,MAAM,+BAA+B,KACnC,SACA,0BACF;CACA,MAAM,6BAA6B,KAAK,SAAS,wBAAwB;CAIzE,MAAM,YAAY;EAChB,GAHuB,wBAAwB,MAG7B;EAClB;EACA;CACF;CAGA,MAAM,eAAe,wBAAwB,iBAAiB,MAAM;CAEpE,MAAM,oBAGF,CAAC;CAEL,aAAa,SAAS,eAAe;EACnC,kBAAkB,WAAW,OAAO,WAAW,cAAc;CAC/D,CAAC;CAED,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,wBAAwB;EACxB;EACA;EACA;EACA;EACA,GAAG;CACL;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"getPurgePluginOptions.mjs","names":[],"sources":["../../src/getPurgePluginOptions.ts"],"sourcesContent":["import { IMPORT_MODE } from '@intlayer/config/defaultValues';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { buildComponentFilesList } from '@intlayer/engine/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { MinifyPluginOptions } from './babel-plugin-intlayer-minify';\nimport type { PurgePluginOptions } from './babel-plugin-intlayer-purge';\n\n// ── Shared config helpers ─────────────────────────────────────────────────────\n\n/**\n * Attempts to load compiled dictionaries from `@intlayer/dictionaries-entry`.\n * Returns an empty array if the entry point is not available (e.g. dictionaries\n * have not been built yet).\n */\nconst loadDictionaries = (config: IntlayerConfig): Dictionary[] => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { getDictionaries } = require('@intlayer/dictionaries-entry');\n const dictionariesRecord = getDictionaries(config) as Record<\n string,\n Dictionary\n >;\n return Object.values(dictionariesRecord);\n } catch {\n return [];\n }\n};\n\n// ── getPurgePluginOptions ─────────────────────────────────────────────────────\n\ntype GetPurgePluginOptionsParams = {\n /**\n * Options forwarded to the intlayer configuration loader.\n * Pass this when `intlayer.config.ts` lives outside the default search path\n * (e.g. in a monorepo workspace root).\n */\n configOptions?: GetConfigurationOptions;\n\n /**\n * Pre-loaded dictionaries (optional – loaded automatically when omitted).\n * Providing them avoids a second `getDictionaries` call when you already\n * have them at hand.\n */\n dictionaries?: Dictionary[];\n\n /**\n * Override specific resolved option values after the defaults are computed.\n */\n overrides?: Partial<PurgePluginOptions>;\n};\n\n/**\n * Returns fully-resolved options for {@link intlayerPurgeBabelPlugin}.\n *\n * Loads the intlayer configuration once at babel.config.js evaluation time so\n * the plugin itself does not need to re-read the config on every file\n * transform.\n *\n * @example\n * ```js\n * // babel.config.js\n * const {\n * intlayerPurgeBabelPlugin,\n * getPurgePluginOptions,\n * } = require(\"@intlayer/babel\");\n *\n * module.exports = {\n * presets: [\"next/babel\"],\n * plugins: [\n * [intlayerPurgeBabelPlugin, getPurgePluginOptions()],\n * ],\n * };\n * ```\n */\nexport const getPurgePluginOptions = (\n params?: GetPurgePluginOptionsParams\n): PurgePluginOptions => {\n const {\n configOptions,\n dictionaries: providedDictionaries,\n overrides,\n } = params ?? {};\n\n const config = getConfiguration(configOptions);\n\n const { baseDir, dictionariesDir, dynamicDictionariesDir } = config.system;\n const { purge, minify, optimize } = config.build;\n const editorEnabled = config.editor.enabled;\n\n const importMode = config.build.importMode ?? config.dictionary?.importMode;\n\n const componentFilesList = buildComponentFilesList(config);\n\n const dictionaries = providedDictionaries ?? loadDictionaries(config);\n\n const dictionaryKeyToImportModeMap: Record<\n string,\n 'static' | 'dynamic' | 'fetch' | undefined\n > = {};\n for (const dictionary of dictionaries) {\n dictionaryKeyToImportModeMap[dictionary.key] =\n dictionary.importMode ?? importMode ?? IMPORT_MODE;\n }\n\n return {\n baseDir,\n purge: Boolean(purge),\n minify: Boolean(minify),\n optimize,\n editorEnabled,\n dictionariesDir,\n dynamicDictionariesDir,\n componentFilesList,\n dictionaryKeyToImportModeMap,\n ...overrides,\n };\n};\n\n// ── getMinifyPluginOptions ────────────────────────────────────────────────────\n\ntype GetMinifyPluginOptionsParams = {\n /**\n * Options forwarded to the intlayer configuration loader.\n */\n configOptions?: GetConfigurationOptions;\n\n /**\n * Override specific resolved option values after the defaults are computed.\n */\n overrides?: Partial<MinifyPluginOptions>;\n};\n\n/**\n * Returns fully-resolved options for {@link intlayerMinifyBabelPlugin}.\n *\n * Loads the intlayer configuration once at babel.config.js evaluation time.\n *\n * @example\n * ```js\n * // babel.config.js\n * const {\n * intlayerMinifyBabelPlugin,\n * getMinifyPluginOptions,\n * } = require(\"@intlayer/babel\");\n *\n * module.exports = {\n * presets: [\"next/babel\"],\n * plugins: [\n * [intlayerMinifyBabelPlugin, getMinifyPluginOptions()],\n * ],\n * };\n * ```\n */\nexport const getMinifyPluginOptions = (\n params?: GetMinifyPluginOptionsParams\n): MinifyPluginOptions => {\n const { configOptions, overrides } = params ?? {};\n\n const config = getConfiguration(configOptions);\n\n const { baseDir } = config.system;\n const { minify, optimize } = config.build;\n const editorEnabled = config.editor.enabled;\n\n return {\n baseDir,\n minify: Boolean(minify),\n optimize,\n editorEnabled,\n ...overrides,\n };\n};\n"],"mappings":";;;;;;;;;;;AAkBA,MAAM,oBAAoB,WAAyC;AACjE,KAAI;EAEF,MAAM,EAAE,8BAA4B,+BAA+B;EACnE,MAAM,qBAAqB,gBAAgB,OAAO;AAIlD,SAAO,OAAO,OAAO,mBAAmB;SAClC;AACN,SAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDb,MAAa,yBACX,WACuB;CACvB,MAAM,EACJ,eACA,cAAc,sBACd,cACE,UAAU,EAAE;CAEhB,MAAM,SAAS,iBAAiB,cAAc;CAE9C,MAAM,EAAE,SAAS,iBAAiB,2BAA2B,OAAO;CACpE,MAAM,EAAE,OAAO,QAAQ,aAAa,OAAO;CAC3C,MAAM,gBAAgB,OAAO,OAAO;CAEpC,MAAM,aAAa,OAAO,MAAM,cAAc,OAAO,YAAY;CAEjE,MAAM,qBAAqB,wBAAwB,OAAO;CAE1D,MAAM,eAAe,wBAAwB,iBAAiB,OAAO;CAErE,MAAM,+BAGF,EAAE;AACN,MAAK,MAAM,cAAc,aACvB,8BAA6B,WAAW,OACtC,WAAW,cAAc,cAAc;AAG3C,QAAO;EACL;EACA,OAAO,QAAQ,MAAM;EACrB,QAAQ,QAAQ,OAAO;EACvB;EACA;EACA;EACA;EACA;EACA;EACA,GAAG;EACJ;;;;;;;;;;;;;;;;;;;;;;;AAsCH,MAAa,0BACX,WACwB;CACxB,MAAM,EAAE,eAAe,cAAc,UAAU,EAAE;CAEjD,MAAM,SAAS,iBAAiB,cAAc;CAE9C,MAAM,EAAE,YAAY,OAAO;CAC3B,MAAM,EAAE,QAAQ,aAAa,OAAO;CACpC,MAAM,gBAAgB,OAAO,OAAO;AAEpC,QAAO;EACL;EACA,QAAQ,QAAQ,OAAO;EACvB;EACA;EACA,GAAG;EACJ"}
1
+ {"version":3,"file":"getPurgePluginOptions.mjs","names":[],"sources":["../../src/getPurgePluginOptions.ts"],"sourcesContent":["import { IMPORT_MODE } from '@intlayer/config/defaultValues';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { buildComponentFilesList } from '@intlayer/engine/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { MinifyPluginOptions } from './babel-plugin-intlayer-minify';\nimport type { PurgePluginOptions } from './babel-plugin-intlayer-purge';\n\n// ── Shared config helpers ─────────────────────────────────────────────────────\n\n/**\n * Attempts to load compiled dictionaries from `@intlayer/dictionaries-entry`.\n * Returns an empty array if the entry point is not available (e.g. dictionaries\n * have not been built yet).\n */\nconst loadDictionaries = (config: IntlayerConfig): Dictionary[] => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { getDictionaries } = require('@intlayer/dictionaries-entry');\n const dictionariesRecord = getDictionaries(config) as Record<\n string,\n Dictionary\n >;\n return Object.values(dictionariesRecord);\n } catch {\n return [];\n }\n};\n\n// ── getPurgePluginOptions ─────────────────────────────────────────────────────\n\ntype GetPurgePluginOptionsParams = {\n /**\n * Options forwarded to the intlayer configuration loader.\n * Pass this when `intlayer.config.ts` lives outside the default search path\n * (e.g. in a monorepo workspace root).\n */\n configOptions?: GetConfigurationOptions;\n\n /**\n * Pre-loaded dictionaries (optional – loaded automatically when omitted).\n * Providing them avoids a second `getDictionaries` call when you already\n * have them at hand.\n */\n dictionaries?: Dictionary[];\n\n /**\n * Override specific resolved option values after the defaults are computed.\n */\n overrides?: Partial<PurgePluginOptions>;\n};\n\n/**\n * Returns fully-resolved options for {@link intlayerPurgeBabelPlugin}.\n *\n * Loads the intlayer configuration once at babel.config.js evaluation time so\n * the plugin itself does not need to re-read the config on every file\n * transform.\n *\n * @example\n * ```js\n * // babel.config.js\n * const {\n * intlayerPurgeBabelPlugin,\n * getPurgePluginOptions,\n * } = require(\"@intlayer/babel\");\n *\n * module.exports = {\n * presets: [\"next/babel\"],\n * plugins: [\n * [intlayerPurgeBabelPlugin, getPurgePluginOptions()],\n * ],\n * };\n * ```\n */\nexport const getPurgePluginOptions = (\n params?: GetPurgePluginOptionsParams\n): PurgePluginOptions => {\n const {\n configOptions,\n dictionaries: providedDictionaries,\n overrides,\n } = params ?? {};\n\n const config = getConfiguration(configOptions);\n\n const { baseDir, dictionariesDir, dynamicDictionariesDir } = config.system;\n const { purge, minify, optimize } = config.build;\n const editorEnabled = config.editor.enabled;\n\n const importMode = config.build.importMode ?? config.dictionary?.importMode;\n\n const componentFilesList = buildComponentFilesList(config);\n\n const dictionaries = providedDictionaries ?? loadDictionaries(config);\n\n const dictionaryKeyToImportModeMap: Record<\n string,\n 'static' | 'dynamic' | 'fetch' | undefined\n > = {};\n for (const dictionary of dictionaries) {\n dictionaryKeyToImportModeMap[dictionary.key] =\n dictionary.importMode ?? importMode ?? IMPORT_MODE;\n }\n\n return {\n baseDir,\n purge: Boolean(purge),\n minify: Boolean(minify),\n optimize,\n editorEnabled,\n dictionariesDir,\n dynamicDictionariesDir,\n componentFilesList,\n dictionaryKeyToImportModeMap,\n ...overrides,\n };\n};\n\n// ── getMinifyPluginOptions ────────────────────────────────────────────────────\n\ntype GetMinifyPluginOptionsParams = {\n /**\n * Options forwarded to the intlayer configuration loader.\n */\n configOptions?: GetConfigurationOptions;\n\n /**\n * Override specific resolved option values after the defaults are computed.\n */\n overrides?: Partial<MinifyPluginOptions>;\n};\n\n/**\n * Returns fully-resolved options for {@link intlayerMinifyBabelPlugin}.\n *\n * Loads the intlayer configuration once at babel.config.js evaluation time.\n *\n * @example\n * ```js\n * // babel.config.js\n * const {\n * intlayerMinifyBabelPlugin,\n * getMinifyPluginOptions,\n * } = require(\"@intlayer/babel\");\n *\n * module.exports = {\n * presets: [\"next/babel\"],\n * plugins: [\n * [intlayerMinifyBabelPlugin, getMinifyPluginOptions()],\n * ],\n * };\n * ```\n */\nexport const getMinifyPluginOptions = (\n params?: GetMinifyPluginOptionsParams\n): MinifyPluginOptions => {\n const { configOptions, overrides } = params ?? {};\n\n const config = getConfiguration(configOptions);\n\n const { baseDir } = config.system;\n const { minify, optimize } = config.build;\n const editorEnabled = config.editor.enabled;\n\n return {\n baseDir,\n minify: Boolean(minify),\n optimize,\n editorEnabled,\n ...overrides,\n };\n};\n"],"mappings":";;;;;;;;;;;AAkBA,MAAM,oBAAoB,WAAyC;CACjE,IAAI;EAEF,MAAM,EAAE,8BAA4B,8BAA8B;EAClE,MAAM,qBAAqB,gBAAgB,MAAM;EAIjD,OAAO,OAAO,OAAO,kBAAkB;CACzC,QAAQ;EACN,OAAO,CAAC;CACV;AACF;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,MAAa,yBACX,WACuB;CACvB,MAAM,EACJ,eACA,cAAc,sBACd,cACE,UAAU,CAAC;CAEf,MAAM,SAAS,iBAAiB,aAAa;CAE7C,MAAM,EAAE,SAAS,iBAAiB,2BAA2B,OAAO;CACpE,MAAM,EAAE,OAAO,QAAQ,aAAa,OAAO;CAC3C,MAAM,gBAAgB,OAAO,OAAO;CAEpC,MAAM,aAAa,OAAO,MAAM,cAAc,OAAO,YAAY;CAEjE,MAAM,qBAAqB,wBAAwB,MAAM;CAEzD,MAAM,eAAe,wBAAwB,iBAAiB,MAAM;CAEpE,MAAM,+BAGF,CAAC;CACL,KAAK,MAAM,cAAc,cACvB,6BAA6B,WAAW,OACtC,WAAW,cAAc,cAAc;CAG3C,OAAO;EACL;EACA,OAAO,QAAQ,KAAK;EACpB,QAAQ,QAAQ,MAAM;EACtB;EACA;EACA;EACA;EACA;EACA;EACA,GAAG;CACL;AACF;;;;;;;;;;;;;;;;;;;;;;AAqCA,MAAa,0BACX,WACwB;CACxB,MAAM,EAAE,eAAe,cAAc,UAAU,CAAC;CAEhD,MAAM,SAAS,iBAAiB,aAAa;CAE7C,MAAM,EAAE,YAAY,OAAO;CAC3B,MAAM,EAAE,QAAQ,aAAa,OAAO;CACpC,MAAM,gBAAgB,OAAO,OAAO;CAEpC,OAAO;EACL;EACA,QAAQ,QAAQ,MAAM;EACtB;EACA;EACA,GAAG;CACL;AACF"}
@@ -10,7 +10,7 @@ import { generateKey } from "./extractContent/utils/generateKey.mjs";
10
10
  import { getComponentName } from "./extractContent/utils/getComponentName.mjs";
11
11
  import { extractContent, extractContentSync } from "./extractContent/extractContent.mjs";
12
12
  import { intlayerExtractBabelPlugin } from "./babel-plugin-intlayer-extract.mjs";
13
- import { buildNestedRenameMapFromContent, generateShortFieldName, makeFieldRenameBabelPlugin, renameIntlayerFieldAccesses } from "./babel-plugin-intlayer-field-rename.mjs";
13
+ import { buildNestedRenameMapFromContent, generateShortFieldName, getNestedRenameEntryAtPath, makeFieldRenameBabelPlugin, renameIntlayerFieldAccesses } from "./babel-plugin-intlayer-field-rename.mjs";
14
14
  import { intlayerOptimizeBabelPlugin } from "./babel-plugin-intlayer-optimize.mjs";
15
15
  import { BABEL_PARSER_OPTIONS, INTLAYER_USAGE_REGEX, SOURCE_FILE_REGEX, analyzeFieldUsageInFile, buildUsageCheckRegex, getUsageCheckRegex, optimizeSourceFile, renameFieldsInCode, renameFieldsInSourceFile } from "./transformers.mjs";
16
16
  import { getSharedPruneContext, intlayerPurgeBabelPlugin } from "./babel-plugin-intlayer-purge.mjs";
@@ -18,4 +18,4 @@ import { intlayerMinifyBabelPlugin } from "./babel-plugin-intlayer-minify.mjs";
18
18
  import { getOptimizePluginOptions } from "./getOptimizePluginOptions.mjs";
19
19
  import { getMinifyPluginOptions, getPurgePluginOptions } from "./getPurgePluginOptions.mjs";
20
20
 
21
- export { ATTRIBUTES_TO_EXTRACT, BABEL_PARSER_OPTIONS, DEFAULT_COMPAT_CALLERS, INTLAYER_CALLER_NAMES, INTLAYER_USAGE_REGEX, SERVER_CAPABLE_PACKAGES, SOURCE_FILE_REGEX, analyzeFieldUsageInFile, buildNestedRenameMapFromContent, buildUsageCheckRegex, createPruneContext, detectPackageName, extractContent, extractContentSync, extractDictionaryInfo, extractDictionaryKey, extractDictionaryKeyFromPath, extractScriptBlocks, generateKey, generateShortFieldName, getComponentName, getExtractPluginOptions, getMinifyPluginOptions, getOptimizePluginOptions, getOutput, getPurgePluginOptions, getSharedPruneContext, getUsageCheckRegex, injectScriptBlocks, intlayerExtractBabelPlugin, intlayerMinifyBabelPlugin, intlayerOptimizeBabelPlugin, intlayerPurgeBabelPlugin, makeFieldRenameBabelPlugin, makeUsageAnalyzerBabelPlugin, mergeWithExistingMultilingualDictionary, mergeWithExistingPerLocaleDictionary, optimizeSourceFile, packageList, renameFieldsInCode, renameFieldsInSourceFile, renameIntlayerFieldAccesses, resolveContentFilePaths, writeContentHelper };
21
+ export { ATTRIBUTES_TO_EXTRACT, BABEL_PARSER_OPTIONS, DEFAULT_COMPAT_CALLERS, INTLAYER_CALLER_NAMES, INTLAYER_USAGE_REGEX, SERVER_CAPABLE_PACKAGES, SOURCE_FILE_REGEX, analyzeFieldUsageInFile, buildNestedRenameMapFromContent, buildUsageCheckRegex, createPruneContext, detectPackageName, extractContent, extractContentSync, extractDictionaryInfo, extractDictionaryKey, extractDictionaryKeyFromPath, extractScriptBlocks, generateKey, generateShortFieldName, getComponentName, getExtractPluginOptions, getMinifyPluginOptions, getNestedRenameEntryAtPath, getOptimizePluginOptions, getOutput, getPurgePluginOptions, getSharedPruneContext, getUsageCheckRegex, injectScriptBlocks, intlayerExtractBabelPlugin, intlayerMinifyBabelPlugin, intlayerOptimizeBabelPlugin, intlayerPurgeBabelPlugin, makeFieldRenameBabelPlugin, makeUsageAnalyzerBabelPlugin, mergeWithExistingMultilingualDictionary, mergeWithExistingPerLocaleDictionary, optimizeSourceFile, packageList, renameFieldsInCode, renameFieldsInSourceFile, renameIntlayerFieldAccesses, resolveContentFilePaths, writeContentHelper };
@@ -1 +1 @@
1
- {"version":3,"file":"normalizedFilesList.mjs","names":[],"sources":["../../src/normalizedFilesList.ts"],"sourcesContent":["import { normalizePath } from '@intlayer/config/utils';\n\n/**\n * Cache of normalized files-list sets, keyed by the files-list array\n * reference. Babel reuses the same plugin options object for every file of a\n * build, so the (potentially large) list is normalized once per build instead\n * of once per transformed file.\n */\nconst normalizedFilesListCache = new WeakMap<readonly string[], Set<string>>();\n\n/**\n * Returns a set of POSIX-normalized paths for the given files list, computed\n * once per unique array reference.\n *\n * @param filesList - The plugin's `filesList` option (absolute file paths).\n * @returns A set of the same paths normalized via `normalizePath`.\n */\nexport const getNormalizedFilesListSet = (\n filesList: readonly string[]\n): Set<string> => {\n let normalizedSet = normalizedFilesListCache.get(filesList);\n\n if (!normalizedSet) {\n normalizedSet = new Set(filesList.map(normalizePath));\n normalizedFilesListCache.set(filesList, normalizedSet);\n }\n\n return normalizedSet;\n};\n"],"mappings":";;;;;;;;;AAQA,MAAM,2CAA2B,IAAI,SAAyC;;;;;;;;AAS9E,MAAa,6BACX,cACgB;CAChB,IAAI,gBAAgB,yBAAyB,IAAI,UAAU;AAE3D,KAAI,CAAC,eAAe;AAClB,kBAAgB,IAAI,IAAI,UAAU,IAAI,cAAc,CAAC;AACrD,2BAAyB,IAAI,WAAW,cAAc;;AAGxD,QAAO"}
1
+ {"version":3,"file":"normalizedFilesList.mjs","names":[],"sources":["../../src/normalizedFilesList.ts"],"sourcesContent":["import { normalizePath } from '@intlayer/config/utils';\n\n/**\n * Cache of normalized files-list sets, keyed by the files-list array\n * reference. Babel reuses the same plugin options object for every file of a\n * build, so the (potentially large) list is normalized once per build instead\n * of once per transformed file.\n */\nconst normalizedFilesListCache = new WeakMap<readonly string[], Set<string>>();\n\n/**\n * Returns a set of POSIX-normalized paths for the given files list, computed\n * once per unique array reference.\n *\n * @param filesList - The plugin's `filesList` option (absolute file paths).\n * @returns A set of the same paths normalized via `normalizePath`.\n */\nexport const getNormalizedFilesListSet = (\n filesList: readonly string[]\n): Set<string> => {\n let normalizedSet = normalizedFilesListCache.get(filesList);\n\n if (!normalizedSet) {\n normalizedSet = new Set(filesList.map(normalizePath));\n normalizedFilesListCache.set(filesList, normalizedSet);\n }\n\n return normalizedSet;\n};\n"],"mappings":";;;;;;;;;AAQA,MAAM,2CAA2B,IAAI,QAAwC;;;;;;;;AAS7E,MAAa,6BACX,cACgB;CAChB,IAAI,gBAAgB,yBAAyB,IAAI,SAAS;CAE1D,IAAI,CAAC,eAAe;EAClB,gBAAgB,IAAI,IAAI,UAAU,IAAI,aAAa,CAAC;EACpD,yBAAyB,IAAI,WAAW,aAAa;CACvD;CAEA,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"transformers.mjs","names":[],"sources":["../../src/transformers.ts"],"sourcesContent":["import { type TransformOptions, transformAsync } from '@babel/core';\nimport { makeFieldRenameBabelPlugin } from './babel-plugin-intlayer-field-rename';\nimport {\n intlayerOptimizeBabelPlugin,\n type OptimizePluginOptions,\n} from './babel-plugin-intlayer-optimize';\nimport {\n type CompatCallerConfig,\n makeUsageAnalyzerBabelPlugin,\n type PruneContext,\n} from './babel-plugin-intlayer-usage-analyzer';\nimport { extractScriptBlocks, injectScriptBlocks } from './extractScriptBlocks';\n\n// ── Shared Babel parser configuration ─────────────────────────────────────────\n\n/**\n * Babel parser options covering the superset of syntaxes used across all\n * supported frameworks (React / Vue / Svelte / Angular / …).\n */\nexport const BABEL_PARSER_OPTIONS: NonNullable<TransformOptions['parserOpts']> =\n {\n sourceType: 'module',\n allowImportExportEverywhere: true,\n plugins: [\n 'typescript',\n 'jsx',\n 'decorators-legacy',\n 'classProperties',\n 'objectRestSpread',\n 'asyncGenerators',\n 'functionBind',\n 'exportDefaultFrom',\n 'exportNamespaceFrom',\n 'dynamicImport',\n 'nullishCoalescingOperator',\n 'optionalChaining',\n ],\n };\n\n/**\n * Fast pre-check: matches files that could contain native intlayer calls\n * (`useIntlayer` / `getIntlayer`). Used by the optimize/transform pass, which\n * only rewrites native calls.\n */\nexport const INTLAYER_USAGE_REGEX = /\\b(use|get)Intlayer\\b/;\n\n/**\n * Builds a fast pre-check regex that matches files potentially containing\n * native intlayer calls and/or the given compat namespace caller names.\n *\n * The result is used to skip files that definitely contain none of the\n * relevant function names, avoiding unnecessary Babel parsing.\n *\n * Compat caller names are NOT hardcoded here — they are provided at runtime by\n * the compat adapter packages that configure the usage-analysis pipeline.\n *\n * @param extraCallerNames - Additional caller function names to match\n * (e.g. `['useTranslation', 'getFixedT']` from `@intlayer/react-i18next`).\n * @returns A `RegExp` matching any of the native or provided caller names.\n */\nexport const buildUsageCheckRegex = (extraCallerNames?: string[]): RegExp => {\n const callerNames = [\n 'useIntlayer',\n 'getIntlayer',\n ...(extraCallerNames ?? []),\n ];\n const uniqueNames = [...new Set(callerNames)];\n return new RegExp(`\\\\b(${uniqueNames.join('|')})\\\\b`);\n};\n\n/** Usage-check regex covering only the native callers (no compat callers). */\nconst NATIVE_USAGE_CHECK_REGEX = buildUsageCheckRegex();\n\n/** Cache of usage-check regexes, keyed by the compat-caller array reference. */\nconst usageCheckRegexCache = new WeakMap<\n readonly CompatCallerConfig[],\n RegExp\n>();\n\n/**\n * Returns the usage-check regex for the given compat callers, memoised by the\n * array reference. Plugins pass the same options array for every analysed\n * file, so the regex is built once per build instead of once per file.\n */\nexport const getUsageCheckRegex = (\n compatCallers?: readonly CompatCallerConfig[]\n): RegExp => {\n if (!compatCallers || compatCallers.length === 0) {\n return NATIVE_USAGE_CHECK_REGEX;\n }\n\n let usageCheckRegex = usageCheckRegexCache.get(compatCallers);\n if (!usageCheckRegex) {\n usageCheckRegex = buildUsageCheckRegex(\n compatCallers.map((caller) => caller.callerName)\n );\n usageCheckRegexCache.set(compatCallers, usageCheckRegex);\n }\n return usageCheckRegex;\n};\n\n/**\n * Matches source files that are valid targets for usage analysis and Babel\n * transformation. Excludes sourcemap files, declaration files, and other\n * non-source extensions.\n */\nexport const SOURCE_FILE_REGEX = /\\.(tsx?|[mc]?jsx?|vue|svelte|astro)$/;\n\n// ── High-level transformer functions ──────────────────────────────────────────\n\n/**\n * Runs the usage-analysis Babel plugin on a single JS/TS code string.\n *\n * This is analysis-only: the transformed code output is discarded.\n * Throws if Babel cannot parse the content.\n */\nconst analyzeScriptContent = async (\n scriptContent: string,\n sourceFilePath: string,\n pruneContext: PruneContext,\n compatCallers?: CompatCallerConfig[]\n): Promise<void> => {\n await transformAsync(scriptContent, {\n filename: sourceFilePath,\n plugins: [makeUsageAnalyzerBabelPlugin(pruneContext, { compatCallers })],\n parserOpts: BABEL_PARSER_OPTIONS,\n ast: false,\n code: false, // analysis only – no output needed\n });\n};\n\n/**\n * Runs the usage-analysis Babel plugin on a source file, accumulating\n * field-usage data into `pruneContext`.\n *\n * For Vue / Svelte SFC files, script blocks are extracted before analysis so\n * Babel does not attempt to parse the full SFC syntax (templates, styles, …).\n * For plain JS/TS files, the whole file content is analysed directly.\n *\n * This is analysis-only: the transformed code output is discarded.\n * Throws if Babel cannot parse the file (caller should handle and flag\n * `pruneContext.hasUnparsableSourceFiles`).\n */\nexport const analyzeFieldUsageInFile = async (\n sourceFilePath: string,\n code: string,\n pruneContext: PruneContext,\n compatCallers?: CompatCallerConfig[]\n): Promise<void> => {\n const usageCheckRegex = getUsageCheckRegex(compatCallers);\n const scriptBlocks = extractScriptBlocks(sourceFilePath, code);\n\n // For SFC files (Vue / Svelte): scriptBlocks[0].contentStartOffset > 0\n // means we extracted actual <script> tags from the file.\n // For plain JS/TS: extractScriptBlocks returns the whole file as a single\n // block with offset 0, so we fall through to the same path.\n for (const block of scriptBlocks) {\n if (!usageCheckRegex.test(block.content)) continue;\n await analyzeScriptContent(\n block.content,\n sourceFilePath,\n pruneContext,\n compatCallers\n );\n }\n};\n\n/**\n * Applies field-renaming to a single JS/TS code string (not an SFC).\n *\n * Returns the renamed code string, or `null` if nothing changed or if\n * Babel failed to parse the input (caller should fall back to original code).\n */\nexport const renameFieldsInCode = async (\n code: string,\n sourceFilePath: string,\n pruneContext: PruneContext\n): Promise<string | null> => {\n try {\n const result = await transformAsync(code, {\n filename: sourceFilePath,\n plugins: [makeFieldRenameBabelPlugin(pruneContext)],\n parserOpts: BABEL_PARSER_OPTIONS,\n ast: false,\n });\n return result?.code ?? null;\n } catch {\n return null; // parse failure – caller falls back to original code\n }\n};\n\n/**\n * Applies field-renaming to a source file, correctly handling both plain\n * JS/TS files and SFC files (Vue / Svelte) by operating on each script block\n * individually and injecting the results back into the original source.\n *\n * Returns the renamed code string, or `null` if nothing changed.\n */\nexport const renameFieldsInSourceFile = async (\n sourceFilePath: string,\n code: string,\n pruneContext: PruneContext\n): Promise<string | null> => {\n if (pruneContext.dictionaryKeyToFieldRenameMap.size === 0) return null;\n if (!INTLAYER_USAGE_REGEX.test(code)) return null;\n\n const scriptBlocks = extractScriptBlocks(sourceFilePath, code);\n\n const isSFC =\n scriptBlocks.length > 0 &&\n ((scriptBlocks[0]?.contentStartOffset ?? 0) > 0 || scriptBlocks.length > 1);\n\n if (isSFC) {\n // Raw SFC: rename each script block individually and inject back.\n const modifications: Array<{\n block: (typeof scriptBlocks)[number];\n modifiedContent: string;\n }> = [];\n\n for (const block of scriptBlocks) {\n if (!INTLAYER_USAGE_REGEX.test(block.content)) continue;\n\n const renamedCode = await renameFieldsInCode(\n block.content,\n sourceFilePath,\n pruneContext\n );\n if (renamedCode && renamedCode !== block.content) {\n modifications.push({ block, modifiedContent: renamedCode });\n }\n }\n\n if (modifications.length === 0) return null;\n return injectScriptBlocks(code, modifications);\n }\n\n // Plain JS/TS or compiled SFC (no block delimiters) – rename the whole file.\n return renameFieldsInCode(code, sourceFilePath, pruneContext);\n};\n\n/**\n * Runs the intlayer optimize Babel plugin on a source file, transforming\n * `useIntlayer('key')` / `getIntlayer('key')` calls into `useDictionary(_hash)`\n * / `getDictionary(_hash)` and injecting the corresponding dictionary imports.\n *\n * Returns `{ code, map }` on success, or `null` if the transformation produced\n * no output.\n */\nexport const optimizeSourceFile = async (\n code: string,\n sourceFilePath: string,\n options: OptimizePluginOptions\n): Promise<{\n code: string;\n map: string | object | null | undefined;\n} | null> => {\n const result = await transformAsync(code, {\n filename: sourceFilePath,\n plugins: [[intlayerOptimizeBabelPlugin, options]],\n parserOpts: BABEL_PARSER_OPTIONS,\n });\n\n if (!result?.code) return null;\n\n return { code: result.code, map: result.map };\n};\n"],"mappings":";;;;;;;;;;;AAmBA,MAAa,uBACX;CACE,YAAY;CACZ,6BAA6B;CAC7B,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACF;;;;;;AAOH,MAAa,uBAAuB;;;;;;;;;;;;;;;AAgBpC,MAAa,wBAAwB,qBAAwC;CAC3E,MAAM,cAAc;EAClB;EACA;EACA,GAAI,oBAAoB,EAAE;EAC3B;CACD,MAAM,cAAc,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC;AAC7C,QAAO,IAAI,OAAO,OAAO,YAAY,KAAK,IAAI,CAAC,MAAM;;;AAIvD,MAAM,2BAA2B,sBAAsB;;AAGvD,MAAM,uCAAuB,IAAI,SAG9B;;;;;;AAOH,MAAa,sBACX,kBACW;AACX,KAAI,CAAC,iBAAiB,cAAc,WAAW,EAC7C,QAAO;CAGT,IAAI,kBAAkB,qBAAqB,IAAI,cAAc;AAC7D,KAAI,CAAC,iBAAiB;AACpB,oBAAkB,qBAChB,cAAc,KAAK,WAAW,OAAO,WAAW,CACjD;AACD,uBAAqB,IAAI,eAAe,gBAAgB;;AAE1D,QAAO;;;;;;;AAQT,MAAa,oBAAoB;;;;;;;AAUjC,MAAM,uBAAuB,OAC3B,eACA,gBACA,cACA,kBACkB;AAClB,OAAM,eAAe,eAAe;EAClC,UAAU;EACV,SAAS,CAAC,6BAA6B,cAAc,EAAE,eAAe,CAAC,CAAC;EACxE,YAAY;EACZ,KAAK;EACL,MAAM;EACP,CAAC;;;;;;;;;;;;;;AAeJ,MAAa,0BAA0B,OACrC,gBACA,MACA,cACA,kBACkB;CAClB,MAAM,kBAAkB,mBAAmB,cAAc;CACzD,MAAM,eAAe,oBAAoB,gBAAgB,KAAK;AAM9D,MAAK,MAAM,SAAS,cAAc;AAChC,MAAI,CAAC,gBAAgB,KAAK,MAAM,QAAQ,CAAE;AAC1C,QAAM,qBACJ,MAAM,SACN,gBACA,cACA,cACD;;;;;;;;;AAUL,MAAa,qBAAqB,OAChC,MACA,gBACA,iBAC2B;AAC3B,KAAI;AAOF,UAAO,MANc,eAAe,MAAM;GACxC,UAAU;GACV,SAAS,CAAC,2BAA2B,aAAa,CAAC;GACnD,YAAY;GACZ,KAAK;GACN,CAAC,GACa,QAAQ;SACjB;AACN,SAAO;;;;;;;;;;AAWX,MAAa,2BAA2B,OACtC,gBACA,MACA,iBAC2B;AAC3B,KAAI,aAAa,8BAA8B,SAAS,EAAG,QAAO;AAClE,KAAI,CAAC,qBAAqB,KAAK,KAAK,CAAE,QAAO;CAE7C,MAAM,eAAe,oBAAoB,gBAAgB,KAAK;AAM9D,KAHE,aAAa,SAAS,OACpB,aAAa,IAAI,sBAAsB,KAAK,KAAK,aAAa,SAAS,IAEhE;EAET,MAAM,gBAGD,EAAE;AAEP,OAAK,MAAM,SAAS,cAAc;AAChC,OAAI,CAAC,qBAAqB,KAAK,MAAM,QAAQ,CAAE;GAE/C,MAAM,cAAc,MAAM,mBACxB,MAAM,SACN,gBACA,aACD;AACD,OAAI,eAAe,gBAAgB,MAAM,QACvC,eAAc,KAAK;IAAE;IAAO,iBAAiB;IAAa,CAAC;;AAI/D,MAAI,cAAc,WAAW,EAAG,QAAO;AACvC,SAAO,mBAAmB,MAAM,cAAc;;AAIhD,QAAO,mBAAmB,MAAM,gBAAgB,aAAa;;;;;;;;;;AAW/D,MAAa,qBAAqB,OAChC,MACA,gBACA,YAIW;CACX,MAAM,SAAS,MAAM,eAAe,MAAM;EACxC,UAAU;EACV,SAAS,CAAC,CAAC,6BAA6B,QAAQ,CAAC;EACjD,YAAY;EACb,CAAC;AAEF,KAAI,CAAC,QAAQ,KAAM,QAAO;AAE1B,QAAO;EAAE,MAAM,OAAO;EAAM,KAAK,OAAO;EAAK"}
1
+ {"version":3,"file":"transformers.mjs","names":[],"sources":["../../src/transformers.ts"],"sourcesContent":["import { type TransformOptions, transformAsync } from '@babel/core';\nimport { makeFieldRenameBabelPlugin } from './babel-plugin-intlayer-field-rename';\nimport {\n intlayerOptimizeBabelPlugin,\n type OptimizePluginOptions,\n} from './babel-plugin-intlayer-optimize';\nimport {\n type CompatCallerConfig,\n makeUsageAnalyzerBabelPlugin,\n type PruneContext,\n} from './babel-plugin-intlayer-usage-analyzer';\nimport { extractScriptBlocks, injectScriptBlocks } from './extractScriptBlocks';\n\n// ── Shared Babel parser configuration ─────────────────────────────────────────\n\n/**\n * Babel parser options covering the superset of syntaxes used across all\n * supported frameworks (React / Vue / Svelte / Angular / …).\n */\nexport const BABEL_PARSER_OPTIONS: NonNullable<TransformOptions['parserOpts']> =\n {\n sourceType: 'module',\n allowImportExportEverywhere: true,\n plugins: [\n 'typescript',\n 'jsx',\n 'decorators-legacy',\n 'classProperties',\n 'objectRestSpread',\n 'asyncGenerators',\n 'functionBind',\n 'exportDefaultFrom',\n 'exportNamespaceFrom',\n 'dynamicImport',\n 'nullishCoalescingOperator',\n 'optionalChaining',\n ],\n };\n\n/**\n * Fast pre-check: matches files that could contain native intlayer calls\n * (`useIntlayer` / `getIntlayer`). Used by the optimize/transform pass, which\n * only rewrites native calls.\n */\nexport const INTLAYER_USAGE_REGEX = /\\b(use|get)Intlayer\\b/;\n\n/**\n * Builds a fast pre-check regex that matches files potentially containing\n * native intlayer calls and/or the given compat namespace caller names.\n *\n * The result is used to skip files that definitely contain none of the\n * relevant function names, avoiding unnecessary Babel parsing.\n *\n * Compat caller names are NOT hardcoded here — they are provided at runtime by\n * the compat adapter packages that configure the usage-analysis pipeline.\n *\n * @param extraCallerNames - Additional caller function names to match\n * (e.g. `['useTranslation', 'getFixedT']` from `@intlayer/react-i18next`).\n * @returns A `RegExp` matching any of the native or provided caller names.\n */\nexport const buildUsageCheckRegex = (extraCallerNames?: string[]): RegExp => {\n const callerNames = [\n 'useIntlayer',\n 'getIntlayer',\n ...(extraCallerNames ?? []),\n ];\n const uniqueNames = [...new Set(callerNames)];\n return new RegExp(`\\\\b(${uniqueNames.join('|')})\\\\b`);\n};\n\n/** Usage-check regex covering only the native callers (no compat callers). */\nconst NATIVE_USAGE_CHECK_REGEX = buildUsageCheckRegex();\n\n/** Cache of usage-check regexes, keyed by the compat-caller array reference. */\nconst usageCheckRegexCache = new WeakMap<\n readonly CompatCallerConfig[],\n RegExp\n>();\n\n/**\n * Returns the usage-check regex for the given compat callers, memoised by the\n * array reference. Plugins pass the same options array for every analysed\n * file, so the regex is built once per build instead of once per file.\n */\nexport const getUsageCheckRegex = (\n compatCallers?: readonly CompatCallerConfig[]\n): RegExp => {\n if (!compatCallers || compatCallers.length === 0) {\n return NATIVE_USAGE_CHECK_REGEX;\n }\n\n let usageCheckRegex = usageCheckRegexCache.get(compatCallers);\n if (!usageCheckRegex) {\n usageCheckRegex = buildUsageCheckRegex(\n compatCallers.map((caller) => caller.callerName)\n );\n usageCheckRegexCache.set(compatCallers, usageCheckRegex);\n }\n return usageCheckRegex;\n};\n\n/**\n * Matches source files that are valid targets for usage analysis and Babel\n * transformation. Excludes sourcemap files, declaration files, and other\n * non-source extensions.\n */\nexport const SOURCE_FILE_REGEX = /\\.(tsx?|[mc]?jsx?|vue|svelte|astro)$/;\n\n// ── High-level transformer functions ──────────────────────────────────────────\n\n/**\n * Runs the usage-analysis Babel plugin on a single JS/TS code string.\n *\n * This is analysis-only: the transformed code output is discarded.\n * Throws if Babel cannot parse the content.\n */\nconst analyzeScriptContent = async (\n scriptContent: string,\n sourceFilePath: string,\n pruneContext: PruneContext,\n compatCallers?: CompatCallerConfig[]\n): Promise<void> => {\n await transformAsync(scriptContent, {\n filename: sourceFilePath,\n plugins: [makeUsageAnalyzerBabelPlugin(pruneContext, { compatCallers })],\n parserOpts: BABEL_PARSER_OPTIONS,\n ast: false,\n code: false, // analysis only – no output needed\n });\n};\n\n/**\n * Runs the usage-analysis Babel plugin on a source file, accumulating\n * field-usage data into `pruneContext`.\n *\n * For Vue / Svelte SFC files, script blocks are extracted before analysis so\n * Babel does not attempt to parse the full SFC syntax (templates, styles, …).\n * For plain JS/TS files, the whole file content is analysed directly.\n *\n * This is analysis-only: the transformed code output is discarded.\n * Throws if Babel cannot parse the file (caller should handle and flag\n * `pruneContext.hasUnparsableSourceFiles`).\n */\nexport const analyzeFieldUsageInFile = async (\n sourceFilePath: string,\n code: string,\n pruneContext: PruneContext,\n compatCallers?: CompatCallerConfig[]\n): Promise<void> => {\n const usageCheckRegex = getUsageCheckRegex(compatCallers);\n const scriptBlocks = extractScriptBlocks(sourceFilePath, code);\n\n // For SFC files (Vue / Svelte): scriptBlocks[0].contentStartOffset > 0\n // means we extracted actual <script> tags from the file.\n // For plain JS/TS: extractScriptBlocks returns the whole file as a single\n // block with offset 0, so we fall through to the same path.\n for (const block of scriptBlocks) {\n if (!usageCheckRegex.test(block.content)) continue;\n await analyzeScriptContent(\n block.content,\n sourceFilePath,\n pruneContext,\n compatCallers\n );\n }\n};\n\n/**\n * Applies field-renaming to a single JS/TS code string (not an SFC).\n *\n * Returns the renamed code string, or `null` if nothing changed or if\n * Babel failed to parse the input (caller should fall back to original code).\n */\nexport const renameFieldsInCode = async (\n code: string,\n sourceFilePath: string,\n pruneContext: PruneContext\n): Promise<string | null> => {\n try {\n const result = await transformAsync(code, {\n filename: sourceFilePath,\n plugins: [makeFieldRenameBabelPlugin(pruneContext)],\n parserOpts: BABEL_PARSER_OPTIONS,\n ast: false,\n });\n return result?.code ?? null;\n } catch {\n return null; // parse failure – caller falls back to original code\n }\n};\n\n/**\n * Applies field-renaming to a source file, correctly handling both plain\n * JS/TS files and SFC files (Vue / Svelte) by operating on each script block\n * individually and injecting the results back into the original source.\n *\n * Returns the renamed code string, or `null` if nothing changed.\n */\nexport const renameFieldsInSourceFile = async (\n sourceFilePath: string,\n code: string,\n pruneContext: PruneContext\n): Promise<string | null> => {\n if (pruneContext.dictionaryKeyToFieldRenameMap.size === 0) return null;\n if (!INTLAYER_USAGE_REGEX.test(code)) return null;\n\n const scriptBlocks = extractScriptBlocks(sourceFilePath, code);\n\n const isSFC =\n scriptBlocks.length > 0 &&\n ((scriptBlocks[0]?.contentStartOffset ?? 0) > 0 || scriptBlocks.length > 1);\n\n if (isSFC) {\n // Raw SFC: rename each script block individually and inject back.\n const modifications: Array<{\n block: (typeof scriptBlocks)[number];\n modifiedContent: string;\n }> = [];\n\n for (const block of scriptBlocks) {\n if (!INTLAYER_USAGE_REGEX.test(block.content)) continue;\n\n const renamedCode = await renameFieldsInCode(\n block.content,\n sourceFilePath,\n pruneContext\n );\n if (renamedCode && renamedCode !== block.content) {\n modifications.push({ block, modifiedContent: renamedCode });\n }\n }\n\n if (modifications.length === 0) return null;\n return injectScriptBlocks(code, modifications);\n }\n\n // Plain JS/TS or compiled SFC (no block delimiters) – rename the whole file.\n return renameFieldsInCode(code, sourceFilePath, pruneContext);\n};\n\n/**\n * Runs the intlayer optimize Babel plugin on a source file, transforming\n * `useIntlayer('key')` / `getIntlayer('key')` calls into `useDictionary(_hash)`\n * / `getDictionary(_hash)` and injecting the corresponding dictionary imports.\n *\n * Returns `{ code, map }` on success, or `null` if the transformation produced\n * no output.\n */\nexport const optimizeSourceFile = async (\n code: string,\n sourceFilePath: string,\n options: OptimizePluginOptions\n): Promise<{\n code: string;\n map: string | object | null | undefined;\n} | null> => {\n const result = await transformAsync(code, {\n filename: sourceFilePath,\n plugins: [[intlayerOptimizeBabelPlugin, options]],\n parserOpts: BABEL_PARSER_OPTIONS,\n });\n\n if (!result?.code) return null;\n\n return { code: result.code, map: result.map };\n};\n"],"mappings":";;;;;;;;;;;AAmBA,MAAa,uBACX;CACE,YAAY;CACZ,6BAA6B;CAC7B,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;;;;;;AAOF,MAAa,uBAAuB;;;;;;;;;;;;;;;AAgBpC,MAAa,wBAAwB,qBAAwC;CAC3E,MAAM,cAAc;EAClB;EACA;EACA,GAAI,oBAAoB,CAAC;CAC3B;CACA,MAAM,cAAc,CAAC,GAAG,IAAI,IAAI,WAAW,CAAC;CAC5C,OAAO,IAAI,OAAO,OAAO,YAAY,KAAK,GAAG,EAAE,KAAK;AACtD;;AAGA,MAAM,2BAA2B,qBAAqB;;AAGtD,MAAM,uCAAuB,IAAI,QAG/B;;;;;;AAOF,MAAa,sBACX,kBACW;CACX,IAAI,CAAC,iBAAiB,cAAc,WAAW,GAC7C,OAAO;CAGT,IAAI,kBAAkB,qBAAqB,IAAI,aAAa;CAC5D,IAAI,CAAC,iBAAiB;EACpB,kBAAkB,qBAChB,cAAc,KAAK,WAAW,OAAO,UAAU,CACjD;EACA,qBAAqB,IAAI,eAAe,eAAe;CACzD;CACA,OAAO;AACT;;;;;;AAOA,MAAa,oBAAoB;;;;;;;AAUjC,MAAM,uBAAuB,OAC3B,eACA,gBACA,cACA,kBACkB;CAClB,MAAM,eAAe,eAAe;EAClC,UAAU;EACV,SAAS,CAAC,6BAA6B,cAAc,EAAE,cAAc,CAAC,CAAC;EACvE,YAAY;EACZ,KAAK;EACL,MAAM;CACR,CAAC;AACH;;;;;;;;;;;;;AAcA,MAAa,0BAA0B,OACrC,gBACA,MACA,cACA,kBACkB;CAClB,MAAM,kBAAkB,mBAAmB,aAAa;CACxD,MAAM,eAAe,oBAAoB,gBAAgB,IAAI;CAM7D,KAAK,MAAM,SAAS,cAAc;EAChC,IAAI,CAAC,gBAAgB,KAAK,MAAM,OAAO,GAAG;EAC1C,MAAM,qBACJ,MAAM,SACN,gBACA,cACA,aACF;CACF;AACF;;;;;;;AAQA,MAAa,qBAAqB,OAChC,MACA,gBACA,iBAC2B;CAC3B,IAAI;EAOF,QAAO,MANc,eAAe,MAAM;GACxC,UAAU;GACV,SAAS,CAAC,2BAA2B,YAAY,CAAC;GAClD,YAAY;GACZ,KAAK;EACP,CAAC,EACY,EAAE,QAAQ;CACzB,QAAQ;EACN,OAAO;CACT;AACF;;;;;;;;AASA,MAAa,2BAA2B,OACtC,gBACA,MACA,iBAC2B;CAC3B,IAAI,aAAa,8BAA8B,SAAS,GAAG,OAAO;CAClE,IAAI,CAAC,qBAAqB,KAAK,IAAI,GAAG,OAAO;CAE7C,MAAM,eAAe,oBAAoB,gBAAgB,IAAI;CAM7D,IAHE,aAAa,SAAS,OACpB,aAAa,EAAE,EAAE,sBAAsB,KAAK,KAAK,aAAa,SAAS,IAEhE;EAET,MAAM,gBAGD,CAAC;EAEN,KAAK,MAAM,SAAS,cAAc;GAChC,IAAI,CAAC,qBAAqB,KAAK,MAAM,OAAO,GAAG;GAE/C,MAAM,cAAc,MAAM,mBACxB,MAAM,SACN,gBACA,YACF;GACA,IAAI,eAAe,gBAAgB,MAAM,SACvC,cAAc,KAAK;IAAE;IAAO,iBAAiB;GAAY,CAAC;EAE9D;EAEA,IAAI,cAAc,WAAW,GAAG,OAAO;EACvC,OAAO,mBAAmB,MAAM,aAAa;CAC/C;CAGA,OAAO,mBAAmB,MAAM,gBAAgB,YAAY;AAC9D;;;;;;;;;AAUA,MAAa,qBAAqB,OAChC,MACA,gBACA,YAIW;CACX,MAAM,SAAS,MAAM,eAAe,MAAM;EACxC,UAAU;EACV,SAAS,CAAC,CAAC,6BAA6B,OAAO,CAAC;EAChD,YAAY;CACd,CAAC;CAED,IAAI,CAAC,QAAQ,MAAM,OAAO;CAE1B,OAAO;EAAE,MAAM,OAAO;EAAM,KAAK,OAAO;CAAI;AAC9C"}
@@ -4,7 +4,6 @@ import * as BabelTypes from "@babel/types";
4
4
  import { Locale } from "@intlayer/types/allLocales";
5
5
  import { IntlayerConfig } from "@intlayer/types/config";
6
6
  import { FilePathPattern } from "@intlayer/types/filePathPattern";
7
-
8
7
  //#region src/babel-plugin-intlayer-extract.d.ts
9
8
  type ExtractResult = {
10
9
  dictionaryKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"babel-plugin-intlayer-extract.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-extract.ts"],"mappings":";;;;;;;;KAeY,aAAA;EACV,aAAA;EACA,QAAA;EACA,OAAA,EAAS,MAAA;EACT,MAAA,EAAQ,MAAA;AAAA;AAAA,KAGE,oBAAA;EACV,WAAA,GAAc,WAAA;EACd,SAAA;EACA,OAAA;EAEA,aAAA,IAAiB,IAAA;EACjB,aAAA,EAAe,cAAA;EATD;;AAGhB;;;EAYE,SAAA,IAAa,MAAA,EAAQ,aAAA,YAAyB,OAAA;EAN/B;;;EAUf,MAAA,GAAS,eAAA;AAAA;AAAA,KAGN,KAAA,GAAQ,UAAA;EAAe,IAAA,EAAM,oBAAA;AAAA;;;;;;;;;;;;;;;AAFhC;;;cAqBW,0BAAA,GAA8B,MAAA;EACzC,KAAA,SAAc,UAAA;AAAA,MACZ,YAAA,CAAa,KAAA"}
1
+ {"version":3,"file":"babel-plugin-intlayer-extract.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-extract.ts"],"mappings":";;;;;;;KAeY;EACV;EACA;EACA,SAAS;EACT,QAAQ;;KAGE;EACV,cAAc;EACd;EACA;EAEA,iBAAiB;EACjB,eAAe;;;;;;EAMf,aAAa,QAAQ,yBAAyB;;;;EAI9C,SAAS;;KAGN,QAAQ;EAAe,MAAM;;;;;;;;;;;;;;;;;;;cAmBrB,6BAA0B;EACrC,cAAc;MACZ,aAAa"}
@@ -1,7 +1,6 @@
1
- import { NestedRenameMap, PruneContext } from "./babel-plugin-intlayer-usage-analyzer.js";
1
+ import { NestedRenameEntry, NestedRenameMap, PruneContext } from "./babel-plugin-intlayer-usage-analyzer.js";
2
2
  import { NodePath, PluginObject } from "@babel/core";
3
3
  import * as BabelTypes from "@babel/types";
4
-
5
4
  //#region src/babel-plugin-intlayer-field-rename.d.ts
6
5
  /**
7
6
  * Converts a zero-based index to a short alphabetic identifier.
@@ -36,6 +35,18 @@ declare const generateShortFieldName: (index: number) => string;
36
35
  * @param contentValue - The dictionary content value to analyse.
37
36
  */
38
37
  declare const buildNestedRenameMapFromContent: (contentValue: unknown) => NestedRenameMap;
38
+ /**
39
+ * Walks `fieldPath` through a {@link NestedRenameMap} and returns the entry at
40
+ * the final path segment, or `undefined` when any segment is missing (e.g. the
41
+ * path crosses an array or leaf value whose children are not mapped).
42
+ *
43
+ * Used to locate the rename entry of an opaquely-consumed content value so its
44
+ * children map can be cleared before the JSON rename is applied.
45
+ *
46
+ * @param renameMap - The root rename map to walk.
47
+ * @param fieldPath - Original (pre-rename) field names from the content root.
48
+ */
49
+ declare const getNestedRenameEntryAtPath: (renameMap: NestedRenameMap, fieldPath: readonly string[]) => NestedRenameEntry | undefined;
39
50
  /**
40
51
  * Rewrites dictionary content field accesses in the given program to the
41
52
  * short aliases defined in `pruneContext.dictionaryKeyToFieldRenameMap`.
@@ -70,11 +81,9 @@ declare const renameIntlayerFieldAccesses: (babelTypes: typeof BabelTypes, progr
70
81
  * `intlayerOptimizeBabelPlugin`, because the latter replaces `useIntlayer`
71
82
  * with `useDictionary`, erasing the dictionary-key information needed here.
72
83
  */
73
- declare const makeFieldRenameBabelPlugin: (pruneContext: PruneContext) => ({
74
- types: babelTypes
75
- }: {
84
+ declare const makeFieldRenameBabelPlugin: (pruneContext: PruneContext) => ({ types: babelTypes }: {
76
85
  types: typeof BabelTypes;
77
86
  }) => PluginObject;
78
87
  //#endregion
79
- export { buildNestedRenameMapFromContent, generateShortFieldName, makeFieldRenameBabelPlugin, renameIntlayerFieldAccesses };
88
+ export { buildNestedRenameMapFromContent, generateShortFieldName, getNestedRenameEntryAtPath, makeFieldRenameBabelPlugin, renameIntlayerFieldAccesses };
80
89
  //# sourceMappingURL=babel-plugin-intlayer-field-rename.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"babel-plugin-intlayer-field-rename.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-field-rename.ts"],"mappings":";;;;;;;AAyBA;;cAAa,sBAAA,GAA0B,KAAA;;;AAoCvC;;;;;AA4SA;;;;;;;;;;;;;;;;;;;AA4IA;cAxba,+BAAA,GACX,YAAA,cACC,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;cA0SU,2BAAA,GACX,UAAA,SAAmB,UAAA,EACnB,WAAA,EAAa,QAAA,CAAS,UAAA,CAAW,OAAA,GACjC,YAAA,EAAc,YAAA;;;;;;;;;;cAyIH,0BAAA,GACV,YAAA,EAAc,YAAA;EACd,KAAA,EAAA;AAAA;EAAyB,KAAA,SAAc,UAAA;AAAA,MAAe,YAAA"}
1
+ {"version":3,"file":"babel-plugin-intlayer-field-rename.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-field-rename.ts"],"mappings":";;;;;;;;cA0Ba,yBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA0CtB,kCAA+B,0BAEzC;;;;;;;;;;;;cA2EU,6BAA0B,WAC1B,iBAAe,iCAEzB;;;;;;;;;;;;;;;;;;;;;;;;;cAiSU,8BAA2B,mBACnB,YAAU,aAChB,SAAS,WAAW,UAAQ,cAC3B;;;;;;;;;;cA8IH,6BAA0B,cACtB,oBAAY,OAAA;EACD,cAAc;MAAe"}
@@ -1,6 +1,5 @@
1
1
  import { PluginObject } from "@babel/core";
2
2
  import * as BabelTypes from "@babel/types";
3
-
4
3
  //#region src/babel-plugin-intlayer-minify.d.ts
5
4
  /**
6
5
  * Pre-resolved options accepted by {@link intlayerMinifyBabelPlugin}.
@@ -1 +1 @@
1
- {"version":3,"file":"babel-plugin-intlayer-minify.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-minify.ts"],"mappings":";;;;;;AAgBA;;;;;KAAY,mBAAA;EAkBV;;;;EAbA,OAAA;EA0FA;;;;;EAnFA,MAAA;EA+DE;;;;EAzDF,QAAA;;;;EAKA,aAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkDW,yBAAA,GAA6B,KAAA;EACxC,KAAA,SAAc,UAAA;AAAA,MACZ,YAAA"}
1
+ {"version":3,"file":"babel-plugin-intlayer-minify.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-minify.ts"],"mappings":";;;;;;;;;;KAgBY;;;;;EAKV;;;;;;EAOA;;;;;EAMA;;;;EAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkDW,4BAAyB;EACpC,cAAc;MACZ"}
@@ -1,9 +1,8 @@
1
1
  import { PluginObject, PluginPass } from "@babel/core";
2
2
  import * as BabelTypes from "@babel/types";
3
3
  import { CallerDescriptor } from "@intlayer/config/callers";
4
-
5
4
  //#region src/babel-plugin-intlayer-optimize.d.ts
6
- declare const CALLER_LIST: readonly ["useIntlayer", "getIntlayer"];
5
+ declare const CALLER_LIST: readonly ['useIntlayer', 'getIntlayer'];
7
6
  /**
8
7
  * Options for the optimization Babel plugin
9
8
  */
@@ -80,14 +79,22 @@ type OptimizePluginOptions = {
80
79
  compatCallers?: CallerDescriptor[];
81
80
  };
82
81
  type State = PluginPass & {
83
- opts: OptimizePluginOptions; /** map key → generated ident (per-file) for static imports */
84
- _newStaticImports?: Map<string, BabelTypes.Identifier>; /** map key → generated ident (per-file) for dynamic imports */
85
- _newDynamicImports?: Map<string, BabelTypes.Identifier>; /** whether the current file imported *any* intlayer package */
86
- _hasValidImport?: boolean; /** map from local identifier name to the imported intlayer func name ('useIntlayer' | 'getIntlayer') */
87
- _callerMap?: Map<string, (typeof CALLER_LIST)[number]>; /** map from local identifier name to the intlayer package it was imported from */
88
- _callerPackageMap?: Map<string, string>; /** map from local identifier name to the compat caller descriptor it was imported as */
89
- _compatCallerMap?: Map<string, CallerDescriptor>; /** whether the current file *is* the dictionaries entry file */
90
- _isDictEntry?: boolean; /** whether the current file is included in the filesList */
82
+ opts: OptimizePluginOptions;
83
+ /** map key → generated ident (per-file) for static imports */
84
+ _newStaticImports?: Map<string, BabelTypes.Identifier>;
85
+ /** map key → generated ident (per-file) for dynamic imports */
86
+ _newDynamicImports?: Map<string, BabelTypes.Identifier>;
87
+ /** whether the current file imported *any* intlayer package */
88
+ _hasValidImport?: boolean;
89
+ /** map from local identifier name to the imported intlayer func name ('useIntlayer' | 'getIntlayer') */
90
+ _callerMap?: Map<string, (typeof CALLER_LIST)[number]>;
91
+ /** map from local identifier name to the intlayer package it was imported from */
92
+ _callerPackageMap?: Map<string, string>;
93
+ /** map from local identifier name to the compat caller descriptor it was imported as */
94
+ _compatCallerMap?: Map<string, CallerDescriptor>;
95
+ /** whether the current file *is* the dictionaries entry file */
96
+ _isDictEntry?: boolean;
97
+ /** whether the current file is included in the filesList */
91
98
  _isIncluded?: boolean;
92
99
  };
93
100
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"babel-plugin-intlayer-optimize.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-optimize.ts"],"mappings":";;;;;cA6BM,WAAA;;AAvB4B;;KA4EtB,qBAAA;EArD+C;;AAqD3D;EAIE,QAAA;;;;EAIA,eAAA;EAIA;;;EAAA,qBAAA;EAgBA;;;EAZA,6BAAA;EA4BA;;;EAxBA,uBAAA;EAuCA;;;EAnCA,sBAAA;EAiDgC;AAChC;;EA9CA,4BAAA;EAgDW;;;EA5CX,oBAAA;EAiDiC;;;EA7CjC,0BAAA;EAmDoB;;;EA/CpB,sBAAA;EAiDsB;;;EA7CtB,UAAA;EAmCA;;;EA/BA,iBAAA,GAAoB,MAAA;EAiCpB;;;EA1BA,SAAA;EA4BA;;;EAxBA,QAAA;EA4BA;;;;;;;;;AAoSF;;;;EAlTE,aAAA,GAAgB,gBAAA;AAAA;AAAA,KAGb,KAAA,GAAQ,UAAA;EACX,IAAA,EAAM,qBAAA,EA+SN;EA7SA,iBAAA,GAAoB,GAAA,SAAY,UAAA,CAAW,UAAA,GA4SD;EA1S1C,kBAAA,GAAqB,GAAA,SAAY,UAAA,CAAW,UAAA,GA4S7B;EA1Sf,eAAA,YA0SoB;EAxSpB,UAAA,GAAa,GAAA,iBAAoB,WAAA;EAEjC,iBAAA,GAAoB,GAAA;EAEpB,gBAAA,GAAmB,GAAA,SAAY,gBAAA;EAE/B,YAAA;EAEA,WAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA8RW,2BAAA,GAA+B,KAAA;EAC1C,KAAA,SAAc,UAAA;AAAA,MACZ,YAAA,CAAa,KAAA"}
1
+ {"version":3,"file":"babel-plugin-intlayer-optimize.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-optimize.ts"],"mappings":";;;;cA6BM;;;;KAqDM;;;;EAIV;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAIA,oBAAoB;;;;EAOpB;;;;EAIA;;;;;;;;;;;;;;EAcA,gBAAgB;;KAGb,QAAQ;EACX,MAAM;;EAEN,oBAAoB,YAAY,WAAW;;EAE3C,qBAAqB,YAAY,WAAW;;EAE5C;;EAEA,aAAa,oBAAoB;;EAEjC,oBAAoB;;EAEpB,mBAAmB,YAAY;;EAE/B;;EAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA8RW,8BAA2B;EACtC,cAAc;MACZ,aAAa"}
@@ -1,7 +1,6 @@
1
1
  import { CompatCallerConfig, PruneContext } from "./babel-plugin-intlayer-usage-analyzer.js";
2
2
  import { PluginObject } from "@babel/core";
3
3
  import * as BabelTypes from "@babel/types";
4
-
5
4
  //#region src/babel-plugin-intlayer-purge.d.ts
6
5
  /**
7
6
  * Pre-resolved options accepted by {@link intlayerPurgeBabelPlugin}.
@@ -1 +1 @@
1
- {"version":3,"file":"babel-plugin-intlayer-purge.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-purge.ts"],"mappings":";;;;;;;AA6BA;;;;;KAAY,kBAAA;EAmBV;;;;;EAbA,OAAA;EAoDA;;;;EA9CA,KAAA;EA8DkC;AAqBpC;;;;EA5EE,MAAA;EAioBW;;;;;EA1nBX,QAAA;EA0nBuC;;;;EApnBvC,aAAA;;;;;EAMA,eAAA;;;;;EAMA,sBAAA;;;;;;EAOA,kBAAA;;;;;;EAOA,4BAAA,EAA8B,MAAA;;;;;;;;;;;;EAgB9B,aAAA,GAAgB,kBAAA;AAAA;;;;;;;;;cAqBL,qBAAA,GAAyB,OAAA,aAAkB,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAqjB3C,wBAAA,GAA4B,MAAA;EACvC,KAAA,SAAc,UAAA;AAAA,MACZ,YAAA"}
1
+ {"version":3,"file":"babel-plugin-intlayer-purge.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-purge.ts"],"mappings":";;;;;;;;;;;KAgCY;;;;;;EAMV;;;;;EAMA;;;;;;EAOA;;;;;;EAOA;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;;;EAOA;;;;;;EAOA,8BAA8B;;;;;;;;;;;;EAgB9B,gBAAgB;;;;;;;;;;cAqBL,wBAAqB,oBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAwjB3C,2BAAwB;EACnC,cAAc;MACZ"}
@@ -1,7 +1,6 @@
1
1
  import { PluginObject } from "@babel/core";
2
2
  import * as BabelTypes from "@babel/types";
3
3
  import { CallerDescriptor, CallerDescriptor as CallerDescriptor$1, CallerResultShape, CallerValueSource } from "@intlayer/config/callers";
4
-
5
4
  //#region src/babel-plugin-intlayer-usage-analyzer.d.ts
6
5
  /**
7
6
  * Dictionary field usage result for a single dictionary key.
@@ -24,6 +23,22 @@ type NestedRenameEntry = {
24
23
  };
25
24
  /** A level of the field-rename tree, mapping original field names to entries. */
26
25
  type NestedRenameMap = Map<string, NestedRenameEntry>;
26
+ /**
27
+ * One opaque consumption of a dictionary content value: the value at
28
+ * `fieldPath` escapes static analysis (passed as-is to a child component or a
29
+ * function argument), so its children must keep their original key names in
30
+ * the compiled JSON.
31
+ */
32
+ type OpaqueFieldOccurrence = {
33
+ /**
34
+ * Original (pre-rename) user-defined field names from the content root to
35
+ * the escaping value, e.g. `['sections', 'hero']` for
36
+ * `<Card data={content.sections.hero} />`.
37
+ */
38
+ fieldPath: string[];
39
+ /** Source locations (`filePath:line`) where the value escapes. */
40
+ locations: string[];
41
+ };
27
42
  /**
28
43
  * Shared mutable state created once by the vite plugin and passed by reference
29
44
  * to the usage-analyzer (writer) and the prune/minify plugins (readers).
@@ -62,14 +77,17 @@ type PruneContext = {
62
77
  */
63
78
  dictionaryKeyToFieldRenameMap: Map<string, NestedRenameMap>;
64
79
  /**
65
- * Maps each dictionary key to a per-field list of source locations where
66
- * the field value is consumed "opaquely" (passed as-is to a child component
67
- * or function argument). When a field is opaque AND has nested user-defined
68
- * structure, its children must not be renamed.
80
+ * Maps each dictionary key to the content field paths whose values are
81
+ * consumed "opaquely" (passed as-is to a child component or function
82
+ * argument). When an opaque value has nested user-defined structure, its
83
+ * children must not be renamed.
84
+ *
85
+ * The inner map is keyed by the dot-joined field path for de-duplication
86
+ * only; the authoritative path is {@link OpaqueFieldOccurrence.fieldPath}.
69
87
  *
70
- * Structure: dictionaryKey → fieldName → ["filePath:line", …]
88
+ * Structure: dictionaryKey → joinedFieldPath → { fieldPath, locations }
71
89
  */
72
- dictionaryKeysWithOpaqueTopLevelFields: Map<string, Map<string, string[]>>;
90
+ dictionaryKeysWithOpaqueFields: Map<string, Map<string, OpaqueFieldOccurrence>>;
73
91
  /**
74
92
  * Dictionary keys for which field-key renaming must be skipped even if a
75
93
  * finite field-usage set was determined.
@@ -100,7 +118,7 @@ type PruneContext = {
100
118
  };
101
119
  declare const createPruneContext: () => PruneContext;
102
120
  /** Canonical intlayer caller names that trigger usage analysis. */
103
- declare const INTLAYER_CALLER_NAMES: readonly ["useIntlayer", "getIntlayer"];
121
+ declare const INTLAYER_CALLER_NAMES: readonly ['useIntlayer', 'getIntlayer'];
104
122
  type IntlayerCallerName = (typeof INTLAYER_CALLER_NAMES)[number];
105
123
  /**
106
124
  * Configuration entry for a single compat namespace caller.
@@ -136,11 +154,9 @@ declare const DEFAULT_COMPAT_CALLERS: CompatCallerConfig[];
136
154
  */
137
155
  declare const makeUsageAnalyzerBabelPlugin: (pruneContext: PruneContext, options?: {
138
156
  compatCallers?: CompatCallerConfig[];
139
- }) => ({
140
- types: babelTypes
141
- }: {
157
+ }) => ({ types: babelTypes }: {
142
158
  types: typeof BabelTypes;
143
159
  }) => PluginObject;
144
160
  //#endregion
145
- export { type CallerDescriptor, type CallerResultShape, type CallerValueSource, CompatCallerConfig, DEFAULT_COMPAT_CALLERS, DictionaryFieldUsage, INTLAYER_CALLER_NAMES, IntlayerCallerName, NestedRenameEntry, NestedRenameMap, PruneContext, createPruneContext, makeUsageAnalyzerBabelPlugin };
161
+ export { type CallerDescriptor, type CallerResultShape, type CallerValueSource, CompatCallerConfig, DEFAULT_COMPAT_CALLERS, DictionaryFieldUsage, INTLAYER_CALLER_NAMES, IntlayerCallerName, NestedRenameEntry, NestedRenameMap, OpaqueFieldOccurrence, PruneContext, createPruneContext, makeUsageAnalyzerBabelPlugin };
146
162
  //# sourceMappingURL=babel-plugin-intlayer-usage-analyzer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"babel-plugin-intlayer-usage-analyzer.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-usage-analyzer.ts"],"mappings":";;;;;;;AAgBA;;;;;KAAY,oBAAA,GAAuB,GAAA;;;;;;;;KASvB,iBAAA;EACV,SAAA;EACA,QAAA,EAAU,eAAA;AAAA;;KAIA,eAAA,GAAkB,GAAA,SAAY,iBAAA;AAS1C;;;;;;;AAAA,KAAY,YAAA;EAiCqB;;;;;EA3B/B,4BAAA,EAA8B,GAAA,SAAY,oBAAA;EA+Db;;;;EAzD7B,yBAAA,EAA2B,GAAA;EAAA;;;;;EAO3B,wBAAA;EAc2C;;;;;EAP3C,mCAAA,EAAqC,GAAA;EA2CrC;;;;;EApCA,6BAAA,EAA+B,GAAA,SAAY,eAAA;EA0ChC;;;;;AAiBb;;;EAjDE,sCAAA,EAAwC,GAAA,SAAY,GAAA;EAiDsB;AAC5E;;;;;AAmBA;;;;;AAYA;EAnEE,+BAAA,EAAiC,GAAA;;;;AA8+BnC;;;;;;;EAl+BE,wBAAA,EAA0B,GAAA;IAEtB,YAAA;IAAsB,aAAA;EAAA;AAAA;AAAA,cAIf,kBAAA,QAAyB,YAAA;;cAiBzB,qBAAA;AAAA,KACD,kBAAA,WAA6B,qBAAA;;;;;;;KAmB7B,kBAAA,GAAqB,kBAAA;;;;;;;;;;;cAYpB,sBAAA,EAAwB,kBAAA;;;;;;;;;;;;;;;cA26BxB,4BAAA,GAET,YAAA,EAAc,YAAA,EACd,OAAA;EAAY,aAAA,GAAgB,kBAAA;AAAA;EAE7B,KAAA,EAAA;AAAA;EAAyB,KAAA,SAAc,UAAA;AAAA,MAAe,YAAA"}
1
+ {"version":3,"file":"babel-plugin-intlayer-usage-analyzer.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-usage-analyzer.ts"],"mappings":";;;;;;;;;;;KAgBY,uBAAuB;;;;;;;;KASvB;EACV;EACA,UAAU;;;KAIA,kBAAkB,YAAY;;;;;;;KAQ9B;;;;;;EAMV;;EAGA;;;;;;;;;KAUU;;;;;;EAMV,8BAA8B,YAAY;;;;;EAM1C,2BAA2B;;;;;;EAO3B;;;;;;EAOA,qCAAqC;;;;;;EAOrC,+BAA+B,YAAY;;;;;;;;;;;;EAa3C,gCAAgC,YAE9B,YAAY;;;;;;;;;;;;;EAed,iCAAiC;;;;;;;;;;;EAYjC,0BAA0B;IAEtB;IAAsB;;;cAIf,0BAAyB;;cAiBzB;KACD,6BAA6B;;;;;;;KAmB7B,qBAAqB;;;;;;;;;;;cAYpB,wBAAwB;;;;;;;;;;;;;;;cAmiCxB,+BAA4B,cAEvB,cAAY;EACd,gBAAgB;SAAsB,OAAA;EAE1B,cAAc;MAAe"}
@@ -1,8 +1,8 @@
1
1
  import { ExistingIntlayerInfo } from "./utils/getExistingIntlayerInfo.js";
2
+ import "./utils/index.js";
2
3
  import * as t from "@babel/types";
3
4
  import { IntlayerConfig } from "@intlayer/types/config";
4
5
  import { NodePath } from "@babel/traverse";
5
-
6
6
  //#region src/extractContent/babelProcessor.d.ts
7
7
  type BabelReplacement = {
8
8
  path: NodePath;
@@ -27,7 +27,8 @@ declare const extractBabelContentForComponents: (ast: t.File, fileCode: string,
27
27
  componentsNeedingHooks: Set<NodePath>;
28
28
  componentKeyMap: Map<t.Node, string>;
29
29
  componentPaths: NodePath[];
30
- hookMap: Map<t.Node, "useIntlayer" | "getIntlayer">; /** Cached `getExistingIntlayerInfo` result per component node, so callers do not re-traverse. */
30
+ hookMap: Map<t.Node, 'useIntlayer' | 'getIntlayer'>;
31
+ /** Cached `getExistingIntlayerInfo` result per component node, so callers do not re-traverse. */
31
32
  existingInfoByNode: Map<t.Node, ExistingIntlayerInfo | undefined>;
32
33
  isSolid: boolean;
33
34
  };
@@ -1 +1 @@
1
- {"version":3,"file":"babelProcessor.d.ts","names":[],"sources":["../../../src/extractContent/babelProcessor.ts"],"mappings":";;;;;;KAaY,gBAAA;EACV,IAAA,EAAM,QAAA;EACN,GAAA;EACA,IAAA;EAOA,YAAA;EACA,iBAAA,GAAoB,CAAA,CAAE,IAAA;EACtB,SAAA;AAAA;;;;;cA4IW,uBAAA,GACX,IAAA,EAAM,QAAA,CAAS,CAAA,CAAE,UAAA,GAAa,CAAA,CAAE,WAAA,GAChC,QAAA,UACA,YAAA,EAAc,GAAA,UACd,sBAAA,GAAyB,IAAA,EAAM,QAAA,aAC/B,gBAAA,EAAkB,MAAA,SAAe,MAAA,mBACjC,YAAA,EAAc,gBAAA,IACd,YAAA,EAAc,GAAA,CAAI,CAAA,CAAE,IAAA;;;;;cAwIT,gCAAA,GACX,GAAA,EAAK,CAAA,CAAE,IAAA,EACP,QAAA,UACA,YAAA,EAAc,GAAA,UACd,UAAA,UACA,aAAA,EAAe,cAAA,EACf,QAAA,UACA,oBAAA,GAAsB,MAAA;EAEtB,gBAAA,EAAkB,MAAA,SAAe,MAAA;EACjC,YAAA,EAAc,gBAAA;EACd,sBAAA,EAAwB,GAAA,CAAI,QAAA;EAC5B,eAAA,EAAiB,GAAA,CAAI,CAAA,CAAE,IAAA;EACvB,cAAA,EAAgB,QAAA;EAChB,OAAA,EAAS,GAAA,CAAI,CAAA,CAAE,IAAA,kCA1JD;EA4Jd,kBAAA,EAAoB,GAAA,CAAI,CAAA,CAAE,IAAA,EAAM,oBAAA;EAChC,OAAA;AAAA;;;;cA6ZW,gBAAA,GACX,GAAA,EAAK,CAAA,CAAE,IAAA,EACP,QAAA,UACA,YAAA,EAAc,GAAA,UACd,aAAA,EAAe,cAAA,EACf,QAAA,UACA,oBAAA,GAAsB,MAAA;EAEtB,gBAAA,EAAkB,MAAA;EAClB,YAAA,EAAc,gBAAA;AAAA"}
1
+ {"version":3,"file":"babelProcessor.d.ts","names":[],"sources":["../../../src/extractContent/babelProcessor.ts"],"mappings":";;;;;;KAaY;EACV,MAAM;EACN;EACA;EAOA;EACA,oBAAoB,EAAE;EACtB;;;;;;cA4IW,0BAAuB,MAC5B,SAAS,EAAE,aAAa,EAAE,cAAY,kBAC5B,cACF,aAAW,yBACA,MAAM,qBAAmB,kBAChC,eAAe,yBAAuB,cAC1C,oBAAkB,cAClB,IAAI,EAAE;;;;;cAwIT,mCAAgC,KACtC,EAAE,MAAI,kBACK,cACF,aAAW,oBACP,eACH,gBAAc,kBACb,uBACM;EAEtB,kBAAkB,eAAe;EACjC,cAAc;EACd,wBAAwB,IAAI;EAC5B,iBAAiB,IAAI,EAAE;EACvB,gBAAgB;EAChB,SAAS,IAAI,EAAE;;EAEf,oBAAoB,IAAI,EAAE,MAAM;EAChC;;;;;cA6ZW,mBAAgB,KACtB,EAAE,MAAI,kBACK,cACF,aAAW,eACV,gBAAc,kBACb,uBACM;EAEtB,kBAAkB;EAClB,cAAc"}
@@ -1,6 +1,5 @@
1
1
  import { IntlayerConfig } from "@intlayer/types/config";
2
2
  import { Dictionary, DictionaryKey } from "@intlayer/types/dictionary";
3
-
4
3
  //#region src/extractContent/contentWriter.d.ts
5
4
  /**
6
5
  * Translation node structure used in dictionaries
@@ -1 +1 @@
1
- {"version":3,"file":"contentWriter.d.ts","names":[],"sources":["../../../src/extractContent/contentWriter.ts"],"mappings":";;;;;;AAY4E;KAuBvE,eAAA;EACH,QAAA;EACA,WAAA,EAAa,MAAA;AAAA;;;;KAMV,oBAAA,GAAuB,MAAA,SAAe,eAAA;AANtB;;;;;AAmBrB;AAnBqB,cAmBR,uCAAA,GACX,gBAAA,EAAkB,MAAA,kBAClB,kBAAA,EAAoB,UAAA,SACpB,aAAA,aACC,oBAAA;;;;;;;cAkDU,oCAAA,GACX,gBAAA,EAAkB,MAAA,kBAClB,kBAAA,EAAoB,UAAA,YACnB,MAAA;;;;cA8CU,kBAAA,GACX,gBAAA,EAAkB,MAAA,kBAClB,aAAA,EAAe,aAAA,EACf,QAAA,UACA,aAAA,EAAe,cAAA,KACd,OAAA"}
1
+ {"version":3,"file":"contentWriter.d.ts","names":[],"sources":["../../../src/extractContent/contentWriter.ts"],"mappings":";;;;;;KAmCK;EACH;EACA,aAAa;;;;;KAMV,uBAAuB,eAAe;;;;;;;cAa9B,0CAAuC,kBAChC,wBAAsB,oBACpB,mBAAiB,0BAEpC;;;;;;;cAkDU,uCAAoC,kBAC7B,wBAAsB,oBACpB,sBACnB;;;;cA8CU,qBAAkB,kBACX,wBAAsB,eACzB,eAAa,kBACZ,eACD,mBACd"}