@intlayer/babel 8.2.3 → 8.3.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/cjs/babel-plugin-intlayer-extract.cjs +1 -1
  2. package/dist/cjs/babel-plugin-intlayer-extract.cjs.map +1 -1
  3. package/dist/cjs/babel-plugin-intlayer-optimize.cjs +1 -1
  4. package/dist/cjs/extractContent/babelProcessor.cjs.map +1 -1
  5. package/dist/cjs/extractContent/contentWriter.cjs +1 -1
  6. package/dist/cjs/extractContent/contentWriter.cjs.map +1 -1
  7. package/dist/cjs/extractContent/extractContent.cjs +1 -1
  8. package/dist/cjs/extractContent/extractContent.cjs.map +1 -1
  9. package/dist/cjs/extractContent/index.cjs +1 -1
  10. package/dist/cjs/extractContent/processTsxFile.cjs +5 -5
  11. package/dist/cjs/extractContent/processTsxFile.cjs.map +1 -1
  12. package/dist/cjs/extractContent/utils/constants.cjs +1 -1
  13. package/dist/cjs/extractContent/utils/constants.cjs.map +1 -1
  14. package/dist/cjs/extractContent/utils/detectPackageName.cjs +1 -1
  15. package/dist/cjs/extractContent/utils/detectPackageName.cjs.map +1 -1
  16. package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs +2 -0
  17. package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs.map +1 -0
  18. package/dist/cjs/extractContent/utils/extractDictionaryKey.cjs +1 -1
  19. package/dist/cjs/extractContent/utils/extractDictionaryKey.cjs.map +1 -1
  20. package/dist/cjs/extractContent/utils/getOrGenerateKey.cjs.map +1 -1
  21. package/dist/cjs/extractContent/utils/index.cjs +1 -1
  22. package/dist/cjs/extractContent/utils/resolveDictionaryKey.cjs +1 -1
  23. package/dist/cjs/extractContent/utils/resolveDictionaryKey.cjs.map +1 -1
  24. package/dist/cjs/getExtractPluginOptions.cjs +1 -1
  25. package/dist/cjs/getExtractPluginOptions.cjs.map +1 -1
  26. package/dist/cjs/getOptimizePluginOptions.cjs +1 -1
  27. package/dist/cjs/getOptimizePluginOptions.cjs.map +1 -1
  28. package/dist/cjs/index.cjs +1 -1
  29. package/dist/esm/babel-plugin-intlayer-extract.mjs +1 -1
  30. package/dist/esm/babel-plugin-intlayer-extract.mjs.map +1 -1
  31. package/dist/esm/babel-plugin-intlayer-optimize.mjs +1 -1
  32. package/dist/esm/extractContent/babelProcessor.mjs.map +1 -1
  33. package/dist/esm/extractContent/contentWriter.mjs +1 -1
  34. package/dist/esm/extractContent/contentWriter.mjs.map +1 -1
  35. package/dist/esm/extractContent/extractContent.mjs +1 -1
  36. package/dist/esm/extractContent/extractContent.mjs.map +1 -1
  37. package/dist/esm/extractContent/index.mjs +1 -1
  38. package/dist/esm/extractContent/processTsxFile.mjs +5 -5
  39. package/dist/esm/extractContent/processTsxFile.mjs.map +1 -1
  40. package/dist/esm/extractContent/utils/constants.mjs +1 -1
  41. package/dist/esm/extractContent/utils/constants.mjs.map +1 -1
  42. package/dist/esm/extractContent/utils/detectPackageName.mjs +1 -1
  43. package/dist/esm/extractContent/utils/detectPackageName.mjs.map +1 -1
  44. package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs +2 -0
  45. package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs.map +1 -0
  46. package/dist/esm/extractContent/utils/extractDictionaryKey.mjs +1 -1
  47. package/dist/esm/extractContent/utils/extractDictionaryKey.mjs.map +1 -1
  48. package/dist/esm/extractContent/utils/getOrGenerateKey.mjs.map +1 -1
  49. package/dist/esm/extractContent/utils/index.mjs +1 -1
  50. package/dist/esm/extractContent/utils/resolveDictionaryKey.mjs +1 -1
  51. package/dist/esm/extractContent/utils/resolveDictionaryKey.mjs.map +1 -1
  52. package/dist/esm/getExtractPluginOptions.mjs +1 -1
  53. package/dist/esm/getExtractPluginOptions.mjs.map +1 -1
  54. package/dist/esm/getOptimizePluginOptions.mjs +1 -1
  55. package/dist/esm/getOptimizePluginOptions.mjs.map +1 -1
  56. package/dist/esm/index.mjs +1 -1
  57. package/dist/types/babel-plugin-intlayer-extract.d.ts +14 -9
  58. package/dist/types/babel-plugin-intlayer-extract.d.ts.map +1 -1
  59. package/dist/types/extractContent/babelProcessor.d.ts +1 -1
  60. package/dist/types/extractContent/contentWriter.d.ts +22 -13
  61. package/dist/types/extractContent/contentWriter.d.ts.map +1 -1
  62. package/dist/types/extractContent/extractContent.d.ts +6 -30
  63. package/dist/types/extractContent/extractContent.d.ts.map +1 -1
  64. package/dist/types/extractContent/index.d.ts +8 -3
  65. package/dist/types/extractContent/processTsxFile.d.ts +3 -2
  66. package/dist/types/extractContent/processTsxFile.d.ts.map +1 -1
  67. package/dist/types/extractContent/utils/constants.d.ts +6 -2
  68. package/dist/types/extractContent/utils/constants.d.ts.map +1 -1
  69. package/dist/types/extractContent/utils/detectPackageName.d.ts +3 -1
  70. package/dist/types/extractContent/utils/detectPackageName.d.ts.map +1 -1
  71. package/dist/types/extractContent/utils/extractDictionaryInfo.d.ts +28 -0
  72. package/dist/types/extractContent/utils/extractDictionaryInfo.d.ts.map +1 -0
  73. package/dist/types/extractContent/utils/extractDictionaryKey.d.ts +1 -1
  74. package/dist/types/extractContent/utils/extractDictionaryKey.d.ts.map +1 -1
  75. package/dist/types/extractContent/utils/index.d.ts +3 -2
  76. package/dist/types/extractContent/utils/resolveDictionaryKey.d.ts +1 -1
  77. package/dist/types/extractContent/utils/resolveDictionaryKey.d.ts.map +1 -1
  78. package/dist/types/getExtractPluginOptions.d.ts +9 -2
  79. package/dist/types/getExtractPluginOptions.d.ts.map +1 -1
  80. package/dist/types/getOptimizePluginOptions.d.ts +1 -1
  81. package/dist/types/getOptimizePluginOptions.d.ts.map +1 -1
  82. package/dist/types/index.d.ts +9 -4
  83. package/package.json +21 -22
