@intlayer/babel 8.2.4 → 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,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./extractContent/utils/detectPackageName.cjs`),t=require(`./extractContent/utils/extractDictionaryKey.cjs`),n=require(`./extractContent/processTsxFile.cjs`);let r=require(`node:path`),i=require(`@babel/parser`),a=require(`@intlayer/config/logger`),o=require(`@intlayer/config/node`);const s=new Set([`next-intlayer`]),c=c=>({name:`babel-plugin-intlayer-extract`,visitor:{Program:{enter(c,l){let u=l.opts;if(u.enabled===!1)return;let d=l.file.opts.filename;if(!d)return;let f=(0,r.extname)(d);if(![`.tsx`,`.jsx`,`.ts`,`.js`].includes(f)||u.filesList&&!u.filesList.includes(d))return;let p=l.file.code??``;if(!p)return;let m=(0,o.getConfiguration)(),h=(0,a.getAppLogger)(m),g=u.packageName??e.detectPackageName((0,r.dirname)(d))??`react-intlayer`,_=t.extractDictionaryKeyFromPath(d,u.prefix??`comp-`),v=u.saveComponents??!1,y=c.node.directives.some(e=>e.value.value===`use client`),b=n.processTsxFile(d,_,s.has(g)&&!y?`${g}/server`:g,m,v,{},p);if(!b)return;let{extractedContent:x,modifiedCode:S}=b;if(u.onExtract){let e=u.defaultLocale??m.internationalization.defaultLocale;for(let[t,n]of Object.entries(x))u.onExtract({dictionaryKey:t,filePath:d,content:n,locale:e})}try{let e=(0,i.parse)(S,{sourceType:`module`,plugins:[`jsx`,`typescript`]});c.node.body=e.program.body,c.node.directives=e.program.directives,h(`${(0,a.colorize)(`Compiler:`,a.ANSIColors.GREY_DARK)} Extracted content from ${(0,a.colorizePath)((0,r.relative)(m.content.baseDir,d))}`,{level:`debug`})}catch(e){console.error(`[intlayer] Failed to parse transformed code for ${d}:`,e)}}}}});exports.intlayerExtractBabelPlugin=c;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./extractContent/utils/detectPackageName.cjs`),t=require(`./extractContent/extractContent.cjs`);let n=require(`@intlayer/config/logger`),r=require(`node:path`),i=require(`@babel/parser`);const a=a=>({name:`babel-plugin-intlayer-extract`,visitor:{Program:{enter(a,o){let s=o.opts;if(s.enabled===!1)return;let c=o.file.opts.filename;if(!c||s.filesList&&!s.filesList.includes(c))return;let l=o.file.code??``;if(!l)return;let u=(0,n.getAppLogger)(s.configuration),d=s.packageName??e.detectPackageName(c),{saveComponents:f}=s.configuration.compiler,p=t.extractContentSync(c,d,{configuration:s.configuration,code:l,onExtract:e=>{s.onExtract&&s.onExtract({dictionaryKey:e.key,filePath:c,content:e.content,locale:s.configuration.internationalization.defaultLocale})},declarationOnly:!f});if(!p)return;let{transformedCode:m}=p;if(m)try{let e=(0,i.parse)(m,{sourceType:`module`,plugins:[`jsx`,`typescript`]});a.node.body=e.program.body,a.node.directives=e.program.directives,u(`${(0,n.colorize)(`Compiler:`,n.ANSIColors.GREY_DARK)} Extracted content from ${(0,n.colorizePath)((0,r.relative)(s.configuration.system.baseDir,c))}`,{level:`debug`})}catch(e){console.error(`[intlayer] Failed to parse transformed code for ${c}:`,e)}}}}});exports.intlayerExtractBabelPlugin=a;
2
2
  //# sourceMappingURL=babel-plugin-intlayer-extract.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"babel-plugin-intlayer-extract.cjs","names":["detectPackageName","extractDictionaryKeyFromPath","processTsxFile","ANSIColors"],"sources":["../../src/babel-plugin-intlayer-extract.ts"],"sourcesContent":["import { dirname, extname, relative } from 'node:path';\nimport type { PluginObj, PluginPass } from '@babel/core';\nimport { parse } from '@babel/parser';\nimport type * as BabelTypes from '@babel/types';\nimport {\n ANSIColors,\n colorize,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { processTsxFile } from './extractContent/processTsxFile';\nimport type { PackageName } from './extractContent/utils/constants';\nimport { detectPackageName } from './extractContent/utils/detectPackageName';\nimport { extractDictionaryKeyFromPath } from './extractContent/utils/extractDictionaryKey';\n\n/** Packages that support a `/server` sub-path for React Server Components. */\nconst SERVER_CAPABLE_PACKAGES: ReadonlySet<string> = new Set(['next-intlayer']);\n\nexport type ExtractResult = {\n dictionaryKey: string;\n filePath: string;\n content: Record<string, string>;\n locale: string;\n};\n\nexport type ExtractPluginOptions = {\n defaultLocale?: string;\n packageName?: string;\n filesList?: string[];\n shouldExtract?: (text: string) => boolean;\n enabled?: boolean;\n prefix?: string;\n saveComponents?: boolean;\n formatCommand?: string;\n /**\n * Callback invoked for each extracted dictionary key/content pair.\n * Used by `getExtractPluginOptions` to write dictionaries to disk.\n * May be async — the plugin will fire-and-forget (Babel transforms are sync).\n */\n onExtract?: (result: ExtractResult) => void | Promise<void>;\n};\n\ntype State = PluginPass & { opts: ExtractPluginOptions };\n\n/**\n * Babel plugin that extracts translatable content from source files and\n * injects Intlayer hooks (`useIntlayer` / `getIntlayer`) automatically.\n *\n * Designed for use with Babel-based build tools such as Next.js and Webpack.\n *\n * @example babel.config.js\n * ```js\n * const { intlayerExtractBabelPlugin, getExtractPluginOptions } = require('@intlayer/babel');\n * module.exports = {\n * presets: ['next/babel'],\n * plugins: [\n * [intlayerExtractBabelPlugin, getExtractPluginOptions()],\n * ],\n * };\n * ```\n */\nexport const intlayerExtractBabelPlugin = (babel: {\n types: typeof BabelTypes;\n}): PluginObj<State> => {\n return {\n name: 'babel-plugin-intlayer-extract',\n\n visitor: {\n Program: {\n enter(programPath, state) {\n const opts = state.opts;\n\n if (opts.enabled === false) return;\n\n const filename = state.file.opts.filename;\n if (!filename) return;\n\n const ext = extname(filename);\n if (!['.tsx', '.jsx', '.ts', '.js'].includes(ext)) return;\n\n if (opts.filesList && !opts.filesList.includes(filename)) return;\n\n // Grab the original source from the Babel file object\n const fileCode: string = (state.file as any).code ?? '';\n if (!fileCode) return;\n\n const configuration = getConfiguration();\n const appLogger = getAppLogger(configuration);\n\n const packageName = (opts.packageName ??\n detectPackageName(dirname(filename)) ??\n 'react-intlayer') as PackageName;\n\n const prefix = opts.prefix ?? 'comp-';\n const componentKey = extractDictionaryKeyFromPath(filename, prefix);\n const saveComponents = opts.saveComponents ?? false;\n\n // For packages that expose a `/server` entry (e.g. next-intlayer),\n // use that sub-path when no \"use client\" directive is present so that\n // React Server Components receive the correct import.\n const hasUseClient = programPath.node.directives.some(\n (d) => d.value.value === 'use client'\n );\n const effectivePackageName =\n SERVER_CAPABLE_PACKAGES.has(packageName) && !hasUseClient\n ? `${packageName}/server`\n : packageName;\n\n const result = processTsxFile(\n filename,\n componentKey,\n effectivePackageName,\n configuration,\n saveComponents,\n {}, // unmergedDictionaries — not needed for Babel plugin use case\n fileCode\n );\n\n if (!result) return;\n\n const { extractedContent, modifiedCode } = result;\n\n // Fire-and-forget: Babel transforms are synchronous, but onExtract may\n // be async (e.g. writing files). We don't await here.\n if (opts.onExtract) {\n const defaultLocale =\n opts.defaultLocale ??\n configuration.internationalization.defaultLocale;\n\n for (const [key, content] of Object.entries(extractedContent)) {\n void opts.onExtract({\n dictionaryKey: key,\n filePath: filename,\n content,\n locale: defaultLocale,\n });\n }\n }\n\n // Replace the Babel AST with the transformed code by re-parsing it.\n // This lets Babel serialise the injected hooks/imports through its\n // own code generator, preserving compatibility with other plugins.\n try {\n const newAst = parse(modifiedCode, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\n programPath.node.body = newAst.program.body;\n programPath.node.directives = newAst.program.directives;\n\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} Extracted content from ${colorizePath(relative(configuration.content.baseDir, filename))}`,\n { level: 'debug' }\n );\n } catch (error) {\n console.error(\n `[intlayer] Failed to parse transformed code for ${filename}:`,\n error\n );\n }\n },\n },\n },\n };\n};\n"],"mappings":"2ZAiBA,MAAM,EAA+C,IAAI,IAAI,CAAC,gBAAgB,CAAC,CA6ClE,EAA8B,IAGlC,CACL,KAAM,gCAEN,QAAS,CACP,QAAS,CACP,MAAM,EAAa,EAAO,CACxB,IAAM,EAAO,EAAM,KAEnB,GAAI,EAAK,UAAY,GAAO,OAE5B,IAAM,EAAW,EAAM,KAAK,KAAK,SACjC,GAAI,CAAC,EAAU,OAEf,IAAM,GAAA,EAAA,EAAA,SAAc,EAAS,CAG7B,GAFI,CAAC,CAAC,OAAQ,OAAQ,MAAO,MAAM,CAAC,SAAS,EAAI,EAE7C,EAAK,WAAa,CAAC,EAAK,UAAU,SAAS,EAAS,CAAE,OAG1D,IAAM,EAAoB,EAAM,KAAa,MAAQ,GACrD,GAAI,CAAC,EAAU,OAEf,IAAM,GAAA,EAAA,EAAA,mBAAkC,CAClC,GAAA,EAAA,EAAA,cAAyB,EAAc,CAEvC,EAAe,EAAK,aACxBA,EAAAA,mBAAAA,EAAAA,EAAAA,SAA0B,EAAS,CAAC,EACpC,iBAGI,EAAeC,EAAAA,6BAA6B,EADnC,EAAK,QAAU,QACqC,CAC7D,EAAiB,EAAK,gBAAkB,GAKxC,EAAe,EAAY,KAAK,WAAW,KAC9C,GAAM,EAAE,MAAM,QAAU,aAC1B,CAMK,EAASC,EAAAA,eACb,EACA,EANA,EAAwB,IAAI,EAAY,EAAI,CAAC,EACzC,GAAG,EAAY,SACf,EAMJ,EACA,EACA,EAAE,CACF,EACD,CAED,GAAI,CAAC,EAAQ,OAEb,GAAM,CAAE,mBAAkB,gBAAiB,EAI3C,GAAI,EAAK,UAAW,CAClB,IAAM,EACJ,EAAK,eACL,EAAc,qBAAqB,cAErC,IAAK,GAAM,CAAC,EAAK,KAAY,OAAO,QAAQ,EAAiB,CACtD,EAAK,UAAU,CAClB,cAAe,EACf,SAAU,EACV,UACA,OAAQ,EACT,CAAC,CAON,GAAI,CACF,IAAM,GAAA,EAAA,EAAA,OAAe,EAAc,CACjC,WAAY,SACZ,QAAS,CAAC,MAAO,aAAa,CAC/B,CAAC,CAEF,EAAY,KAAK,KAAO,EAAO,QAAQ,KACvC,EAAY,KAAK,WAAa,EAAO,QAAQ,WAE7C,EACE,IAAA,EAAA,EAAA,UAAY,YAAaC,EAAAA,WAAW,UAAU,CAAC,2BAAA,EAAA,EAAA,eAAA,EAAA,EAAA,UAAgD,EAAc,QAAQ,QAAS,EAAS,CAAC,GACxI,CAAE,MAAO,QAAS,CACnB,OACM,EAAO,CACd,QAAQ,MACN,mDAAmD,EAAS,GAC5D,EACD,GAGN,CACF,CACF"}
