@intlayer/babel 8.4.4 → 8.4.6

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 (139) hide show
  1. package/dist/cjs/_virtual/_rolldown/runtime.cjs +29 -0
  2. package/dist/cjs/babel-plugin-intlayer-extract.cjs +75 -1
  3. package/dist/cjs/babel-plugin-intlayer-extract.cjs.map +1 -1
  4. package/dist/cjs/babel-plugin-intlayer-optimize.cjs +306 -1
  5. package/dist/cjs/babel-plugin-intlayer-optimize.cjs.map +1 -1
  6. package/dist/cjs/extractContent/babelProcessor.cjs +261 -1
  7. package/dist/cjs/extractContent/babelProcessor.cjs.map +1 -1
  8. package/dist/cjs/extractContent/contentWriter.cjs +134 -1
  9. package/dist/cjs/extractContent/contentWriter.cjs.map +1 -1
  10. package/dist/cjs/extractContent/extractContent.cjs +184 -1
  11. package/dist/cjs/extractContent/extractContent.cjs.map +1 -1
  12. package/dist/cjs/extractContent/index.cjs +26 -1
  13. package/dist/cjs/extractContent/processTsxFile.cjs +263 -5
  14. package/dist/cjs/extractContent/processTsxFile.cjs.map +1 -1
  15. package/dist/cjs/extractContent/utils/constants.cjs +42 -1
  16. package/dist/cjs/extractContent/utils/constants.cjs.map +1 -1
  17. package/dist/cjs/extractContent/utils/detectPackageName.cjs +26 -1
  18. package/dist/cjs/extractContent/utils/detectPackageName.cjs.map +1 -1
  19. package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs +103 -1
  20. package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs.map +1 -1
  21. package/dist/cjs/extractContent/utils/extractDictionaryKey.cjs +29 -1
  22. package/dist/cjs/extractContent/utils/extractDictionaryKey.cjs.map +1 -1
  23. package/dist/cjs/extractContent/utils/generateKey.cjs +16 -1
  24. package/dist/cjs/extractContent/utils/generateKey.cjs.map +1 -1
  25. package/dist/cjs/extractContent/utils/getComponentName.cjs +18 -1
  26. package/dist/cjs/extractContent/utils/getComponentName.cjs.map +1 -1
  27. package/dist/cjs/extractContent/utils/getExistingIntlayerInfo.cjs +50 -1
  28. package/dist/cjs/extractContent/utils/getExistingIntlayerInfo.cjs.map +1 -1
  29. package/dist/cjs/extractContent/utils/getOrGenerateKey.cjs +19 -1
  30. package/dist/cjs/extractContent/utils/getOrGenerateKey.cjs.map +1 -1
  31. package/dist/cjs/extractContent/utils/index.cjs +27 -1
  32. package/dist/cjs/extractContent/utils/resolveDictionaryKey.cjs +34 -1
  33. package/dist/cjs/extractContent/utils/resolveDictionaryKey.cjs.map +1 -1
  34. package/dist/cjs/extractContent/utils/shouldExtract.cjs +23 -1
  35. package/dist/cjs/extractContent/utils/shouldExtract.cjs.map +1 -1
  36. package/dist/cjs/getExtractPluginOptions.cjs +41 -1
  37. package/dist/cjs/getExtractPluginOptions.cjs.map +1 -1
  38. package/dist/cjs/getOptimizePluginOptions.cjs +63 -1
  39. package/dist/cjs/getOptimizePluginOptions.cjs.map +1 -1
  40. package/dist/cjs/index.cjs +34 -1
  41. package/dist/esm/_virtual/_rolldown/runtime.mjs +8 -0
  42. package/dist/esm/babel-plugin-intlayer-extract.mjs +72 -1
  43. package/dist/esm/babel-plugin-intlayer-extract.mjs.map +1 -1
  44. package/dist/esm/babel-plugin-intlayer-optimize.mjs +304 -1
  45. package/dist/esm/babel-plugin-intlayer-optimize.mjs.map +1 -1
  46. package/dist/esm/extractContent/babelProcessor.mjs +255 -1
  47. package/dist/esm/extractContent/babelProcessor.mjs.map +1 -1
  48. package/dist/esm/extractContent/contentWriter.mjs +129 -1
  49. package/dist/esm/extractContent/contentWriter.mjs.map +1 -1
  50. package/dist/esm/extractContent/extractContent.mjs +180 -1
  51. package/dist/esm/extractContent/extractContent.mjs.map +1 -1
  52. package/dist/esm/extractContent/index.mjs +10 -1
  53. package/dist/esm/extractContent/processTsxFile.mjs +259 -5
  54. package/dist/esm/extractContent/processTsxFile.mjs.map +1 -1
  55. package/dist/esm/extractContent/utils/constants.mjs +38 -1
  56. package/dist/esm/extractContent/utils/constants.mjs.map +1 -1
  57. package/dist/esm/extractContent/utils/detectPackageName.mjs +24 -1
  58. package/dist/esm/extractContent/utils/detectPackageName.mjs.map +1 -1
  59. package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs +98 -1
  60. package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs.map +1 -1
  61. package/dist/esm/extractContent/utils/extractDictionaryKey.mjs +26 -1
  62. package/dist/esm/extractContent/utils/extractDictionaryKey.mjs.map +1 -1
  63. package/dist/esm/extractContent/utils/generateKey.mjs +14 -1
  64. package/dist/esm/extractContent/utils/generateKey.mjs.map +1 -1
  65. package/dist/esm/extractContent/utils/getComponentName.mjs +15 -1
  66. package/dist/esm/extractContent/utils/getComponentName.mjs.map +1 -1
  67. package/dist/esm/extractContent/utils/getExistingIntlayerInfo.mjs +47 -1
  68. package/dist/esm/extractContent/utils/getExistingIntlayerInfo.mjs.map +1 -1
  69. package/dist/esm/extractContent/utils/getOrGenerateKey.mjs +18 -1
  70. package/dist/esm/extractContent/utils/getOrGenerateKey.mjs.map +1 -1
  71. package/dist/esm/extractContent/utils/index.mjs +12 -1
  72. package/dist/esm/extractContent/utils/resolveDictionaryKey.mjs +32 -1
  73. package/dist/esm/extractContent/utils/resolveDictionaryKey.mjs.map +1 -1
  74. package/dist/esm/extractContent/utils/shouldExtract.mjs +21 -1
  75. package/dist/esm/extractContent/utils/shouldExtract.mjs.map +1 -1
  76. package/dist/esm/getExtractPluginOptions.mjs +38 -1
  77. package/dist/esm/getExtractPluginOptions.mjs.map +1 -1
  78. package/dist/esm/getOptimizePluginOptions.mjs +63 -1
  79. package/dist/esm/getOptimizePluginOptions.mjs.map +1 -0
  80. package/dist/esm/index.mjs +14 -1
  81. package/dist/types/babel-plugin-intlayer-extract.d.ts +1 -1
  82. package/dist/types/extractContent/contentWriter.d.ts +36 -2
  83. package/dist/types/extractContent/contentWriter.d.ts.map +1 -0
  84. package/dist/types/extractContent/extractContent.d.ts +37 -2
  85. package/dist/types/extractContent/extractContent.d.ts.map +1 -0
  86. package/dist/types/extractContent/index.d.ts +8 -8
  87. package/dist/types/extractContent/processTsxFile.d.ts +1 -1
  88. package/dist/types/extractContent/processTsxFile.d.ts.map +1 -1
  89. package/dist/types/extractContent/utils/constants.d.ts +20 -2
  90. package/dist/types/extractContent/utils/constants.d.ts.map +1 -0
  91. package/dist/types/extractContent/utils/detectPackageName.d.ts +10 -2
  92. package/dist/types/extractContent/utils/detectPackageName.d.ts.map +1 -0
  93. package/dist/types/extractContent/utils/extractDictionaryInfo.d.ts +28 -2
  94. package/dist/types/extractContent/utils/extractDictionaryInfo.d.ts.map +1 -0
  95. package/dist/types/extractContent/utils/extractDictionaryKey.d.ts +11 -2
  96. package/dist/types/extractContent/utils/extractDictionaryKey.d.ts.map +1 -0
  97. package/dist/types/extractContent/utils/generateKey.d.ts +5 -2
  98. package/dist/types/extractContent/utils/generateKey.d.ts.map +1 -0
  99. package/dist/types/extractContent/utils/getComponentName.d.ts +10 -2
  100. package/dist/types/extractContent/utils/getComponentName.d.ts.map +1 -0
  101. package/dist/types/extractContent/utils/getExistingIntlayerInfo.d.ts +19 -2
  102. package/dist/types/extractContent/utils/getExistingIntlayerInfo.d.ts.map +1 -0
  103. package/dist/types/extractContent/utils/getOrGenerateKey.d.ts +8 -2
  104. package/dist/types/extractContent/utils/getOrGenerateKey.d.ts.map +1 -0
  105. package/dist/types/extractContent/utils/index.d.ts +10 -10
  106. package/dist/types/extractContent/utils/resolveDictionaryKey.d.ts +12 -2
  107. package/dist/types/extractContent/utils/resolveDictionaryKey.d.ts.map +1 -0
  108. package/dist/types/extractContent/utils/shouldExtract.d.ts +14 -2
  109. package/dist/types/extractContent/utils/shouldExtract.d.ts.map +1 -0
  110. package/dist/types/index.d.ts +8 -8
  111. package/package.json +9 -9
  112. package/dist/cjs/chunk-Bmb41Sf3.cjs +0 -1
  113. package/dist/esm/getOptimizePluginOptions-BAFPfVq5.mjs +0 -2
  114. package/dist/esm/getOptimizePluginOptions-BAFPfVq5.mjs.map +0 -1
  115. package/dist/types/constants-BLArAqsA.d.ts +0 -20
  116. package/dist/types/constants-BLArAqsA.d.ts.map +0 -1
  117. package/dist/types/contentWriter-I2Ch5yQY.d.ts +0 -36
  118. package/dist/types/contentWriter-I2Ch5yQY.d.ts.map +0 -1
  119. package/dist/types/detectPackageName-C0TfbHa3.d.ts +0 -10
  120. package/dist/types/detectPackageName-C0TfbHa3.d.ts.map +0 -1
  121. package/dist/types/extractContent-AFk68B7L.d.ts +0 -37
  122. package/dist/types/extractContent-AFk68B7L.d.ts.map +0 -1
  123. package/dist/types/extractDictionaryInfo-5GLZsA_I.d.ts +0 -28
  124. package/dist/types/extractDictionaryInfo-5GLZsA_I.d.ts.map +0 -1
  125. package/dist/types/extractDictionaryKey-CHgfwRo6.d.ts +0 -11
  126. package/dist/types/extractDictionaryKey-CHgfwRo6.d.ts.map +0 -1
  127. package/dist/types/generateKey-Cgdh6seq.d.ts +0 -5
  128. package/dist/types/generateKey-Cgdh6seq.d.ts.map +0 -1
  129. package/dist/types/getComponentName-DGlmJa-F.d.ts +0 -10
  130. package/dist/types/getComponentName-DGlmJa-F.d.ts.map +0 -1
  131. package/dist/types/getExistingIntlayerInfo-Cy6Vpcfb.d.ts +0 -19
  132. package/dist/types/getExistingIntlayerInfo-Cy6Vpcfb.d.ts.map +0 -1
  133. package/dist/types/getOrGenerateKey-DtIR0WeU.d.ts +0 -8
  134. package/dist/types/getOrGenerateKey-DtIR0WeU.d.ts.map +0 -1
  135. package/dist/types/index-DK_kKFOF.d.ts +0 -1
  136. package/dist/types/resolveDictionaryKey-CcbieIfX.d.ts +0 -12
  137. package/dist/types/resolveDictionaryKey-CcbieIfX.d.ts.map +0 -1
  138. package/dist/types/shouldExtract-BRaeB9eg.d.ts +0 -14
  139. package/dist/types/shouldExtract-BRaeB9eg.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"processTsxFile.mjs","names":[],"sources":["../../../src/extractContent/processTsxFile.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { parse } from '@babel/parser';\nimport _traverse, { type NodePath } from '@babel/traverse';\nimport * as t from '@babel/types';\nimport { detectFormatCommand } from '@intlayer/chokidar/cli';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { extractBabelContentForComponents } from './babelProcessor';\nimport {\n type ExistingIntlayerInfo,\n getExistingIntlayerInfo,\n type PackageName,\n SERVER_CAPABLE_PACKAGES,\n} from './utils';\n\nexport type TextEdit = {\n start: number;\n end: number;\n replacement: string;\n};\n\nconst traverse = (\n typeof _traverse === 'function' ? _traverse : (_traverse as any).default\n) as typeof _traverse;\n\n/**\n * Processes a TSX/JSX/TS/JS file to extract content and inject Intlayer hooks/calls.\n */\nexport const processTsxFile = (\n filePath: string,\n componentKey: string,\n packageName: PackageName,\n configuration: IntlayerConfig,\n save: boolean = true,\n unmergedDictionaries: Record<string, unknown> = {},\n providedFileCode?: string\n): {\n extractedContent: Record<string, Record<string, string>>;\n modifiedCode: string;\n} | null => {\n const fileCode = providedFileCode ?? readFileSync(filePath, 'utf-8');\n\n const ast = parse(fileCode, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\n const hasUseClient = ast.program.directives.some(\n (directive) => directive.value.value === 'use client'\n );\n\n const effectivePackageName =\n SERVER_CAPABLE_PACKAGES.has(packageName) && !hasUseClient\n ? `${packageName}/server`\n : packageName;\n\n const isSolid = packageName === 'solid-intlayer';\n const existingKeys = new Set<string>();\n\n const {\n extractedContent,\n replacements,\n componentsNeedingHooks,\n componentKeyMap,\n componentPaths,\n hookMap,\n } = extractBabelContentForComponents(\n ast,\n fileCode,\n existingKeys,\n componentKey,\n configuration,\n filePath,\n unmergedDictionaries\n );\n\n if (Object.keys(extractedContent).length === 0) return null;\n\n const textEdits: TextEdit[] = [];\n\n // Build a lookup map: component AST node → NodePath (O(1) access)\n const componentNodeToPath = new Map<t.Node, NodePath>();\n for (const componentPath of componentPaths) {\n componentNodeToPath.set(componentPath.node, componentPath);\n }\n\n // Cache getExistingIntlayerInfo results for all component paths (avoids repeated traversals)\n const existingInfoCache = new Map<t.Node, ExistingIntlayerInfo | undefined>();\n for (const componentPath of componentPaths) {\n existingInfoCache.set(\n componentPath.node,\n getExistingIntlayerInfo(componentPath)\n );\n }\n\n /**\n * Walks up the ancestor chain to find the nearest enclosing component's\n * existing Intlayer info (if any).\n */\n const getExistingInfoForPath = (\n path: NodePath\n ): ExistingIntlayerInfo | undefined => {\n let current: NodePath | null = path;\n while (current) {\n if (componentNodeToPath.has(current.node)) {\n return existingInfoCache.get(current.node);\n }\n current = current.parentPath;\n }\n return undefined;\n };\n\n const getProvidingHookType = (\n path: NodePath\n ): 'useIntlayer' | 'getIntlayer' => {\n let current: NodePath | null = path;\n while (current) {\n const componentPath = componentNodeToPath.get(current.node);\n\n if (componentPath) {\n const existingInfo = existingInfoCache.get(componentPath.node);\n\n if (existingInfo) {\n return existingInfo.hook;\n }\n\n if (componentsNeedingHooks.has(componentPath)) {\n return hookMap.get(componentPath.node) || 'useIntlayer';\n }\n }\n current = current.parentPath;\n }\n return 'useIntlayer';\n };\n\n for (const {\n path,\n key,\n type,\n variables,\n childrenToReplace,\n } of replacements) {\n const existingInfo = getExistingInfoForPath(path);\n // When the existing call is destructured (e.g. `const { a } = getIntlayer(...)`),\n // new keys are added directly to that destructuring, so access them by name alone.\n const varName = existingInfo?.variableName ?? 'content';\n const contentAccessCode = existingInfo?.isDestructured\n ? key\n : isSolid\n ? `${varName}().${key}`\n : `${varName}.${key}`;\n const hookType = getProvidingHookType(path);\n const valueSuffix = hookType === 'getIntlayer' ? '' : '.value';\n\n if (type === 'jsx-text' && path.isJSXText()) {\n textEdits.push({\n start: path.node.start!,\n end: path.node.end!,\n replacement: `{${contentAccessCode}}`,\n });\n } else if (type === 'jsx-attribute' && path.isJSXAttribute()) {\n const valNode = path.node.value;\n\n if (valNode) {\n textEdits.push({\n start: valNode.start!,\n end: valNode.end!,\n replacement: `{${contentAccessCode}${valueSuffix}}`,\n });\n }\n } else if (type === 'string-literal' && path.isStringLiteral()) {\n textEdits.push({\n start: path.node.start!,\n end: path.node.end!,\n replacement: `${contentAccessCode}${valueSuffix}`,\n });\n } else if (\n type === 'jsx-text-combined' &&\n childrenToReplace &&\n childrenToReplace.length > 0\n ) {\n const accessStr = `{${contentAccessCode}}`;\n const start = childrenToReplace[0].start!;\n const end = childrenToReplace[childrenToReplace.length - 1].end!;\n textEdits.push({ start, end, replacement: accessStr });\n } else if (\n type === 'jsx-insertion' &&\n variables &&\n childrenToReplace &&\n childrenToReplace.length > 0\n ) {\n const objProps = variables\n .map((variableString) => {\n const [key, variableValue] = variableString\n .split(':')\n .map((part) => part.trim());\n return `${key}: ${variableValue}`;\n })\n .join(', ');\n\n const accessStr = `{${contentAccessCode}({ ${objProps} })}`;\n const start = childrenToReplace[0].start!;\n const end = childrenToReplace[childrenToReplace.length - 1].end!;\n textEdits.push({ start, end, replacement: accessStr });\n }\n }\n\n let needsUseIntlayer = false;\n let needsGetIntlayer = false;\n\n for (const componentPath of componentsNeedingHooks) {\n const finalKey = componentKeyMap.get(componentPath.node)!;\n const existingInfo = existingInfoCache.get(componentPath.node);\n\n if (existingInfo) {\n if (existingInfo.hook === 'useIntlayer') needsUseIntlayer = true;\n\n if (existingInfo.hook === 'getIntlayer') needsGetIntlayer = true;\n\n // When the existing call is destructured, inject any missing keys into\n // the destructuring pattern so they can be accessed by name directly.\n if (existingInfo.isDestructured && existingInfo.objectPatternNode) {\n const neededKeys = new Set<string>();\n\n for (const { path: rPath, key: rKey } of replacements) {\n let current: NodePath | null = rPath;\n\n while (current) {\n if (current.node === componentPath.node) {\n neededKeys.add(rKey);\n break;\n }\n current = current.parentPath;\n }\n }\n\n const missingKeys = [...neededKeys].filter(\n (key) => !existingInfo.existingDestructuredKeys.includes(key)\n );\n\n if (missingKeys.length > 0) {\n const { objectPatternNode } = existingInfo;\n // Insert right after the last property so the space/newline before\n // `}` is naturally preserved: `{ a }` → `{ a, b }`.\n const lastProp =\n objectPatternNode.properties[\n objectPatternNode.properties.length - 1\n ];\n textEdits.push({\n start: lastProp.end!,\n end: lastProp.end!,\n replacement: `, ${missingKeys.join(', ')}`,\n });\n }\n }\n } else {\n const hook = hookMap.get(componentPath.node) || 'useIntlayer';\n\n if (hook === 'useIntlayer') needsUseIntlayer = true;\n\n if (hook === 'getIntlayer') needsGetIntlayer = true;\n\n const bodyPath = componentPath.get('body') as NodePath;\n const hookStatementStr = `\\n const content = ${hook}('${finalKey}');\\n`;\n\n if (bodyPath.isBlockStatement()) {\n textEdits.push({\n start: bodyPath.node.start! + 1,\n end: bodyPath.node.start! + 1,\n replacement: hookStatementStr,\n });\n } else if (bodyPath.isExpression()) {\n const start = bodyPath.node.start!;\n const end = bodyPath.node.end!;\n\n // Detect wrapping parentheses: `() => (expr)` — scan backward from\n // the expression start and forward from its end for matching `(` / `)`.\n let parenStart = -1;\n let parenEnd = -1;\n\n for (let i = start - 1; i >= 0; i--) {\n const char = fileCode[i];\n if (char === '(') {\n parenStart = i;\n break;\n }\n if (char !== ' ' && char !== '\\n' && char !== '\\r' && char !== '\\t')\n break;\n }\n\n if (parenStart !== -1) {\n for (let i = end; i < fileCode.length; i++) {\n const char = fileCode[i];\n if (char === ')') {\n parenEnd = i;\n break;\n }\n if (char !== ' ' && char !== '\\n' && char !== '\\r' && char !== '\\t')\n break;\n }\n }\n\n if (parenStart !== -1 && parenEnd !== -1) {\n // Replace the surrounding `(` … `)` with a block statement. We keep\n // the parentheses as `return (…)` to prevent automatic semicolon\n // insertion when the returned expression starts on a new line.\n textEdits.push({\n start: parenEnd,\n end: parenEnd + 1,\n replacement: `)\\n}`,\n });\n textEdits.push({\n start: parenStart,\n end: parenStart + 1,\n replacement: `{\\n const content = ${hook}('${finalKey}');\\n return (`,\n });\n } else {\n textEdits.push({\n start: end,\n end: end,\n replacement: `\\n}`,\n });\n textEdits.push({\n start: start,\n end: start,\n replacement: `{\\n const content = ${hook}('${finalKey}');\\n return `,\n });\n }\n }\n }\n }\n\n const injectImport = (hookName: string, targetPackage: string) => {\n let existingImportPath: NodePath<t.ImportDeclaration> | undefined;\n\n traverse(ast, {\n ImportDeclaration(path) {\n if (path.node.source.value === targetPackage) {\n existingImportPath = path;\n path.stop();\n }\n },\n });\n\n if (!existingImportPath) {\n const newImportStr = `import { ${hookName} } from '${targetPackage}';\\n`;\n let insertPos = 0;\n\n if (ast.program.body.length > 0) {\n insertPos = ast.program.body[0].start!;\n } else if (ast.program.directives && ast.program.directives.length > 0) {\n insertPos =\n ast.program.directives[ast.program.directives.length - 1].end!;\n\n if (fileCode[insertPos] === ';') insertPos++;\n\n textEdits.push({\n start: insertPos,\n end: insertPos,\n replacement: `\\n${newImportStr}`,\n });\n return;\n }\n\n if (\n insertPos === 0 ||\n (ast.program.body.length > 0 &&\n insertPos === ast.program.body[0].start!)\n ) {\n textEdits.push({\n start: insertPos,\n end: insertPos,\n replacement: newImportStr,\n });\n }\n } else {\n const existingSpecifiers = existingImportPath.node.specifiers;\n const missingImport = !existingSpecifiers.some(\n (specifier) =>\n t.isImportSpecifier(specifier) &&\n t.isIdentifier(specifier.imported) &&\n specifier.imported.name === hookName\n );\n\n if (missingImport) {\n const importCode = fileCode.slice(\n existingImportPath.node.start!,\n existingImportPath.node.end!\n );\n const closingBraceIndex = importCode.lastIndexOf('}');\n\n if (closingBraceIndex !== -1) {\n const isCommaNeeded = !importCode\n .slice(0, closingBraceIndex)\n .trim()\n .endsWith(',');\n const absolutePos =\n existingImportPath.node.start! + closingBraceIndex;\n const prefix = isCommaNeeded ? ', ' : ' ';\n textEdits.push({\n start: absolutePos,\n end: absolutePos,\n replacement: `${prefix}${hookName} `,\n });\n }\n }\n }\n };\n\n if (needsUseIntlayer) injectImport('useIntlayer', effectivePackageName);\n\n if (needsGetIntlayer) injectImport('getIntlayer', 'intlayer');\n\n textEdits.sort((editA, editB) => {\n if (editB.start !== editA.start) return editB.start - editA.start;\n\n return editB.end - editA.end;\n });\n\n let formattedCode = fileCode;\n\n for (const edit of textEdits) {\n formattedCode =\n formattedCode.slice(0, edit.start) +\n edit.replacement +\n formattedCode.slice(edit.end);\n }\n\n if (save) {\n writeFileSync(filePath, formattedCode);\n\n const formatCommand = detectFormatCommand(configuration);\n\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', filePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n }\n\n return { extractedContent, modifiedCode: formattedCode };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"processTsxFile.mjs","names":[],"sources":["../../../src/extractContent/processTsxFile.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { parse } from '@babel/parser';\nimport _traverse, { type NodePath } from '@babel/traverse';\nimport * as t from '@babel/types';\nimport { detectFormatCommand } from '@intlayer/chokidar/cli';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { extractBabelContentForComponents } from './babelProcessor';\nimport {\n type ExistingIntlayerInfo,\n getExistingIntlayerInfo,\n type PackageName,\n SERVER_CAPABLE_PACKAGES,\n} from './utils';\n\nexport type TextEdit = {\n start: number;\n end: number;\n replacement: string;\n};\n\nconst traverse = (\n typeof _traverse === 'function' ? _traverse : (_traverse as any).default\n) as typeof _traverse;\n\n/**\n * Processes a TSX/JSX/TS/JS file to extract content and inject Intlayer hooks/calls.\n */\nexport const processTsxFile = (\n filePath: string,\n componentKey: string,\n packageName: PackageName,\n configuration: IntlayerConfig,\n save: boolean = true,\n unmergedDictionaries: Record<string, unknown> = {},\n providedFileCode?: string\n): {\n extractedContent: Record<string, Record<string, string>>;\n modifiedCode: string;\n} | null => {\n const fileCode = providedFileCode ?? readFileSync(filePath, 'utf-8');\n\n const ast = parse(fileCode, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\n const hasUseClient = ast.program.directives.some(\n (directive) => directive.value.value === 'use client'\n );\n\n const effectivePackageName =\n SERVER_CAPABLE_PACKAGES.has(packageName) && !hasUseClient\n ? `${packageName}/server`\n : packageName;\n\n const isSolid = packageName === 'solid-intlayer';\n const existingKeys = new Set<string>();\n\n const {\n extractedContent,\n replacements,\n componentsNeedingHooks,\n componentKeyMap,\n componentPaths,\n hookMap,\n } = extractBabelContentForComponents(\n ast,\n fileCode,\n existingKeys,\n componentKey,\n configuration,\n filePath,\n unmergedDictionaries\n );\n\n if (Object.keys(extractedContent).length === 0) return null;\n\n const textEdits: TextEdit[] = [];\n\n // Build a lookup map: component AST node → NodePath (O(1) access)\n const componentNodeToPath = new Map<t.Node, NodePath>();\n for (const componentPath of componentPaths) {\n componentNodeToPath.set(componentPath.node, componentPath);\n }\n\n // Cache getExistingIntlayerInfo results for all component paths (avoids repeated traversals)\n const existingInfoCache = new Map<t.Node, ExistingIntlayerInfo | undefined>();\n for (const componentPath of componentPaths) {\n existingInfoCache.set(\n componentPath.node,\n getExistingIntlayerInfo(componentPath)\n );\n }\n\n /**\n * Walks up the ancestor chain to find the nearest enclosing component's\n * existing Intlayer info (if any).\n */\n const getExistingInfoForPath = (\n path: NodePath\n ): ExistingIntlayerInfo | undefined => {\n let current: NodePath | null = path;\n while (current) {\n if (componentNodeToPath.has(current.node)) {\n return existingInfoCache.get(current.node);\n }\n current = current.parentPath;\n }\n return undefined;\n };\n\n const getProvidingHookType = (\n path: NodePath\n ): 'useIntlayer' | 'getIntlayer' => {\n let current: NodePath | null = path;\n while (current) {\n const componentPath = componentNodeToPath.get(current.node);\n\n if (componentPath) {\n const existingInfo = existingInfoCache.get(componentPath.node);\n\n if (existingInfo) {\n return existingInfo.hook;\n }\n\n if (componentsNeedingHooks.has(componentPath)) {\n return hookMap.get(componentPath.node) || 'useIntlayer';\n }\n }\n current = current.parentPath;\n }\n return 'useIntlayer';\n };\n\n for (const {\n path,\n key,\n type,\n variables,\n childrenToReplace,\n } of replacements) {\n const existingInfo = getExistingInfoForPath(path);\n // When the existing call is destructured (e.g. `const { a } = getIntlayer(...)`),\n // new keys are added directly to that destructuring, so access them by name alone.\n const varName = existingInfo?.variableName ?? 'content';\n const contentAccessCode = existingInfo?.isDestructured\n ? key\n : isSolid\n ? `${varName}().${key}`\n : `${varName}.${key}`;\n const hookType = getProvidingHookType(path);\n const valueSuffix = hookType === 'getIntlayer' ? '' : '.value';\n\n if (type === 'jsx-text' && path.isJSXText()) {\n textEdits.push({\n start: path.node.start!,\n end: path.node.end!,\n replacement: `{${contentAccessCode}}`,\n });\n } else if (type === 'jsx-attribute' && path.isJSXAttribute()) {\n const valNode = path.node.value;\n\n if (valNode) {\n textEdits.push({\n start: valNode.start!,\n end: valNode.end!,\n replacement: `{${contentAccessCode}${valueSuffix}}`,\n });\n }\n } else if (type === 'string-literal' && path.isStringLiteral()) {\n textEdits.push({\n start: path.node.start!,\n end: path.node.end!,\n replacement: `${contentAccessCode}${valueSuffix}`,\n });\n } else if (\n type === 'jsx-text-combined' &&\n childrenToReplace &&\n childrenToReplace.length > 0\n ) {\n const accessStr = `{${contentAccessCode}}`;\n const start = childrenToReplace[0].start!;\n const end = childrenToReplace[childrenToReplace.length - 1].end!;\n textEdits.push({ start, end, replacement: accessStr });\n } else if (\n type === 'jsx-insertion' &&\n variables &&\n childrenToReplace &&\n childrenToReplace.length > 0\n ) {\n const objProps = variables\n .map((variableString) => {\n const [key, variableValue] = variableString\n .split(':')\n .map((part) => part.trim());\n return `${key}: ${variableValue}`;\n })\n .join(', ');\n\n const accessStr = `{${contentAccessCode}({ ${objProps} })}`;\n const start = childrenToReplace[0].start!;\n const end = childrenToReplace[childrenToReplace.length - 1].end!;\n textEdits.push({ start, end, replacement: accessStr });\n }\n }\n\n let needsUseIntlayer = false;\n let needsGetIntlayer = false;\n\n for (const componentPath of componentsNeedingHooks) {\n const finalKey = componentKeyMap.get(componentPath.node)!;\n const existingInfo = existingInfoCache.get(componentPath.node);\n\n if (existingInfo) {\n if (existingInfo.hook === 'useIntlayer') needsUseIntlayer = true;\n\n if (existingInfo.hook === 'getIntlayer') needsGetIntlayer = true;\n\n // When the existing call is destructured, inject any missing keys into\n // the destructuring pattern so they can be accessed by name directly.\n if (existingInfo.isDestructured && existingInfo.objectPatternNode) {\n const neededKeys = new Set<string>();\n\n for (const { path: rPath, key: rKey } of replacements) {\n let current: NodePath | null = rPath;\n\n while (current) {\n if (current.node === componentPath.node) {\n neededKeys.add(rKey);\n break;\n }\n current = current.parentPath;\n }\n }\n\n const missingKeys = [...neededKeys].filter(\n (key) => !existingInfo.existingDestructuredKeys.includes(key)\n );\n\n if (missingKeys.length > 0) {\n const { objectPatternNode } = existingInfo;\n // Insert right after the last property so the space/newline before\n // `}` is naturally preserved: `{ a }` → `{ a, b }`.\n const lastProp =\n objectPatternNode.properties[\n objectPatternNode.properties.length - 1\n ];\n textEdits.push({\n start: lastProp.end!,\n end: lastProp.end!,\n replacement: `, ${missingKeys.join(', ')}`,\n });\n }\n }\n } else {\n const hook = hookMap.get(componentPath.node) || 'useIntlayer';\n\n if (hook === 'useIntlayer') needsUseIntlayer = true;\n\n if (hook === 'getIntlayer') needsGetIntlayer = true;\n\n const bodyPath = componentPath.get('body') as NodePath;\n const hookStatementStr = `\\n const content = ${hook}('${finalKey}');\\n`;\n\n if (bodyPath.isBlockStatement()) {\n textEdits.push({\n start: bodyPath.node.start! + 1,\n end: bodyPath.node.start! + 1,\n replacement: hookStatementStr,\n });\n } else if (bodyPath.isExpression()) {\n const start = bodyPath.node.start!;\n const end = bodyPath.node.end!;\n\n // Detect wrapping parentheses: `() => (expr)` — scan backward from\n // the expression start and forward from its end for matching `(` / `)`.\n let parenStart = -1;\n let parenEnd = -1;\n\n for (let i = start - 1; i >= 0; i--) {\n const char = fileCode[i];\n if (char === '(') {\n parenStart = i;\n break;\n }\n if (char !== ' ' && char !== '\\n' && char !== '\\r' && char !== '\\t')\n break;\n }\n\n if (parenStart !== -1) {\n for (let i = end; i < fileCode.length; i++) {\n const char = fileCode[i];\n if (char === ')') {\n parenEnd = i;\n break;\n }\n if (char !== ' ' && char !== '\\n' && char !== '\\r' && char !== '\\t')\n break;\n }\n }\n\n if (parenStart !== -1 && parenEnd !== -1) {\n // Replace the surrounding `(` … `)` with a block statement. We keep\n // the parentheses as `return (…)` to prevent automatic semicolon\n // insertion when the returned expression starts on a new line.\n textEdits.push({\n start: parenEnd,\n end: parenEnd + 1,\n replacement: `)\\n}`,\n });\n textEdits.push({\n start: parenStart,\n end: parenStart + 1,\n replacement: `{\\n const content = ${hook}('${finalKey}');\\n return (`,\n });\n } else {\n textEdits.push({\n start: end,\n end: end,\n replacement: `\\n}`,\n });\n textEdits.push({\n start: start,\n end: start,\n replacement: `{\\n const content = ${hook}('${finalKey}');\\n return `,\n });\n }\n }\n }\n }\n\n const injectImport = (hookName: string, targetPackage: string) => {\n let existingImportPath: NodePath<t.ImportDeclaration> | undefined;\n\n traverse(ast, {\n ImportDeclaration(path) {\n if (path.node.source.value === targetPackage) {\n existingImportPath = path;\n path.stop();\n }\n },\n });\n\n if (!existingImportPath) {\n const newImportStr = `import { ${hookName} } from '${targetPackage}';\\n`;\n let insertPos = 0;\n\n if (ast.program.body.length > 0) {\n insertPos = ast.program.body[0].start!;\n } else if (ast.program.directives && ast.program.directives.length > 0) {\n insertPos =\n ast.program.directives[ast.program.directives.length - 1].end!;\n\n if (fileCode[insertPos] === ';') insertPos++;\n\n textEdits.push({\n start: insertPos,\n end: insertPos,\n replacement: `\\n${newImportStr}`,\n });\n return;\n }\n\n if (\n insertPos === 0 ||\n (ast.program.body.length > 0 &&\n insertPos === ast.program.body[0].start!)\n ) {\n textEdits.push({\n start: insertPos,\n end: insertPos,\n replacement: newImportStr,\n });\n }\n } else {\n const existingSpecifiers = existingImportPath.node.specifiers;\n const missingImport = !existingSpecifiers.some(\n (specifier) =>\n t.isImportSpecifier(specifier) &&\n t.isIdentifier(specifier.imported) &&\n specifier.imported.name === hookName\n );\n\n if (missingImport) {\n const importCode = fileCode.slice(\n existingImportPath.node.start!,\n existingImportPath.node.end!\n );\n const closingBraceIndex = importCode.lastIndexOf('}');\n\n if (closingBraceIndex !== -1) {\n const isCommaNeeded = !importCode\n .slice(0, closingBraceIndex)\n .trim()\n .endsWith(',');\n const absolutePos =\n existingImportPath.node.start! + closingBraceIndex;\n const prefix = isCommaNeeded ? ', ' : ' ';\n textEdits.push({\n start: absolutePos,\n end: absolutePos,\n replacement: `${prefix}${hookName} `,\n });\n }\n }\n }\n };\n\n if (needsUseIntlayer) injectImport('useIntlayer', effectivePackageName);\n\n if (needsGetIntlayer) injectImport('getIntlayer', 'intlayer');\n\n textEdits.sort((editA, editB) => {\n if (editB.start !== editA.start) return editB.start - editA.start;\n\n return editB.end - editA.end;\n });\n\n let formattedCode = fileCode;\n\n for (const edit of textEdits) {\n formattedCode =\n formattedCode.slice(0, edit.start) +\n edit.replacement +\n formattedCode.slice(edit.end);\n }\n\n if (save) {\n writeFileSync(filePath, formattedCode);\n\n const formatCommand = detectFormatCommand(configuration);\n\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', filePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n }\n\n return { extractedContent, modifiedCode: formattedCode };\n};\n"],"mappings":"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"}
@@ -1,2 +1,39 @@
1
- const e=[`title`,`placeholder`,`alt`,`aria-label`,`label`],t=[`next-intlayer`,`react-intlayer`,`vue-intlayer`,`svelte-intlayer`,`preact-intlayer`,`solid-intlayer`,`angular-intlayer`,`express-intlayer`,`hono-intlayer`,`fastify-intlayer`,`adonis-intlayer`,`intlayer`],n=new Set([`next-intlayer`]);export{e as ATTRIBUTES_TO_EXTRACT,n as SERVER_CAPABLE_PACKAGES,t as packageList};
1
+ //#region src/extractContent/utils/constants.ts
2
+ /**
3
+ * Attributes that should be extracted as translatable strings from JSX/HTML elements.
4
+ * This is the single source of truth shared across all Intlayer compiler packages
5
+ * (@intlayer/babel, @intlayer/vue-compiler, @intlayer/svelte-compiler, @intlayer/chokidar).
6
+ */
7
+ const ATTRIBUTES_TO_EXTRACT = [
8
+ "title",
9
+ "placeholder",
10
+ "alt",
11
+ "aria-label",
12
+ "label"
13
+ ];
14
+ /**
15
+ * The list of supported Intlayer integration packages.
16
+ * This is the single source of truth for package name validation.
17
+ *
18
+ * Order matter for resolution
19
+ */
20
+ const packageList = [
21
+ "next-intlayer",
22
+ "react-intlayer",
23
+ "vue-intlayer",
24
+ "svelte-intlayer",
25
+ "preact-intlayer",
26
+ "solid-intlayer",
27
+ "angular-intlayer",
28
+ "express-intlayer",
29
+ "hono-intlayer",
30
+ "fastify-intlayer",
31
+ "adonis-intlayer",
32
+ "intlayer"
33
+ ];
34
+ /** Packages that support a `/server` sub-path for React Server Components. */
35
+ const SERVER_CAPABLE_PACKAGES = new Set(["next-intlayer"]);
36
+
37
+ //#endregion
38
+ export { ATTRIBUTES_TO_EXTRACT, SERVER_CAPABLE_PACKAGES, packageList };
2
39
  //# sourceMappingURL=constants.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.mjs","names":[],"sources":["../../../../src/extractContent/utils/constants.ts"],"sourcesContent":["/**\n * Attributes that should be extracted as translatable strings from JSX/HTML elements.\n * This is the single source of truth shared across all Intlayer compiler packages\n * (@intlayer/babel, @intlayer/vue-compiler, @intlayer/svelte-compiler, @intlayer/chokidar).\n */\nexport const ATTRIBUTES_TO_EXTRACT = [\n 'title',\n 'placeholder',\n 'alt',\n 'aria-label',\n 'label',\n] as const;\n\n/**\n * The list of supported Intlayer integration packages.\n * This is the single source of truth for package name validation.\n *\n * Order matter for resolution\n */\nexport const packageList = [\n 'next-intlayer',\n 'react-intlayer',\n 'vue-intlayer',\n 'svelte-intlayer',\n 'preact-intlayer',\n 'solid-intlayer',\n 'angular-intlayer',\n 'express-intlayer',\n 'hono-intlayer',\n 'fastify-intlayer',\n 'adonis-intlayer',\n 'intlayer',\n] as const;\n\n/** Packages that support a `/server` sub-path for React Server Components. */\nexport const SERVER_CAPABLE_PACKAGES: ReadonlySet<string> = new Set([\n 'next-intlayer',\n]);\n\nexport type PackageName = (typeof packageList)[number];\n"],"mappings":"AAKA,MAAa,EAAwB,CACnC,QACA,cACA,MACA,aACA,QACD,CAQY,EAAc,CACzB,gBACA,iBACA,eACA,kBACA,kBACA,iBACA,mBACA,mBACA,gBACA,mBACA,kBACA,WACD,CAGY,EAA+C,IAAI,IAAI,CAClE,gBACD,CAAC"}
1
+ {"version":3,"file":"constants.mjs","names":[],"sources":["../../../../src/extractContent/utils/constants.ts"],"sourcesContent":["/**\n * Attributes that should be extracted as translatable strings from JSX/HTML elements.\n * This is the single source of truth shared across all Intlayer compiler packages\n * (@intlayer/babel, @intlayer/vue-compiler, @intlayer/svelte-compiler, @intlayer/chokidar).\n */\nexport const ATTRIBUTES_TO_EXTRACT = [\n 'title',\n 'placeholder',\n 'alt',\n 'aria-label',\n 'label',\n] as const;\n\n/**\n * The list of supported Intlayer integration packages.\n * This is the single source of truth for package name validation.\n *\n * Order matter for resolution\n */\nexport const packageList = [\n 'next-intlayer',\n 'react-intlayer',\n 'vue-intlayer',\n 'svelte-intlayer',\n 'preact-intlayer',\n 'solid-intlayer',\n 'angular-intlayer',\n 'express-intlayer',\n 'hono-intlayer',\n 'fastify-intlayer',\n 'adonis-intlayer',\n 'intlayer',\n] as const;\n\n/** Packages that support a `/server` sub-path for React Server Components. */\nexport const SERVER_CAPABLE_PACKAGES: ReadonlySet<string> = new Set([\n 'next-intlayer',\n]);\n\nexport type PackageName = (typeof packageList)[number];\n"],"mappings":";;;;;;AAKA,MAAa,wBAAwB;CACnC;CACA;CACA;CACA;CACA;CACD;;;;;;;AAQD,MAAa,cAAc;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAa,0BAA+C,IAAI,IAAI,CAClE,gBACD,CAAC"}
@@ -1,2 +1,25 @@
1
- import{packageList as e}from"./constants.mjs";import{existsSync as t,readFileSync as n}from"node:fs";import{getPackageJsonPath as r}from"@intlayer/config/utils";const i=i=>{let{packageJsonPath:a}=r(i);if(t(a))try{let t=JSON.parse(n(a,`utf-8`)),r={...t.dependencies,...t.devDependencies,...t.peerDependencies};for(let t of e)if(r[t])return t}catch{}return e[e.length-1]};export{i as detectPackageName};
1
+ import { packageList } from "./constants.mjs";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { getPackageJsonPath } from "@intlayer/config/utils";
4
+
5
+ //#region src/extractContent/utils/detectPackageName.ts
6
+ /**
7
+ * Detects which intlayer package is used in the project by reading package.json.
8
+ */
9
+ const detectPackageName = (searchDir) => {
10
+ const { packageJsonPath } = getPackageJsonPath(searchDir);
11
+ if (existsSync(packageJsonPath)) try {
12
+ const pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
13
+ const allDeps = {
14
+ ...pkg.dependencies,
15
+ ...pkg.devDependencies,
16
+ ...pkg.peerDependencies
17
+ };
18
+ for (const pkgName of packageList) if (allDeps[pkgName]) return pkgName;
19
+ } catch {}
20
+ return packageList[packageList.length - 1];
21
+ };
22
+
23
+ //#endregion
24
+ export { detectPackageName };
2
25
  //# sourceMappingURL=detectPackageName.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"detectPackageName.mjs","names":[],"sources":["../../../../src/extractContent/utils/detectPackageName.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { getPackageJsonPath } from '@intlayer/config/utils';\nimport { type PackageName, packageList } from './constants';\n\n/**\n * Detects which intlayer package is used in the project by reading package.json.\n */\nexport const detectPackageName = (searchDir: string): PackageName => {\n const { packageJsonPath } = getPackageJsonPath(searchDir);\n\n if (existsSync(packageJsonPath)) {\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const allDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n ...pkg.peerDependencies,\n };\n\n for (const pkgName of packageList) {\n if (allDeps[pkgName]) return pkgName;\n }\n } catch {\n // Ignore JSON errors\n }\n }\n\n return packageList[packageList.length - 1];\n};\n"],"mappings":"iKAOA,MAAa,EAAqB,GAAmC,CACnE,GAAM,CAAE,mBAAoB,EAAmB,EAAU,CAEzD,GAAI,EAAW,EAAgB,CAC7B,GAAI,CACF,IAAM,EAAM,KAAK,MAAM,EAAa,EAAiB,QAAQ,CAAC,CACxD,EAAU,CACd,GAAG,EAAI,aACP,GAAG,EAAI,gBACP,GAAG,EAAI,iBACR,CAED,IAAK,IAAM,KAAW,EACpB,GAAI,EAAQ,GAAU,OAAO,OAEzB,EAKV,OAAO,EAAY,EAAY,OAAS"}
1
+ {"version":3,"file":"detectPackageName.mjs","names":[],"sources":["../../../../src/extractContent/utils/detectPackageName.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { getPackageJsonPath } from '@intlayer/config/utils';\nimport { type PackageName, packageList } from './constants';\n\n/**\n * Detects which intlayer package is used in the project by reading package.json.\n */\nexport const detectPackageName = (searchDir: string): PackageName => {\n const { packageJsonPath } = getPackageJsonPath(searchDir);\n\n if (existsSync(packageJsonPath)) {\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const allDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n ...pkg.peerDependencies,\n };\n\n for (const pkgName of packageList) {\n if (allDeps[pkgName]) return pkgName;\n }\n } catch {\n // Ignore JSON errors\n }\n }\n\n return packageList[packageList.length - 1];\n};\n"],"mappings":";;;;;;;;AAOA,MAAa,qBAAqB,cAAmC;CACnE,MAAM,EAAE,oBAAoB,mBAAmB,UAAU;AAEzD,KAAI,WAAW,gBAAgB,CAC7B,KAAI;EACF,MAAM,MAAM,KAAK,MAAM,aAAa,iBAAiB,QAAQ,CAAC;EAC9D,MAAM,UAAU;GACd,GAAG,IAAI;GACP,GAAG,IAAI;GACP,GAAG,IAAI;GACR;AAED,OAAK,MAAM,WAAW,YACpB,KAAI,QAAQ,SAAU,QAAO;SAEzB;AAKV,QAAO,YAAY,YAAY,SAAS"}
@@ -1,2 +1,99 @@
1
- import{extractDictionaryKey as e}from"./extractDictionaryKey.mjs";import{getFormatFromExtension as t,resolveRelativePath as n}from"@intlayer/chokidar/utils";import*as r from"@intlayer/config/colors";import{colorize as i}from"@intlayer/config/logger";import{basename as a,dirname as o,extname as s,relative as c,resolve as l}from"node:path";import{parseStringPattern as u}from"@intlayer/config/utils";import{getUnmergedDictionaries as d}from"@intlayer/unmerged-dictionaries-entry";const f=e=>{if(typeof e.compiler?.output==`string`)return t=>u(e.compiler.output,t);if(typeof e.compiler?.output==`function`)return e.compiler.output;throw Error(`No output configuration found. Add a ${i(`compiler.output`,r.BLUE)} in your configuration.`)},p=async(e,r,i,u)=>{let{baseDir:p}=i.system,{defaultLocale:m}=i.internationalization,h=(d(i)??{})[r]?.filter(e=>e.location!==`remote`).filter(e=>e.locale===void 0||e.locale===(u??m));if(h?.[0]?.filePath){let e=h[0].filePath,t=l(p,e);return{absolutePath:t,relativePath:c(p,t),isPerLocale:!1}}let g=f(i),_=s(e),v=a(e,_),y=v.charAt(0).toLowerCase()+v.slice(1),b=t(_),x={key:r,componentDirPath:c(p,o(e)),componentFileName:v,fileName:y,componentFormat:b,componentExtension:_,format:b,locale:m,extension:i.content.fileExtensions[0]},S=n(await g(x),e,p),C=`###########locale###########`,w=(await g({...x,locale:C})).includes(C);return{absolutePath:S,relativePath:c(p,S),isPerLocale:w}},m=async(t,n,r)=>{let i=e(t,n);return{dictionaryKey:i,...await p(t,i,r)}};export{m as extractDictionaryInfo,f as getOutput,p as resolveContentFilePaths};
1
+ import { extractDictionaryKey } from "./extractDictionaryKey.mjs";
2
+ import { getFormatFromExtension, resolveRelativePath } from "@intlayer/chokidar/utils";
3
+ import * as ANSIColors from "@intlayer/config/colors";
4
+ import { colorize } from "@intlayer/config/logger";
5
+ import { basename, dirname, extname, relative, resolve } from "node:path";
6
+ import { parseStringPattern } from "@intlayer/config/utils";
7
+ import { getUnmergedDictionaries } from "@intlayer/unmerged-dictionaries-entry";
8
+
9
+ //#region src/extractContent/utils/extractDictionaryInfo.ts
10
+ const getOutput = (configuration, locale) => {
11
+ const output = configuration.compiler?.output;
12
+ if (output === void 0 || output === null) throw new Error(`No output configuration found. Add a ${colorize("compiler.output", ANSIColors.BLUE)} in your configuration.`);
13
+ if (output === false) return false;
14
+ if (typeof output === "object" && typeof output !== "function") {
15
+ const entry = locale ? output[locale] : void 0;
16
+ if (entry === false) return false;
17
+ if (entry === void 0 || entry === true) throw new Error(`No output pattern configured for locale "${locale}" in compiler.output.`);
18
+ return typeof entry === "string" ? (context) => parseStringPattern(entry, context) : entry;
19
+ }
20
+ if (typeof output === "string") return (context) => parseStringPattern(output, context);
21
+ if (typeof output === "function") return output;
22
+ throw new Error(`No output configuration found. Add a ${colorize("compiler.output", ANSIColors.BLUE)} in your configuration.`);
23
+ };
24
+ /**
25
+ * Resolves the paths for the content files associated with a component.
26
+ * Checks for existing dictionaries first.
27
+ */
28
+ const resolveContentFilePaths = async (filePath, componentKey, configuration, locale) => {
29
+ const { baseDir } = configuration.system;
30
+ const { defaultLocale } = configuration.internationalization;
31
+ const existingDicts = (getUnmergedDictionaries(configuration) ?? {})[componentKey]?.filter((dictionary) => dictionary.location !== "remote").filter((dictionary) => dictionary.locale === void 0 || dictionary.locale === (locale ?? defaultLocale));
32
+ if (existingDicts?.[0]?.filePath) {
33
+ const existingPath = existingDicts[0].filePath;
34
+ const resolvedAbsolutePath = resolve(baseDir, existingPath);
35
+ return {
36
+ absolutePath: resolvedAbsolutePath,
37
+ relativePath: relative(baseDir, resolvedAbsolutePath),
38
+ isPerLocale: false
39
+ };
40
+ }
41
+ const output = configuration.compiler?.output;
42
+ const isObjectOutput = typeof output === "object" && output !== null && typeof output !== "function";
43
+ const extension = extname(filePath);
44
+ const componentName = basename(filePath, extension);
45
+ const uncapitalizedName = componentName.charAt(0).toLowerCase() + componentName.slice(1);
46
+ const componentFormat = getFormatFromExtension(extension);
47
+ const targetLocale = locale ?? defaultLocale;
48
+ const context = {
49
+ key: componentKey,
50
+ componentDirPath: relative(baseDir, dirname(filePath)),
51
+ componentFileName: componentName,
52
+ fileName: uncapitalizedName,
53
+ componentFormat,
54
+ componentExtension: extension,
55
+ format: componentFormat,
56
+ locale: targetLocale,
57
+ extension: configuration.content.fileExtensions[0]
58
+ };
59
+ if (isObjectOutput) {
60
+ const pattern = getOutput(configuration, targetLocale);
61
+ if (pattern === false) throw new Error(`compiler.output is disabled for locale "${targetLocale}".`);
62
+ const absolutePath = resolveRelativePath(await pattern(context), filePath, baseDir);
63
+ return {
64
+ absolutePath,
65
+ relativePath: relative(baseDir, absolutePath),
66
+ isPerLocale: true
67
+ };
68
+ }
69
+ const pattern = getOutput(configuration);
70
+ if (pattern === false) throw new Error(`No output configuration found. Add a ${colorize("compiler.output", ANSIColors.BLUE)} in your configuration.`);
71
+ const absolutePath = resolveRelativePath(await pattern({
72
+ ...context,
73
+ locale: defaultLocale
74
+ }), filePath, baseDir);
75
+ const localeIdentifier = "###########locale###########";
76
+ const isPerLocale = (await pattern({
77
+ ...context,
78
+ locale: localeIdentifier
79
+ })).includes(localeIdentifier);
80
+ return {
81
+ absolutePath,
82
+ relativePath: relative(baseDir, absolutePath),
83
+ isPerLocale
84
+ };
85
+ };
86
+ /**
87
+ * Extracts the dictionary key and dictionary file path for a given component file.
88
+ */
89
+ const extractDictionaryInfo = async (filePath, fileText, configuration) => {
90
+ const dictionaryKey = extractDictionaryKey(filePath, fileText);
91
+ return {
92
+ dictionaryKey,
93
+ ...await resolveContentFilePaths(filePath, dictionaryKey, configuration)
94
+ };
95
+ };
96
+
97
+ //#endregion
98
+ export { extractDictionaryInfo, getOutput, resolveContentFilePaths };
2
99
  //# sourceMappingURL=extractDictionaryInfo.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractDictionaryInfo.mjs","names":[],"sources":["../../../../src/extractContent/utils/extractDictionaryInfo.ts"],"sourcesContent":["import { basename, dirname, extname, relative, resolve } from 'node:path';\nimport {\n getFormatFromExtension,\n resolveRelativePath,\n} from '@intlayer/chokidar/utils';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize } from '@intlayer/config/logger';\nimport { parseStringPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type {\n FilePathPatternContext,\n FilePathPatternFunction,\n} from '@intlayer/types/filePathPattern';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { extractDictionaryKey } from './extractDictionaryKey';\n\nexport const getOutput = (\n configuration: IntlayerConfig\n): FilePathPatternFunction => {\n if (typeof configuration.compiler?.output === 'string') {\n return (context: FilePathPatternContext) =>\n parseStringPattern(configuration.compiler.output as string, context);\n }\n\n if (typeof configuration.compiler?.output === 'function') {\n return configuration.compiler.output;\n }\n\n throw new Error(\n `No output configuration found. Add a ${colorize('compiler.output', ANSIColors.BLUE)} in your configuration.`\n );\n};\n\nexport type ResolveContentFilePaths = {\n absolutePath: string;\n relativePath: string;\n isPerLocale: boolean;\n};\n\n/**\n * Resolves the paths for the content files associated with a component.\n * Checks for existing dictionaries first.\n */\nexport const resolveContentFilePaths = async (\n filePath: string,\n componentKey: string,\n configuration: IntlayerConfig,\n locale?: Locale\n): Promise<ResolveContentFilePaths> => {\n const { baseDir } = configuration.system;\n const { defaultLocale } = configuration.internationalization;\n\n const unmergedDictionaries = getUnmergedDictionaries(configuration) ?? {};\n const existingDicts = unmergedDictionaries[componentKey]\n ?.filter(\n (dictionary) =>\n // Remove remote dictionaries (Fix: Check for !== instead of ===)\n dictionary.location !== 'remote'\n )\n .filter(\n (dictionary) =>\n // Check for first locale dictionary sorted by priority that include the targeted locale\n dictionary.locale === undefined ||\n dictionary.locale === (locale ?? defaultLocale)\n );\n\n if (existingDicts?.[0]?.filePath) {\n const existingPath = existingDicts[0].filePath;\n const resolvedAbsolutePath = resolve(baseDir, existingPath);\n\n return {\n absolutePath: resolvedAbsolutePath,\n relativePath: relative(baseDir, resolvedAbsolutePath),\n isPerLocale: false,\n };\n }\n\n const pattern = getOutput(configuration);\n\n const extension = extname(\n filePath\n ) as FilePathPatternContext['componentExtension'];\n const componentName = basename(filePath, extension);\n const uncapitalizedName =\n componentName.charAt(0).toLowerCase() + componentName.slice(1);\n const componentFormat = getFormatFromExtension(\n extension!\n ) as FilePathPatternContext['componentFormat'];\n\n const context: FilePathPatternContext = {\n key: componentKey,\n componentDirPath: relative(baseDir, dirname(filePath)),\n componentFileName: componentName,\n fileName: uncapitalizedName,\n componentFormat,\n componentExtension: extension,\n format: componentFormat!,\n locale: defaultLocale,\n extension: configuration.content.fileExtensions[0],\n };\n\n const rawAbsolutePath = await pattern(context);\n\n // Apply the resolution rules\n const absolutePath = resolveRelativePath(rawAbsolutePath, filePath, baseDir);\n\n const localeIdentifier = '###########locale###########' as Locale;\n\n const rawPerLocalePath = await pattern({\n ...context,\n locale: localeIdentifier,\n });\n const isPerLocale = rawPerLocalePath.includes(localeIdentifier);\n\n return {\n absolutePath,\n relativePath: relative(baseDir, absolutePath),\n isPerLocale,\n };\n};\n\nexport type ExtractDictionaryInfoOptions = {\n configuration?: IntlayerConfig;\n};\n\n/**\n * Extracts the dictionary key and dictionary file path for a given component file.\n */\nexport const extractDictionaryInfo = async (\n filePath: string,\n fileText: string,\n configuration: IntlayerConfig\n): Promise<\n {\n dictionaryKey: string;\n } & ResolveContentFilePaths\n> => {\n const dictionaryKey = extractDictionaryKey(filePath, fileText);\n\n const resolvedPaths = await resolveContentFilePaths(\n filePath,\n dictionaryKey,\n configuration\n );\n\n return {\n dictionaryKey,\n ...resolvedPaths,\n };\n};\n"],"mappings":"geAiBA,MAAa,EACX,GAC4B,CAC5B,GAAI,OAAO,EAAc,UAAU,QAAW,SAC5C,MAAQ,IACN,EAAmB,EAAc,SAAS,OAAkB,EAAQ,CAGxE,GAAI,OAAO,EAAc,UAAU,QAAW,WAC5C,OAAO,EAAc,SAAS,OAGhC,MAAU,MACR,wCAAwC,EAAS,kBAAmB,EAAW,KAAK,CAAC,yBACtF,EAaU,EAA0B,MACrC,EACA,EACA,EACA,IACqC,CACrC,GAAM,CAAE,WAAY,EAAc,OAC5B,CAAE,iBAAkB,EAAc,qBAGlC,GADuB,EAAwB,EAAc,EAAI,EAAE,EAC9B,IACvC,OACC,GAEC,EAAW,WAAa,SAC3B,CACA,OACE,GAEC,EAAW,SAAW,IAAA,IACtB,EAAW,UAAY,GAAU,GACpC,CAEH,GAAI,IAAgB,IAAI,SAAU,CAChC,IAAM,EAAe,EAAc,GAAG,SAChC,EAAuB,EAAQ,EAAS,EAAa,CAE3D,MAAO,CACL,aAAc,EACd,aAAc,EAAS,EAAS,EAAqB,CACrD,YAAa,GACd,CAGH,IAAM,EAAU,EAAU,EAAc,CAElC,EAAY,EAChB,EACD,CACK,EAAgB,EAAS,EAAU,EAAU,CAC7C,EACJ,EAAc,OAAO,EAAE,CAAC,aAAa,CAAG,EAAc,MAAM,EAAE,CAC1D,EAAkB,EACtB,EACD,CAEK,EAAkC,CACtC,IAAK,EACL,iBAAkB,EAAS,EAAS,EAAQ,EAAS,CAAC,CACtD,kBAAmB,EACnB,SAAU,EACV,kBACA,mBAAoB,EACpB,OAAQ,EACR,OAAQ,EACR,UAAW,EAAc,QAAQ,eAAe,GACjD,CAKK,EAAe,EAHG,MAAM,EAAQ,EAAQ,CAGY,EAAU,EAAQ,CAEtE,EAAmB,+BAMnB,GAJmB,MAAM,EAAQ,CACrC,GAAG,EACH,OAAQ,EACT,CAAC,EACmC,SAAS,EAAiB,CAE/D,MAAO,CACL,eACA,aAAc,EAAS,EAAS,EAAa,CAC7C,cACD,EAUU,EAAwB,MACnC,EACA,EACA,IAKG,CACH,IAAM,EAAgB,EAAqB,EAAU,EAAS,CAQ9D,MAAO,CACL,gBACA,GARoB,MAAM,EAC1B,EACA,EACA,EACD,CAKA"}
1
+ {"version":3,"file":"extractDictionaryInfo.mjs","names":[],"sources":["../../../../src/extractContent/utils/extractDictionaryInfo.ts"],"sourcesContent":["import { basename, dirname, extname, relative, resolve } from 'node:path';\nimport {\n getFormatFromExtension,\n resolveRelativePath,\n} from '@intlayer/chokidar/utils';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize } from '@intlayer/config/logger';\nimport { parseStringPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Fill } from '@intlayer/types/dictionary';\nimport type {\n FilePathPattern,\n FilePathPatternContext,\n FilePathPatternFunction,\n} from '@intlayer/types/filePathPattern';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { extractDictionaryKey } from './extractDictionaryKey';\n\nexport const getOutput = (\n configuration: IntlayerConfig,\n locale?: Locale\n): FilePathPatternFunction | false => {\n const output = configuration.compiler?.output as Fill | undefined;\n\n if (output === undefined || output === null) {\n throw new Error(\n `No output configuration found. Add a ${colorize('compiler.output', ANSIColors.BLUE)} in your configuration.`\n );\n }\n\n if (output === false) return false;\n\n // Object per-locale record: look up the entry for the given locale\n if (typeof output === 'object' && typeof output !== 'function') {\n const entry = locale\n ? (output as Record<string, boolean | FilePathPattern>)[locale]\n : undefined;\n if (entry === false) return false;\n if (entry === undefined || entry === true) {\n throw new Error(\n `No output pattern configured for locale \"${locale}\" in compiler.output.`\n );\n }\n return typeof entry === 'string'\n ? (context: FilePathPatternContext) =>\n parseStringPattern(entry as string, context)\n : (entry as FilePathPatternFunction);\n }\n\n if (typeof output === 'string') {\n return (context: FilePathPatternContext) =>\n parseStringPattern(output, context);\n }\n\n if (typeof output === 'function') {\n return output as FilePathPatternFunction;\n }\n\n throw new Error(\n `No output configuration found. Add a ${colorize('compiler.output', ANSIColors.BLUE)} in your configuration.`\n );\n};\n\nexport type ResolveContentFilePaths = {\n absolutePath: string;\n relativePath: string;\n isPerLocale: boolean;\n};\n\n/**\n * Resolves the paths for the content files associated with a component.\n * Checks for existing dictionaries first.\n */\nexport const resolveContentFilePaths = async (\n filePath: string,\n componentKey: string,\n configuration: IntlayerConfig,\n locale?: Locale\n): Promise<ResolveContentFilePaths> => {\n const { baseDir } = configuration.system;\n const { defaultLocale } = configuration.internationalization;\n\n const unmergedDictionaries = getUnmergedDictionaries(configuration) ?? {};\n const existingDicts = unmergedDictionaries[componentKey]\n ?.filter(\n (dictionary) =>\n // Remove remote dictionaries (Fix: Check for !== instead of ===)\n dictionary.location !== 'remote'\n )\n .filter(\n (dictionary) =>\n // Check for first locale dictionary sorted by priority that include the targeted locale\n dictionary.locale === undefined ||\n dictionary.locale === (locale ?? defaultLocale)\n );\n\n if (existingDicts?.[0]?.filePath) {\n const existingPath = existingDicts[0].filePath;\n const resolvedAbsolutePath = resolve(baseDir, existingPath);\n\n return {\n absolutePath: resolvedAbsolutePath,\n relativePath: relative(baseDir, resolvedAbsolutePath),\n isPerLocale: false,\n };\n }\n\n const output = configuration.compiler?.output as Fill | undefined;\n const isObjectOutput =\n typeof output === 'object' &&\n output !== null &&\n typeof output !== 'function';\n\n // Build shared context (used for both object and scalar output paths)\n const extension = extname(\n filePath\n ) as FilePathPatternContext['componentExtension'];\n const componentName = basename(filePath, extension);\n const uncapitalizedName =\n componentName.charAt(0).toLowerCase() + componentName.slice(1);\n const componentFormat = getFormatFromExtension(\n extension!\n ) as FilePathPatternContext['componentFormat'];\n\n const targetLocale = (locale ?? defaultLocale) as Locale;\n\n const context: FilePathPatternContext = {\n key: componentKey,\n componentDirPath: relative(baseDir, dirname(filePath)),\n componentFileName: componentName,\n fileName: uncapitalizedName,\n componentFormat,\n componentExtension: extension,\n format: componentFormat!,\n locale: targetLocale,\n extension: configuration.content.fileExtensions[0],\n };\n\n // Object output: each locale has its own pattern → always per-locale\n if (isObjectOutput) {\n const pattern = getOutput(configuration, targetLocale);\n if (pattern === false) {\n throw new Error(\n `compiler.output is disabled for locale \"${targetLocale}\".`\n );\n }\n const rawAbsolutePath = await pattern(context);\n const absolutePath = resolveRelativePath(\n rawAbsolutePath,\n filePath,\n baseDir\n );\n return {\n absolutePath,\n relativePath: relative(baseDir, absolutePath),\n isPerLocale: true,\n };\n }\n\n // Scalar string/function output: detect per-locale via dummy locale probe\n const pattern = getOutput(configuration);\n if (pattern === false) {\n throw new Error(\n `No output configuration found. Add a ${colorize('compiler.output', ANSIColors.BLUE)} in your configuration.`\n );\n }\n\n const rawAbsolutePath = await pattern({ ...context, locale: defaultLocale });\n\n // Apply the resolution rules\n const absolutePath = resolveRelativePath(rawAbsolutePath, filePath, baseDir);\n\n const localeIdentifier = '###########locale###########' as Locale;\n\n const rawPerLocalePath = await pattern({\n ...context,\n locale: localeIdentifier,\n });\n const isPerLocale = rawPerLocalePath.includes(localeIdentifier);\n\n return {\n absolutePath,\n relativePath: relative(baseDir, absolutePath),\n isPerLocale,\n };\n};\n\nexport type ExtractDictionaryInfoOptions = {\n configuration?: IntlayerConfig;\n};\n\n/**\n * Extracts the dictionary key and dictionary file path for a given component file.\n */\nexport const extractDictionaryInfo = async (\n filePath: string,\n fileText: string,\n configuration: IntlayerConfig\n): Promise<\n {\n dictionaryKey: string;\n } & ResolveContentFilePaths\n> => {\n const dictionaryKey = extractDictionaryKey(filePath, fileText);\n\n const resolvedPaths = await resolveContentFilePaths(\n filePath,\n dictionaryKey,\n configuration\n );\n\n return {\n dictionaryKey,\n ...resolvedPaths,\n };\n};\n"],"mappings":"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"}
@@ -1,2 +1,27 @@
1
- import{COMPILER_DICTIONARY_KEY_PREFIX as e}from"@intlayer/config/defaultValues";import{camelCaseToKebabCase as t}from"@intlayer/config/utils";import{detectExportedComponentName as n}from"@intlayer/chokidar/cli";const r=(t,n=e)=>{let r=t.split(/[\\/]/),i=r.pop()||``,a=i.lastIndexOf(`.`),o=a===-1?i:i.slice(0,a);return o.toLowerCase()===`index`&&(o=r.pop()||o),`${n}${o.replace(/([a-z])([A-Z])/g,`$1-$2`).replace(/[\s_]+/g,`-`).toLowerCase()}`},i=(i,a,o=e)=>{let s=n(a);return s?`${o}${t(s)}`:r(i,o)};export{i as extractDictionaryKey,r as extractDictionaryKeyFromPath};
1
+ import { COMPILER_DICTIONARY_KEY_PREFIX } from "@intlayer/config/defaultValues";
2
+ import { camelCaseToKebabCase } from "@intlayer/config/utils";
3
+ import { detectExportedComponentName } from "@intlayer/chokidar/cli";
4
+
5
+ //#region src/extractContent/utils/extractDictionaryKey.ts
6
+ /**
7
+ * Extracts a dictionary key from a file path.
8
+ *
9
+ * Example: "src/components/MyComponent/index.tsx" -> "comp-my-component"
10
+ */
11
+ const extractDictionaryKeyFromPath = (filePath, prefix = COMPILER_DICTIONARY_KEY_PREFIX) => {
12
+ const pathParts = filePath.split(/[\\/]/);
13
+ const fileNameWithExt = pathParts.pop() || "";
14
+ const lastDotIndex = fileNameWithExt.lastIndexOf(".");
15
+ let baseName = lastDotIndex !== -1 ? fileNameWithExt.slice(0, lastDotIndex) : fileNameWithExt;
16
+ if (baseName.toLowerCase() === "index") baseName = pathParts.pop() || baseName;
17
+ return `${prefix}${baseName.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase()}`;
18
+ };
19
+ const extractDictionaryKey = (filePath, fileText, prefix = COMPILER_DICTIONARY_KEY_PREFIX) => {
20
+ const componentName = detectExportedComponentName(fileText);
21
+ if (componentName) return `${prefix}${camelCaseToKebabCase(componentName)}`;
22
+ return extractDictionaryKeyFromPath(filePath, prefix);
23
+ };
24
+
25
+ //#endregion
26
+ export { extractDictionaryKey, extractDictionaryKeyFromPath };
2
27
  //# sourceMappingURL=extractDictionaryKey.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractDictionaryKey.mjs","names":[],"sources":["../../../../src/extractContent/utils/extractDictionaryKey.ts"],"sourcesContent":["import { detectExportedComponentName } from '@intlayer/chokidar/cli';\nimport { COMPILER_DICTIONARY_KEY_PREFIX } from '@intlayer/config/defaultValues';\nimport { camelCaseToKebabCase } from '@intlayer/config/utils';\n\n/**\n * Extracts a dictionary key from a file path.\n *\n * Example: \"src/components/MyComponent/index.tsx\" -> \"comp-my-component\"\n */\nexport const extractDictionaryKeyFromPath = (\n filePath: string,\n prefix = COMPILER_DICTIONARY_KEY_PREFIX\n): string => {\n const pathParts = filePath.split(/[\\\\/]/);\n const fileNameWithExt = pathParts.pop() || '';\n const lastDotIndex = fileNameWithExt.lastIndexOf('.');\n let baseName =\n lastDotIndex !== -1\n ? fileNameWithExt.slice(0, lastDotIndex)\n : fileNameWithExt;\n\n if (baseName.toLowerCase() === 'index') {\n baseName = pathParts.pop() || baseName;\n }\n\n return `${prefix}${baseName\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase()}`;\n};\n\nexport const extractDictionaryKey = (\n filePath: string,\n fileText: string,\n prefix = COMPILER_DICTIONARY_KEY_PREFIX\n): string => {\n const componentName = detectExportedComponentName(fileText);\n\n if (componentName) {\n return `${prefix}${camelCaseToKebabCase(componentName)}`;\n }\n\n return extractDictionaryKeyFromPath(filePath, prefix);\n};\n"],"mappings":"mNASA,MAAa,GACX,EACA,EAAS,IACE,CACX,IAAM,EAAY,EAAS,MAAM,QAAQ,CACnC,EAAkB,EAAU,KAAK,EAAI,GACrC,EAAe,EAAgB,YAAY,IAAI,CACjD,EACF,IAAiB,GAEb,EADA,EAAgB,MAAM,EAAG,EAAa,CAO5C,OAJI,EAAS,aAAa,GAAK,UAC7B,EAAW,EAAU,KAAK,EAAI,GAGzB,GAAG,IAAS,EAChB,QAAQ,kBAAmB,QAAQ,CACnC,QAAQ,UAAW,IAAI,CACvB,aAAa,IAGL,GACX,EACA,EACA,EAAS,IACE,CACX,IAAM,EAAgB,EAA4B,EAAS,CAM3D,OAJI,EACK,GAAG,IAAS,EAAqB,EAAc,GAGjD,EAA6B,EAAU,EAAO"}
1
+ {"version":3,"file":"extractDictionaryKey.mjs","names":[],"sources":["../../../../src/extractContent/utils/extractDictionaryKey.ts"],"sourcesContent":["import { detectExportedComponentName } from '@intlayer/chokidar/cli';\nimport { COMPILER_DICTIONARY_KEY_PREFIX } from '@intlayer/config/defaultValues';\nimport { camelCaseToKebabCase } from '@intlayer/config/utils';\n\n/**\n * Extracts a dictionary key from a file path.\n *\n * Example: \"src/components/MyComponent/index.tsx\" -> \"comp-my-component\"\n */\nexport const extractDictionaryKeyFromPath = (\n filePath: string,\n prefix = COMPILER_DICTIONARY_KEY_PREFIX\n): string => {\n const pathParts = filePath.split(/[\\\\/]/);\n const fileNameWithExt = pathParts.pop() || '';\n const lastDotIndex = fileNameWithExt.lastIndexOf('.');\n let baseName =\n lastDotIndex !== -1\n ? fileNameWithExt.slice(0, lastDotIndex)\n : fileNameWithExt;\n\n if (baseName.toLowerCase() === 'index') {\n baseName = pathParts.pop() || baseName;\n }\n\n return `${prefix}${baseName\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase()}`;\n};\n\nexport const extractDictionaryKey = (\n filePath: string,\n fileText: string,\n prefix = COMPILER_DICTIONARY_KEY_PREFIX\n): string => {\n const componentName = detectExportedComponentName(fileText);\n\n if (componentName) {\n return `${prefix}${camelCaseToKebabCase(componentName)}`;\n }\n\n return extractDictionaryKeyFromPath(filePath, prefix);\n};\n"],"mappings":";;;;;;;;;;AASA,MAAa,gCACX,UACA,SAAS,mCACE;CACX,MAAM,YAAY,SAAS,MAAM,QAAQ;CACzC,MAAM,kBAAkB,UAAU,KAAK,IAAI;CAC3C,MAAM,eAAe,gBAAgB,YAAY,IAAI;CACrD,IAAI,WACF,iBAAiB,KACb,gBAAgB,MAAM,GAAG,aAAa,GACtC;AAEN,KAAI,SAAS,aAAa,KAAK,QAC7B,YAAW,UAAU,KAAK,IAAI;AAGhC,QAAO,GAAG,SAAS,SAChB,QAAQ,mBAAmB,QAAQ,CACnC,QAAQ,WAAW,IAAI,CACvB,aAAa;;AAGlB,MAAa,wBACX,UACA,UACA,SAAS,mCACE;CACX,MAAM,gBAAgB,4BAA4B,SAAS;AAE3D,KAAI,cACF,QAAO,GAAG,SAAS,qBAAqB,cAAc;AAGxD,QAAO,6BAA6B,UAAU,OAAO"}
@@ -1,2 +1,15 @@
1
- const e=(e,t)=>{let n=e.normalize(`NFD`).replace(/[\u0300-\u036f]/g,``).replace(/[\s_-]+/g,` `).replace(/[^\p{L}\p{N} ]/gu,``).trim().split(` `).filter(Boolean).slice(0,5).map((e,t)=>t===0?e.toLowerCase():e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``);if(n||=`content`,t.has(n)){let e=1;for(;t.has(`${n}${e}`);)e++;n=`${n}${e}`}return n};export{e as generateKey};
1
+ //#region src/extractContent/utils/generateKey.ts
2
+ const generateKey = (text, existingKeys) => {
3
+ let key = text.normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[\s_-]+/g, " ").replace(/[^\p{L}\p{N} ]/gu, "").trim().split(" ").filter(Boolean).slice(0, 5).map((word, index) => index === 0 ? word.toLowerCase() : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
4
+ if (!key) key = "content";
5
+ if (existingKeys.has(key)) {
6
+ let i = 1;
7
+ while (existingKeys.has(`${key}${i}`)) i++;
8
+ key = `${key}${i}`;
9
+ }
10
+ return key;
11
+ };
12
+
13
+ //#endregion
14
+ export { generateKey };
2
15
  //# sourceMappingURL=generateKey.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateKey.mjs","names":[],"sources":["../../../../src/extractContent/utils/generateKey.ts"],"sourcesContent":["export const generateKey = (\n text: string,\n existingKeys: Set<string>\n): string => {\n const maxWords = 5;\n let key = text\n .normalize('NFD') // Normalize to decomposes combined characters (e.g., é -> e + ´)\n .replace(/[\\u0300-\\u036f]/g, '') // Remove the accent characters\n .replace(/[\\s_-]+/g, ' ')\n .replace(/[^\\p{L}\\p{N} ]/gu, '')\n .trim()\n .split(' ')\n .filter(Boolean)\n .slice(0, maxWords)\n .map((word, index) =>\n index === 0\n ? word.toLowerCase()\n : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()\n )\n .join('');\n\n if (!key) key = 'content';\n if (existingKeys.has(key)) {\n let i = 1;\n while (existingKeys.has(`${key}${i}`)) i++;\n key = `${key}${i}`;\n }\n return key;\n};\n"],"mappings":"AAAA,MAAa,GACX,EACA,IACW,CAEX,IAAI,EAAM,EACP,UAAU,MAAM,CAChB,QAAQ,mBAAoB,GAAG,CAC/B,QAAQ,WAAY,IAAI,CACxB,QAAQ,mBAAoB,GAAG,CAC/B,MAAM,CACN,MAAM,IAAI,CACV,OAAO,QAAQ,CACf,MAAM,EATQ,EASI,CAClB,KAAK,EAAM,IACV,IAAU,EACN,EAAK,aAAa,CAClB,EAAK,OAAO,EAAE,CAAC,aAAa,CAAG,EAAK,MAAM,EAAE,CAAC,aAAa,CAC/D,CACA,KAAK,GAAG,CAGX,GADA,AAAU,IAAM,UACZ,EAAa,IAAI,EAAI,CAAE,CACzB,IAAI,EAAI,EACR,KAAO,EAAa,IAAI,GAAG,IAAM,IAAI,EAAE,IACvC,EAAM,GAAG,IAAM,IAEjB,OAAO"}
1
+ {"version":3,"file":"generateKey.mjs","names":[],"sources":["../../../../src/extractContent/utils/generateKey.ts"],"sourcesContent":["export const generateKey = (\n text: string,\n existingKeys: Set<string>\n): string => {\n const maxWords = 5;\n let key = text\n .normalize('NFD') // Normalize to decomposes combined characters (e.g., é -> e + ´)\n .replace(/[\\u0300-\\u036f]/g, '') // Remove the accent characters\n .replace(/[\\s_-]+/g, ' ')\n .replace(/[^\\p{L}\\p{N} ]/gu, '')\n .trim()\n .split(' ')\n .filter(Boolean)\n .slice(0, maxWords)\n .map((word, index) =>\n index === 0\n ? word.toLowerCase()\n : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()\n )\n .join('');\n\n if (!key) key = 'content';\n if (existingKeys.has(key)) {\n let i = 1;\n while (existingKeys.has(`${key}${i}`)) i++;\n key = `${key}${i}`;\n }\n return key;\n};\n"],"mappings":";AAAA,MAAa,eACX,MACA,iBACW;CAEX,IAAI,MAAM,KACP,UAAU,MAAM,CAChB,QAAQ,oBAAoB,GAAG,CAC/B,QAAQ,YAAY,IAAI,CACxB,QAAQ,oBAAoB,GAAG,CAC/B,MAAM,CACN,MAAM,IAAI,CACV,OAAO,QAAQ,CACf,MAAM,GATQ,EASI,CAClB,KAAK,MAAM,UACV,UAAU,IACN,KAAK,aAAa,GAClB,KAAK,OAAO,EAAE,CAAC,aAAa,GAAG,KAAK,MAAM,EAAE,CAAC,aAAa,CAC/D,CACA,KAAK,GAAG;AAEX,KAAI,CAAC,IAAK,OAAM;AAChB,KAAI,aAAa,IAAI,IAAI,EAAE;EACzB,IAAI,IAAI;AACR,SAAO,aAAa,IAAI,GAAG,MAAM,IAAI,CAAE;AACvC,QAAM,GAAG,MAAM;;AAEjB,QAAO"}
@@ -1,2 +1,16 @@
1
- import*as e from"@babel/types";const t=t=>{if(t.isFunctionDeclaration())return t.node.id?.name;if((t.isArrowFunctionExpression()||t.isFunctionExpression())&&t.parentPath.isVariableDeclarator()&&e.isIdentifier(t.parentPath.node.id))return t.parentPath.node.id.name};export{t as getComponentName};
1
+ import * as t from "@babel/types";
2
+
3
+ //#region src/extractContent/utils/getComponentName.ts
4
+ /**
5
+ * Resolves the name of the component from various function declaration types.
6
+ */
7
+ const getComponentName = (path) => {
8
+ if (path.isFunctionDeclaration()) return path.node.id?.name;
9
+ if (path.isArrowFunctionExpression() || path.isFunctionExpression()) {
10
+ if (path.parentPath.isVariableDeclarator() && t.isIdentifier(path.parentPath.node.id)) return path.parentPath.node.id.name;
11
+ }
12
+ };
13
+
14
+ //#endregion
15
+ export { getComponentName };
2
16
  //# sourceMappingURL=getComponentName.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"getComponentName.mjs","names":[],"sources":["../../../../src/extractContent/utils/getComponentName.ts"],"sourcesContent":["import type { NodePath } from '@babel/traverse';\nimport * as t from '@babel/types';\n\n/**\n * Resolves the name of the component from various function declaration types.\n */\nexport const getComponentName = (path: NodePath): string | undefined => {\n if (path.isFunctionDeclaration()) {\n return path.node.id?.name;\n }\n\n if (path.isArrowFunctionExpression() || path.isFunctionExpression()) {\n if (\n path.parentPath.isVariableDeclarator() &&\n t.isIdentifier(path.parentPath.node.id)\n ) {\n return path.parentPath.node.id.name;\n }\n }\n\n return undefined;\n};\n"],"mappings":"+BAMA,MAAa,EAAoB,GAAuC,CACtE,GAAI,EAAK,uBAAuB,CAC9B,OAAO,EAAK,KAAK,IAAI,KAGvB,IAAI,EAAK,2BAA2B,EAAI,EAAK,sBAAsB,GAE/D,EAAK,WAAW,sBAAsB,EACtC,EAAE,aAAa,EAAK,WAAW,KAAK,GAAG,CAEvC,OAAO,EAAK,WAAW,KAAK,GAAG"}
1
+ {"version":3,"file":"getComponentName.mjs","names":[],"sources":["../../../../src/extractContent/utils/getComponentName.ts"],"sourcesContent":["import type { NodePath } from '@babel/traverse';\nimport * as t from '@babel/types';\n\n/**\n * Resolves the name of the component from various function declaration types.\n */\nexport const getComponentName = (path: NodePath): string | undefined => {\n if (path.isFunctionDeclaration()) {\n return path.node.id?.name;\n }\n\n if (path.isArrowFunctionExpression() || path.isFunctionExpression()) {\n if (\n path.parentPath.isVariableDeclarator() &&\n t.isIdentifier(path.parentPath.node.id)\n ) {\n return path.parentPath.node.id.name;\n }\n }\n\n return undefined;\n};\n"],"mappings":";;;;;;AAMA,MAAa,oBAAoB,SAAuC;AACtE,KAAI,KAAK,uBAAuB,CAC9B,QAAO,KAAK,KAAK,IAAI;AAGvB,KAAI,KAAK,2BAA2B,IAAI,KAAK,sBAAsB,EACjE;MACE,KAAK,WAAW,sBAAsB,IACtC,EAAE,aAAa,KAAK,WAAW,KAAK,GAAG,CAEvC,QAAO,KAAK,WAAW,KAAK,GAAG"}
@@ -1,2 +1,48 @@
1
- import*as e from"@babel/types";const t=t=>{let n;return t.traverse({CallExpression(t){let r=t.node.callee;if(e.isIdentifier(r)&&(r.name===`useIntlayer`||r.name===`getIntlayer`)){let i=t.node.arguments[0];if(e.isStringLiteral(i)){let a=t.parent,o=!1,s=[],c,l=`content`;e.isVariableDeclarator(a)&&(e.isObjectPattern(a.id)?(o=!0,c=a.id,s=a.id.properties.filter(t=>e.isObjectProperty(t)&&e.isIdentifier(t.key)).map(e=>e.key.name)):e.isIdentifier(a.id)&&(l=a.id.name)),n={key:i.value,hook:r.name,variableName:l,isDestructured:o,existingDestructuredKeys:s,objectPatternNode:c},t.stop()}}},Function(e){e.skip()}}),n};export{t as getExistingIntlayerInfo};
1
+ import * as t from "@babel/types";
2
+
3
+ //#region src/extractContent/utils/getExistingIntlayerInfo.ts
4
+ /**
5
+ * Searches for an existing useIntlayer or getIntlayer call in the function body.
6
+ */
7
+ const getExistingIntlayerInfo = (path) => {
8
+ let result;
9
+ path.traverse({
10
+ CallExpression(childPath) {
11
+ const callee = childPath.node.callee;
12
+ if (t.isIdentifier(callee) && (callee.name === "useIntlayer" || callee.name === "getIntlayer")) {
13
+ const arg = childPath.node.arguments[0];
14
+ if (t.isStringLiteral(arg)) {
15
+ const parentNode = childPath.parent;
16
+ let isDestructured = false;
17
+ let existingDestructuredKeys = [];
18
+ let objectPatternNode;
19
+ let variableName = "content";
20
+ if (t.isVariableDeclarator(parentNode)) {
21
+ if (t.isObjectPattern(parentNode.id)) {
22
+ isDestructured = true;
23
+ objectPatternNode = parentNode.id;
24
+ existingDestructuredKeys = parentNode.id.properties.filter((p) => t.isObjectProperty(p) && t.isIdentifier(p.key)).map((p) => p.key.name);
25
+ } else if (t.isIdentifier(parentNode.id)) variableName = parentNode.id.name;
26
+ }
27
+ result = {
28
+ key: arg.value,
29
+ hook: callee.name,
30
+ variableName,
31
+ isDestructured,
32
+ existingDestructuredKeys,
33
+ objectPatternNode
34
+ };
35
+ childPath.stop();
36
+ }
37
+ }
38
+ },
39
+ Function(childPath) {
40
+ childPath.skip();
41
+ }
42
+ });
43
+ return result;
44
+ };
45
+
46
+ //#endregion
47
+ export { getExistingIntlayerInfo };
2
48
  //# sourceMappingURL=getExistingIntlayerInfo.mjs.map
@@ -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":"+BAmBA,MAAa,EACX,GACqC,CACrC,IAAI,EAoDJ,OAjDA,EAAK,SAAS,CACZ,eAAe,EAAW,CACxB,IAAM,EAAS,EAAU,KAAK,OAE9B,GACE,EAAE,aAAa,EAAO,GACrB,EAAO,OAAS,eAAiB,EAAO,OAAS,eAClD,CACA,IAAM,EAAM,EAAU,KAAK,UAAU,GAErC,GAAI,EAAE,gBAAgB,EAAI,CAAE,CAC1B,IAAM,EAAa,EAAU,OACzB,EAAiB,GACjB,EAAqC,EAAE,CACvC,EACA,EAAe,UAEf,EAAE,qBAAqB,EAAW,GAChC,EAAE,gBAAgB,EAAW,GAAG,EAClC,EAAiB,GACjB,EAAoB,EAAW,GAC/B,EAA2B,EAAW,GAAG,WACtC,OACE,GACC,EAAE,iBAAiB,EAAE,EAAI,EAAE,aAAa,EAAE,IAAI,CACjD,CACA,IAAK,GAAO,EAAE,IAAqB,KAAK,EAClC,EAAE,aAAa,EAAW,GAAG,GACtC,EAAe,EAAW,GAAG,OAIjC,EAAS,CACP,IAAK,EAAI,MACT,KAAM,EAAO,KACb,eACA,iBACA,2BACA,oBACD,CACD,EAAU,MAAM,IAItB,SAAS,EAAW,CAClB,EAAU,MAAM,EAEnB,CAAC,CAEK"}
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,2 +1,19 @@
1
- import{generateKey as e}from"./generateKey.mjs";const t=(t,n,r,i)=>{i[n]||(i[n]={});let a=Object.entries(i[n]).find(([e,n])=>n===t);if(a)return a[0];let o=e(t,r);return r.add(o),i[n][o]=t,o};export{t as getOrGenerateKey};
1
+ import { generateKey } from "./generateKey.mjs";
2
+
3
+ //#region src/extractContent/utils/getOrGenerateKey.ts
4
+ /**
5
+ * Gets an existing key for a given text or generates a new one.
6
+ */
7
+ const getOrGenerateKey = (text, componentKey, existingKeys, extractedContent) => {
8
+ if (!extractedContent[componentKey]) extractedContent[componentKey] = {};
9
+ const existingEntry = Object.entries(extractedContent[componentKey]).find(([_, value]) => value === text);
10
+ if (existingEntry) return existingEntry[0];
11
+ const key = generateKey(text, existingKeys);
12
+ existingKeys.add(key);
13
+ extractedContent[componentKey][key] = text;
14
+ return key;
15
+ };
16
+
17
+ //#endregion
18
+ export { getOrGenerateKey };
2
19
  //# sourceMappingURL=getOrGenerateKey.mjs.map
@@ -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":"gDAKA,MAAa,GACX,EACA,EACA,EACA,IACW,CACN,EAAiB,KACpB,EAAiB,GAAgB,EAAE,EAErC,IAAM,EAAgB,OAAO,QAAQ,EAAiB,GAAc,CAAC,MAClE,CAAC,EAAG,KAAW,IAAU,EAC3B,CAED,GAAI,EACF,OAAO,EAAc,GAEvB,IAAM,EAAM,EAAY,EAAM,EAAa,CAI3C,OAFA,EAAa,IAAI,EAAI,CACrB,EAAiB,GAAc,GAAO,EAC/B"}
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 +1,12 @@
1
- import{extractDictionaryKey as e,extractDictionaryKeyFromPath as t}from"./extractDictionaryKey.mjs";import{extractDictionaryInfo as n,getOutput as r,resolveContentFilePaths as i}from"./extractDictionaryInfo.mjs";import{ATTRIBUTES_TO_EXTRACT as a,SERVER_CAPABLE_PACKAGES as o,packageList as s}from"./constants.mjs";import{detectPackageName as c}from"./detectPackageName.mjs";import{generateKey as l}from"./generateKey.mjs";import{getComponentName as u}from"./getComponentName.mjs";import{getExistingIntlayerInfo as d}from"./getExistingIntlayerInfo.mjs";import{getOrGenerateKey as f}from"./getOrGenerateKey.mjs";import{resolveDictionaryKey as p}from"./resolveDictionaryKey.mjs";import{shouldExtract as m}from"./shouldExtract.mjs";export{a as ATTRIBUTES_TO_EXTRACT,o as SERVER_CAPABLE_PACKAGES,c as detectPackageName,n as extractDictionaryInfo,e as extractDictionaryKey,t as extractDictionaryKeyFromPath,l as generateKey,u as getComponentName,d as getExistingIntlayerInfo,f as getOrGenerateKey,r as getOutput,s as packageList,i as resolveContentFilePaths,p as resolveDictionaryKey,m as shouldExtract};
1
+ import { extractDictionaryKey, extractDictionaryKeyFromPath } from "./extractDictionaryKey.mjs";
2
+ import { extractDictionaryInfo, getOutput, resolveContentFilePaths } from "./extractDictionaryInfo.mjs";
3
+ import { ATTRIBUTES_TO_EXTRACT, SERVER_CAPABLE_PACKAGES, packageList } from "./constants.mjs";
4
+ import { detectPackageName } from "./detectPackageName.mjs";
5
+ import { generateKey } from "./generateKey.mjs";
6
+ import { getComponentName } from "./getComponentName.mjs";
7
+ import { getExistingIntlayerInfo } from "./getExistingIntlayerInfo.mjs";
8
+ import { getOrGenerateKey } from "./getOrGenerateKey.mjs";
9
+ import { resolveDictionaryKey } from "./resolveDictionaryKey.mjs";
10
+ import { shouldExtract } from "./shouldExtract.mjs";
11
+
12
+ export { ATTRIBUTES_TO_EXTRACT, SERVER_CAPABLE_PACKAGES, detectPackageName, extractDictionaryInfo, extractDictionaryKey, extractDictionaryKeyFromPath, generateKey, getComponentName, getExistingIntlayerInfo, getOrGenerateKey, getOutput, packageList, resolveContentFilePaths, resolveDictionaryKey, shouldExtract };
@@ -1,2 +1,33 @@
1
- import{existsSync as e}from"node:fs";import{dirname as t,join as n}from"node:path";import{getUnmergedDictionaries as r}from"@intlayer/unmerged-dictionaries-entry";const i=(i,a,o,s,c=new Set)=>{let l=s??r(o)??{},{fileExtensions:u}=o.content,d=t(a),f=u[0],p=f.startsWith(`.`)?f:`.${f}`,m=0;for(;m<100;){let t=m===0?i:`${i}${m}`,r=l[t],a=n(d,`${t}${p}`),o=c.has(t),s=r&&r.length>0,u=e(a);if(!o&&!s&&!u)return t;m++}return i};export{i as resolveDictionaryKey};
1
+ import { existsSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { getUnmergedDictionaries } from "@intlayer/unmerged-dictionaries-entry";
4
+
5
+ //#region src/extractContent/utils/resolveDictionaryKey.ts
6
+ /**
7
+ * Resolves a unique dictionary key, checking for existing dictionaries and files.
8
+ * Note: this chokidar-specific variant fetches unmergedDictionaries internally
9
+ * from the configuration (unlike the `@intlayer/babel` version which takes it as a parameter).
10
+ */
11
+ const resolveDictionaryKey = (initialKey, filePath, configuration, unmergedDictionaries, usedKeys = /* @__PURE__ */ new Set()) => {
12
+ const dicts = unmergedDictionaries ?? getUnmergedDictionaries(configuration) ?? {};
13
+ const { fileExtensions } = configuration.content;
14
+ const dirName = dirname(filePath);
15
+ const firstExtension = fileExtensions[0];
16
+ const extension = firstExtension.startsWith(".") ? firstExtension : `.${firstExtension}`;
17
+ let index = 0;
18
+ while (index < 100) {
19
+ const keyToTest = index === 0 ? initialKey : `${initialKey}${index}`;
20
+ const dictionaries = dicts[keyToTest];
21
+ const contentFilePath = join(dirName, `${keyToTest}${extension}`);
22
+ const isKeyUsed = usedKeys.has(keyToTest);
23
+ const hasDictionaries = dictionaries && dictionaries.length > 0;
24
+ const fileExists = existsSync(contentFilePath);
25
+ if (!isKeyUsed && !hasDictionaries && !fileExists) return keyToTest;
26
+ index++;
27
+ }
28
+ return initialKey;
29
+ };
30
+
31
+ //#endregion
32
+ export { resolveDictionaryKey };
2
33
  //# sourceMappingURL=resolveDictionaryKey.mjs.map