@@ -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';\nimport { extractBabelContentForComponents } from './babelProcessor';\nimport { getExistingIntlayerInfo } 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: string,\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 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 const getProvidingHookType = (\n path: NodePath\n ): 'useIntlayer' | 'getIntlayer' => {\n let current: NodePath | null = path;\n while (current) {\n const functionPath = componentPaths.find(\n (path) => path.node === current?.node\n );\n\n if (functionPath) {\n const existingInfo = getExistingIntlayerInfo(functionPath);\n\n if (existingInfo) {\n return existingInfo.hook;\n }\n\n if (componentsNeedingHooks.has(functionPath)) {\n return hookMap.get(functionPath.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 contentAccessCode = isSolid ? `content().${key}` : `content.${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 = getExistingIntlayerInfo(componentPath);\n\n if (existingInfo) {\n if (existingInfo.hook === 'useIntlayer') needsUseIntlayer = true;\n\n if (existingInfo.hook === 'getIntlayer') needsGetIntlayer = true;\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 ch = fileCode[i];\n if (ch === '(') {\n parenStart = i;\n break;\n }\n if (ch !== ' ' && ch !== '\\n' && ch !== '\\r' && ch !== '\\t') break;\n }\n\n if (parenStart !== -1) {\n for (let i = end; i < fileCode.length; i++) {\n const ch = fileCode[i];\n if (ch === ')') {\n parenEnd = i;\n break;\n }\n if (ch !== ' ' && ch !== '\\n' && ch !== '\\r' && ch !== '\\t') 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', packageName);\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.content.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 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 const getProvidingHookType = (\n path: NodePath\n ): 'useIntlayer' | 'getIntlayer' => {\n let current: NodePath | null = path;\n while (current) {\n const functionPath = componentPaths.find(\n (path) => path.node === current?.node\n );\n\n if (functionPath) {\n const existingInfo = getExistingIntlayerInfo(functionPath);\n\n if (existingInfo) {\n return existingInfo.hook;\n }\n\n if (componentsNeedingHooks.has(functionPath)) {\n return hookMap.get(functionPath.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 contentAccessCode = isSolid ? `content().${key}` : `content.${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 = getExistingIntlayerInfo(componentPath);\n\n if (existingInfo) {\n if (existingInfo.hook === 'useIntlayer') needsUseIntlayer = true;\n\n if (existingInfo.hook === 'getIntlayer') needsGetIntlayer = true;\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,2 @@
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`];export{e as ATTRIBUTES_TO_EXTRACT,t as packageList};
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};
2
2
  //# 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 */\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] as const;\n\nexport type PackageName = (typeof packageList)[number];\n"],"mappings":"AAKA,MAAa,EAAwB,CACnC,QACA,cACA,MACA,aACA,QACD,CAMY,EAAc,CACzB,gBACA,iBACA,eACA,kBACA,kBACA,iBACA,mBACA,mBACA,gBACA,mBACA,kBACD"}
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,2 +1,2 @@
1
- import{packageList as e}from"./constants.mjs";import{dirname as t,join as n}from"node:path";import{existsSync as r,readFileSync as i}from"node:fs";const a=a=>{let o=a;for(;o!==t(o);){let a=n(o,`package.json`);if(r(a))try{let t=JSON.parse(i(a,`utf-8`)),n={...t.dependencies,...t.devDependencies,...t.peerDependencies};for(let t of e)if(n[t])return t}catch{}o=t(o)}};export{a as detectPackageName};
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};
2
2
  //# 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 { dirname, join } from 'node:path';\nimport { 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): string | undefined => {\n let currentDir = searchDir;\n\n while (currentDir !== dirname(currentDir)) {\n const pkgPath = join(currentDir, 'package.json');\n\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n const allDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n ...pkg.peerDependencies,\n };\n for (const pkgName of packageList) {\n if (allDeps[pkgName]) return pkgName;\n }\n } catch {\n // Ignore JSON errors\n }\n }\n currentDir = dirname(currentDir);\n }\n\n return undefined;\n};\n"],"mappings":"mJAOA,MAAa,EAAqB,GAA0C,CAC1E,IAAI,EAAa,EAEjB,KAAO,IAAe,EAAQ,EAAW,EAAE,CACzC,IAAM,EAAU,EAAK,EAAY,eAAe,CAEhD,GAAI,EAAW,EAAQ,CACrB,GAAI,CACF,IAAM,EAAM,KAAK,MAAM,EAAa,EAAS,QAAQ,CAAC,CAChD,EAAU,CACd,GAAG,EAAI,aACP,GAAG,EAAI,gBACP,GAAG,EAAI,iBACR,CACD,IAAK,IAAM,KAAW,EACpB,GAAI,EAAQ,GAAU,OAAO,OAEzB,EAIV,EAAa,EAAQ,EAAW"}
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"}
@@ -0,0 +1,2 @@
1
+ import{extractDictionaryKey as e}from"./extractDictionaryKey.mjs";import{getFormatFromExtension as t,resolveRelativePath as n}from"@intlayer/chokidar/utils";import{DefaultValues as r}from"@intlayer/config/node";import{basename as i,dirname as a,extname as o,relative as s,resolve as c}from"node:path";import{parseStringPattern as l}from"@intlayer/config/utils";import{getUnmergedDictionaries as u}from"@intlayer/unmerged-dictionaries-entry";const d=e=>{if(typeof e.compiler?.output==`string`)return t=>l(e.compiler.output,t);if(typeof e.compiler?.output==`function`)return e.compiler.output;if(typeof e.compiler?.outputDir==`string`){let t=c(e.system.baseDir,e.compiler.outputDir);return n=>l(`${t}/{{fileName}}.${e.content.fileExtensions[0].split(`.`)[1]}.json`,n)}return r.Compiler.COMPILER_OUTPUT},f=async(e,r,l,f)=>{let{baseDir:p}=l.system,{defaultLocale:m}=l.internationalization,h=(u(l)??{})[r]?.filter(e=>e.location!==`remote`).filter(e=>e.locale===void 0||e.locale===(f??m));if(h?.[0]?.filePath){let e=h[0].filePath,t=c(p,e);return{absolutePath:t,relativePath:s(p,t),isPerLocale:!1}}let g=d(l),_=o(e),v=i(e,_),y=v.charAt(0).toLowerCase()+v.slice(1),b=t(_),x={key:r,componentDirPath:s(p,a(e)),componentFileName:v,fileName:y,componentFormat:b,componentExtension:_,format:b,locale:m,extension:l.content.fileExtensions[0]},S=n(await g(x),e,p),C=`###########locale###########`,w=(await g({...x,locale:C})).includes(C);return{absolutePath:S,relativePath:s(p,S),isPerLocale:w}},p=async(t,n,r)=>{let i=e(t,n);return{dictionaryKey:i,...await f(t,i,r)}};export{p as extractDictionaryInfo,d as getOutput,f as resolveContentFilePaths};
2
+ //# sourceMappingURL=extractDictionaryInfo.mjs.map
@@ -0,0 +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 { DefaultValues } from '@intlayer/config/node';\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 if (typeof configuration.compiler?.outputDir === 'string') {\n // Resolve outputDir against baseDir immediately to guarantee a valid absolute path everywhere\n const absoluteOutputDir = resolve(\n configuration.system.baseDir,\n configuration.compiler.outputDir\n );\n\n return (context: FilePathPatternContext) =>\n parseStringPattern(\n `${absoluteOutputDir}/{{fileName}}.${configuration.content.fileExtensions[0].split('.')[1]}.json`,\n context\n );\n }\n\n return DefaultValues.Compiler.COMPILER_OUTPUT;\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":"ybAgBA,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,GAAI,OAAO,EAAc,UAAU,WAAc,SAAU,CAEzD,IAAM,EAAoB,EACxB,EAAc,OAAO,QACrB,EAAc,SAAS,UACxB,CAED,MAAQ,IACN,EACE,GAAG,EAAkB,gBAAgB,EAAc,QAAQ,eAAe,GAAG,MAAM,IAAI,CAAC,GAAG,OAC3F,EACD,CAGL,OAAO,EAAc,SAAS,iBAanB,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,2 +1,2 @@
1
- import{detectExportedComponentName as e}from"@intlayer/chokidar/cli";import{camelCaseToKebabCase as t}from"@intlayer/config/utils";const n=(e,t=`comp-`)=>{let n=e.split(/[\\/]/),r=n.pop()||``,i=r.lastIndexOf(`.`),a=i===-1?r:r.slice(0,i);return a.toLowerCase()===`index`&&(a=n.pop()||a),`${t}${a.replace(/([a-z])([A-Z])/g,`$1-$2`).replace(/[\s_]+/g,`-`).toLowerCase()}`},r=(r,i)=>{let a=e(i);return a?t(a):n(r,``)};export{r as extractDictionaryKey,n as extractDictionaryKeyFromPath};
1
+ import{DefaultValues as e}from"@intlayer/config/node";import{camelCaseToKebabCase as t}from"@intlayer/config/utils";import{detectExportedComponentName as n}from"@intlayer/chokidar/cli";const r=(t,n=e.Compiler.COMPILER_DICTIONARY_KEY_PREFIX)=>{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.Compiler.COMPILER_DICTIONARY_KEY_PREFIX)=>{let s=n(a);return s?`${o}${t(s)}`:r(i,o)};export{i as extractDictionaryKey,r as extractDictionaryKeyFromPath};
2
2
  //# 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 { 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 = 'comp-'\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): string => {\n const componentName = detectExportedComponentName(fileText);\n\n if (componentName) {\n return camelCaseToKebabCase(componentName);\n }\n\n return extractDictionaryKeyFromPath(filePath, '');\n};\n"],"mappings":"mIAQA,MAAa,GACX,EACA,EAAS,UACE,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,IACW,CACX,IAAM,EAAgB,EAA4B,EAAS,CAM3D,OAJI,EACK,EAAqB,EAAc,CAGrC,EAA6B,EAAU,GAAG"}
1
+ {"version":3,"file":"extractDictionaryKey.mjs","names":[],"sources":["../../../../src/extractContent/utils/extractDictionaryKey.ts"],"sourcesContent":["import { detectExportedComponentName } from '@intlayer/chokidar/cli';\nimport { DefaultValues } from '@intlayer/config/node';\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 = DefaultValues.Compiler.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 = DefaultValues.Compiler.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":"yLASA,MAAa,GACX,EACA,EAAS,EAAc,SAAS,iCACrB,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,EAAc,SAAS,iCACrB,CACX,IAAM,EAAgB,EAA4B,EAAS,CAM3D,OAJI,EACK,GAAG,IAAS,EAAqB,EAAc,GAGjD,EAA6B,EAAU,EAAO"}
@@ -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 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,CAG3C,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":"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 +1 @@
1
- import{ATTRIBUTES_TO_EXTRACT as e,packageList as t}from"./constants.mjs";import{detectPackageName as n}from"./detectPackageName.mjs";import{extractDictionaryKey as r,extractDictionaryKeyFromPath as i}from"./extractDictionaryKey.mjs";import{generateKey as a}from"./generateKey.mjs";import{getComponentName as o}from"./getComponentName.mjs";import{getExistingIntlayerInfo as s}from"./getExistingIntlayerInfo.mjs";import{getOrGenerateKey as c}from"./getOrGenerateKey.mjs";import{resolveDictionaryKey as l}from"./resolveDictionaryKey.mjs";import{shouldExtract as u}from"./shouldExtract.mjs";export{e as ATTRIBUTES_TO_EXTRACT,n as detectPackageName,r as extractDictionaryKey,i as extractDictionaryKeyFromPath,a as generateKey,o as getComponentName,s as getExistingIntlayerInfo,c as getOrGenerateKey,t as packageList,l as resolveDictionaryKey,u as shouldExtract};
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,2 +1,2 @@
1
- import{dirname as e,join as t}from"node:path";import{existsSync as n}from"node:fs";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=e(a),f=u[0],p=f.startsWith(`.`)?f:`.${f}`,m=0;for(;m<100;){let e=m===0?i:`${i}${m}`,r=l[e],a=t(d,`${e}${p}`),o=c.has(e),s=r&&r.length>0,u=n(a);if(!o&&!s&&!u)return e;m++}return i};export{i as resolveDictionaryKey};
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};
2
2
  //# sourceMappingURL=resolveDictionaryKey.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolveDictionaryKey.mjs","names":[],"sources":["../../../../src/extractContent/utils/resolveDictionaryKey.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { Dictionary, IntlayerConfig } from '@intlayer/types';\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];\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 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":"mKAUA,MAAa,GACX,EACA,EACA,EACA,EACA,EAAwB,IAAI,MACjB,CACX,IAAM,EACJ,GAAwB,EAAwB,EAAc,EAAI,EAAE,CAEhE,CAAE,kBAAmB,EAAc,QAEnC,EAAU,EAAQ,EAAS,CAC3B,EAAiB,EAAe,GAChC,EAAY,EAAe,WAAW,IAAI,CAC5C,EACA,IAAI,IAEJ,EAAQ,EAEZ,KAAO,EAAQ,KAAK,CAClB,IAAM,EAAY,IAAU,EAAI,EAAa,GAAG,IAAa,IACvD,EAAe,EAAM,GACrB,EAAkB,EAAK,EAAS,GAAG,IAAY,IAAY,CAC3D,EAAY,EAAS,IAAI,EAAU,CACnC,EAAkB,GAAgB,EAAa,OAAS,EACxD,EAAa,EAAW,EAAgB,CAE9C,GAAI,CAAC,GAAa,CAAC,GAAmB,CAAC,EACrC,OAAO,EAET,IAGF,OAAO"}
1
+ {"version":3,"file":"resolveDictionaryKey.mjs","names":[],"sources":["../../../../src/extractContent/utils/resolveDictionaryKey.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { IntlayerConfig } from '@intlayer/types/config';\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];\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 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":"mKAWA,MAAa,GACX,EACA,EACA,EACA,EACA,EAAwB,IAAI,MACjB,CACX,IAAM,EACJ,GAAwB,EAAwB,EAAc,EAAI,EAAE,CAEhE,CAAE,kBAAmB,EAAc,QAEnC,EAAU,EAAQ,EAAS,CAC3B,EAAiB,EAAe,GAChC,EAAY,EAAe,WAAW,IAAI,CAC5C,EACA,IAAI,IAEJ,EAAQ,EAEZ,KAAO,EAAQ,KAAK,CAClB,IAAM,EAAY,IAAU,EAAI,EAAa,GAAG,IAAa,IACvD,EAAe,EAAM,GACrB,EAAkB,EAAK,EAAS,GAAG,IAAY,IAAY,CAC3D,EAAY,EAAS,IAAI,EAAU,CACnC,EAAkB,GAAgB,EAAa,OAAS,EACxD,EAAa,EAAW,EAAgB,CAE9C,GAAI,CAAC,GAAa,CAAC,GAAmB,CAAC,EACrC,OAAO,EAET,IAGF,OAAO"}
@@ -1,2 +1,2 @@
1
- import{__require as e}from"./_virtual/_rolldown/runtime.mjs";import{join as t,relative as n}from"node:path";import{ANSIColors as r,colorize as i,getAppLogger as a}from"@intlayer/config/logger";import{getConfiguration as o}from"@intlayer/config/node";import{existsSync as s}from"node:fs";import{readFile as c}from"node:fs/promises";import{buildDictionary as l,writeContentDeclaration as u}from"@intlayer/chokidar/build";const d=(d=process.env.INTLAYER_IS_DEV_COMMAND)=>{let f=o(),{baseDir:p}=f.content,m=t(p,f.compiler?.outputDir??`compiler`),h=async e=>{try{if(!s(e))return null;let t=await c(e,`utf-8`);if(!t||t.trim()===``)return null;let n=JSON.parse(t);return Array.isArray(n)?n[0]??null:n}catch(t){return s(e)&&(await c(e,`utf-8`)).trim()!==``&&console.warn(`[intlayer] Warning: Failed to read existing dictionary at ${e}. It might be corrupt. Translations may be lost. Error:`,t),null}},g=(e,t,n)=>{let r={},i=t?.content,a=Object.keys(e).sort();for(let t of a){let a=e[t],o=i?.[t];o&&o.nodeType===`translation`&&o.translation?r[t]={...o,nodeType:`translation`,translation:{...o.translation,[n]:o.translation[n]??a}}:r[t]={nodeType:`translation`,translation:{[n]:a}}}return r},_=async r=>{let{dictionaryKey:i,content:a,locale:o}=r;try{let e=await h(t(m,`${i}.content.json`)),r=g(a,e,o),s={...e,key:i,content:r,filePath:t(n(p,m),`${i}.content.json`)},c=await u(s,f,{newDictionariesPath:n(p,m)});await l([{...s,filePath:n(p,c.path)}],f)}catch(t){if(console.error(`[intlayer] Failed to process extracted content for ${i}:`,t),t instanceof SyntaxError&&t.message.includes(`Unexpected end of JSON input`)){let n=t.message.match(/^(.*\.json):\s*Unexpected end of JSON input/);if(n){let t=n[1];try{let n=e(`fs`).readFileSync(t,`utf-8`);console.error(`[intlayer] Content of the corrupted file (${t}):\n"${n}"`)}catch(e){console.error(`[intlayer] Could not read corrupted file ${t}`,e)}}}}},v=String(d)===`true`,y=f.compiler?.enabled===`build-only`?!v:f.compiler?.enabled??!0,b=a(f);return f.compiler?.enabled===`build-only`&&v&&b(`${i(`Compiler:`,r.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)`),{enabled:y,defaultLocale:f.internationalization.defaultLocale,prefix:f.compiler?.dictionaryKeyPrefix,saveComponents:f.compiler?.saveComponents,onExtract:_}};export{d as getExtractPluginOptions};
1
+ import{writeContentHelper as e}from"./extractContent/contentWriter.mjs";import{buildFilesList as t}from"@intlayer/chokidar/utils";import{ANSIColors as n,colorize as r,colorizeKey as i,getAppLogger as a}from"@intlayer/config/logger";import{DefaultValues as o,getConfiguration as s}from"@intlayer/config/node";const c=(c=s(),l=process.env.INTLAYER_IS_DEV_COMMAND)=>{let u=String(l)===`true`,d=u?`dev`:`build`,f=a(c);c.compiler?.enabled===`build-only`&&u&&f(`${r(`Compiler:`,n.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)`);let p=c.compiler?.enabled??o.Compiler.COMPILER_ENABLED;p===`build-only`&&(p=d?d===`build`:!0);let m=t({transformPattern:c.build.traversePattern??c.compiler?.transformPattern,excludePattern:[...c.content.fileExtensions.map(e=>`**/*${e}`),...Array.isArray(c.compiler.excludePattern)?c.compiler.excludePattern:[c.compiler.excludePattern]],baseDir:c.system.baseDir});return{enabled:p,configuration:c,filesList:m,onExtract:async({dictionaryKey:t,content:n,filePath:r})=>{try{await e(n,t,r,c)}catch(e){f([`Failed to process extracted content for ${i(t)}:`,e],{level:`error`})}}}};export{c as getExtractPluginOptions};
2
2
  //# sourceMappingURL=getExtractPluginOptions.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"getExtractPluginOptions.mjs","names":[],"sources":["../../src/getExtractPluginOptions.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport {\n buildDictionary,\n writeContentDeclaration,\n} from '@intlayer/chokidar/build';\nimport { ANSIColors, colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport type { Dictionary } from '@intlayer/types';\nimport type {\n ExtractPluginOptions,\n ExtractResult,\n} from './babel-plugin-intlayer-extract';\n\n/**\n * Translation node structure used in dictionaries\n */\ntype TranslationNode = {\n nodeType: 'translation';\n translation: Record<string, string>;\n};\n\n/**\n * Dictionary content structure - map of keys to translation nodes\n */\ntype DictionaryContentMap = Record<string, TranslationNode>;\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 isDev = process.env.INTLAYER_IS_DEV_COMMAND\n): ExtractPluginOptions => {\n const config = getConfiguration();\n const { baseDir } = config.content;\n\n const compilerDir = join(baseDir, config.compiler?.outputDir ?? 'compiler');\n\n /**\n * Read existing dictionary file if it exists\n */\n const readExistingDictionary = async (\n dictionaryPath: string\n ): Promise<Dictionary | null> => {\n try {\n if (!existsSync(dictionaryPath)) {\n return null;\n }\n const content = await readFile(dictionaryPath, 'utf-8');\n\n if (!content || content.trim() === '') {\n return null;\n }\n\n const parsed = JSON.parse(content);\n\n if (Array.isArray(parsed)) {\n return (parsed[0] ?? null) as Dictionary | null;\n }\n\n return parsed as Dictionary;\n } catch (error) {\n if (existsSync(dictionaryPath)) {\n const content = await readFile(dictionaryPath, 'utf-8');\n\n if (content.trim() !== '') {\n console.warn(\n `[intlayer] Warning: Failed to read existing dictionary at ${dictionaryPath}. It might be corrupt. Translations may be lost. Error:`,\n error\n );\n }\n }\n return null;\n }\n };\n\n /**\n * Merge extracted content with existing dictionary, preserving translations.\n * - Keys in extracted but not in existing: added with default locale only\n * - Keys in both: preserve existing translations, update default locale value\n * - Keys in existing but not in extracted: removed (no longer in source)\n */\n const mergeWithExistingDictionary = (\n extractedContent: Record<string, string>,\n existingDictionary: Dictionary | null,\n defaultLocale: string\n ): DictionaryContentMap => {\n const mergedContent: DictionaryContentMap = {};\n const existingContent = existingDictionary?.content as\n | DictionaryContentMap\n | undefined;\n\n const sortedKeys = Object.keys(extractedContent).sort();\n\n for (const key of sortedKeys) {\n const value = extractedContent[key];\n const existingEntry = existingContent?.[key];\n\n if (\n existingEntry &&\n existingEntry.nodeType === 'translation' &&\n existingEntry.translation\n ) {\n // Key exists in both - preserve existing translations AND existing metadata\n mergedContent[key] = {\n ...existingEntry,\n nodeType: 'translation',\n translation: {\n ...existingEntry.translation,\n [defaultLocale]: existingEntry.translation[defaultLocale] ?? value,\n },\n };\n } else {\n // New key - add with default locale only\n mergedContent[key] = {\n nodeType: 'translation',\n translation: {\n [defaultLocale]: value,\n },\n };\n }\n }\n\n return mergedContent;\n };\n\n const handleExtractedContent = async (result: ExtractResult) => {\n const { dictionaryKey, content, locale } = result;\n\n try {\n const dictionaryPath = join(compilerDir, `${dictionaryKey}.content.json`);\n\n // Read existing dictionary to preserve translations\n const existingDictionary = await readExistingDictionary(dictionaryPath);\n\n // Merge extracted content with existing translations\n const mergedContent = mergeWithExistingDictionary(\n content,\n existingDictionary,\n locale\n );\n\n const dictionary: Dictionary = {\n ...existingDictionary,\n key: dictionaryKey,\n content: mergedContent,\n filePath: join(\n relative(baseDir, compilerDir),\n `${dictionaryKey}.content.json`\n ),\n };\n\n const writeResult = await writeContentDeclaration(dictionary, config, {\n newDictionariesPath: relative(baseDir, compilerDir),\n });\n\n // Build the dictionary immediately\n const dictionaryToBuild: Dictionary = {\n ...dictionary,\n filePath: relative(baseDir, writeResult.path),\n };\n\n await buildDictionary([dictionaryToBuild], config);\n } catch (error: any) {\n console.error(\n `[intlayer] Failed to process extracted content for ${dictionaryKey}:`,\n error\n );\n if (\n error instanceof SyntaxError &&\n error.message.includes('Unexpected end of JSON input')\n ) {\n const match = error.message.match(\n /^(.*\\.json):\\s*Unexpected end of JSON input/\n );\n if (match) {\n const filePath = match[1];\n try {\n const fs = require('fs');\n const fileContent = fs.readFileSync(filePath, 'utf-8');\n console.error(\n `[intlayer] Content of the corrupted file (${filePath}):\\n\"${fileContent}\"`\n );\n } catch (e) {\n console.error(\n `[intlayer] Could not read corrupted file ${filePath}`,\n e\n );\n }\n }\n }\n }\n };\n\n const isDevBoolean = String(isDev) === 'true';\n const isEnabled =\n config.compiler?.enabled === 'build-only'\n ? !isDevBoolean\n : (config.compiler?.enabled ?? true);\n\n const logger = getAppLogger(config);\n\n if (config.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 return {\n enabled: isEnabled,\n defaultLocale: config.internationalization.defaultLocale,\n prefix: config.compiler?.dictionaryKeyPrefix,\n saveComponents: config.compiler?.saveComponents,\n // filesList can be passed if needed, but usually handled by include/exclude in build tool\n onExtract: handleExtractedContent,\n };\n};\n"],"mappings":"maAiCA,MAAa,GACX,EAAQ,QAAQ,IAAI,0BACK,CACzB,IAAM,EAAS,GAAkB,CAC3B,CAAE,WAAY,EAAO,QAErB,EAAc,EAAK,EAAS,EAAO,UAAU,WAAa,WAAW,CAKrE,EAAyB,KAC7B,IAC+B,CAC/B,GAAI,CACF,GAAI,CAAC,EAAW,EAAe,CAC7B,OAAO,KAET,IAAM,EAAU,MAAM,EAAS,EAAgB,QAAQ,CAEvD,GAAI,CAAC,GAAW,EAAQ,MAAM,GAAK,GACjC,OAAO,KAGT,IAAM,EAAS,KAAK,MAAM,EAAQ,CAMlC,OAJI,MAAM,QAAQ,EAAO,CACf,EAAO,IAAM,KAGhB,QACA,EAAO,CAWd,OAVI,EAAW,EAAe,GACZ,MAAM,EAAS,EAAgB,QAAQ,EAE3C,MAAM,GAAK,IACrB,QAAQ,KACN,6DAA6D,EAAe,yDAC5E,EACD,CAGE,OAUL,GACJ,EACA,EACA,IACyB,CACzB,IAAM,EAAsC,EAAE,CACxC,EAAkB,GAAoB,QAItC,EAAa,OAAO,KAAK,EAAiB,CAAC,MAAM,CAEvD,IAAK,IAAM,KAAO,EAAY,CAC5B,IAAM,EAAQ,EAAiB,GACzB,EAAgB,IAAkB,GAGtC,GACA,EAAc,WAAa,eAC3B,EAAc,YAGd,EAAc,GAAO,CACnB,GAAG,EACH,SAAU,cACV,YAAa,CACX,GAAG,EAAc,aAChB,GAAgB,EAAc,YAAY,IAAkB,EAC9D,CACF,CAGD,EAAc,GAAO,CACnB,SAAU,cACV,YAAa,EACV,GAAgB,EAClB,CACF,CAIL,OAAO,GAGH,EAAyB,KAAO,IAA0B,CAC9D,GAAM,CAAE,gBAAe,UAAS,UAAW,EAE3C,GAAI,CAIF,IAAM,EAAqB,MAAM,EAHV,EAAK,EAAa,GAAG,EAAc,eAAe,CAGF,CAGjE,EAAgB,EACpB,EACA,EACA,EACD,CAEK,EAAyB,CAC7B,GAAG,EACH,IAAK,EACL,QAAS,EACT,SAAU,EACR,EAAS,EAAS,EAAY,CAC9B,GAAG,EAAc,eAClB,CACF,CAEK,EAAc,MAAM,EAAwB,EAAY,EAAQ,CACpE,oBAAqB,EAAS,EAAS,EAAY,CACpD,CAAC,CAQF,MAAM,EAAgB,CALgB,CACpC,GAAG,EACH,SAAU,EAAS,EAAS,EAAY,KAAK,CAC9C,CAEwC,CAAE,EAAO,OAC3C,EAAY,CAKnB,GAJA,QAAQ,MACN,sDAAsD,EAAc,GACpE,EACD,CAEC,aAAiB,aACjB,EAAM,QAAQ,SAAS,+BAA+B,CACtD,CACA,IAAM,EAAQ,EAAM,QAAQ,MAC1B,8CACD,CACD,GAAI,EAAO,CACT,IAAM,EAAW,EAAM,GACvB,GAAI,CAEF,IAAM,EAAA,EADa,KAAK,CACD,aAAa,EAAU,QAAQ,CACtD,QAAQ,MACN,6CAA6C,EAAS,OAAO,EAAY,GAC1E,OACM,EAAG,CACV,QAAQ,MACN,4CAA4C,IAC5C,EACD,MAOL,EAAe,OAAO,EAAM,GAAK,OACjC,EACJ,EAAO,UAAU,UAAY,aACzB,CAAC,EACA,EAAO,UAAU,SAAW,GAE7B,EAAS,EAAa,EAAO,CAQnC,OANI,EAAO,UAAU,UAAY,cAAgB,GAC/C,EACE,GAAG,EAAS,YAAa,EAAW,UAAU,CAAC,wIAChD,CAGI,CACL,QAAS,EACT,cAAe,EAAO,qBAAqB,cAC3C,OAAQ,EAAO,UAAU,oBACzB,eAAgB,EAAO,UAAU,eAEjC,UAAW,EACZ"}
1
+ {"version":3,"file":"getExtractPluginOptions.mjs","names":[],"sources":["../../src/getExtractPluginOptions.ts"],"sourcesContent":["import { buildFilesList } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizeKey,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport { DefaultValues, getConfiguration } from '@intlayer/config/node';\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 = process.env.INTLAYER_IS_DEV_COMMAND\n): ExtractPluginOptions => {\n const isDevBoolean = String(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 =\n configuration.compiler?.enabled ?? DefaultValues.Compiler.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 transformPattern =\n configuration.build.traversePattern ??\n configuration.compiler?.transformPattern;\n\n const excludePattern = [\n // Ensure extensions are treated as glob patterns (e.g., **/*.ts)\n ...configuration.content.fileExtensions.map((ext) => `**/*${ext}`),\n\n ...(Array.isArray(configuration.compiler.excludePattern)\n ? configuration.compiler.excludePattern\n : [configuration.compiler.excludePattern]),\n ] as string[];\n\n const filesList = buildFilesList({\n transformPattern,\n excludePattern,\n baseDir: configuration.system.baseDir,\n });\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":"oTAwBA,MAAa,GACX,EAAgC,GAAkB,CAClD,EAAQ,QAAQ,IAAI,0BACK,CACzB,IAAM,EAAe,OAAO,EAAM,GAAK,OAEjC,EAA6B,EAAe,MAAQ,QAEpD,EAAS,EAAa,EAAc,CAEtC,EAAc,UAAU,UAAY,cAAgB,GACtD,EACE,GAAG,EAAS,YAAa,EAAW,UAAU,CAAC,wIAChD,CAGH,IAAI,EACF,EAAc,UAAU,SAAW,EAAc,SAAS,iBAExD,IAAY,eACd,AAIE,EAJE,EACQ,IAAiB,QAGjB,IAiBd,IAAM,EAAY,EAAe,CAC/B,iBAbA,EAAc,MAAM,iBACpB,EAAc,UAAU,iBAaxB,eAXqB,CAErB,GAAG,EAAc,QAAQ,eAAe,IAAK,GAAQ,OAAO,IAAM,CAElE,GAAI,MAAM,QAAQ,EAAc,SAAS,eAAe,CACpD,EAAc,SAAS,eACvB,CAAC,EAAc,SAAS,eAAe,CAC5C,CAKC,QAAS,EAAc,OAAO,QAC/B,CAAC,CAEF,MAAO,CACL,UACA,gBACA,YACA,UAAW,MAAO,CAAE,gBAAe,UAAS,cAAe,CACzD,GAAI,CACF,MAAM,EACJ,EACA,EACA,EACA,EACD,OACM,EAAO,CACd,EACE,CACE,2CAA2C,EAAY,EAAc,CAAC,GACtE,EACD,CACD,CAAE,MAAO,QAAS,CACnB,GAGN"}
@@ -1,2 +1,2 @@
1
- import{__require as e}from"./_virtual/_rolldown/runtime.mjs";import{join as t}from"node:path";import{getConfiguration as n}from"@intlayer/config/node";import{getComponentTransformPatternSync as r}from"@intlayer/chokidar/utils";const i=t=>{try{let{getDictionaries:n}=e(`@intlayer/dictionaries-entry`),r=n(t);return Object.values(r)}catch{return[]}},a=e=>{let{configOptions:a,dictionaries:o,overrides:s}=e??{},c=n(a),{mainDir:l,dictionariesDir:u,unmergedDictionariesDir:d,dynamicDictionariesDir:f,fetchDictionariesDir:p}=c.system,{importMode:m,optimize:h}=c.build,g=r(c),_=t(l,`dictionaries.mjs`),v=t(l,`unmerged_dictionaries.mjs`),y=t(l,`dynamic_dictionaries.mjs`),b=t(l,`fetch_dictionaries.mjs`),x=[...g,_,v],S=o??i(c),C={};return S.forEach(e=>{C[e.key]=e.importMode??m}),{optimize:h,dictionariesDir:u,dictionariesEntryPath:_,unmergedDictionariesDir:d,unmergedDictionariesEntryPath:v,dynamicDictionariesDir:f,dynamicDictionariesEntryPath:y,fetchDictionariesDir:p,fetchDictionariesEntryPath:b,replaceDictionaryEntry:!0,importMode:m,dictionaryModeMap:C,filesList:x,...s}};export{a as getOptimizePluginOptions};
1
+ import{__require as e}from"./_virtual/_rolldown/runtime.mjs";import{getComponentTransformPatternSync as t}from"@intlayer/chokidar/utils";import{getConfiguration as n}from"@intlayer/config/node";import{join as r}from"node:path";const i=t=>{try{let{getDictionaries:n}=e(`@intlayer/dictionaries-entry`),r=n(t);return Object.values(r)}catch{return[]}},a=e=>{let{configOptions:a,dictionaries:o,overrides:s}=e??{},c=n(a),{mainDir:l,dictionariesDir:u,unmergedDictionariesDir:d,dynamicDictionariesDir:f,fetchDictionariesDir:p}=c.system,{importMode:m,optimize:h}=c.build,g=t(c),_=r(l,`dictionaries.mjs`),v=r(l,`unmerged_dictionaries.mjs`),y=r(l,`dynamic_dictionaries.mjs`),b=r(l,`fetch_dictionaries.mjs`),x=[...g,_,v],S=o??i(c),C={};return S.forEach(e=>{C[e.key]=e.importMode??m}),{optimize:h,dictionariesDir:u,dictionariesEntryPath:_,unmergedDictionariesDir:d,unmergedDictionariesEntryPath:v,dynamicDictionariesDir:f,dynamicDictionariesEntryPath:y,fetchDictionariesDir:p,fetchDictionariesEntryPath:b,replaceDictionaryEntry:!0,importMode:m,dictionaryModeMap:C,filesList:x,...s}};export{a as getOptimizePluginOptions};
2
2
  //# sourceMappingURL=getOptimizePluginOptions.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"getOptimizePluginOptions.mjs","names":[],"sources":["../../src/getOptimizePluginOptions.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { getComponentTransformPatternSync } from '@intlayer/chokidar/utils';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { Dictionary, IntlayerConfig } from '@intlayer/types';\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 * 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) as Record<\n string,\n Dictionary\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 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, optimize } = config.build;\n\n // Build files list from traverse pattern\n const filesListPattern = getComponentTransformPatternSync(config);\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 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 ...overrides,\n };\n};\n"],"mappings":"mOA2BA,MAAM,EAAoB,GAAyC,CACjE,GAAI,CAGF,GAAM,CAAE,mBAAA,EAA4B,+BAA+B,CAC7D,EAAqB,EAAgB,EAAO,CAIlD,OAAO,OAAO,OAAO,EAAmB,MAClC,CAEN,MAAO,EAAE,GASA,EACX,GAC0B,CAC1B,GAAM,CACJ,gBACA,aAAc,EACd,aACE,GAAU,EAAE,CAEV,EAAS,EAAiB,EAAc,CACxC,CACJ,UACA,kBACA,0BACA,yBACA,wBACE,EAAO,OACL,CAAE,aAAY,YAAa,EAAO,MAGlC,EAAmB,EAAiC,EAAO,CAE3D,EAAwB,EAAK,EAAS,mBAAmB,CACzD,EAAgC,EACpC,EACA,4BACD,CACK,EAA+B,EACnC,EACA,2BACD,CACK,EAA6B,EAAK,EAAS,yBAAyB,CAEpE,EAAY,CAChB,GAAG,EACH,EACA,EACD,CAGK,EAAe,GAAwB,EAAiB,EAAO,CAE/D,EAGF,EAAE,CAMN,OAJA,EAAa,QAAS,GAAe,CACnC,EAAkB,EAAW,KAAO,EAAW,YAAc,GAC7D,CAEK,CACL,WACA,kBACA,wBACA,0BACA,gCACA,yBACA,+BACA,uBACA,6BACA,uBAAwB,GACxB,aACA,oBACA,YACA,GAAG,EACJ"}
1
+ {"version":3,"file":"getOptimizePluginOptions.mjs","names":[],"sources":["../../src/getOptimizePluginOptions.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { getComponentTransformPatternSync } from '@intlayer/chokidar/utils';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { IntlayerConfig } from '@intlayer/types/config';\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 * 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) as Record<\n string,\n Dictionary\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 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, optimize } = config.build;\n\n // Build files list from traverse pattern\n const filesListPattern = getComponentTransformPatternSync(config);\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 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 ...overrides,\n };\n};\n"],"mappings":"mOA4BA,MAAM,EAAoB,GAAyC,CACjE,GAAI,CAGF,GAAM,CAAE,mBAAA,EAA4B,+BAA+B,CAC7D,EAAqB,EAAgB,EAAO,CAIlD,OAAO,OAAO,OAAO,EAAmB,MAClC,CAEN,MAAO,EAAE,GASA,EACX,GAC0B,CAC1B,GAAM,CACJ,gBACA,aAAc,EACd,aACE,GAAU,EAAE,CAEV,EAAS,EAAiB,EAAc,CACxC,CACJ,UACA,kBACA,0BACA,yBACA,wBACE,EAAO,OACL,CAAE,aAAY,YAAa,EAAO,MAGlC,EAAmB,EAAiC,EAAO,CAE3D,EAAwB,EAAK,EAAS,mBAAmB,CACzD,EAAgC,EACpC,EACA,4BACD,CACK,EAA+B,EACnC,EACA,2BACD,CACK,EAA6B,EAAK,EAAS,yBAAyB,CAEpE,EAAY,CAChB,GAAG,EACH,EACA,EACD,CAGK,EAAe,GAAwB,EAAiB,EAAO,CAE/D,EAGF,EAAE,CAMN,OAJA,EAAa,QAAS,GAAe,CACnC,EAAkB,EAAW,KAAO,EAAW,YAAc,GAC7D,CAEK,CACL,WACA,kBACA,wBACA,0BACA,gCACA,yBACA,+BACA,uBACA,6BACA,uBAAwB,GACxB,aACA,oBACA,YACA,GAAG,EACJ"}
@@ -1 +1 @@
1
- import{ATTRIBUTES_TO_EXTRACT as e,packageList as t}from"./extractContent/utils/constants.mjs";import{detectPackageName as n}from"./extractContent/utils/detectPackageName.mjs";import{intlayerExtractBabelPlugin as r}from"./babel-plugin-intlayer-extract.mjs";import{intlayerOptimizeBabelPlugin as i}from"./babel-plugin-intlayer-optimize.mjs";import{getExtractPluginOptions as a}from"./getExtractPluginOptions.mjs";import{getOptimizePluginOptions as o}from"./getOptimizePluginOptions.mjs";import{extractContent as s}from"./extractContent/extractContent.mjs";export{e as ATTRIBUTES_TO_EXTRACT,n as detectPackageName,s as extractContent,a as getExtractPluginOptions,o as getOptimizePluginOptions,r as intlayerExtractBabelPlugin,i as intlayerOptimizeBabelPlugin,t as packageList};
1
+ import{extractDictionaryKey as e,extractDictionaryKeyFromPath as t}from"./extractContent/utils/extractDictionaryKey.mjs";import{extractDictionaryInfo as n,getOutput as r,resolveContentFilePaths as i}from"./extractContent/utils/extractDictionaryInfo.mjs";import{mergeWithExistingMultilingualDictionary as a,mergeWithExistingPerLocaleDictionary as o,writeContentHelper as s}from"./extractContent/contentWriter.mjs";import{getExtractPluginOptions as c}from"./getExtractPluginOptions.mjs";import{ATTRIBUTES_TO_EXTRACT as l,SERVER_CAPABLE_PACKAGES as u,packageList as d}from"./extractContent/utils/constants.mjs";import{detectPackageName as f}from"./extractContent/utils/detectPackageName.mjs";import{generateKey as p}from"./extractContent/utils/generateKey.mjs";import{getComponentName as m}from"./extractContent/utils/getComponentName.mjs";import{extractContent as h,extractContentSync as g}from"./extractContent/extractContent.mjs";import{intlayerExtractBabelPlugin as _}from"./babel-plugin-intlayer-extract.mjs";import{getOptimizePluginOptions as v}from"./getOptimizePluginOptions.mjs";import{intlayerOptimizeBabelPlugin as y}from"./babel-plugin-intlayer-optimize.mjs";export{l as ATTRIBUTES_TO_EXTRACT,u as SERVER_CAPABLE_PACKAGES,f as detectPackageName,h as extractContent,g as extractContentSync,n as extractDictionaryInfo,e as extractDictionaryKey,t as extractDictionaryKeyFromPath,p as generateKey,m as getComponentName,c as getExtractPluginOptions,v as getOptimizePluginOptions,r as getOutput,_ as intlayerExtractBabelPlugin,y as intlayerOptimizeBabelPlugin,a as mergeWithExistingMultilingualDictionary,o as mergeWithExistingPerLocaleDictionary,d as packageList,i as resolveContentFilePaths,s as writeContentHelper};
@@ -1,28 +1,33 @@
1
+ import { PackageName } from "./extractContent/utils/constants.js";
1
2
  import { PluginObj, PluginPass } from "@babel/core";
2
3
  import * as BabelTypes from "@babel/types";
4
+ import { Locale } from "@intlayer/types/allLocales";
5
+ import { IntlayerConfig } from "@intlayer/types/config";
6
+ import { FilePathPattern } from "@intlayer/types/filePathPattern";
3
7
 
4
8
  //#region src/babel-plugin-intlayer-extract.d.ts
5
9
  type ExtractResult = {
6
10
  dictionaryKey: string;
7
11
  filePath: string;
8
12
  content: Record<string, string>;
9
- locale: string;
13
+ locale: Locale;
10
14
  };
11
15
  type ExtractPluginOptions = {
12
- defaultLocale?: string;
13
- packageName?: string;
14
- filesList?: string[];
16
+ packageName?: PackageName;
17
+ filesList: string[];
18
+ enabled: boolean;
15
19
  shouldExtract?: (text: string) => boolean;
16
- enabled?: boolean;
17
- prefix?: string;
18
- saveComponents?: boolean;
19
- formatCommand?: string;
20
+ configuration: IntlayerConfig;
20
21
  /**
21
22
  * Callback invoked for each extracted dictionary key/content pair.
22
23
  * Used by `getExtractPluginOptions` to write dictionaries to disk.
23
24
  * May be async — the plugin will fire-and-forget (Babel transforms are sync).
24
25
  */
25
26
  onExtract?: (result: ExtractResult) => void | Promise<void>;
27
+ /**
28
+ * Defines the output files path.
29
+ */
30
+ output?: FilePathPattern;
26
31
  };
27
32
  type State = PluginPass & {
28
33
  opts: ExtractPluginOptions;
@@ -44,7 +49,7 @@ type State = PluginPass & {
44
49
  * };
45
50
  * ```
46
51
  */
47
- declare const intlayerExtractBabelPlugin: (babel: {
52
+ declare const intlayerExtractBabelPlugin: (_babel: {
48
53
  types: typeof BabelTypes;
49
54
  }) => PluginObj<State>;
50
55
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"babel-plugin-intlayer-extract.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-extract.ts"],"mappings":";;;;KAmBY,aAAA;EACV,aAAA;EACA,QAAA;EACA,OAAA,EAAS,MAAA;EACT,MAAA;AAAA;AAAA,KAGU,oBAAA;EACV,aAAA;EACA,WAAA;EACA,SAAA;EACA,aAAA,IAAiB,IAAA;EACjB,OAAA;EACA,MAAA;EACA,cAAA;EACA,aAAA;;;;;;EAMA,SAAA,IAAa,MAAA,EAAQ,aAAA,YAAyB,OAAA;AAAA;AAAA,KAG3C,KAAA,GAAQ,UAAA;EAAe,IAAA,EAAM,oBAAA;AAAA;;;;;;;;AAFhC;;;;;;;;;AAqBF;cAAa,0BAAA,GAA8B,KAAA;EACzC,KAAA,SAAc,UAAA;AAAA,MACZ,SAAA,CAAU,KAAA"}
1
+ {"version":3,"file":"babel-plugin-intlayer-extract.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-extract.ts"],"mappings":";;;;;;;;KAiBY,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,SAAA,CAAU,KAAA"}
@@ -1,6 +1,6 @@
1
1
  import * as t from "@babel/types";
2
+ import { IntlayerConfig } from "@intlayer/types/config";
2
3
  import { NodePath } from "@babel/traverse";
3
- import { IntlayerConfig } from "@intlayer/types";
4
4
 
5
5
  //#region src/extractContent/babelProcessor.d.ts
6
6
  type BabelReplacement = {
@@ -1,27 +1,36 @@
1
- import { Dictionary, IntlayerConfig } from "@intlayer/types";
1
+ import { IntlayerConfig } from "@intlayer/types/config";
2
+ import { Dictionary, DictionaryKey } from "@intlayer/types/dictionary";
2
3
 
3
4
  //#region src/extractContent/contentWriter.d.ts
5
+ /**
6
+ * Translation node structure used in dictionaries
7
+ */
4
8
  type TranslationNode = {
5
9
  nodeType: 'translation';
6
10
  translation: Record<string, string>;
7
11
  };
8
12
  /**
9
- * Resolves the path for the content file associated with a component.
10
- * Checks for existing dictionaries first.
13
+ * Dictionary content structure - map of keys to translation nodes
11
14
  */
12
- declare const resolveContentFilePath: (filePath: string, componentKey: string, configuration: IntlayerConfig, outputDir?: string) => {
13
- contentFilePath: string;
14
- relativeContentFilePath: string;
15
- };
15
+ type DictionaryContentMap = Record<string, TranslationNode>;
16
+ /**
17
+ * Merge extracted content with existing dictionary for multilingual format.
18
+ * - Keys in extracted but not in existing: added with default locale only
19
+ * - Keys in both: preserve existing translations, update default locale value
20
+ * - Keys in existing but not in extracted: removed (no longer in source)
21
+ */
22
+ declare const mergeWithExistingMultilingualDictionary: (extractedContent: Record<string, string>, existingDictionary: Dictionary | null, defaultLocale: string) => DictionaryContentMap;
16
23
  /**
17
- * Creates a dictionary object from extracted content.
18
- * Handles both single-locale and multi-locale formats based on configuration.
24
+ * Merge extracted content with existing dictionary for per-locale format.
25
+ * - Keys in extracted but not in existing: added
26
+ * - Keys in both: update value
27
+ * - Keys in existing but not in extracted: removed (no longer in source)
19
28
  */
20
- declare const createDictionary: (extractedContent: Record<string, string>, componentKey: string, relativeContentFilePath: string, configuration: IntlayerConfig) => Dictionary;
29
+ declare const mergeWithExistingPerLocaleDictionary: (extractedContent: Record<string, string>, existingDictionary: Dictionary | null) => Record<string, string>;
21
30
  /**
22
- * Helper to write extracted content to a dictionary file.
31
+ * Helper to write extracted content to dictionary file(s).
23
32
  */
24
- declare const writeContentHelper: (extractedContent: Record<string, string>, componentKey: string, filePath: string, configuration: IntlayerConfig, outputDir?: string) => Promise<string>;
33
+ declare const writeContentHelper: (extractedContent: Record<string, string>, dictionaryKey: DictionaryKey, filePath: string, configuration: IntlayerConfig) => Promise<string>;
25
34
  //#endregion
26
- export { TranslationNode, createDictionary, resolveContentFilePath, writeContentHelper };
35
+ export { mergeWithExistingMultilingualDictionary, mergeWithExistingPerLocaleDictionary, writeContentHelper };
27
36
  //# sourceMappingURL=contentWriter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"contentWriter.d.ts","names":[],"sources":["../../../src/extractContent/contentWriter.ts"],"mappings":";;;KASY,eAAA;EACV,QAAA;EACA,WAAA,EAAa,MAAA;AAAA;;;;;cAOF,sBAAA,GACX,QAAA,UACA,YAAA,UACA,aAAA,EAAe,cAAA,EACf,SAAA;EACG,eAAA;EAAyB,uBAAA;AAAA;;;;;cAgCjB,gBAAA,GACX,gBAAA,EAAkB,MAAA,kBAClB,YAAA,UACA,uBAAA,UACA,aAAA,EAAe,cAAA,KACd,UAAA;;;;cAkCU,kBAAA,GACX,gBAAA,EAAkB,MAAA,kBAClB,YAAA,UACA,QAAA,UACA,aAAA,EAAe,cAAA,EACf,SAAA,cACC,OAAA"}
1
+ {"version":3,"file":"contentWriter.d.ts","names":[],"sources":["../../../src/extractContent/contentWriter.ts"],"mappings":";;;;;;AAY4E;KAMvE,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;;;;;;;cAgCU,oCAAA,GACX,gBAAA,EAAkB,MAAA,kBAClB,kBAAA,EAAoB,UAAA,YACnB,MAAA;;;;cA4BU,kBAAA,GACX,gBAAA,EAAkB,MAAA,kBAClB,aAAA,EAAe,aAAA,EACf,QAAA,UACA,aAAA,EAAe,cAAA,KACd,OAAA"}
@@ -1,52 +1,28 @@
1
1
  import { PackageName } from "./utils/constants.js";
2
- import { IntlayerConfig } from "@intlayer/types";
2
+ import { IntlayerConfig } from "@intlayer/types/config";
3
3
  import { GetConfigurationOptions } from "@intlayer/config/node";
4
4
 
5
5
  //#region src/extractContent/extractContent.d.ts
6
6
  type ExtractIntlayerOptions = {
7
7
  configOptions?: GetConfigurationOptions;
8
- outputDir?: string;
9
- /**
10
- * If true, only transform the source file — skip writing content declarations.
11
- */
12
8
  codeOnly?: boolean;
13
- /**
14
- * If true, only write content declarations — skip transforming the source file.
15
- * When set, `transformedCode` will still be returned (computed but not written to disk).
16
- */
17
9
  declarationOnly?: boolean;
18
10
  unmergedDictionaries?: Record<string, unknown>;
19
11
  configuration?: IntlayerConfig;
20
- /**
21
- * Raw source code to process instead of reading from disk.
22
- * Useful for Vite/webpack transform hooks where the code may already
23
- * have been modified by a previous plugin.
24
- */
25
12
  code?: string;
26
- /**
27
- * Callback invoked for each extracted dictionary key/content pair.
28
- * When provided, the caller is responsible for writing content declarations
29
- * (the built-in `writeContentHelper` is skipped unless `writeContent` is also true).
30
- * Used by Vite/webpack plugins that manage their own dictionary write pipeline.
31
- */
32
13
  onExtract?: (result: {
33
14
  key: string;
34
15
  content: Record<string, string>;
35
16
  filePath: string;
36
17
  }) => void | Promise<void>;
37
18
  };
38
- /**
39
- * Extracts Intlayer content from a single source file and optionally transforms it.
40
- *
41
- * - For `.vue` / `.svelte` files the matching optional compiler package is used.
42
- * - For `.tsx` / `.jsx` / `.ts` / `.js` files the Babel-based `processTsxFile` is used.
43
- *
44
- * Returns `{ transformedCode }` so callers (e.g. the Vite plugin) can pass the
45
- * modified source back to the bundler without writing the file to disk.
46
- */
47
19
  declare const extractContent: (filePath: string, packageName: PackageName, options?: ExtractIntlayerOptions) => Promise<{
48
20
  transformedCode: string | null;
49
21
  } | undefined>;
22
+ declare const extractContentSync: (filePath: string, packageName: PackageName, options?: ExtractIntlayerOptions) => {
23
+ transformedCode: string | null;
24
+ extractedContent: Record<string, Record<string, string>>;
25
+ } | undefined;
50
26
  //#endregion
51
- export { ExtractIntlayerOptions, extractContent };
27
+ export { ExtractIntlayerOptions, extractContent, extractContentSync };
52
28
  //# sourceMappingURL=extractContent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractContent.d.ts","names":[],"sources":["../../../src/extractContent/extractContent.ts"],"mappings":";;;;;KA4BY,sBAAA;EACV,aAAA,GAAgB,uBAAA;EAChB,SAAA;EAFU;;;EAMV,QAAA;EAMuB;;;;EADvB,eAAA;EACA,oBAAA,GAAuB,MAAA;EACvB,aAAA,GAAgB,cAAA;EAZA;;;;;EAkBhB,IAAA;EANA;;;;;;EAaA,SAAA,IAAa,MAAA;IACX,GAAA;IACA,OAAA,EAAS,MAAA;IACT,QAAA;EAAA,aACW,OAAA;AAAA;AAgBf;;;;;;;;;AAAA,cAAa,cAAA,GACX,QAAA,UACA,WAAA,EAAa,WAAA,EACb,OAAA,GAAU,sBAAA,KACT,OAAA;EAAU,eAAA;AAAA"}
1
+ {"version":3,"file":"extractContent.d.ts","names":[],"sources":["../../../src/extractContent/extractContent.ts"],"mappings":";;;;;KAgCY,sBAAA;EACV,aAAA,GAAgB,uBAAA;EAChB,QAAA;EACA,eAAA;EACA,oBAAA,GAAuB,MAAA;EACvB,aAAA,GAAgB,cAAA;EAChB,IAAA;EACA,SAAA,IAAa,MAAA;IACX,GAAA;IACA,OAAA,EAAS,MAAA;IACT,QAAA;EAAA,aACW,OAAA;AAAA;AAAA,cAsNF,cAAA,GACX,QAAA,UACA,WAAA,EAAa,WAAA,EACb,OAAA,GAAU,sBAAA,KACT,OAAA;EAAU,eAAA;AAAA;AAAA,cAqEA,kBAAA,GACX,QAAA,UACA,WAAA,EAAa,WAAA,EACb,OAAA,GAAU,sBAAA;EAGN,eAAA;EACA,gBAAA,EAAkB,MAAA,SAAe,MAAA;AAAA"}
@@ -1,4 +1,9 @@
1
- import { ATTRIBUTES_TO_EXTRACT, PackageName, packageList } from "./utils/constants.js";
1
+ import { ATTRIBUTES_TO_EXTRACT, PackageName, SERVER_CAPABLE_PACKAGES, packageList } from "./utils/constants.js";
2
+ import { mergeWithExistingMultilingualDictionary, mergeWithExistingPerLocaleDictionary, writeContentHelper } from "./contentWriter.js";
2
3
  import { detectPackageName } from "./utils/detectPackageName.js";
3
- import { ExtractIntlayerOptions, extractContent } from "./extractContent.js";
4
- export { ATTRIBUTES_TO_EXTRACT, ExtractIntlayerOptions, PackageName, detectPackageName, extractContent, packageList };
4
+ import { ExtractDictionaryInfoOptions, ResolveContentFilePaths, extractDictionaryInfo, getOutput, resolveContentFilePaths } from "./utils/extractDictionaryInfo.js";
5
+ import { extractDictionaryKey, extractDictionaryKeyFromPath } from "./utils/extractDictionaryKey.js";
6
+ import { generateKey } from "./utils/generateKey.js";
7
+ import { getComponentName } from "./utils/getComponentName.js";
8
+ import { ExtractIntlayerOptions, extractContent, extractContentSync } from "./extractContent.js";
9
+ export { ATTRIBUTES_TO_EXTRACT, ExtractDictionaryInfoOptions, ExtractIntlayerOptions, PackageName, ResolveContentFilePaths, SERVER_CAPABLE_PACKAGES, detectPackageName, extractContent, extractContentSync, extractDictionaryInfo, extractDictionaryKey, extractDictionaryKeyFromPath, generateKey, getComponentName, getOutput, mergeWithExistingMultilingualDictionary, mergeWithExistingPerLocaleDictionary, packageList, resolveContentFilePaths, writeContentHelper };
@@ -1,4 +1,5 @@
1
- import { IntlayerConfig } from "@intlayer/types";
1
+ import { PackageName } from "./utils/constants.js";
2
+ import { IntlayerConfig } from "@intlayer/types/config";
2
3
 
3
4
  //#region src/extractContent/processTsxFile.d.ts
4
5
  type TextEdit = {
@@ -9,7 +10,7 @@ type TextEdit = {
9
10
  /**
10
11
  * Processes a TSX/JSX/TS/JS file to extract content and inject Intlayer hooks/calls.
11
12
  */
12
- declare const processTsxFile: (filePath: string, componentKey: string, packageName: string, configuration: IntlayerConfig, save?: boolean, unmergedDictionaries?: Record<string, unknown>, providedFileCode?: string) => {
13
+ declare const processTsxFile: (filePath: string, componentKey: string, packageName: PackageName, configuration: IntlayerConfig, save?: boolean, unmergedDictionaries?: Record<string, unknown>, providedFileCode?: string) => {
13
14
  extractedContent: Record<string, Record<string, string>>;
14
15
  modifiedCode: string;
15
16
  } | null;
@@ -1 +1 @@
1
- {"version":3,"file":"processTsxFile.d.ts","names":[],"sources":["../../../src/extractContent/processTsxFile.ts"],"mappings":";;;KAUY,QAAA;EACV,KAAA;EACA,GAAA;EACA,WAAA;AAAA;;;;cAUW,cAAA,GACX,QAAA,UACA,YAAA,UACA,WAAA,UACA,aAAA,EAAe,cAAA,EACf,IAAA,YACA,oBAAA,GAAsB,MAAA,mBACtB,gBAAA;EAEA,gBAAA,EAAkB,MAAA,SAAe,MAAA;EACjC,YAAA;AAAA"}
1
+ {"version":3,"file":"processTsxFile.d.ts","names":[],"sources":["../../../src/extractContent/processTsxFile.ts"],"mappings":";;;;KAcY,QAAA;EACV,KAAA;EACA,GAAA;EACA,WAAA;AAAA;;;;cAUW,cAAA,GACX,QAAA,UACA,YAAA,UACA,WAAA,EAAa,WAAA,EACb,aAAA,EAAe,cAAA,EACf,IAAA,YACA,oBAAA,GAAsB,MAAA,mBACtB,gBAAA;EAEA,gBAAA,EAAkB,MAAA,SAAe,MAAA;EACjC,YAAA;AAAA"}
@@ -8,9 +8,13 @@ declare const ATTRIBUTES_TO_EXTRACT: readonly ["title", "placeholder", "alt", "a
8
8
  /**
9
9
  * The list of supported Intlayer integration packages.
10
10
  * This is the single source of truth for package name validation.
11
+ *
12
+ * Order matter for resolution
11
13
  */
12
- declare const packageList: readonly ["next-intlayer", "react-intlayer", "vue-intlayer", "svelte-intlayer", "preact-intlayer", "solid-intlayer", "angular-intlayer", "express-intlayer", "hono-intlayer", "fastify-intlayer", "adonis-intlayer"];
14
+ declare const packageList: readonly ["next-intlayer", "react-intlayer", "vue-intlayer", "svelte-intlayer", "preact-intlayer", "solid-intlayer", "angular-intlayer", "express-intlayer", "hono-intlayer", "fastify-intlayer", "adonis-intlayer", "intlayer"];
15
+ /** Packages that support a `/server` sub-path for React Server Components. */
16
+ declare const SERVER_CAPABLE_PACKAGES: ReadonlySet<string>;
13
17
  type PackageName = (typeof packageList)[number];
14
18
  //#endregion
15
- export { ATTRIBUTES_TO_EXTRACT, PackageName, packageList };
19
+ export { ATTRIBUTES_TO_EXTRACT, PackageName, SERVER_CAPABLE_PACKAGES, packageList };
16
20
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","names":[],"sources":["../../../../src/extractContent/utils/constants.ts"],"mappings":";;AAKA;;;;cAAa,qBAAA;AAYb;;;;AAAA,cAAa,WAAA;AAAA,KAcD,WAAA,WAAsB,WAAA"}
1
+ {"version":3,"file":"constants.d.ts","names":[],"sources":["../../../../src/extractContent/utils/constants.ts"],"mappings":";;AAKA;;;;cAAa,qBAAA;AAcb;;;;;AAgBA;AAhBA,cAAa,WAAA;;cAgBA,uBAAA,EAAyB,WAAA;AAAA,KAI1B,WAAA,WAAsB,WAAA"}
@@ -1,8 +1,10 @@
1
+ import { PackageName } from "./constants.js";
2
+
1
3
  //#region src/extractContent/utils/detectPackageName.d.ts
2
4
  /**
3
5
  * Detects which intlayer package is used in the project by reading package.json.
4
6
  */
5
- declare const detectPackageName: (searchDir: string) => string | undefined;
7
+ declare const detectPackageName: (searchDir: string) => PackageName;
6
8
  //#endregion
7
9
  export { detectPackageName };
8
10
  //# sourceMappingURL=detectPackageName.d.ts.map