1
+ {"version":3,"file":"babel-plugin-intlayer-extract.cjs","names":["detectPackageName","extractContentSync","ANSIColors"],"sources":["../../src/babel-plugin-intlayer-extract.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport type { PluginObj, PluginPass } from '@babel/core';\nimport { parse } from '@babel/parser';\nimport type * as BabelTypes from '@babel/types';\nimport {\n ANSIColors,\n colorize,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { FilePathPattern } from '@intlayer/types/filePathPattern';\nimport { extractContentSync } from './extractContent/extractContent';\nimport type { PackageName } from './extractContent/utils/constants';\nimport { detectPackageName } from './extractContent/utils/detectPackageName';\n\nexport type ExtractResult = {\n dictionaryKey: string;\n filePath: string;\n content: Record<string, string>;\n locale: Locale;\n};\n\nexport type ExtractPluginOptions = {\n packageName?: PackageName;\n filesList: string[];\n enabled: boolean;\n\n shouldExtract?: (text: string) => boolean;\n configuration: IntlayerConfig;\n /**\n * Callback invoked for each extracted dictionary key/content pair.\n * Used by `getExtractPluginOptions` to write dictionaries to disk.\n * May be async — the plugin will fire-and-forget (Babel transforms are sync).\n */\n onExtract?: (result: ExtractResult) => void | Promise<void>;\n /**\n * Defines the output files path.\n */\n output?: FilePathPattern;\n};\n\ntype State = PluginPass & { opts: ExtractPluginOptions };\n\n/**\n * Babel plugin that extracts translatable content from source files and\n * injects Intlayer hooks (`useIntlayer` / `getIntlayer`) automatically.\n *\n * Designed for use with Babel-based build tools such as Next.js and Webpack.\n *\n * @example babel.config.js\n * ```js\n * const { intlayerExtractBabelPlugin, getExtractPluginOptions } = require('@intlayer/babel');\n * module.exports = {\n * presets: ['next/babel'],\n * plugins: [\n * [intlayerExtractBabelPlugin, getExtractPluginOptions()],\n * ],\n * };\n * ```\n */\nexport const intlayerExtractBabelPlugin = (_babel: {\n types: typeof BabelTypes;\n}): PluginObj<State> => {\n return {\n name: 'babel-plugin-intlayer-extract',\n\n visitor: {\n Program: {\n enter(programPath, state) {\n const opts = state.opts;\n\n // Merge plugin options with the unified compiler config\n const isEnabled = opts.enabled;\n\n if (isEnabled === false) return;\n\n const filename = state.file.opts.filename;\n\n if (!filename) return;\n\n if (opts.filesList && !opts.filesList.includes(filename)) return;\n\n const fileCode: string = state.file.code ?? '';\n if (!fileCode) return;\n\n const appLogger = getAppLogger(opts.configuration);\n const packageName = opts.packageName ?? detectPackageName(filename);\n\n const { saveComponents } = opts.configuration.compiler;\n\n const result = extractContentSync(filename, packageName, {\n configuration: opts.configuration,\n code: fileCode,\n onExtract: (extractResult: {\n key: string;\n content: Record<string, string>;\n }) => {\n if (opts.onExtract) {\n void opts.onExtract({\n dictionaryKey: extractResult.key,\n filePath: filename,\n content: extractResult.content,\n locale: opts.configuration.internationalization.defaultLocale,\n });\n }\n },\n declarationOnly: !saveComponents,\n });\n\n if (!result) return;\n\n const { transformedCode: modifiedCode } = result;\n\n if (!modifiedCode) return;\n\n // Replace the Babel AST with the transformed code by re-parsing it.\n // This lets Babel serialise the injected hooks/imports through its\n // own code generator, preserving compatibility with other plugins.\n try {\n const newAst = parse(modifiedCode, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\n programPath.node.body = newAst.program.body;\n programPath.node.directives = newAst.program.directives;\n\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} Extracted content from ${colorizePath(relative(opts.configuration.system.baseDir, filename))}`,\n { level: 'debug' }\n );\n } catch (error) {\n console.error(\n `[intlayer] Failed to parse transformed code for ${filename}:`,\n error\n );\n }\n },\n },\n },\n };\n};\n"],"mappings":"2TA8DA,MAAa,EAA8B,IAGlC,CACL,KAAM,gCAEN,QAAS,CACP,QAAS,CACP,MAAM,EAAa,EAAO,CACxB,IAAM,EAAO,EAAM,KAKnB,GAFkB,EAAK,UAEL,GAAO,OAEzB,IAAM,EAAW,EAAM,KAAK,KAAK,SAIjC,GAFI,CAAC,GAED,EAAK,WAAa,CAAC,EAAK,UAAU,SAAS,EAAS,CAAE,OAE1D,IAAM,EAAmB,EAAM,KAAK,MAAQ,GAC5C,GAAI,CAAC,EAAU,OAEf,IAAM,GAAA,EAAA,EAAA,cAAyB,EAAK,cAAc,CAC5C,EAAc,EAAK,aAAeA,EAAAA,kBAAkB,EAAS,CAE7D,CAAE,kBAAmB,EAAK,cAAc,SAExC,EAASC,EAAAA,mBAAmB,EAAU,EAAa,CACvD,cAAe,EAAK,cACpB,KAAM,EACN,UAAY,GAGN,CACA,EAAK,WACF,EAAK,UAAU,CAClB,cAAe,EAAc,IAC7B,SAAU,EACV,QAAS,EAAc,QACvB,OAAQ,EAAK,cAAc,qBAAqB,cACjD,CAAC,EAGN,gBAAiB,CAAC,EACnB,CAAC,CAEF,GAAI,CAAC,EAAQ,OAEb,GAAM,CAAE,gBAAiB,GAAiB,EAErC,KAKL,GAAI,CACF,IAAM,GAAA,EAAA,EAAA,OAAe,EAAc,CACjC,WAAY,SACZ,QAAS,CAAC,MAAO,aAAa,CAC/B,CAAC,CAEF,EAAY,KAAK,KAAO,EAAO,QAAQ,KACvC,EAAY,KAAK,WAAa,EAAO,QAAQ,WAE7C,EACE,IAAA,EAAA,EAAA,UAAY,YAAaC,EAAAA,WAAW,UAAU,CAAC,2BAAA,EAAA,EAAA,eAAA,EAAA,EAAA,UAAgD,EAAK,cAAc,OAAO,QAAS,EAAS,CAAC,GAC5I,CAAE,MAAO,QAAS,CACnB,OACM,EAAO,CACd,QAAQ,MACN,mDAAmD,EAAS,GAC5D,EACD,GAGN,CACF,CACF"}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`node:path`),t=require(`@intlayer/config/utils`),n=require(`@intlayer/chokidar/utils`);const r=[`intlayer`,`@intlayer/core`,`react-intlayer`,`react-intlayer/client`,`react-intlayer/server`,`next-intlayer`,`next-intlayer/client`,`next-intlayer/server`,`svelte-intlayer`,`vue-intlayer`,`angular-intlayer`,`preact-intlayer`,`solid-intlayer`],i=[`useIntlayer`,`getIntlayer`],a=[`react-intlayer`,`react-intlayer/client`,`react-intlayer/server`,`next-intlayer`,`next-intlayer/client`,`next-intlayer/server`,`preact-intlayer`,`vue-intlayer`,`solid-intlayer`,`svelte-intlayer`,`angular-intlayer`],o={getIntlayer:`getDictionary`,useIntlayer:`useDictionary`},s={useIntlayer:`useDictionaryDynamic`},c=(e,t)=>{let r=(0,n.getPathHash)(e);return t.identifier(`_${r}`)},l=(n,r,i,a,o,s)=>{let c=(0,e.join)(r,`${o}.json`);s===`fetch`&&(c=(0,e.join)(a,`${o}.mjs`)),s===`dynamic`&&(c=(0,e.join)(i,`${o}.mjs`));let l=(0,e.relative)((0,e.dirname)(n),c);return l=(0,t.normalizePath)(l),!l.startsWith(`./`)&&!l.startsWith(`../`)&&(l=`./${l}`),l},u=e=>{let{types:t}=e;return{name:`babel-plugin-intlayer-transform`,pre(){if(this._newStaticImports=new Map,this._newDynamicImports=new Map,this._callerMap=new Map,this._isIncluded=!0,this._hasValidImport=!1,this._isDictEntry=!1,this._useDynamicHelpers=!1,this.opts.optimize===!1){this._isIncluded=!1;return}let e=this.file.opts.filename;if(this.opts.filesList&&e&&!this.opts.filesList.includes(e)){this._isIncluded=!1;return}},visitor:{Program:{enter(e,n){let r=n.file.opts.filename;n.opts.replaceDictionaryEntry&&r===n.opts.dictionariesEntryPath&&(n._isDictEntry=!0,e.traverse({ImportDeclaration(e){e.remove()},VariableDeclarator(e){t.isObjectExpression(e.node.init)&&(e.node.init.properties=[])}}))},exit(e,u){if(u._isDictEntry||!u._isIncluded)return;let d=!1;if(e.traverse({CallExpression(e){let n=e.node.callee;if(!t.isIdentifier(n)||u._callerMap?.get(n.name)!==`useIntlayer`)return;let r=e.node.arguments[0],i;if(r&&t.isStringLiteral(r)?i=r.value:r&&t.isTemplateLiteral(r)&&r.expressions.length===0&&r.quasis.length===1&&(i=r.quasis[0].value.cooked??r.quasis[0].value.raw),!i)return;let a=u.opts.dictionaryModeMap?.[i];(a===`dynamic`||a===`fetch`)&&(d=!0)}}),e.traverse({ImportDeclaration(e){let n=e.node.source.value;if(r.includes(n)){u._hasValidImport=!0;for(let r of e.node.specifiers){if(!t.isImportSpecifier(r))continue;let e=t.isIdentifier(r.imported)?r.imported.name:r.imported.value;i.includes(e)&&u._callerMap?.set(r.local.name,e);let c=u.opts.importMode,l=(c===`dynamic`||c===`fetch`||d)&&a.includes(n);l&&(u._useDynamicHelpers=!0);let f;f=l?{...o,...s}:o;let p=f[e];p&&(r.imported=t.identifier(p))}}},CallExpression(e){let r=e.node.callee;if(!t.isIdentifier(r))return;let i=u._callerMap?.get(r.name);if(!i)return;u._hasValidImport=!0;let a=e.node.arguments[0],o;if(a&&t.isStringLiteral(a)?o=a.value:a&&t.isTemplateLiteral(a)&&a.expressions.length===0&&a.quasis.length===1&&(o=a.quasis[0].value.cooked??a.quasis[0].value.raw),!o)return;let s=u.opts.importMode,l=i===`useIntlayer`,d=!!u._useDynamicHelpers,f=`static`,p=u.opts.dictionaryModeMap?.[o];l&&d?p?f=p:s===`dynamic`?f=`dynamic`:s===`fetch`&&(f=`fetch`):l&&!d&&(p===`dynamic`||p===`fetch`)&&(f=p);let m;if(f===`fetch`){let r=u._newDynamicImports?.get(o);if(!r){let e=(0,n.getPathHash)(o);r=t.identifier(`_${e}_fetch`),u._newDynamicImports?.set(o,r)}m=r,e.node.arguments=[t.identifier(m.name),...e.node.arguments]}else if(f===`dynamic`){let r=u._newDynamicImports?.get(o);if(!r){let e=(0,n.getPathHash)(o);r=t.identifier(`_${e}_dyn`),u._newDynamicImports?.set(o,r)}m=r,e.node.arguments=[t.identifier(m.name),...e.node.arguments]}else{let n=u._newStaticImports?.get(o);n||(n=c(o,t),u._newStaticImports?.set(o,n)),m=n,e.node.arguments[0]=t.identifier(m.name)}}}),!u._hasValidImport)return;let f=u.file.opts.filename,p=u.opts.dictionariesDir,m=u.opts.dynamicDictionariesDir,h=u.opts.fetchDictionariesDir,g=[];for(let[e,n]of u._newStaticImports){let r=l(f,p,m,h,e,`static`),i=t.importDeclaration([t.importDefaultSpecifier(t.identifier(n.name))],t.stringLiteral(r));i.attributes=[t.importAttribute(t.identifier(`type`),t.stringLiteral(`json`))],g.push(i)}for(let[e,n]of u._newDynamicImports){let r=l(f,p,m,h,e,n.name.endsWith(`_fetch`)?`fetch`:`dynamic`);g.push(t.importDeclaration([t.importDefaultSpecifier(t.identifier(n.name))],t.stringLiteral(r)))}if(!g.length)return;let _=e.get(`body`),v=0;for(let e of _){let n=e.node;if(t.isExpressionStatement(n)&&t.isStringLiteral(n.expression)&&!n.expression.value.startsWith(`import`)&&!n.expression.value.startsWith(`require`))v+=1;else break}e.node.body.splice(v,0,...g)}}}}};exports.intlayerOptimizeBabelPlugin=u;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`@intlayer/chokidar/utils`),t=require(`node:path`),n=require(`@intlayer/config/utils`);const r=[`intlayer`,`@intlayer/core`,`react-intlayer`,`react-intlayer/client`,`react-intlayer/server`,`next-intlayer`,`next-intlayer/client`,`next-intlayer/server`,`svelte-intlayer`,`vue-intlayer`,`angular-intlayer`,`preact-intlayer`,`solid-intlayer`],i=[`useIntlayer`,`getIntlayer`],a=[`react-intlayer`,`react-intlayer/client`,`react-intlayer/server`,`next-intlayer`,`next-intlayer/client`,`next-intlayer/server`,`preact-intlayer`,`vue-intlayer`,`solid-intlayer`,`svelte-intlayer`,`angular-intlayer`],o={getIntlayer:`getDictionary`,useIntlayer:`useDictionary`},s={useIntlayer:`useDictionaryDynamic`},c=(t,n)=>{let r=(0,e.getPathHash)(t);return n.identifier(`_${r}`)},l=(e,r,i,a,o,s)=>{let c=(0,t.join)(r,`${o}.json`);s===`fetch`&&(c=(0,t.join)(a,`${o}.mjs`)),s===`dynamic`&&(c=(0,t.join)(i,`${o}.mjs`));let l=(0,t.relative)((0,t.dirname)(e),c);return l=(0,n.normalizePath)(l),!l.startsWith(`./`)&&!l.startsWith(`../`)&&(l=`./${l}`),l},u=t=>{let{types:n}=t;return{name:`babel-plugin-intlayer-transform`,pre(){if(this._newStaticImports=new Map,this._newDynamicImports=new Map,this._callerMap=new Map,this._isIncluded=!0,this._hasValidImport=!1,this._isDictEntry=!1,this._useDynamicHelpers=!1,this.opts.optimize===!1){this._isIncluded=!1;return}let e=this.file.opts.filename;if(this.opts.filesList&&e&&!this.opts.filesList.includes(e)){this._isIncluded=!1;return}},visitor:{Program:{enter(e,t){let r=t.file.opts.filename;t.opts.replaceDictionaryEntry&&r===t.opts.dictionariesEntryPath&&(t._isDictEntry=!0,e.traverse({ImportDeclaration(e){e.remove()},VariableDeclarator(e){n.isObjectExpression(e.node.init)&&(e.node.init.properties=[])}}))},exit(t,u){if(u._isDictEntry||!u._isIncluded)return;let d=!1;if(t.traverse({CallExpression(e){let t=e.node.callee;if(!n.isIdentifier(t)||u._callerMap?.get(t.name)!==`useIntlayer`)return;let r=e.node.arguments[0],i;if(r&&n.isStringLiteral(r)?i=r.value:r&&n.isTemplateLiteral(r)&&r.expressions.length===0&&r.quasis.length===1&&(i=r.quasis[0].value.cooked??r.quasis[0].value.raw),!i)return;let a=u.opts.dictionaryModeMap?.[i];(a===`dynamic`||a===`fetch`)&&(d=!0)}}),t.traverse({ImportDeclaration(e){let t=e.node.source.value;if(r.includes(t)){u._hasValidImport=!0;for(let r of e.node.specifiers){if(!n.isImportSpecifier(r))continue;let e=n.isIdentifier(r.imported)?r.imported.name:r.imported.value;i.includes(e)&&u._callerMap?.set(r.local.name,e);let c=u.opts.importMode,l=(c===`dynamic`||c===`fetch`||d)&&a.includes(t);l&&(u._useDynamicHelpers=!0);let f;f=l?{...o,...s}:o;let p=f[e];p&&(r.imported=n.identifier(p))}}},CallExpression(t){let r=t.node.callee;if(!n.isIdentifier(r))return;let i=u._callerMap?.get(r.name);if(!i)return;u._hasValidImport=!0;let a=t.node.arguments[0],o;if(a&&n.isStringLiteral(a)?o=a.value:a&&n.isTemplateLiteral(a)&&a.expressions.length===0&&a.quasis.length===1&&(o=a.quasis[0].value.cooked??a.quasis[0].value.raw),!o)return;let s=u.opts.importMode,l=i===`useIntlayer`,d=!!u._useDynamicHelpers,f=`static`,p=u.opts.dictionaryModeMap?.[o];l&&d?p?f=p:s===`dynamic`?f=`dynamic`:s===`fetch`&&(f=`fetch`):l&&!d&&(p===`dynamic`||p===`fetch`)&&(f=p);let m;if(f===`fetch`){let r=u._newDynamicImports?.get(o);if(!r){let t=(0,e.getPathHash)(o);r=n.identifier(`_${t}_fetch`),u._newDynamicImports?.set(o,r)}m=r,t.node.arguments=[n.identifier(m.name),...t.node.arguments]}else if(f===`dynamic`){let r=u._newDynamicImports?.get(o);if(!r){let t=(0,e.getPathHash)(o);r=n.identifier(`_${t}_dyn`),u._newDynamicImports?.set(o,r)}m=r,t.node.arguments=[n.identifier(m.name),...t.node.arguments]}else{let e=u._newStaticImports?.get(o);e||(e=c(o,n),u._newStaticImports?.set(o,e)),m=e,t.node.arguments[0]=n.identifier(m.name)}}}),!u._hasValidImport)return;let f=u.file.opts.filename,p=u.opts.dictionariesDir,m=u.opts.dynamicDictionariesDir,h=u.opts.fetchDictionariesDir,g=[];for(let[e,t]of u._newStaticImports){let r=l(f,p,m,h,e,`static`),i=n.importDeclaration([n.importDefaultSpecifier(n.identifier(t.name))],n.stringLiteral(r));i.attributes=[n.importAttribute(n.identifier(`type`),n.stringLiteral(`json`))],g.push(i)}for(let[e,t]of u._newDynamicImports){let r=l(f,p,m,h,e,t.name.endsWith(`_fetch`)?`fetch`:`dynamic`);g.push(n.importDeclaration([n.importDefaultSpecifier(n.identifier(t.name))],n.stringLiteral(r)))}if(!g.length)return;let _=t.get(`body`),v=0;for(let e of _){let t=e.node;if(n.isExpressionStatement(t)&&n.isStringLiteral(t.expression)&&!t.expression.value.startsWith(`import`)&&!t.expression.value.startsWith(`require`))v+=1;else break}t.node.body.splice(v,0,...g)}}}}};exports.intlayerOptimizeBabelPlugin=u;
2
2
  //# sourceMappingURL=babel-plugin-intlayer-optimize.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"babelProcessor.cjs","names":["_traverse","t","shouldExtract","getOrGenerateKey","getExistingIntlayerInfo","resolveDictionaryKey","getComponentName","ATTRIBUTES_TO_EXTRACT"],"sources":["../../../src/extractContent/babelProcessor.ts"],"sourcesContent":["import _traverse, { type NodePath } from '@babel/traverse';\nimport * as t from '@babel/types';\nimport type { IntlayerConfig } from '@intlayer/types';\nimport { resolveDictionaryKey } from '../extractContent/utils';\nimport {\n ATTRIBUTES_TO_EXTRACT,\n getComponentName,\n getExistingIntlayerInfo,\n getOrGenerateKey,\n shouldExtract,\n} from './utils';\n\nexport type BabelReplacement = {\n path: NodePath;\n key: string;\n type:\n | 'jsx-text'\n | 'jsx-attribute'\n | 'string-literal'\n | 'jsx-insertion'\n | 'jsx-text-combined';\n componentKey: string;\n childrenToReplace?: t.Node[];\n variables?: string[];\n};\n\n// CJS/ESM interop: @babel/traverse exports its function as `.default` in CJS bundles\nconst traverse = (\n typeof _traverse === 'function' ? _traverse : (_traverse as any).default\n) as typeof _traverse;\n\n/**\n * Handles JSX insertions (elements with multiple children, including expressions).\n * Replaces complex JSX structures with variable-based translations.\n */\nexport const handleJsxInsertionBabel = (\n path: NodePath<t.JSXElement | t.JSXFragment>,\n fileCode: string,\n existingKeys: Set<string>,\n getComponentKeyForPath: (path: NodePath) => string,\n extractedContent: Record<string, Record<string, string>>,\n replacements: BabelReplacement[],\n handledNodes: Set<t.Node>\n): boolean => {\n const children = path.node.children;\n\n if (children.length <= 1) return false;\n\n const parts: {\n type: 'text' | 'var';\n value: string;\n originalExpr?: string;\n }[] = [];\n let hasSignificantText = false;\n let hasVariables = false;\n\n for (const child of children) {\n if (t.isJSXText(child)) {\n const text = child.value;\n\n if (text.trim().length > 0) hasSignificantText = true;\n\n parts.push({ type: 'text', value: text });\n } else if (t.isJSXExpressionContainer(child)) {\n if (t.isJSXEmptyExpression(child.expression)) {\n parts.push({ type: 'text', value: '' });\n } else {\n const expr = child.expression;\n\n if (t.isIdentifier(expr)) {\n parts.push({\n type: 'var',\n value: expr.name,\n originalExpr: expr.name,\n });\n hasVariables = true;\n } else if (t.isMemberExpression(expr)) {\n const code = fileCode.substring(expr.start!, expr.end!);\n\n const varName = t.isIdentifier(expr.property)\n ? expr.property.name\n : 'var';\n\n parts.push({ type: 'var', value: varName, originalExpr: code });\n\n hasVariables = true;\n } else {\n return false;\n }\n }\n } else {\n return false;\n }\n }\n\n if (!hasSignificantText) return false;\n\n let combinedString = '';\n for (const part of parts) {\n if (part.type === 'var') combinedString += `{{${part.value}}}`;\n else combinedString += part.value;\n }\n\n const cleanString = combinedString.replace(/\\s+/g, ' ').trim();\n\n if (shouldExtract(cleanString)) {\n const componentKey = getComponentKeyForPath(path);\n const key = getOrGenerateKey(\n cleanString,\n componentKey,\n existingKeys,\n extractedContent\n );\n\n const varMap = parts\n .filter((part) => part.type === 'var')\n .map((part) => `${part.value}: ${part.originalExpr}`);\n const uniqueVars = Array.from(new Set(varMap));\n\n if (hasVariables) {\n replacements.push({\n path,\n key,\n type: 'jsx-insertion',\n componentKey,\n childrenToReplace: children,\n variables: uniqueVars,\n });\n } else {\n replacements.push({\n path,\n key,\n type: 'jsx-text-combined',\n componentKey,\n childrenToReplace: children,\n });\n }\n\n children.forEach((child) => {\n handledNodes.add(child);\n });\n return true;\n }\n\n return false;\n};\n\n/**\n * Traverses the AST to identify components and extract content.\n * Returns extraction results and metadata about which components need Intlayer hooks.\n */\nexport const extractBabelContentForComponents = (\n ast: t.File,\n fileCode: string,\n existingKeys: Set<string>,\n defaultKey: string = 'default',\n configuration: IntlayerConfig,\n filePath: string,\n unmergedDictionaries: Record<string, unknown> = {}\n): {\n extractedContent: Record<string, Record<string, string>>;\n replacements: BabelReplacement[];\n componentsNeedingHooks: Set<NodePath>;\n componentKeyMap: Map<t.Node, string>;\n componentPaths: NodePath[];\n hookMap: Map<t.Node, 'useIntlayer' | 'getIntlayer'>;\n isSolid: boolean;\n} => {\n const extractedContent: Record<string, Record<string, string>> = {};\n const replacements: BabelReplacement[] = [];\n const handledNodes = new Set<t.Node>();\n const componentKeyMap = new Map<t.Node, string>();\n const hookMap = new Map<t.Node, 'useIntlayer' | 'getIntlayer'>();\n const usedKeysInFile = new Set<string>();\n let globalFileKey: string | undefined;\n\n const componentPaths: NodePath[] = [];\n\n traverse(ast, {\n FunctionDeclaration(path) {\n componentPaths.push(path);\n },\n ArrowFunctionExpression(path) {\n componentPaths.push(path);\n },\n FunctionExpression(path) {\n componentPaths.push(path);\n },\n });\n\n for (const path of componentPaths) {\n const existingInfo = getExistingIntlayerInfo(path);\n\n if (existingInfo) {\n componentKeyMap.set(path.node, existingInfo.key);\n usedKeysInFile.add(existingInfo.key);\n hookMap.set(path.node, existingInfo.hook);\n } else {\n if (!globalFileKey) {\n globalFileKey = resolveDictionaryKey(\n defaultKey,\n filePath,\n configuration,\n unmergedDictionaries,\n usedKeysInFile\n );\n usedKeysInFile.add(globalFileKey);\n }\n componentKeyMap.set(path.node, globalFileKey);\n\n const compName = getComponentName(path);\n const isComponent = compName ? /^[A-Z]/.test(compName) : false;\n hookMap.set(path.node, isComponent ? 'useIntlayer' : 'getIntlayer');\n }\n }\n\n const getComponentKeyForPath = (path: NodePath): string => {\n let current: NodePath | null = path;\n while (current) {\n if (componentKeyMap.has(current.node)) {\n return componentKeyMap.get(current.node)!;\n }\n current = current.parentPath;\n }\n return globalFileKey || defaultKey;\n };\n\n traverse(ast, {\n JSXElement(path) {\n if (handledNodes.has(path.node)) return;\n\n handleJsxInsertionBabel(\n path,\n fileCode,\n existingKeys,\n getComponentKeyForPath,\n extractedContent,\n replacements,\n handledNodes\n );\n },\n JSXFragment(path) {\n if (handledNodes.has(path.node)) return;\n\n handleJsxInsertionBabel(\n path,\n fileCode,\n existingKeys,\n getComponentKeyForPath,\n extractedContent,\n replacements,\n handledNodes\n );\n },\n JSXText(path) {\n if (handledNodes.has(path.node)) return;\n\n const text = path.node.value;\n\n if (shouldExtract(text)) {\n const componentKey = getComponentKeyForPath(path);\n const key = getOrGenerateKey(\n text.replace(/\\s+/g, ' ').trim(),\n componentKey,\n existingKeys,\n extractedContent\n );\n replacements.push({ path, key, type: 'jsx-text', componentKey });\n }\n },\n JSXAttribute(path) {\n if (handledNodes.has(path.node)) return;\n\n const name = path.node.name.name;\n\n if (\n typeof name !== 'string' ||\n !ATTRIBUTES_TO_EXTRACT.includes(name as any)\n )\n return;\n const value = path.node.value;\n\n if (t.isStringLiteral(value) && shouldExtract(value.value)) {\n const componentKey = getComponentKeyForPath(path);\n const key = getOrGenerateKey(\n value.value.trim(),\n componentKey,\n existingKeys,\n extractedContent\n );\n replacements.push({ path, key, type: 'jsx-attribute', componentKey });\n }\n },\n StringLiteral(path) {\n if (handledNodes.has(path.node)) return;\n\n const text = path.node.value;\n\n if (!shouldExtract(text)) return;\n\n const parent = path.parentPath;\n\n if (\n parent.isImportDeclaration() ||\n parent.isImportSpecifier() ||\n parent.isExportDeclaration()\n )\n return;\n\n if (parent.isJSXAttribute()) return;\n\n if (\n parent.isCallExpression() &&\n t.isMemberExpression(parent.node.callee)\n ) {\n if (\n t.isIdentifier(parent.node.callee.object) &&\n parent.node.callee.object.name === 'console' &&\n t.isIdentifier(parent.node.callee.property) &&\n parent.node.callee.property.name === 'log'\n ) {\n return;\n }\n }\n\n if (parent.isObjectProperty() && parent.node.key === path.node) return;\n\n if (parent.isMemberExpression() && parent.node.property === path.node)\n return;\n\n const componentKey = getComponentKeyForPath(path);\n const key = getOrGenerateKey(\n text.trim(),\n componentKey,\n existingKeys,\n extractedContent\n );\n replacements.push({ path, key, type: 'string-literal', componentKey });\n },\n });\n\n const componentsNeedingHooks = new Set<NodePath>();\n for (const componentPath of componentPaths) {\n const hasReplacements = replacements.some((replacement) => {\n let current: NodePath | null = replacement.path;\n while (current) {\n if (current.node === componentPath.node) return true;\n\n current = current.parentPath;\n }\n return false;\n });\n\n if (hasReplacements) {\n const key = componentKeyMap.get(componentPath.node)!;\n let ancestorProvidesKey = false;\n let currentPath: NodePath | null = componentPath.parentPath;\n while (currentPath) {\n const ancestorPath = componentPaths.find(\n (path) => path.node === currentPath?.node\n );\n\n if (ancestorPath) {\n const ancestorKey = componentKeyMap.get(ancestorPath.node);\n\n if (ancestorKey === key) {\n const ancestorHasReplacements = replacements.some((replacement) => {\n let rPath: NodePath | null = replacement.path;\n while (rPath) {\n if (rPath.node === ancestorPath.node) return true;\n\n rPath = rPath.parentPath;\n }\n return false;\n });\n const existingInfo = getExistingIntlayerInfo(ancestorPath);\n\n if (ancestorHasReplacements || existingInfo) {\n ancestorProvidesKey = true;\n break;\n }\n }\n }\n currentPath = currentPath.parentPath;\n }\n\n if (!ancestorProvidesKey) {\n componentsNeedingHooks.add(componentPath);\n }\n }\n }\n\n return {\n extractedContent,\n replacements,\n componentsNeedingHooks,\n componentKeyMap,\n componentPaths,\n hookMap,\n isSolid: false,\n };\n};\n\n/**\n * High-level function to extract content from TS/JS/JSX/TSX AST.\n */\nexport const extractTsContent = (\n ast: t.File,\n fileCode: string,\n existingKeys: Set<string>,\n configuration: IntlayerConfig,\n filePath: string,\n unmergedDictionaries: Record<string, unknown> = {}\n): {\n extractedContent: Record<string, string>;\n replacements: BabelReplacement[];\n} => {\n const { extractedContent, replacements } = extractBabelContentForComponents(\n ast,\n fileCode,\n existingKeys,\n 'default',\n configuration,\n filePath,\n unmergedDictionaries\n );\n\n const flatContent: Record<string, string> = {};\n for (const group of Object.values(extractedContent)) {\n Object.assign(flatContent, group);\n }\n\n return { extractedContent: flatContent, replacements };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"babelProcessor.cjs","names":["_traverse","t","shouldExtract","getOrGenerateKey","getExistingIntlayerInfo","resolveDictionaryKey","getComponentName","ATTRIBUTES_TO_EXTRACT"],"sources":["../../../src/extractContent/babelProcessor.ts"],"sourcesContent":["import _traverse, { type NodePath } from '@babel/traverse';\nimport * as t from '@babel/types';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { resolveDictionaryKey } from '../extractContent/utils';\nimport {\n ATTRIBUTES_TO_EXTRACT,\n getComponentName,\n getExistingIntlayerInfo,\n getOrGenerateKey,\n shouldExtract,\n} from './utils';\n\nexport type BabelReplacement = {\n path: NodePath;\n key: string;\n type:\n | 'jsx-text'\n | 'jsx-attribute'\n | 'string-literal'\n | 'jsx-insertion'\n | 'jsx-text-combined';\n componentKey: string;\n childrenToReplace?: t.Node[];\n variables?: string[];\n};\n\n// CJS/ESM interop: @babel/traverse exports its function as `.default` in CJS bundles\nconst traverse = (\n typeof _traverse === 'function' ? _traverse : (_traverse as any).default\n) as typeof _traverse;\n\n/**\n * Handles JSX insertions (elements with multiple children, including expressions).\n * Replaces complex JSX structures with variable-based translations.\n */\nexport const handleJsxInsertionBabel = (\n path: NodePath<t.JSXElement | t.JSXFragment>,\n fileCode: string,\n existingKeys: Set<string>,\n getComponentKeyForPath: (path: NodePath) => string,\n extractedContent: Record<string, Record<string, string>>,\n replacements: BabelReplacement[],\n handledNodes: Set<t.Node>\n): boolean => {\n const children = path.node.children;\n\n if (children.length <= 1) return false;\n\n const parts: {\n type: 'text' | 'var';\n value: string;\n originalExpr?: string;\n }[] = [];\n let hasSignificantText = false;\n let hasVariables = false;\n\n for (const child of children) {\n if (t.isJSXText(child)) {\n const text = child.value;\n\n if (text.trim().length > 0) hasSignificantText = true;\n\n parts.push({ type: 'text', value: text });\n } else if (t.isJSXExpressionContainer(child)) {\n if (t.isJSXEmptyExpression(child.expression)) {\n parts.push({ type: 'text', value: '' });\n } else {\n const expr = child.expression;\n\n if (t.isIdentifier(expr)) {\n parts.push({\n type: 'var',\n value: expr.name,\n originalExpr: expr.name,\n });\n hasVariables = true;\n } else if (t.isMemberExpression(expr)) {\n const code = fileCode.substring(expr.start!, expr.end!);\n\n const varName = t.isIdentifier(expr.property)\n ? expr.property.name\n : 'var';\n\n parts.push({ type: 'var', value: varName, originalExpr: code });\n\n hasVariables = true;\n } else {\n return false;\n }\n }\n } else {\n return false;\n }\n }\n\n if (!hasSignificantText) return false;\n\n let combinedString = '';\n for (const part of parts) {\n if (part.type === 'var') combinedString += `{{${part.value}}}`;\n else combinedString += part.value;\n }\n\n const cleanString = combinedString.replace(/\\s+/g, ' ').trim();\n\n if (shouldExtract(cleanString)) {\n const componentKey = getComponentKeyForPath(path);\n const key = getOrGenerateKey(\n cleanString,\n componentKey,\n existingKeys,\n extractedContent\n );\n\n const varMap = parts\n .filter((part) => part.type === 'var')\n .map((part) => `${part.value}: ${part.originalExpr}`);\n const uniqueVars = Array.from(new Set(varMap));\n\n if (hasVariables) {\n replacements.push({\n path,\n key,\n type: 'jsx-insertion',\n componentKey,\n childrenToReplace: children,\n variables: uniqueVars,\n });\n } else {\n replacements.push({\n path,\n key,\n type: 'jsx-text-combined',\n componentKey,\n childrenToReplace: children,\n });\n }\n\n children.forEach((child) => {\n handledNodes.add(child);\n });\n return true;\n }\n\n return false;\n};\n\n/**\n * Traverses the AST to identify components and extract content.\n * Returns extraction results and metadata about which components need Intlayer hooks.\n */\nexport const extractBabelContentForComponents = (\n ast: t.File,\n fileCode: string,\n existingKeys: Set<string>,\n defaultKey: string = 'default',\n configuration: IntlayerConfig,\n filePath: string,\n unmergedDictionaries: Record<string, unknown> = {}\n): {\n extractedContent: Record<string, Record<string, string>>;\n replacements: BabelReplacement[];\n componentsNeedingHooks: Set<NodePath>;\n componentKeyMap: Map<t.Node, string>;\n componentPaths: NodePath[];\n hookMap: Map<t.Node, 'useIntlayer' | 'getIntlayer'>;\n isSolid: boolean;\n} => {\n const extractedContent: Record<string, Record<string, string>> = {};\n const replacements: BabelReplacement[] = [];\n const handledNodes = new Set<t.Node>();\n const componentKeyMap = new Map<t.Node, string>();\n const hookMap = new Map<t.Node, 'useIntlayer' | 'getIntlayer'>();\n const usedKeysInFile = new Set<string>();\n let globalFileKey: string | undefined;\n\n const componentPaths: NodePath[] = [];\n\n traverse(ast, {\n FunctionDeclaration(path) {\n componentPaths.push(path);\n },\n ArrowFunctionExpression(path) {\n componentPaths.push(path);\n },\n FunctionExpression(path) {\n componentPaths.push(path);\n },\n });\n\n for (const path of componentPaths) {\n const existingInfo = getExistingIntlayerInfo(path);\n\n if (existingInfo) {\n componentKeyMap.set(path.node, existingInfo.key);\n usedKeysInFile.add(existingInfo.key);\n hookMap.set(path.node, existingInfo.hook);\n } else {\n if (!globalFileKey) {\n globalFileKey = resolveDictionaryKey(\n defaultKey,\n filePath,\n configuration,\n unmergedDictionaries,\n usedKeysInFile\n );\n usedKeysInFile.add(globalFileKey);\n }\n componentKeyMap.set(path.node, globalFileKey);\n\n const compName = getComponentName(path);\n const isComponent = compName ? /^[A-Z]/.test(compName) : false;\n hookMap.set(path.node, isComponent ? 'useIntlayer' : 'getIntlayer');\n }\n }\n\n const getComponentKeyForPath = (path: NodePath): string => {\n let current: NodePath | null = path;\n while (current) {\n if (componentKeyMap.has(current.node)) {\n return componentKeyMap.get(current.node)!;\n }\n current = current.parentPath;\n }\n return globalFileKey || defaultKey;\n };\n\n traverse(ast, {\n JSXElement(path) {\n if (handledNodes.has(path.node)) return;\n\n handleJsxInsertionBabel(\n path,\n fileCode,\n existingKeys,\n getComponentKeyForPath,\n extractedContent,\n replacements,\n handledNodes\n );\n },\n JSXFragment(path) {\n if (handledNodes.has(path.node)) return;\n\n handleJsxInsertionBabel(\n path,\n fileCode,\n existingKeys,\n getComponentKeyForPath,\n extractedContent,\n replacements,\n handledNodes\n );\n },\n JSXText(path) {\n if (handledNodes.has(path.node)) return;\n\n const text = path.node.value;\n\n if (shouldExtract(text)) {\n const componentKey = getComponentKeyForPath(path);\n const key = getOrGenerateKey(\n text.replace(/\\s+/g, ' ').trim(),\n componentKey,\n existingKeys,\n extractedContent\n );\n replacements.push({ path, key, type: 'jsx-text', componentKey });\n }\n },\n JSXAttribute(path) {\n if (handledNodes.has(path.node)) return;\n\n const name = path.node.name.name;\n\n if (\n typeof name !== 'string' ||\n !ATTRIBUTES_TO_EXTRACT.includes(name as any)\n )\n return;\n const value = path.node.value;\n\n if (t.isStringLiteral(value) && shouldExtract(value.value)) {\n const componentKey = getComponentKeyForPath(path);\n const key = getOrGenerateKey(\n value.value.trim(),\n componentKey,\n existingKeys,\n extractedContent\n );\n replacements.push({ path, key, type: 'jsx-attribute', componentKey });\n }\n },\n StringLiteral(path) {\n if (handledNodes.has(path.node)) return;\n\n const text = path.node.value;\n\n if (!shouldExtract(text)) return;\n\n const parent = path.parentPath;\n\n if (\n parent.isImportDeclaration() ||\n parent.isImportSpecifier() ||\n parent.isExportDeclaration()\n )\n return;\n\n if (parent.isJSXAttribute()) return;\n\n if (\n parent.isCallExpression() &&\n t.isMemberExpression(parent.node.callee)\n ) {\n if (\n t.isIdentifier(parent.node.callee.object) &&\n parent.node.callee.object.name === 'console' &&\n t.isIdentifier(parent.node.callee.property) &&\n parent.node.callee.property.name === 'log'\n ) {\n return;\n }\n }\n\n if (parent.isObjectProperty() && parent.node.key === path.node) return;\n\n if (parent.isMemberExpression() && parent.node.property === path.node)\n return;\n\n const componentKey = getComponentKeyForPath(path);\n const key = getOrGenerateKey(\n text.trim(),\n componentKey,\n existingKeys,\n extractedContent\n );\n replacements.push({ path, key, type: 'string-literal', componentKey });\n },\n });\n\n const componentsNeedingHooks = new Set<NodePath>();\n for (const componentPath of componentPaths) {\n const hasReplacements = replacements.some((replacement) => {\n let current: NodePath | null = replacement.path;\n while (current) {\n if (current.node === componentPath.node) return true;\n\n current = current.parentPath;\n }\n return false;\n });\n\n if (hasReplacements) {\n const key = componentKeyMap.get(componentPath.node)!;\n let ancestorProvidesKey = false;\n let currentPath: NodePath | null = componentPath.parentPath;\n while (currentPath) {\n const ancestorPath = componentPaths.find(\n (path) => path.node === currentPath?.node\n );\n\n if (ancestorPath) {\n const ancestorKey = componentKeyMap.get(ancestorPath.node);\n\n if (ancestorKey === key) {\n const ancestorHasReplacements = replacements.some((replacement) => {\n let rPath: NodePath | null = replacement.path;\n while (rPath) {\n if (rPath.node === ancestorPath.node) return true;\n\n rPath = rPath.parentPath;\n }\n return false;\n });\n const existingInfo = getExistingIntlayerInfo(ancestorPath);\n\n if (ancestorHasReplacements || existingInfo) {\n ancestorProvidesKey = true;\n break;\n }\n }\n }\n currentPath = currentPath.parentPath;\n }\n\n if (!ancestorProvidesKey) {\n componentsNeedingHooks.add(componentPath);\n }\n }\n }\n\n return {\n extractedContent,\n replacements,\n componentsNeedingHooks,\n componentKeyMap,\n componentPaths,\n hookMap,\n isSolid: false,\n };\n};\n\n/**\n * High-level function to extract content from TS/JS/JSX/TSX AST.\n */\nexport const extractTsContent = (\n ast: t.File,\n fileCode: string,\n existingKeys: Set<string>,\n configuration: IntlayerConfig,\n filePath: string,\n unmergedDictionaries: Record<string, unknown> = {}\n): {\n extractedContent: Record<string, string>;\n replacements: BabelReplacement[];\n} => {\n const { extractedContent, replacements } = extractBabelContentForComponents(\n ast,\n fileCode,\n existingKeys,\n 'default',\n configuration,\n filePath,\n unmergedDictionaries\n );\n\n const flatContent: Record<string, string> = {};\n for (const group of Object.values(extractedContent)) {\n Object.assign(flatContent, group);\n }\n\n return { extractedContent: flatContent, replacements };\n};\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);let e=require(`node:path`),t=require(`@intlayer/chokidar/cli`),n=require(`@intlayer/unmerged-dictionaries-entry`);const r=(t,r,i,a)=>{let{baseDir:o,fileExtensions:s}=i.content,c=((0,n.getUnmergedDictionaries)(i)??{})[r];if(c?.[0]?.filePath)return{contentFilePath:(0,e.resolve)(o,c[0].filePath),relativeContentFilePath:c[0].filePath};let l=a?(0,e.resolve)(a):(0,e.dirname)(t),u=s[0],d=u.startsWith(`.`)?u:`.${u}`,f=(0,e.basename)(t,(0,e.extname)(t)),p=(0,e.join)(l,`${f.charAt(0).toLowerCase()+f.slice(1)}${d}`);return{contentFilePath:p,relativeContentFilePath:(0,e.relative)(o,p)}},i=(e,t,n,r)=>{let{defaultLocale:i}=r.internationalization;if(r?.dictionary?.locale)return{key:t,content:e,locale:i,filePath:n};let a={};for(let[t,n]of Object.entries(e))a[t]={nodeType:`translation`,translation:{[i]:n}};return{key:t,content:a,filePath:n}},a=async(n,a,o,s,c)=>{let{contentFilePath:l,relativeContentFilePath:u}=r(o,a,s,c);return await(0,t.writeContentDeclaration)(i(n,a,u,s),s,{newDictionariesPath:(0,e.relative)(s.content.baseDir,(0,e.dirname)(l))}),l};exports.createDictionary=i,exports.resolveContentFilePath=r,exports.writeContentHelper=a;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./utils/extractDictionaryInfo.cjs`);let t=require(`node:fs`),n=require(`node:fs/promises`),r=require(`node:path`),i=require(`@intlayer/chokidar/build`),a=require(`@intlayer/core/plugins`),o;const s=(e,t,n)=>{let r=(0,a.insertContentInDictionary)(t??{key:``,content:{},filePath:``},e,n).content,i={};for(let t in e)i[t]=r[t];return i},c=(e,t)=>{let n=(0,a.insertContentInDictionary)(t??{key:``,content:{},filePath:``},e).content,r={};for(let t in e)r[t]=n[t];return r},l=async(a,l,u,d)=>{let{absolutePath:f,isPerLocale:p}=await e.resolveContentFilePaths(u,l,d),{defaultLocale:m}=d.internationalization,{baseDir:h}=d.system;o||=await(0,i.ensureIntlayerBundle)(d);let g=(0,r.dirname)(f);await(0,n.mkdir)(g,{recursive:!0});let _=null;if((0,t.existsSync)(f))try{_=await(0,i.loadContentDeclaration)(f,d,o)??null}catch(e){console.error(e)}let v=(0,r.relative)(h,f),y;if(p){let e=c(a,_);y={..._,key:l,content:e,locale:m,filePath:v}}else{let e=s(a,_,m);y={..._,key:l,content:e,filePath:v}}let b=(0,r.relative)(h,g),x=await(0,i.writeContentDeclaration)(y,d,{newDictionariesPath:b,localeList:[m]});return await(0,i.buildDictionary)([{...y,filePath:(0,r.relative)(h,x?.path??f)}],d),f};exports.mergeWithExistingMultilingualDictionary=s,exports.mergeWithExistingPerLocaleDictionary=c,exports.writeContentHelper=l;
2
2
  //# sourceMappingURL=contentWriter.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"contentWriter.cjs","names":[],"sources":["../../../src/extractContent/contentWriter.ts"],"sourcesContent":["import { basename, dirname, extname, join, relative, resolve } from 'node:path';\nimport { writeContentDeclaration } from '@intlayer/chokidar/cli';\nimport type {\n Dictionary,\n DictionaryKey,\n IntlayerConfig,\n} from '@intlayer/types';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\n\nexport type TranslationNode = {\n nodeType: 'translation';\n translation: Record<string, string>;\n};\n\n/**\n * Resolves the path for the content file associated with a component.\n * Checks for existing dictionaries first.\n */\nexport const resolveContentFilePath = (\n filePath: string,\n componentKey: string,\n configuration: IntlayerConfig,\n outputDir?: string\n): { contentFilePath: string; relativeContentFilePath: string } => {\n const { baseDir, fileExtensions } = configuration.content;\n const unmergedDictionaries = getUnmergedDictionaries(configuration) ?? {};\n const existingDicts = unmergedDictionaries[componentKey] as\n | Dictionary[]\n | undefined;\n\n if (existingDicts?.[0]?.filePath) {\n return {\n contentFilePath: resolve(baseDir, existingDicts[0].filePath),\n relativeContentFilePath: existingDicts[0].filePath,\n };\n }\n\n const dirName = outputDir ? resolve(outputDir) : dirname(filePath);\n const firstExtension = fileExtensions[0];\n const extension = firstExtension.startsWith('.')\n ? firstExtension\n : `.${firstExtension}`;\n const originalFileBase = basename(filePath, extname(filePath));\n const contentBaseName =\n originalFileBase.charAt(0).toLowerCase() + originalFileBase.slice(1);\n const contentFilePath = join(dirName, `${contentBaseName}${extension}`);\n const relativeContentFilePath = relative(baseDir, contentFilePath);\n\n return { contentFilePath, relativeContentFilePath };\n};\n\n/**\n * Creates a dictionary object from extracted content.\n * Handles both single-locale and multi-locale formats based on configuration.\n */\nexport const createDictionary = (\n extractedContent: Record<string, string>,\n componentKey: string,\n relativeContentFilePath: string,\n configuration: IntlayerConfig\n): Dictionary => {\n const { defaultLocale } = configuration.internationalization;\n const isPerLocaleFile = configuration?.dictionary?.locale;\n\n if (isPerLocaleFile) {\n return {\n key: componentKey,\n content: extractedContent,\n locale: defaultLocale,\n filePath: relativeContentFilePath,\n } as Dictionary;\n }\n\n const multilingualContent: Record<string, TranslationNode> = {};\n\n for (const [key, value] of Object.entries(extractedContent)) {\n multilingualContent[key] = {\n nodeType: 'translation',\n translation: {\n [defaultLocale]: value,\n },\n };\n }\n\n return {\n key: componentKey as DictionaryKey,\n content: multilingualContent,\n filePath: relativeContentFilePath,\n } as Dictionary;\n};\n\n/**\n * Helper to write extracted content to a dictionary file.\n */\nexport const writeContentHelper = async (\n extractedContent: Record<string, string>,\n componentKey: string,\n filePath: string,\n configuration: IntlayerConfig,\n outputDir?: string\n): Promise<string> => {\n const { contentFilePath, relativeContentFilePath } = resolveContentFilePath(\n filePath,\n componentKey,\n configuration,\n outputDir\n );\n\n const dictionary = createDictionary(\n extractedContent,\n componentKey,\n relativeContentFilePath,\n configuration\n );\n\n const relativeDir = relative(\n configuration.content.baseDir,\n dirname(contentFilePath)\n );\n\n await writeContentDeclaration(dictionary, configuration, {\n newDictionariesPath: relativeDir,\n });\n\n return contentFilePath;\n};\n"],"mappings":"kOAkBA,MAAa,GACX,EACA,EACA,EACA,IACiE,CACjE,GAAM,CAAE,UAAS,kBAAmB,EAAc,QAE5C,IAAA,EAAA,EAAA,yBAD+C,EAAc,EAAI,EAAE,EAC9B,GAI3C,GAAI,IAAgB,IAAI,SACtB,MAAO,CACL,iBAAA,EAAA,EAAA,SAAyB,EAAS,EAAc,GAAG,SAAS,CAC5D,wBAAyB,EAAc,GAAG,SAC3C,CAGH,IAAM,EAAU,GAAA,EAAA,EAAA,SAAoB,EAAU,EAAA,EAAA,EAAA,SAAW,EAAS,CAC5D,EAAiB,EAAe,GAChC,EAAY,EAAe,WAAW,IAAI,CAC5C,EACA,IAAI,IACF,GAAA,EAAA,EAAA,UAA4B,GAAA,EAAA,EAAA,SAAkB,EAAS,CAAC,CAGxD,GAAA,EAAA,EAAA,MAAuB,EAAS,GADpC,EAAiB,OAAO,EAAE,CAAC,aAAa,CAAG,EAAiB,MAAM,EAAE,GACX,IAAY,CAGvE,MAAO,CAAE,kBAAiB,yBAAA,EAAA,EAAA,UAFe,EAAS,EAAgB,CAEf,EAOxC,GACX,EACA,EACA,EACA,IACe,CACf,GAAM,CAAE,iBAAkB,EAAc,qBAGxC,GAFwB,GAAe,YAAY,OAGjD,MAAO,CACL,IAAK,EACL,QAAS,EACT,OAAQ,EACR,SAAU,EACX,CAGH,IAAM,EAAuD,EAAE,CAE/D,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAiB,CACzD,EAAoB,GAAO,CACzB,SAAU,cACV,YAAa,EACV,GAAgB,EAClB,CACF,CAGH,MAAO,CACL,IAAK,EACL,QAAS,EACT,SAAU,EACX,EAMU,EAAqB,MAChC,EACA,EACA,EACA,EACA,IACoB,CACpB,GAAM,CAAE,kBAAiB,2BAA4B,EACnD,EACA,EACA,EACA,EACD,CAkBD,OAJA,MAAA,EAAA,EAAA,yBAZmB,EACjB,EACA,EACA,EACA,EACD,CAOyC,EAAe,CACvD,qBAAA,EAAA,EAAA,UALA,EAAc,QAAQ,SAAA,EAAA,EAAA,SACd,EAAgB,CACzB,CAIA,CAAC,CAEK"}
1
+ {"version":3,"file":"contentWriter.cjs","names":["resolveContentFilePaths"],"sources":["../../../src/extractContent/contentWriter.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { dirname, relative } from 'node:path';\nimport {\n buildDictionary,\n ensureIntlayerBundle,\n loadContentDeclaration,\n writeContentDeclaration,\n} from '@intlayer/chokidar/build';\nimport { insertContentInDictionary } from '@intlayer/core/plugins';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary, DictionaryKey } from '@intlayer/types/dictionary';\nimport { resolveContentFilePaths } from './utils/extractDictionaryInfo';\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 * Cached bundle file path to optimize performance\n */\nlet cachedBundleFilePath: string | undefined;\n\n/**\n * Merge extracted content with existing dictionary for multilingual format.\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 */\nexport const mergeWithExistingMultilingualDictionary = (\n extractedContent: Record<string, string>,\n existingDictionary: Dictionary | null,\n defaultLocale: string\n): DictionaryContentMap => {\n const dictionary: Dictionary =\n existingDictionary ??\n ({\n key: '',\n content: {},\n filePath: '',\n } as Dictionary);\n\n const mergedDictionary = insertContentInDictionary(\n dictionary,\n extractedContent,\n defaultLocale as Locale\n );\n\n const mergedContent = mergedDictionary.content as DictionaryContentMap;\n\n // Pruning: remove keys not in extractedContent\n const finalContent: DictionaryContentMap = {};\n for (const key in extractedContent) {\n finalContent[key] = mergedContent[key];\n }\n\n return finalContent;\n};\n\n/**\n * Merge extracted content with existing dictionary for per-locale format.\n * - Keys in extracted but not in existing: added\n * - Keys in both: update value\n * - Keys in existing but not in extracted: removed (no longer in source)\n */\nexport const mergeWithExistingPerLocaleDictionary = (\n extractedContent: Record<string, string>,\n existingDictionary: Dictionary | null\n): Record<string, string> => {\n const dictionary: Dictionary =\n existingDictionary ??\n ({\n key: '',\n content: {},\n filePath: '',\n } as Dictionary);\n\n const mergedDictionary = insertContentInDictionary(\n dictionary,\n extractedContent\n );\n\n const mergedContent = mergedDictionary.content as Record<string, string>;\n\n // Pruning: remove keys not in extractedContent\n const finalContent: Record<string, string> = {};\n for (const key in extractedContent) {\n finalContent[key] = mergedContent[key];\n }\n\n return finalContent;\n};\n\n/**\n * Helper to write extracted content to dictionary file(s).\n */\nexport const writeContentHelper = async (\n extractedContent: Record<string, string>,\n dictionaryKey: DictionaryKey,\n filePath: string,\n configuration: IntlayerConfig\n): Promise<string> => {\n const { absolutePath, isPerLocale } = await resolveContentFilePaths(\n filePath,\n dictionaryKey,\n configuration\n );\n\n const { defaultLocale } = configuration.internationalization;\n const { baseDir } = configuration.system;\n\n if (!cachedBundleFilePath) {\n cachedBundleFilePath = await ensureIntlayerBundle(configuration);\n }\n\n const outputDir = dirname(absolutePath);\n\n // Ensure output directory exists\n await mkdir(outputDir, { recursive: true });\n\n // Read existing dictionary to preserve translations and metadata\n let existingDictionary: Dictionary | null = null;\n\n if (existsSync(absolutePath)) {\n try {\n const dictionary = await loadContentDeclaration(\n absolutePath,\n configuration,\n cachedBundleFilePath\n );\n\n existingDictionary = dictionary ?? null;\n } catch (error) {\n console.error(error);\n }\n }\n\n const relativeContentFilePath = relative(baseDir, absolutePath);\n\n let mergedDictionary: Dictionary;\n\n if (isPerLocale) {\n // Per-locale format: simple string content for a single locale\n const mergedContent = mergeWithExistingPerLocaleDictionary(\n extractedContent,\n existingDictionary\n );\n\n mergedDictionary = {\n // Preserve existing metadata\n ...existingDictionary,\n key: dictionaryKey,\n content: mergedContent,\n locale: defaultLocale,\n filePath: relativeContentFilePath,\n };\n } else {\n // Multilingual format: content wrapped in translation nodes for multiple locales\n const mergedContent = mergeWithExistingMultilingualDictionary(\n extractedContent,\n existingDictionary,\n defaultLocale\n );\n\n mergedDictionary = {\n // Preserve existing metadata\n ...existingDictionary,\n key: dictionaryKey,\n content: mergedContent,\n filePath: relativeContentFilePath,\n };\n }\n\n const relativeDir = relative(baseDir, outputDir);\n\n const writeResult = await writeContentDeclaration(\n mergedDictionary,\n configuration,\n {\n newDictionariesPath: relativeDir,\n localeList: [defaultLocale],\n }\n );\n\n // Build the dictionary immediately\n const dictionaryToBuild: Dictionary = {\n ...mergedDictionary,\n filePath: relative(baseDir, writeResult?.path ?? absolutePath),\n };\n\n await buildDictionary([dictionaryToBuild], configuration);\n\n return absolutePath;\n};\n"],"mappings":"6TA+BI,EAQJ,MAAa,GACX,EACA,EACA,IACyB,CAezB,IAAM,GAAA,EAAA,EAAA,2BAbJ,GACC,CACC,IAAK,GACL,QAAS,EAAE,CACX,SAAU,GACX,CAID,EACA,EACD,CAEsC,QAGjC,EAAqC,EAAE,CAC7C,IAAK,IAAM,KAAO,EAChB,EAAa,GAAO,EAAc,GAGpC,OAAO,GASI,GACX,EACA,IAC2B,CAc3B,IAAM,GAAA,EAAA,EAAA,2BAZJ,GACC,CACC,IAAK,GACL,QAAS,EAAE,CACX,SAAU,GACX,CAID,EACD,CAEsC,QAGjC,EAAuC,EAAE,CAC/C,IAAK,IAAM,KAAO,EAChB,EAAa,GAAO,EAAc,GAGpC,OAAO,GAMI,EAAqB,MAChC,EACA,EACA,EACA,IACoB,CACpB,GAAM,CAAE,eAAc,eAAgB,MAAMA,EAAAA,wBAC1C,EACA,EACA,EACD,CAEK,CAAE,iBAAkB,EAAc,qBAClC,CAAE,WAAY,EAAc,OAElC,AACE,IAAuB,MAAA,EAAA,EAAA,sBAA2B,EAAc,CAGlE,IAAM,GAAA,EAAA,EAAA,SAAoB,EAAa,CAGvC,MAAA,EAAA,EAAA,OAAY,EAAW,CAAE,UAAW,GAAM,CAAC,CAG3C,IAAI,EAAwC,KAE5C,IAAA,EAAA,EAAA,YAAe,EAAa,CAC1B,GAAI,CAOF,EANmB,MAAA,EAAA,EAAA,wBACjB,EACA,EACA,EACD,EAEkC,WAC5B,EAAO,CACd,QAAQ,MAAM,EAAM,CAIxB,IAAM,GAAA,EAAA,EAAA,UAAmC,EAAS,EAAa,CAE3D,EAEJ,GAAI,EAAa,CAEf,IAAM,EAAgB,EACpB,EACA,EACD,CAED,EAAmB,CAEjB,GAAG,EACH,IAAK,EACL,QAAS,EACT,OAAQ,EACR,SAAU,EACX,KACI,CAEL,IAAM,EAAgB,EACpB,EACA,EACA,EACD,CAED,EAAmB,CAEjB,GAAG,EACH,IAAK,EACL,QAAS,EACT,SAAU,EACX,CAGH,IAAM,GAAA,EAAA,EAAA,UAAuB,EAAS,EAAU,CAE1C,EAAc,MAAA,EAAA,EAAA,yBAClB,EACA,EACA,CACE,oBAAqB,EACrB,WAAY,CAAC,EAAc,CAC5B,CACF,CAUD,OAFA,MAAA,EAAA,EAAA,iBAAsB,CALgB,CACpC,GAAG,EACH,UAAA,EAAA,EAAA,UAAmB,EAAS,GAAa,MAAQ,EAAa,CAC/D,CAEwC,CAAE,EAAc,CAElD"}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./utils/constants.cjs`),t=require(`./utils/extractDictionaryKey.cjs`),n=require(`./utils/generateKey.cjs`),r=require(`./utils/shouldExtract.cjs`),i=require(`./babelProcessor.cjs`),a=require(`./processTsxFile.cjs`),o=require(`./contentWriter.cjs`);let s=require(`node:path`),c=require(`@intlayer/config/logger`),l=require(`@intlayer/config/node`),u=require(`node:child_process`),d=require(`node:fs`),f=require(`@intlayer/chokidar/cli`),p=require(`@intlayer/unmerged-dictionaries-entry`),m=null,h=null;const g=async(g,_,v)=>{let y=!v?.declarationOnly,b=!v?.codeOnly&&!v?.onExtract,x=v?.configuration??(0,l.getConfiguration)(v?.configOptions),S=(0,c.getAppLogger)(x),{baseDir:C}=x.content,w=v?.unmergedDictionaries??(0,p.getUnmergedDictionaries)(x),T=v?.code??(0,d.readFileSync)(g,`utf-8`),E=t.extractDictionaryKey(g,T),D=(0,s.extname)(g),O=(0,s.relative)(C,g),k=null,A=null;if(D===`.vue`)try{m??=await import(`@intlayer/vue-compiler`);let a=await m.processVueFile(g,E,_,{generateKey:n.generateKey,shouldExtract:r.shouldExtract,attributesToExtract:e.ATTRIBUTES_TO_EXTRACT,extractDictionaryKeyFromPath:t.extractDictionaryKeyFromPath,extractTsContent:(e,t,n,r,a)=>i.extractTsContent(e,t,n,r,a,w)},y);a&&(k={[E]:a})}catch(e){throw e.code===`ERR_MODULE_NOT_FOUND`||e.message?.includes(`Cannot find module`)?Error(`Please install ${(0,c.colorizePath)(`@intlayer/vue-compiler`,c.ANSIColors.YELLOW)} to process Vue files.`):e}else if(D===`.svelte`)try{h??=await import(`@intlayer/svelte-compiler`);let a=await h.processSvelteFile(g,E,_,{generateKey:n.generateKey,shouldExtract:r.shouldExtract,attributesToExtract:e.ATTRIBUTES_TO_EXTRACT,extractDictionaryKeyFromPath:t.extractDictionaryKeyFromPath,extractTsContent:(e,t,n,r,a)=>i.extractTsContent(e,t,n,r,a,w)},y);a&&(k={[E]:a})}catch(e){throw e.code===`ERR_MODULE_NOT_FOUND`||e.message?.includes(`Cannot find module`)?Error(`Please install ${(0,c.colorizePath)(`@intlayer/svelte-compiler`,c.ANSIColors.YELLOW)} to process Svelte files.`):e}else if([`.tsx`,`.jsx`,`.ts`,`.js`].includes(D))try{let e=a.processTsxFile(g,E,_,x,y,w,T);e&&(k=e.extractedContent,A=e.modifiedCode)}catch(e){throw e.code===`ERR_MODULE_NOT_FOUND`||e.message?.includes(`Cannot find module`)?Error(`Please install ${(0,c.colorizePath)(`@intlayer/babel`,c.ANSIColors.YELLOW)} to process TSX/JSX/TS/JS files.`):e}if(!k||Object.keys(k).length===0){S(`${(0,c.colorize)(`Compiler:`,c.ANSIColors.GREY_DARK)} No extractable text found in ${(0,c.colorizePath)(O)}`,{isVerbose:!0});return}if(v?.onExtract)for(let[e,t]of Object.entries(k))await v.onExtract({key:e,content:t,filePath:g});if(b)for(let[e,t]of Object.entries(k)){let n=await o.writeContentHelper(t,e,g,x,v?.outputDir),r=(0,s.relative)(x.content.baseDir,n);S(`${(0,c.colorize)(`Compiler:`,c.ANSIColors.GREY_DARK)} Created content file: ${(0,c.colorizePath)(r)}`)}if(y){let e=(0,f.detectFormatCommand)(x);if(e)try{(0,u.execSync)(e.replace(`{{file}}`,g),{stdio:`inherit`,cwd:C})}catch(e){console.error(e)}S(`${(0,c.colorize)(`Compiler:`,c.ANSIColors.GREY_DARK)} Updated component: ${(0,c.colorizePath)((0,s.relative)(C,g))}`)}return{transformedCode:A}};exports.extractContent=g;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./utils/extractDictionaryKey.cjs`),t=require(`./utils/extractDictionaryInfo.cjs`),n=require(`./contentWriter.cjs`),r=require(`./utils/constants.cjs`),i=require(`./utils/generateKey.cjs`),a=require(`./utils/shouldExtract.cjs`),o=require(`./babelProcessor.cjs`),s=require(`./processTsxFile.cjs`);let c=require(`@intlayer/chokidar/utils`),l=require(`@intlayer/config/logger`),u=require(`@intlayer/config/node`),d=require(`node:fs`),f=require(`node:path`),p=require(`@intlayer/config/utils`),m=require(`@intlayer/unmerged-dictionaries-entry`),h=require(`@intlayer/chokidar/cli`),g=require(`node:child_process`),_=null,v=null;const y=(e,t)=>{if(t)return{extractedContentMap:{[e]:t.extractedContent},transformedCode:t.code}},b=(t,n,c,u,p,m)=>{let h=c?.code??(0,d.readFileSync)(t,`utf-8`),g=m??e.extractDictionaryKey(t,h,u.configuration.compiler.dictionaryKeyPrefix),_=(0,f.extname)(t),{vueCompiler:v,svelteCompiler:b,unmergedDictionaries:x,configuration:S}=u,C={generateKey:i.generateKey,shouldExtract:a.shouldExtract,attributesToExtract:r.ATTRIBUTES_TO_EXTRACT,extractDictionaryKeyFromPath:e.extractDictionaryKeyFromPath,extractTsContent:(e,t,n,r,i)=>o.extractTsContent(e,t,n,r,i,x)};if(_===`.vue`){if(!v)throw Error(`Please install ${(0,l.colorizePath)(`@intlayer/vue-compiler`,l.ANSIColors.YELLOW)} to process Vue files.`);let e=v.processVueFile(t,g,n,C,p);if(e)return y(g,e)}if(_===`.svelte`){if(!b)throw Error(`Please install ${(0,l.colorizePath)(`@intlayer/svelte-compiler`,l.ANSIColors.YELLOW)} to process Svelte files.`);let e=b.processSvelteFile(t,g,n,C,p);if(e)return y(g,e)}if([`.tsx`,`.jsx`,`.ts`,`.js`,`.cjs`,`.mjs`].includes(_)){let e=s.processTsxFile(t,g,n,S,p,x,h);if(e)return{extractedContentMap:e.extractedContent,transformedCode:e.modifiedCode}}},x=async(e,t,r,{configuration:i,baseDir:a,appLogger:o},s)=>{if(r?.onExtract)for(let[n,i]of Object.entries(e))await r.onExtract({key:n,content:i,filePath:t});if(!r?.codeOnly&&!r?.onExtract)for(let[r,s]of Object.entries(e)){let e=(0,f.relative)(a,await n.writeContentHelper(s,r,t,i));o(`${(0,l.colorize)(`Compiler:`,l.ANSIColors.GREY_DARK)} Created content file: ${(0,l.colorizePath)(e)}`)}if(s){let e=(0,h.detectFormatCommand)(i);if(e)try{(0,g.execSync)(e.replace(`{{file}}`,t),{stdio:`inherit`,cwd:a})}catch(e){console.error(e)}o(`${(0,l.colorize)(`Compiler:`,l.ANSIColors.GREY_DARK)} Updated component: ${(0,l.colorizePath)((0,f.relative)(a,t))}`)}},S=async(n,r,i)=>{let a=i?.configuration??(0,u.getConfiguration)(i?.configOptions),o=(0,l.getAppLogger)(a),{baseDir:s}=a.system,c=i?.unmergedDictionaries??(0,m.getUnmergedDictionaries)(a),p=!i?.declarationOnly,h=(0,f.extname)(n);h===`.vue`&&!_&&(_=await import(`@intlayer/vue-compiler`)),h===`.svelte`&&!v&&(v=await import(`@intlayer/svelte-compiler`));let g=e.extractDictionaryKey(n,i?.code??(0,d.readFileSync)(n,`utf-8`),a.compiler.dictionaryKeyPrefix),y=await b(n,r,i,{vueCompiler:_,svelteCompiler:v,unmergedDictionaries:c,configuration:a},p,g);if(!y||!y.extractedContentMap){o(`${(0,l.colorize)(`Compiler:`,l.ANSIColors.GREY_DARK)} No extractable text found in ${(0,l.colorizePath)((0,f.relative)(s,n))}`,{isVerbose:!0});return}let{relativePath:S}=await t.resolveContentFilePaths(n,g,a);return o(`${(0,l.colorize)(`Compiler:`,l.ANSIColors.GREY_DARK)} Target dictionary path: ${(0,l.colorizePath)(S)}`,{isVerbose:!0}),await x(y.extractedContentMap,n,i,{configuration:a,baseDir:s,appLogger:o},p),{transformedCode:y.transformedCode}},C=(e,t,n)=>{let r=n?.configuration??(0,u.getConfiguration)(n?.configOptions),i=(0,l.getAppLogger)(r),{baseDir:a}=r.system,o=n?.unmergedDictionaries??(0,m.getUnmergedDictionaries)(r),s=!n?.declarationOnly,d=(0,f.extname)(e),h=(0,p.getProjectRequire)();if(d===`.vue`&&!_)try{_=h(`@intlayer/vue-compiler`)}catch{}if(d===`.svelte`&&!v)try{v=h(`@intlayer/svelte-compiler`)}catch{}let g=b(e,t,n,{vueCompiler:_,svelteCompiler:v,unmergedDictionaries:o,configuration:r},s);if(g instanceof Promise)throw Error(`Synchronous extraction failed: External compiler returned a Promise for ${(0,c.formatPath)((0,f.relative)(a,e))}`);if(g?.extractedContentMap){let{extractedContentMap:t,transformedCode:r}=g;if(n?.onExtract)for(let[r,i]of Object.entries(t))n.onExtract({key:r,content:i,filePath:e});return{transformedCode:r,extractedContent:t}}i(`${(0,l.colorize)(`Compiler:`,l.ANSIColors.GREY_DARK)} No extractable text found in ${(0,l.colorizePath)((0,f.relative)(a,e))}`,{isVerbose:!0})};exports.extractContent=S,exports.extractContentSync=C;
2
2
  //# sourceMappingURL=extractContent.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractContent.cjs","names":["extractDictionaryKey","ATTRIBUTES_TO_EXTRACT","extractTsContent","ANSIColors","processTsxFile","writeContentHelper"],"sources":["../../../src/extractContent/extractContent.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { readFileSync } from 'node:fs';\nimport { extname, relative } from 'node:path';\nimport { detectFormatCommand } from '@intlayer/chokidar/cli';\nimport {\n ANSIColors,\n colorize,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { IntlayerConfig } from '@intlayer/types';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { extractTsContent } from './babelProcessor';\nimport { writeContentHelper } from './contentWriter';\nimport { processTsxFile } from './processTsxFile';\nimport {\n ATTRIBUTES_TO_EXTRACT,\n extractDictionaryKeyFromPath,\n type PackageName,\n shouldExtract,\n} from './utils';\nimport { extractDictionaryKey } from './utils/extractDictionaryKey';\nimport { generateKey } from './utils/generateKey';\n\nexport type ExtractIntlayerOptions = {\n configOptions?: GetConfigurationOptions;\n outputDir?: string;\n /**\n * If true, only transform the source file — skip writing content declarations.\n */\n codeOnly?: boolean;\n /**\n * If true, only write content declarations — skip transforming the source file.\n * When set, `transformedCode` will still be returned (computed but not written to disk).\n */\n declarationOnly?: boolean;\n unmergedDictionaries?: Record<string, unknown>;\n configuration?: IntlayerConfig;\n /**\n * Raw source code to process instead of reading from disk.\n * Useful for Vite/webpack transform hooks where the code may already\n * have been modified by a previous plugin.\n */\n code?: string;\n /**\n * Callback invoked for each extracted dictionary key/content pair.\n * When provided, the caller is responsible for writing content declarations\n * (the built-in `writeContentHelper` is skipped unless `writeContent` is also true).\n * Used by Vite/webpack plugins that manage their own dictionary write pipeline.\n */\n onExtract?: (result: {\n key: string;\n content: Record<string, string>;\n filePath: string;\n }) => void | Promise<void>;\n};\n\n// Module caches for optional compiler packages\nlet vueCompiler: typeof import('@intlayer/vue-compiler') | null = null;\nlet svelteCompiler: typeof import('@intlayer/svelte-compiler') | null = null;\n\n/**\n * Extracts Intlayer content from a single source file and optionally transforms it.\n *\n * - For `.vue` / `.svelte` files the matching optional compiler package is used.\n * - For `.tsx` / `.jsx` / `.ts` / `.js` files the Babel-based `processTsxFile` is used.\n *\n * Returns `{ transformedCode }` so callers (e.g. the Vite plugin) can pass the\n * modified source back to the bundler without writing the file to disk.\n */\nexport const extractContent = async (\n filePath: string,\n packageName: PackageName,\n options?: ExtractIntlayerOptions\n): Promise<{ transformedCode: string | null } | undefined> => {\n const saveComponent = !options?.declarationOnly;\n const writeContent = !options?.codeOnly && !options?.onExtract;\n\n const configuration =\n options?.configuration ?? getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(configuration);\n const { baseDir } = configuration.content;\n\n const unmergedDictionaries =\n options?.unmergedDictionaries ?? getUnmergedDictionaries(configuration);\n\n const fileText = options?.code ?? readFileSync(filePath, 'utf-8');\n const componentKey = extractDictionaryKey(filePath, fileText);\n const ext = extname(filePath);\n const relativeFilePath = relative(baseDir, filePath);\n\n let extractedContentMap: Record<string, Record<string, string>> | null = null;\n let transformedCode: string | null = null;\n\n if (ext === '.vue') {\n try {\n vueCompiler ??= await import('@intlayer/vue-compiler');\n\n const res = await vueCompiler.processVueFile(\n filePath,\n componentKey,\n packageName,\n {\n generateKey,\n shouldExtract,\n attributesToExtract: ATTRIBUTES_TO_EXTRACT,\n extractDictionaryKeyFromPath,\n extractTsContent: (\n ast: any,\n code: string,\n keys: Set<string>,\n config: any,\n path: string\n ) =>\n extractTsContent(\n ast,\n code,\n keys,\n config,\n path,\n unmergedDictionaries\n ),\n },\n saveComponent\n );\n\n if (res) {\n extractedContentMap = {\n [componentKey]: res as Record<string, string>,\n };\n }\n } catch (error: any) {\n if (\n error.code === 'ERR_MODULE_NOT_FOUND' ||\n error.message?.includes('Cannot find module')\n ) {\n throw new Error(\n `Please install ${colorizePath('@intlayer/vue-compiler', ANSIColors.YELLOW)} to process Vue files.`\n );\n }\n throw error;\n }\n } else if (ext === '.svelte') {\n try {\n svelteCompiler ??= await import('@intlayer/svelte-compiler');\n\n const res = await svelteCompiler.processSvelteFile(\n filePath,\n componentKey,\n packageName,\n {\n generateKey,\n shouldExtract,\n attributesToExtract: ATTRIBUTES_TO_EXTRACT,\n extractDictionaryKeyFromPath,\n extractTsContent: (\n ast: any,\n code: string,\n keys: Set<string>,\n config: any,\n path: string\n ) =>\n extractTsContent(\n ast,\n code,\n keys,\n config,\n path,\n unmergedDictionaries\n ),\n },\n saveComponent\n );\n\n if (res) {\n extractedContentMap = {\n [componentKey]: res as Record<string, string>,\n };\n }\n } catch (error: any) {\n if (\n error.code === 'ERR_MODULE_NOT_FOUND' ||\n error.message?.includes('Cannot find module')\n ) {\n throw new Error(\n `Please install ${colorizePath('@intlayer/svelte-compiler', ANSIColors.YELLOW)} to process Svelte files.`\n );\n }\n throw error;\n }\n } else if (['.tsx', '.jsx', '.ts', '.js'].includes(ext)) {\n try {\n const result = processTsxFile(\n filePath,\n componentKey,\n packageName,\n configuration,\n saveComponent,\n unmergedDictionaries,\n fileText\n );\n\n if (result) {\n extractedContentMap = result.extractedContent;\n transformedCode = result.modifiedCode;\n }\n } catch (error: any) {\n if (\n error.code === 'ERR_MODULE_NOT_FOUND' ||\n error.message?.includes('Cannot find module')\n ) {\n throw new Error(\n `Please install ${colorizePath('@intlayer/babel', ANSIColors.YELLOW)} to process TSX/JSX/TS/JS files.`\n );\n }\n throw error;\n }\n }\n\n if (!extractedContentMap || Object.keys(extractedContentMap).length === 0) {\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} No extractable text found in ${colorizePath(relativeFilePath)}`,\n {\n isVerbose: true,\n }\n );\n return undefined;\n }\n\n // Notify caller via callback (e.g. Vite plugin's own dictionary pipeline)\n if (options?.onExtract) {\n for (const [key, content] of Object.entries(extractedContentMap)) {\n await options.onExtract({ key, content, filePath });\n }\n }\n\n // Write content declarations using the built-in helper when no custom callback\n if (writeContent) {\n for (const [key, content] of Object.entries(extractedContentMap)) {\n const contentFilePath = await writeContentHelper(\n content,\n key,\n filePath,\n configuration,\n options?.outputDir\n );\n\n const relativeContentFilePath = relative(\n configuration.content.baseDir,\n contentFilePath\n );\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} Created content file: ${colorizePath(relativeContentFilePath)}`\n );\n }\n }\n\n if (saveComponent) {\n const formatCommand = detectFormatCommand(configuration);\n\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', filePath), {\n stdio: 'inherit',\n cwd: baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} Updated component: ${colorizePath(relative(baseDir, filePath))}`\n );\n }\n\n return { transformedCode };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"extractContent.cjs","names":["extractDictionaryKey","ATTRIBUTES_TO_EXTRACT","extractTsContent","ANSIColors","processTsxFile","writeContentHelper","resolveContentFilePaths"],"sources":["../../../src/extractContent/extractContent.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { readFileSync } from 'node:fs';\nimport { extname, relative } from 'node:path';\nimport type * as t from '@babel/types';\nimport { detectFormatCommand } from '@intlayer/chokidar/cli';\nimport { formatPath } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { getProjectRequire } from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { extractTsContent } from './babelProcessor';\nimport { writeContentHelper } from './contentWriter';\nimport { processTsxFile } from './processTsxFile';\nimport {\n ATTRIBUTES_TO_EXTRACT,\n extractDictionaryKeyFromPath,\n type PackageName,\n shouldExtract,\n} from './utils';\nimport { resolveContentFilePaths } from './utils/extractDictionaryInfo';\nimport { extractDictionaryKey } from './utils/extractDictionaryKey';\nimport { generateKey } from './utils/generateKey';\n\nexport type ExtractIntlayerOptions = {\n configOptions?: GetConfigurationOptions;\n codeOnly?: boolean;\n declarationOnly?: boolean;\n unmergedDictionaries?: Record<string, unknown>;\n configuration?: IntlayerConfig;\n code?: string;\n onExtract?: (result: {\n key: string;\n content: Record<string, string>;\n filePath: string;\n }) => void | Promise<void>;\n};\n\ntype ExternalCompilerResult = {\n extractedContent: Record<string, string>;\n code: string;\n};\n\ntype ExternalCompilerOptions = {\n generateKey: typeof generateKey;\n shouldExtract: typeof shouldExtract;\n attributesToExtract: typeof ATTRIBUTES_TO_EXTRACT;\n extractDictionaryKeyFromPath: typeof extractDictionaryKeyFromPath;\n extractTsContent: (\n ast: unknown,\n code: string,\n keys: Set<string>,\n config: IntlayerConfig,\n path: string\n ) => ReturnType<typeof extractTsContent>;\n};\n\ntype VueCompiler = typeof import('@intlayer/vue-compiler');\ntype SvelteCompiler = typeof import('@intlayer/svelte-compiler');\n\n// Module caches\nlet vueCompiler: VueCompiler | null = null;\nlet svelteCompiler: SvelteCompiler | null = null;\n\ntype InternalExtractResult = {\n extractedContentMap: Record<string, Record<string, string>> | null;\n transformedCode: string | null;\n};\n\nconst formatCompilerResult = (\n componentKey: string,\n res?: ExternalCompilerResult\n): InternalExtractResult | undefined => {\n if (!res) return undefined;\n\n return {\n extractedContentMap: { [componentKey]: res.extractedContent },\n transformedCode: res.code,\n };\n};\n\ntype Dependencies = {\n vueCompiler: VueCompiler | null;\n svelteCompiler: SvelteCompiler | null;\n unmergedDictionaries: Record<string, unknown>;\n configuration: IntlayerConfig;\n};\n\nconst processFileInternal = (\n filePath: string,\n packageName: PackageName,\n options: ExtractIntlayerOptions | undefined,\n dependencies: Dependencies,\n saveComponent: boolean,\n providedComponentKey?: string\n):\n | InternalExtractResult\n | Promise<InternalExtractResult | undefined>\n | undefined => {\n const fileText = options?.code ?? readFileSync(filePath, 'utf-8');\n const componentKey =\n providedComponentKey ??\n extractDictionaryKey(\n filePath,\n fileText,\n dependencies.configuration.compiler.dictionaryKeyPrefix\n );\n const ext = extname(filePath);\n\n const { vueCompiler, svelteCompiler, unmergedDictionaries, configuration } =\n dependencies;\n\n const compilerCommonOptions: ExternalCompilerOptions = {\n generateKey,\n shouldExtract,\n attributesToExtract: ATTRIBUTES_TO_EXTRACT,\n extractDictionaryKeyFromPath,\n extractTsContent: (ast, code, keys, config, path) =>\n extractTsContent(\n ast as t.File,\n code,\n keys,\n config,\n path,\n unmergedDictionaries\n ),\n };\n\n if (ext === '.vue') {\n if (!vueCompiler) {\n throw new Error(\n `Please install ${colorizePath('@intlayer/vue-compiler', ANSIColors.YELLOW)} to process Vue files.`\n );\n }\n\n const res = vueCompiler.processVueFile(\n filePath,\n componentKey,\n packageName,\n compilerCommonOptions,\n saveComponent\n );\n\n if (res) {\n return formatCompilerResult(componentKey, res);\n }\n }\n\n if (ext === '.svelte') {\n if (!svelteCompiler) {\n throw new Error(\n `Please install ${colorizePath('@intlayer/svelte-compiler', ANSIColors.YELLOW)} to process Svelte files.`\n );\n }\n\n const res = svelteCompiler.processSvelteFile(\n filePath,\n componentKey,\n packageName,\n compilerCommonOptions,\n saveComponent\n );\n\n if (res) {\n return formatCompilerResult(componentKey, res);\n }\n }\n\n if (['.tsx', '.jsx', '.ts', '.js', '.cjs', '.mjs'].includes(ext)) {\n const result = processTsxFile(\n filePath,\n componentKey,\n packageName,\n configuration,\n saveComponent,\n unmergedDictionaries,\n fileText\n );\n\n if (result) {\n return {\n extractedContentMap: result.extractedContent,\n transformedCode: result.modifiedCode,\n };\n }\n }\n\n return undefined;\n};\n\nconst handleExtractionSideEffects = async (\n extractedContentMap: Record<string, Record<string, string>>,\n filePath: string,\n options: ExtractIntlayerOptions | undefined,\n {\n configuration,\n baseDir,\n appLogger,\n }: {\n configuration: IntlayerConfig;\n baseDir: string;\n appLogger: ReturnType<typeof getAppLogger>;\n },\n saveComponent: boolean\n) => {\n if (options?.onExtract) {\n for (const [key, content] of Object.entries(extractedContentMap)) {\n await options.onExtract({ key, content, filePath });\n }\n }\n\n const writeContent = !options?.codeOnly && !options?.onExtract;\n\n if (writeContent) {\n for (const [key, content] of Object.entries(extractedContentMap)) {\n const contentFilePath = await writeContentHelper(\n content,\n key,\n filePath,\n configuration\n );\n\n const relativeContentFilePath = relative(baseDir, contentFilePath);\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} Created content file: ${colorizePath(relativeContentFilePath)}`\n );\n }\n }\n\n if (saveComponent) {\n const formatCommand = detectFormatCommand(configuration);\n\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', filePath), {\n stdio: 'inherit',\n cwd: baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} Updated component: ${colorizePath(relative(baseDir, filePath))}`\n );\n }\n};\n\nexport const extractContent = async (\n filePath: string,\n packageName: PackageName,\n options?: ExtractIntlayerOptions\n): Promise<{ transformedCode: string | null } | undefined> => {\n const configuration =\n options?.configuration ?? getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(configuration);\n\n const { baseDir } = configuration.system;\n const unmergedDictionaries =\n options?.unmergedDictionaries ?? getUnmergedDictionaries(configuration);\n const saveComponent = !options?.declarationOnly;\n const componentExtension = extname(filePath);\n\n if (componentExtension === '.vue' && !vueCompiler) {\n vueCompiler = (await import(\n '@intlayer/vue-compiler'\n )) as unknown as VueCompiler;\n }\n\n if (componentExtension === '.svelte' && !svelteCompiler) {\n svelteCompiler = (await import(\n '@intlayer/svelte-compiler'\n )) as unknown as SvelteCompiler;\n }\n\n const fileText = options?.code ?? readFileSync(filePath, 'utf-8');\n const dictionaryKey = extractDictionaryKey(\n filePath,\n fileText,\n configuration.compiler.dictionaryKeyPrefix\n );\n\n const result = await processFileInternal(\n filePath,\n packageName,\n options,\n { vueCompiler, svelteCompiler, unmergedDictionaries, configuration },\n saveComponent,\n dictionaryKey\n );\n\n if (!result || !result.extractedContentMap) {\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} No extractable text found in ${colorizePath(relative(baseDir, filePath))}`,\n { isVerbose: true }\n );\n return undefined;\n }\n\n const { relativePath } = await resolveContentFilePaths(\n filePath,\n dictionaryKey,\n configuration\n );\n\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} Target dictionary path: ${colorizePath(relativePath)}`,\n { isVerbose: true }\n );\n\n await handleExtractionSideEffects(\n result.extractedContentMap,\n filePath,\n options,\n { configuration, baseDir, appLogger },\n saveComponent\n );\n\n return { transformedCode: result.transformedCode };\n};\n\nexport const extractContentSync = (\n filePath: string,\n packageName: PackageName,\n options?: ExtractIntlayerOptions\n):\n | {\n transformedCode: string | null;\n extractedContent: Record<string, Record<string, string>>;\n }\n | undefined => {\n const configuration =\n options?.configuration ?? getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(configuration);\n const { baseDir } = configuration.system;\n const unmergedDictionaries =\n options?.unmergedDictionaries ?? getUnmergedDictionaries(configuration);\n const saveComponent = !options?.declarationOnly;\n const componentExtension = extname(filePath);\n\n const requireFn = getProjectRequire();\n\n if (componentExtension === '.vue' && !vueCompiler) {\n try {\n vueCompiler = requireFn('@intlayer/vue-compiler') as VueCompiler;\n } catch {\n // Ignored\n }\n }\n if (componentExtension === '.svelte' && !svelteCompiler) {\n try {\n svelteCompiler = requireFn('@intlayer/svelte-compiler') as SvelteCompiler;\n } catch {\n // Ignored\n }\n }\n\n const result = processFileInternal(\n filePath,\n packageName,\n options,\n { vueCompiler, svelteCompiler, unmergedDictionaries, configuration },\n saveComponent\n );\n\n if (result instanceof Promise) {\n throw new Error(\n `Synchronous extraction failed: External compiler returned a Promise for ${formatPath(relative(baseDir, filePath))}`\n );\n }\n\n if (result?.extractedContentMap) {\n const { extractedContentMap, transformedCode } = result;\n\n if (options?.onExtract) {\n for (const [key, content] of Object.entries(extractedContentMap)) {\n void options.onExtract({ key, content, filePath });\n }\n }\n\n return { transformedCode, extractedContent: extractedContentMap };\n }\n\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} No extractable text found in ${colorizePath(relative(baseDir, filePath))}`,\n { isVerbose: true }\n );\n\n return undefined;\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./utils/constants.cjs`),t=require(`./utils/detectPackageName.cjs`),n=require(`./extractContent.cjs`);exports.ATTRIBUTES_TO_EXTRACT=e.ATTRIBUTES_TO_EXTRACT,exports.detectPackageName=t.detectPackageName,exports.extractContent=n.extractContent,exports.packageList=e.packageList;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./utils/extractDictionaryKey.cjs`),t=require(`./utils/extractDictionaryInfo.cjs`),n=require(`./contentWriter.cjs`),r=require(`./utils/constants.cjs`),i=require(`./utils/detectPackageName.cjs`),a=require(`./utils/generateKey.cjs`),o=require(`./utils/getComponentName.cjs`),s=require(`./extractContent.cjs`);exports.ATTRIBUTES_TO_EXTRACT=r.ATTRIBUTES_TO_EXTRACT,exports.SERVER_CAPABLE_PACKAGES=r.SERVER_CAPABLE_PACKAGES,exports.detectPackageName=i.detectPackageName,exports.extractContent=s.extractContent,exports.extractContentSync=s.extractContentSync,exports.extractDictionaryInfo=t.extractDictionaryInfo,exports.extractDictionaryKey=e.extractDictionaryKey,exports.extractDictionaryKeyFromPath=e.extractDictionaryKeyFromPath,exports.generateKey=a.generateKey,exports.getComponentName=o.getComponentName,exports.getOutput=t.getOutput,exports.mergeWithExistingMultilingualDictionary=n.mergeWithExistingMultilingualDictionary,exports.mergeWithExistingPerLocaleDictionary=n.mergeWithExistingPerLocaleDictionary,exports.packageList=r.packageList,exports.resolveContentFilePaths=t.resolveContentFilePaths,exports.writeContentHelper=n.writeContentHelper;
@@ -1,6 +1,6 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`./utils/getExistingIntlayerInfo.cjs`),n=require(`./babelProcessor.cjs`);let r=require(`@babel/parser`),i=require(`node:child_process`),a=require(`node:fs`),o=require(`@babel/traverse`);o=e.__toESM(o);let s=require(`@babel/types`);s=e.__toESM(s);let c=require(`@intlayer/chokidar/cli`);const l=typeof o.default==`function`?o.default:o.default.default,u=(e,o,u,d,f=!0,p={},m)=>{let h=m??(0,a.readFileSync)(e,`utf-8`),g=(0,r.parse)(h,{sourceType:`module`,plugins:[`jsx`,`typescript`]}),_=u===`solid-intlayer`,{extractedContent:v,replacements:y,componentsNeedingHooks:b,componentKeyMap:x,componentPaths:S,hookMap:C}=n.extractBabelContentForComponents(g,h,new Set,o,d,e,p);if(Object.keys(v).length===0)return null;let w=[],T=e=>{let n=e;for(;n;){let e=S.find(e=>e.node===n?.node);if(e){let n=t.getExistingIntlayerInfo(e);if(n)return n.hook;if(b.has(e))return C.get(e.node)||`useIntlayer`}n=n.parentPath}return`useIntlayer`};for(let{path:e,key:t,type:n,variables:r,childrenToReplace:i}of y){let a=_?`content().${t}`:`content.${t}`,o=T(e)===`getIntlayer`?``:`.value`;if(n===`jsx-text`&&e.isJSXText())w.push({start:e.node.start,end:e.node.end,replacement:`{${a}}`});else if(n===`jsx-attribute`&&e.isJSXAttribute()){let t=e.node.value;t&&w.push({start:t.start,end:t.end,replacement:`{${a}${o}}`})}else if(n===`string-literal`&&e.isStringLiteral())w.push({start:e.node.start,end:e.node.end,replacement:`${a}${o}`});else if(n===`jsx-text-combined`&&i&&i.length>0){let e=`{${a}}`,t=i[0].start,n=i[i.length-1].end;w.push({start:t,end:n,replacement:e})}else if(n===`jsx-insertion`&&r&&i&&i.length>0){let e=`{${a}({ ${r.map(e=>{let[t,n]=e.split(`:`).map(e=>e.trim());return`${t}: ${n}`}).join(`, `)} })}`,t=i[0].start,n=i[i.length-1].end;w.push({start:t,end:n,replacement:e})}}let E=!1,D=!1;for(let e of b){let n=x.get(e.node),r=t.getExistingIntlayerInfo(e);if(r)r.hook===`useIntlayer`&&(E=!0),r.hook===`getIntlayer`&&(D=!0);else{let t=C.get(e.node)||`useIntlayer`;t===`useIntlayer`&&(E=!0),t===`getIntlayer`&&(D=!0);let r=e.get(`body`),i=`\n const content = ${t}('${n}');\n`;if(r.isBlockStatement())w.push({start:r.node.start+1,end:r.node.start+1,replacement:i});else if(r.isExpression()){let e=r.node.start,i=r.node.end,a=-1,o=-1;for(let t=e-1;t>=0;t--){let e=h[t];if(e===`(`){a=t;break}if(e!==` `&&e!==`
2
- `&&e!==`\r`&&e!==` `)break}if(a!==-1)for(let e=i;e<h.length;e++){let t=h[e];if(t===`)`){o=e;break}if(t!==` `&&t!==`
3
- `&&t!==`\r`&&t!==` `)break}a!==-1&&o!==-1?(w.push({start:o,end:o+1,replacement:`)
4
- }`}),w.push({start:a,end:a+1,replacement:`{\n const content = ${t}('${n}');\n return (`})):(w.push({start:i,end:i,replacement:`
5
- }`}),w.push({start:e,end:e,replacement:`{\n const content = ${t}('${n}');\n return `}))}}}let O=(e,t)=>{let n;if(l(g,{ImportDeclaration(e){e.node.source.value===t&&(n=e,e.stop())}}),!n){let n=`import { ${e} } from '${t}';\n`,r=0;if(g.program.body.length>0)r=g.program.body[0].start;else if(g.program.directives&&g.program.directives.length>0){r=g.program.directives[g.program.directives.length-1].end,h[r]===`;`&&r++,w.push({start:r,end:r,replacement:`\n${n}`});return}(r===0||g.program.body.length>0&&r===g.program.body[0].start)&&w.push({start:r,end:r,replacement:n})}else if(!n.node.specifiers.some(t=>s.isImportSpecifier(t)&&s.isIdentifier(t.imported)&&t.imported.name===e)){let t=h.slice(n.node.start,n.node.end),r=t.lastIndexOf(`}`);if(r!==-1){let i=!t.slice(0,r).trim().endsWith(`,`),a=n.node.start+r,o=i?`, `:` `;w.push({start:a,end:a,replacement:`${o}${e} `})}}};E&&O(`useIntlayer`,u),D&&O(`getIntlayer`,`intlayer`),w.sort((e,t)=>t.start===e.start?t.end-e.end:t.start-e.start);let k=h;for(let e of w)k=k.slice(0,e.start)+e.replacement+k.slice(e.end);if(f){(0,a.writeFileSync)(e,k);let t=(0,c.detectFormatCommand)(d);if(t)try{(0,i.execSync)(t.replace(`{{file}}`,e),{stdio:`inherit`,cwd:d.content.baseDir})}catch(e){console.error(e)}}return{extractedContent:v,modifiedCode:k}};exports.processTsxFile=u;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`./utils/constants.cjs`),n=require(`./utils/getExistingIntlayerInfo.cjs`),r=require(`./babelProcessor.cjs`);let i=require(`node:fs`),a=require(`@intlayer/chokidar/cli`),o=require(`@babel/parser`),s=require(`node:child_process`),c=require(`@babel/traverse`);c=e.__toESM(c);let l=require(`@babel/types`);l=e.__toESM(l);const u=typeof c.default==`function`?c.default:c.default.default,d=(e,c,d,f,p=!0,m={},h)=>{let g=h??(0,i.readFileSync)(e,`utf-8`),_=(0,o.parse)(g,{sourceType:`module`,plugins:[`jsx`,`typescript`]}),v=_.program.directives.some(e=>e.value.value===`use client`),y=t.SERVER_CAPABLE_PACKAGES.has(d)&&!v?`${d}/server`:d,b=d===`solid-intlayer`,{extractedContent:x,replacements:S,componentsNeedingHooks:C,componentKeyMap:w,componentPaths:T,hookMap:E}=r.extractBabelContentForComponents(_,g,new Set,c,f,e,m);if(Object.keys(x).length===0)return null;let D=[],O=e=>{let t=e;for(;t;){let e=T.find(e=>e.node===t?.node);if(e){let t=n.getExistingIntlayerInfo(e);if(t)return t.hook;if(C.has(e))return E.get(e.node)||`useIntlayer`}t=t.parentPath}return`useIntlayer`};for(let{path:e,key:t,type:n,variables:r,childrenToReplace:i}of S){let a=b?`content().${t}`:`content.${t}`,o=O(e)===`getIntlayer`?``:`.value`;if(n===`jsx-text`&&e.isJSXText())D.push({start:e.node.start,end:e.node.end,replacement:`{${a}}`});else if(n===`jsx-attribute`&&e.isJSXAttribute()){let t=e.node.value;t&&D.push({start:t.start,end:t.end,replacement:`{${a}${o}}`})}else if(n===`string-literal`&&e.isStringLiteral())D.push({start:e.node.start,end:e.node.end,replacement:`${a}${o}`});else if(n===`jsx-text-combined`&&i&&i.length>0){let e=`{${a}}`,t=i[0].start,n=i[i.length-1].end;D.push({start:t,end:n,replacement:e})}else if(n===`jsx-insertion`&&r&&i&&i.length>0){let e=`{${a}({ ${r.map(e=>{let[t,n]=e.split(`:`).map(e=>e.trim());return`${t}: ${n}`}).join(`, `)} })}`,t=i[0].start,n=i[i.length-1].end;D.push({start:t,end:n,replacement:e})}}let k=!1,A=!1;for(let e of C){let t=w.get(e.node),r=n.getExistingIntlayerInfo(e);if(r)r.hook===`useIntlayer`&&(k=!0),r.hook===`getIntlayer`&&(A=!0);else{let n=E.get(e.node)||`useIntlayer`;n===`useIntlayer`&&(k=!0),n===`getIntlayer`&&(A=!0);let r=e.get(`body`),i=`\n const content = ${n}('${t}');\n`;if(r.isBlockStatement())D.push({start:r.node.start+1,end:r.node.start+1,replacement:i});else if(r.isExpression()){let e=r.node.start,i=r.node.end,a=-1,o=-1;for(let t=e-1;t>=0;t--){let e=g[t];if(e===`(`){a=t;break}if(e!==` `&&e!==`
2
+ `&&e!==`\r`&&e!==` `)break}if(a!==-1)for(let e=i;e<g.length;e++){let t=g[e];if(t===`)`){o=e;break}if(t!==` `&&t!==`
3
+ `&&t!==`\r`&&t!==` `)break}a!==-1&&o!==-1?(D.push({start:o,end:o+1,replacement:`)
4
+ }`}),D.push({start:a,end:a+1,replacement:`{\n const content = ${n}('${t}');\n return (`})):(D.push({start:i,end:i,replacement:`
5
+ }`}),D.push({start:e,end:e,replacement:`{\n const content = ${n}('${t}');\n return `}))}}}let j=(e,t)=>{let n;if(u(_,{ImportDeclaration(e){e.node.source.value===t&&(n=e,e.stop())}}),!n){let n=`import { ${e} } from '${t}';\n`,r=0;if(_.program.body.length>0)r=_.program.body[0].start;else if(_.program.directives&&_.program.directives.length>0){r=_.program.directives[_.program.directives.length-1].end,g[r]===`;`&&r++,D.push({start:r,end:r,replacement:`\n${n}`});return}(r===0||_.program.body.length>0&&r===_.program.body[0].start)&&D.push({start:r,end:r,replacement:n})}else if(!n.node.specifiers.some(t=>l.isImportSpecifier(t)&&l.isIdentifier(t.imported)&&t.imported.name===e)){let t=g.slice(n.node.start,n.node.end),r=t.lastIndexOf(`}`);if(r!==-1){let i=!t.slice(0,r).trim().endsWith(`,`),a=n.node.start+r,o=i?`, `:` `;D.push({start:a,end:a,replacement:`${o}${e} `})}}};k&&j(`useIntlayer`,y),A&&j(`getIntlayer`,`intlayer`),D.sort((e,t)=>t.start===e.start?t.end-e.end:t.start-e.start);let M=g;for(let e of D)M=M.slice(0,e.start)+e.replacement+M.slice(e.end);if(p){(0,i.writeFileSync)(e,M);let t=(0,a.detectFormatCommand)(f);if(t)try{(0,s.execSync)(t.replace(`{{file}}`,e),{stdio:`inherit`,cwd:f.system.baseDir})}catch(e){console.error(e)}}return{extractedContent:x,modifiedCode:M}};exports.processTsxFile=d;
6
6
  //# sourceMappingURL=processTsxFile.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"processTsxFile.cjs","names":["_traverse","extractBabelContentForComponents","getExistingIntlayerInfo","t"],"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.cjs","names":["_traverse","SERVER_CAPABLE_PACKAGES","extractBabelContentForComponents","getExistingIntlayerInfo","t"],"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
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});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`];exports.ATTRIBUTES_TO_EXTRACT=e,exports.packageList=t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});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`]);exports.ATTRIBUTES_TO_EXTRACT=e,exports.SERVER_CAPABLE_PACKAGES=n,exports.packageList=t;
2
2
  //# sourceMappingURL=constants.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.cjs","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":"mEAKA,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.cjs","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":"mEAKA,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
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`./constants.cjs`);let t=require(`node:path`),n=require(`node:fs`);const r=r=>{let i=r;for(;i!==(0,t.dirname)(i);){let r=(0,t.join)(i,`package.json`);if((0,n.existsSync)(r))try{let t=JSON.parse((0,n.readFileSync)(r,`utf-8`)),i={...t.dependencies,...t.devDependencies,...t.peerDependencies};for(let t of e.packageList)if(i[t])return t}catch{}i=(0,t.dirname)(i)}};exports.detectPackageName=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`./constants.cjs`);let t=require(`node:fs`),n=require(`@intlayer/config/utils`);const r=r=>{let{packageJsonPath:i}=(0,n.getPackageJsonPath)(r);if((0,t.existsSync)(i))try{let n=JSON.parse((0,t.readFileSync)(i,`utf-8`)),r={...n.dependencies,...n.devDependencies,...n.peerDependencies};for(let t of e.packageList)if(r[t])return t}catch{}return e.packageList[e.packageList.length-1]};exports.detectPackageName=r;
2
2
  //# sourceMappingURL=detectPackageName.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"detectPackageName.cjs","names":["packageList"],"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":"sMAOA,MAAa,EAAqB,GAA0C,CAC1E,IAAI,EAAa,EAEjB,KAAO,KAAA,EAAA,EAAA,SAAuB,EAAW,EAAE,CACzC,IAAM,GAAA,EAAA,EAAA,MAAe,EAAY,eAAe,CAEhD,IAAA,EAAA,EAAA,YAAe,EAAQ,CACrB,GAAI,CACF,IAAM,EAAM,KAAK,OAAA,EAAA,EAAA,cAAmB,EAAS,QAAQ,CAAC,CAChD,EAAU,CACd,GAAG,EAAI,aACP,GAAG,EAAI,gBACP,GAAG,EAAI,iBACR,CACD,IAAK,IAAM,KAAWA,EAAAA,YACpB,GAAI,EAAQ,GAAU,OAAO,OAEzB,EAIV,GAAA,EAAA,EAAA,SAAqB,EAAW"}
1
+ {"version":3,"file":"detectPackageName.cjs","names":["packageList"],"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":"mNAOA,MAAa,EAAqB,GAAmC,CACnE,GAAM,CAAE,oBAAA,EAAA,EAAA,oBAAuC,EAAU,CAEzD,IAAA,EAAA,EAAA,YAAe,EAAgB,CAC7B,GAAI,CACF,IAAM,EAAM,KAAK,OAAA,EAAA,EAAA,cAAmB,EAAiB,QAAQ,CAAC,CACxD,EAAU,CACd,GAAG,EAAI,aACP,GAAG,EAAI,gBACP,GAAG,EAAI,iBACR,CAED,IAAK,IAAM,KAAWA,EAAAA,YACpB,GAAI,EAAQ,GAAU,OAAO,OAEzB,EAKV,OAAOA,EAAAA,YAAYA,EAAAA,YAAY,OAAS"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`./extractDictionaryKey.cjs`);let t=require(`@intlayer/chokidar/utils`),n=require(`@intlayer/config/node`),r=require(`node:path`),i=require(`@intlayer/config/utils`),a=require(`@intlayer/unmerged-dictionaries-entry`);const o=e=>{if(typeof e.compiler?.output==`string`)return t=>(0,i.parseStringPattern)(e.compiler.output,t);if(typeof e.compiler?.output==`function`)return e.compiler.output;if(typeof e.compiler?.outputDir==`string`){let t=(0,r.resolve)(e.system.baseDir,e.compiler.outputDir);return n=>(0,i.parseStringPattern)(`${t}/{{fileName}}.${e.content.fileExtensions[0].split(`.`)[1]}.json`,n)}return n.DefaultValues.Compiler.COMPILER_OUTPUT},s=async(e,n,i,s)=>{let{baseDir:c}=i.system,{defaultLocale:l}=i.internationalization,u=((0,a.getUnmergedDictionaries)(i)??{})[n]?.filter(e=>e.location!==`remote`).filter(e=>e.locale===void 0||e.locale===(s??l));if(u?.[0]?.filePath){let e=u[0].filePath,t=(0,r.resolve)(c,e);return{absolutePath:t,relativePath:(0,r.relative)(c,t),isPerLocale:!1}}let d=o(i),f=(0,r.extname)(e),p=(0,r.basename)(e,f),m=p.charAt(0).toLowerCase()+p.slice(1),h=(0,t.getFormatFromExtension)(f),g={key:n,componentDirPath:(0,r.relative)(c,(0,r.dirname)(e)),componentFileName:p,fileName:m,componentFormat:h,componentExtension:f,format:h,locale:l,extension:i.content.fileExtensions[0]},_=(0,t.resolveRelativePath)(await d(g),e,c),v=`###########locale###########`,y=(await d({...g,locale:v})).includes(v);return{absolutePath:_,relativePath:(0,r.relative)(c,_),isPerLocale:y}},c=async(t,n,r)=>{let i=e.extractDictionaryKey(t,n);return{dictionaryKey:i,...await s(t,i,r)}};exports.extractDictionaryInfo=c,exports.getOutput=o,exports.resolveContentFilePaths=s;
2
+ //# sourceMappingURL=extractDictionaryInfo.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractDictionaryInfo.cjs","names":["DefaultValues","extractDictionaryKey"],"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":"4VAgBA,MAAa,EACX,GAC4B,CAC5B,GAAI,OAAO,EAAc,UAAU,QAAW,SAC5C,MAAQ,KAAA,EAAA,EAAA,oBACa,EAAc,SAAS,OAAkB,EAAQ,CAGxE,GAAI,OAAO,EAAc,UAAU,QAAW,WAC5C,OAAO,EAAc,SAAS,OAGhC,GAAI,OAAO,EAAc,UAAU,WAAc,SAAU,CAEzD,IAAM,GAAA,EAAA,EAAA,SACJ,EAAc,OAAO,QACrB,EAAc,SAAS,UACxB,CAED,MAAQ,KAAA,EAAA,EAAA,oBAEJ,GAAG,EAAkB,gBAAgB,EAAc,QAAQ,eAAe,GAAG,MAAM,IAAI,CAAC,GAAG,OAC3F,EACD,CAGL,OAAOA,EAAAA,cAAc,SAAS,iBAanB,EAA0B,MACrC,EACA,EACA,EACA,IACqC,CACrC,GAAM,CAAE,WAAY,EAAc,OAC5B,CAAE,iBAAkB,EAAc,qBAGlC,IAAA,EAAA,EAAA,yBAD+C,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,GAAA,EAAA,EAAA,SAA+B,EAAS,EAAa,CAE3D,MAAO,CACL,aAAc,EACd,cAAA,EAAA,EAAA,UAAuB,EAAS,EAAqB,CACrD,YAAa,GACd,CAGH,IAAM,EAAU,EAAU,EAAc,CAElC,GAAA,EAAA,EAAA,SACJ,EACD,CACK,GAAA,EAAA,EAAA,UAAyB,EAAU,EAAU,CAC7C,EACJ,EAAc,OAAO,EAAE,CAAC,aAAa,CAAG,EAAc,MAAM,EAAE,CAC1D,GAAA,EAAA,EAAA,wBACJ,EACD,CAEK,EAAkC,CACtC,IAAK,EACL,kBAAA,EAAA,EAAA,UAA2B,GAAA,EAAA,EAAA,SAAiB,EAAS,CAAC,CACtD,kBAAmB,EACnB,SAAU,EACV,kBACA,mBAAoB,EACpB,OAAQ,EACR,OAAQ,EACR,UAAW,EAAc,QAAQ,eAAe,GACjD,CAKK,GAAA,EAAA,EAAA,qBAHkB,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,cAAA,EAAA,EAAA,UAAuB,EAAS,EAAa,CAC7C,cACD,EAUU,EAAwB,MACnC,EACA,EACA,IAKG,CACH,IAAM,EAAgBC,EAAAA,qBAAqB,EAAU,EAAS,CAQ9D,MAAO,CACL,gBACA,GARoB,MAAM,EAC1B,EACA,EACA,EACD,CAKA"}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../../_virtual/_rolldown/runtime.cjs`);let e=require(`@intlayer/chokidar/cli`),t=require(`@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=(0,e.detectExportedComponentName)(i);return a?(0,t.camelCaseToKebabCase)(a):n(r,``)};exports.extractDictionaryKey=r,exports.extractDictionaryKeyFromPath=n;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../../_virtual/_rolldown/runtime.cjs`);let e=require(`@intlayer/config/node`),t=require(`@intlayer/config/utils`),n=require(`@intlayer/chokidar/cli`);const r=(t,n=e.DefaultValues.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.DefaultValues.Compiler.COMPILER_DICTIONARY_KEY_PREFIX)=>{let s=(0,n.detectExportedComponentName)(a);return s?`${o}${(0,t.camelCaseToKebabCase)(s)}`:r(i,o)};exports.extractDictionaryKey=i,exports.extractDictionaryKeyFromPath=r;
2
2
  //# sourceMappingURL=extractDictionaryKey.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractDictionaryKey.cjs","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":"+LAQA,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,GAAA,EAAA,EAAA,6BAA4C,EAAS,CAM3D,OAJI,GACF,EAAA,EAAA,sBAA4B,EAAc,CAGrC,EAA6B,EAAU,GAAG"}
1
+ {"version":3,"file":"extractDictionaryKey.cjs","names":["DefaultValues"],"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":"kOASA,MAAa,GACX,EACA,EAASA,EAAAA,cAAc,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,EAASA,EAAAA,cAAc,SAAS,iCACrB,CACX,IAAM,GAAA,EAAA,EAAA,6BAA4C,EAAS,CAM3D,OAJI,EACK,GAAG,KAAA,EAAA,EAAA,sBAA8B,EAAc,GAGjD,EAA6B,EAAU,EAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"getOrGenerateKey.cjs","names":["generateKey"],"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":"wGAKa,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,EAAMA,EAAAA,YAAY,EAAM,EAAa,CAG3C,OAFA,EAAa,IAAI,EAAI,CACrB,EAAiB,GAAc,GAAO,EAC/B"}
1
+ {"version":3,"file":"getOrGenerateKey.cjs","names":["generateKey"],"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":"wGAKa,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,EAAMA,EAAAA,YAAY,EAAM,EAAa,CAI3C,OAFA,EAAa,IAAI,EAAI,CACrB,EAAiB,GAAc,GAAO,EAC/B"}