@intlayer/babel 8.3.0 → 8.3.1

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 (46) 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/extractContent/contentWriter.cjs +1 -1
  4. package/dist/cjs/extractContent/contentWriter.cjs.map +1 -1
  5. package/dist/cjs/extractContent/extractContent.cjs +1 -1
  6. package/dist/cjs/extractContent/extractContent.cjs.map +1 -1
  7. package/dist/cjs/extractContent/processTsxFile.cjs +2 -2
  8. package/dist/cjs/extractContent/processTsxFile.cjs.map +1 -1
  9. package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs +1 -1
  10. package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs.map +1 -1
  11. package/dist/cjs/extractContent/utils/getExistingIntlayerInfo.cjs +1 -1
  12. package/dist/cjs/extractContent/utils/getExistingIntlayerInfo.cjs.map +1 -1
  13. package/dist/cjs/extractContent/utils/resolveDictionaryKey.cjs.map +1 -1
  14. package/dist/cjs/getExtractPluginOptions.cjs +1 -1
  15. package/dist/cjs/getExtractPluginOptions.cjs.map +1 -1
  16. package/dist/cjs/getOptimizePluginOptions.cjs +1 -1
  17. package/dist/cjs/getOptimizePluginOptions.cjs.map +1 -1
  18. package/dist/esm/babel-plugin-intlayer-extract.mjs +1 -1
  19. package/dist/esm/babel-plugin-intlayer-extract.mjs.map +1 -1
  20. package/dist/esm/extractContent/contentWriter.mjs +1 -1
  21. package/dist/esm/extractContent/contentWriter.mjs.map +1 -1
  22. package/dist/esm/extractContent/extractContent.mjs +1 -1
  23. package/dist/esm/extractContent/extractContent.mjs.map +1 -1
  24. package/dist/esm/extractContent/processTsxFile.mjs +3 -3
  25. package/dist/esm/extractContent/processTsxFile.mjs.map +1 -1
  26. package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs +1 -1
  27. package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs.map +1 -1
  28. package/dist/esm/extractContent/utils/getExistingIntlayerInfo.mjs +1 -1
  29. package/dist/esm/extractContent/utils/getExistingIntlayerInfo.mjs.map +1 -1
  30. package/dist/esm/extractContent/utils/resolveDictionaryKey.mjs.map +1 -1
  31. package/dist/esm/getExtractPluginOptions.mjs +1 -1
  32. package/dist/esm/getExtractPluginOptions.mjs.map +1 -1
  33. package/dist/esm/getOptimizePluginOptions.mjs +1 -1
  34. package/dist/esm/getOptimizePluginOptions.mjs.map +1 -1
  35. package/dist/types/extractContent/contentWriter.d.ts.map +1 -1
  36. package/dist/types/extractContent/extractContent.d.ts +15 -6
  37. package/dist/types/extractContent/extractContent.d.ts.map +1 -1
  38. package/dist/types/extractContent/processTsxFile.d.ts.map +1 -1
  39. package/dist/types/extractContent/utils/extractDictionaryInfo.d.ts.map +1 -1
  40. package/dist/types/extractContent/utils/getExistingIntlayerInfo.d.ts +11 -5
  41. package/dist/types/extractContent/utils/getExistingIntlayerInfo.d.ts.map +1 -1
  42. package/dist/types/extractContent/utils/index.d.ts +2 -2
  43. package/dist/types/getExtractPluginOptions.d.ts +1 -1
  44. package/dist/types/getExtractPluginOptions.d.ts.map +1 -1
  45. package/dist/types/getOptimizePluginOptions.d.ts.map +1 -1
  46. package/package.json +9 -9
@@ -1 +1 @@
1
- {"version":3,"file":"contentWriter.mjs","names":[],"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":"6ZA+BA,IAAI,EAQJ,MAAa,GACX,EACA,EACA,IACyB,CAezB,IAAM,EANmB,EAPvB,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,EALmB,EAPvB,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,MAAM,EAC1C,EACA,EACA,EACD,CAEK,CAAE,iBAAkB,EAAc,qBAClC,CAAE,WAAY,EAAc,OAElC,AACE,IAAuB,MAAM,EAAqB,EAAc,CAGlE,IAAM,EAAY,EAAQ,EAAa,CAGvC,MAAM,EAAM,EAAW,CAAE,UAAW,GAAM,CAAC,CAG3C,IAAI,EAAwC,KAE5C,GAAI,EAAW,EAAa,CAC1B,GAAI,CAOF,EANmB,MAAM,EACvB,EACA,EACA,EACD,EAEkC,WAC5B,EAAO,CACd,QAAQ,MAAM,EAAM,CAIxB,IAAM,EAA0B,EAAS,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,EAAc,EAAS,EAAS,EAAU,CAE1C,EAAc,MAAM,EACxB,EACA,EACA,CACE,oBAAqB,EACrB,WAAY,CAAC,EAAc,CAC5B,CACF,CAUD,OAFA,MAAM,EAAgB,CALgB,CACpC,GAAG,EACH,SAAU,EAAS,EAAS,GAAa,MAAQ,EAAa,CAC/D,CAEwC,CAAE,EAAc,CAElD"}
1
+ {"version":3,"file":"contentWriter.mjs","names":[],"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 { NodeType } from '@intlayer/types/nodeType';\nimport { resolveContentFilePaths } from './utils/extractDictionaryInfo';\n\nconst hasInsertionVars = (str: string): boolean => /\\{\\{[^}]+\\}\\}/.test(str);\n\nconst getInsertionFields = (template: string): string[] => {\n const fields: string[] = [];\n const regex = /\\{\\{([^}]+)\\}\\}/g;\n let match: RegExpExecArray | null;\n for (\n let result = regex.exec(template);\n result !== null;\n result = regex.exec(template)\n ) {\n match = result;\n const field = match[1].trim();\n if (!fields.includes(field)) fields.push(field);\n }\n return fields;\n};\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 // Promote any key whose source text contains {{vars}} to an insertion node\n for (const key in extractedContent) {\n const rawValue = extractedContent[key];\n if (typeof rawValue === 'string' && hasInsertionVars(rawValue)) {\n const node = finalContent[key] as any;\n if (node && node.nodeType === NodeType.Translation) {\n (finalContent as any)[key] = {\n nodeType: NodeType.Insertion,\n [NodeType.Insertion]: node,\n fields: getInsertionFields(rawValue),\n };\n }\n }\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 // Promote any key whose source text contains {{vars}} to an insertion node\n for (const key in extractedContent) {\n const rawValue = extractedContent[key];\n if (typeof rawValue === 'string' && hasInsertionVars(rawValue)) {\n const currentVal = finalContent[key];\n if (typeof currentVal === 'string') {\n (finalContent as any)[key] = {\n nodeType: NodeType.Insertion,\n [NodeType.Insertion]: currentVal,\n fields: getInsertionFields(rawValue),\n };\n }\n }\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":"idAgBA,MAAM,EAAoB,GAAyB,gBAAgB,KAAK,EAAI,CAEtE,EAAsB,GAA+B,CACzD,IAAM,EAAmB,EAAE,CACrB,EAAQ,mBACV,EACJ,IACE,IAAI,EAAS,EAAM,KAAK,EAAS,CACjC,IAAW,KACX,EAAS,EAAM,KAAK,EAAS,CAC7B,CACA,EAAQ,EACR,IAAM,EAAQ,EAAM,GAAG,MAAM,CACxB,EAAO,SAAS,EAAM,EAAE,EAAO,KAAK,EAAM,CAEjD,OAAO,GAmBT,IAAI,EAQJ,MAAa,GACX,EACA,EACA,IACyB,CAezB,IAAM,EANmB,EAPvB,GACC,CACC,IAAK,GACL,QAAS,EAAE,CACX,SAAU,GACX,CAID,EACA,EACD,CAEsC,QAGjC,EAAqC,EAAE,CAC7C,IAAK,IAAM,KAAO,EAChB,EAAa,GAAO,EAAc,GAIpC,IAAK,IAAM,KAAO,EAAkB,CAClC,IAAM,EAAW,EAAiB,GAClC,GAAI,OAAO,GAAa,UAAY,EAAiB,EAAS,CAAE,CAC9D,IAAM,EAAO,EAAa,GACtB,GAAQ,EAAK,WAAa,EAAS,cACpC,EAAqB,GAAO,CAC3B,SAAU,EAAS,WAClB,EAAS,WAAY,EACtB,OAAQ,EAAmB,EAAS,CACrC,GAKP,OAAO,GASI,GACX,EACA,IAC2B,CAc3B,IAAM,EALmB,EAPvB,GACC,CACC,IAAK,GACL,QAAS,EAAE,CACX,SAAU,GACX,CAID,EACD,CAEsC,QAGjC,EAAuC,EAAE,CAC/C,IAAK,IAAM,KAAO,EAChB,EAAa,GAAO,EAAc,GAIpC,IAAK,IAAM,KAAO,EAAkB,CAClC,IAAM,EAAW,EAAiB,GAClC,GAAI,OAAO,GAAa,UAAY,EAAiB,EAAS,CAAE,CAC9D,IAAM,EAAa,EAAa,GAC5B,OAAO,GAAe,WACvB,EAAqB,GAAO,CAC3B,SAAU,EAAS,WAClB,EAAS,WAAY,EACtB,OAAQ,EAAmB,EAAS,CACrC,GAKP,OAAO,GAMI,EAAqB,MAChC,EACA,EACA,EACA,IACoB,CACpB,GAAM,CAAE,eAAc,eAAgB,MAAM,EAC1C,EACA,EACA,EACD,CAEK,CAAE,iBAAkB,EAAc,qBAClC,CAAE,WAAY,EAAc,OAElC,AACE,IAAuB,MAAM,EAAqB,EAAc,CAGlE,IAAM,EAAY,EAAQ,EAAa,CAGvC,MAAM,EAAM,EAAW,CAAE,UAAW,GAAM,CAAC,CAG3C,IAAI,EAAwC,KAE5C,GAAI,EAAW,EAAa,CAC1B,GAAI,CAOF,EANmB,MAAM,EACvB,EACA,EACA,EACD,EAEkC,WAC5B,EAAO,CACd,QAAQ,MAAM,EAAM,CAIxB,IAAM,EAA0B,EAAS,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,EAAc,EAAS,EAAS,EAAU,CAE1C,EAAc,MAAM,EACxB,EACA,EACA,CACE,oBAAqB,EACrB,WAAY,CAAC,EAAc,CAC5B,CACF,CAUD,OAFA,MAAM,EAAgB,CALgB,CACpC,GAAG,EACH,SAAU,EAAS,EAAS,GAAa,MAAQ,EAAa,CAC/D,CAEwC,CAAE,EAAc,CAElD"}
@@ -1,2 +1,2 @@
1
- import{extractDictionaryKey as e,extractDictionaryKeyFromPath as t}from"./utils/extractDictionaryKey.mjs";import{writeContentHelper as n}from"./contentWriter.mjs";import{ATTRIBUTES_TO_EXTRACT as r}from"./utils/constants.mjs";import{generateKey as i}from"./utils/generateKey.mjs";import{shouldExtract as a}from"./utils/shouldExtract.mjs";import{extractTsContent as o}from"./babelProcessor.mjs";import{processTsxFile as s}from"./processTsxFile.mjs";import{formatPath as c}from"@intlayer/chokidar/utils";import{ANSIColors as l,colorize as u,colorizePath as d,getAppLogger as f}from"@intlayer/config/logger";import{getConfiguration as p}from"@intlayer/config/node";import{readFileSync as m}from"node:fs";import{extname as h,relative as g}from"node:path";import{getProjectRequire as _}from"@intlayer/config/utils";import{getUnmergedDictionaries as v}from"@intlayer/unmerged-dictionaries-entry";import{detectFormatCommand as y}from"@intlayer/chokidar/cli";import{execSync as b}from"node:child_process";let x=null,S=null;const C=(e,t)=>{if(t)return{extractedContentMap:{[e]:t.extractedContent},transformedCode:t.code}},w=(n,c,u,f,p,g)=>{let _=u?.code??m(n,`utf-8`),v=g??e(n,_,f.configuration.compiler.dictionaryKeyPrefix),y=h(n),{vueCompiler:b,svelteCompiler:x,unmergedDictionaries:S,configuration:w}=f,T={generateKey:i,shouldExtract:a,attributesToExtract:r,extractDictionaryKeyFromPath:t,extractTsContent:(e,t,n,r,i)=>o(e,t,n,r,i,S)};if(y===`.vue`){if(!b)throw Error(`Please install ${d(`@intlayer/vue-compiler`,l.YELLOW)} to process Vue files.`);let e=b.processVueFile(n,v,c,T,p);if(e)return C(v,e)}if(y===`.svelte`){if(!x)throw Error(`Please install ${d(`@intlayer/svelte-compiler`,l.YELLOW)} to process Svelte files.`);let e=x.processSvelteFile(n,v,c,T,p);if(e)return C(v,e)}if([`.tsx`,`.jsx`,`.ts`,`.js`,`.cjs`,`.mjs`].includes(y)){let e=s(n,v,c,w,p,S,_);if(e)return{extractedContentMap:e.extractedContent,transformedCode:e.modifiedCode}}},T=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=g(a,await n(s,r,t,i));o(`${u(`Compiler:`,l.GREY_DARK)} Created content file: ${d(e)}`)}if(s){let e=y(i);if(e)try{b(e.replace(`{{file}}`,t),{stdio:`inherit`,cwd:a})}catch(e){console.error(e)}o(`${u(`Compiler:`,l.GREY_DARK)} Updated component: ${d(g(a,t))}`)}},E=async(t,n,r)=>{let i=r?.configuration??p(r?.configOptions),a=f(i),{baseDir:o}=i.system,s=r?.unmergedDictionaries??v(i),c=!r?.declarationOnly,_=h(t);_===`.vue`&&!x&&(x=await import(`@intlayer/vue-compiler`)),_===`.svelte`&&!S&&(S=await import(`@intlayer/svelte-compiler`));let y=e(t,r?.code??m(t,`utf-8`),i.compiler.dictionaryKeyPrefix),b=await w(t,n,r,{vueCompiler:x,svelteCompiler:S,unmergedDictionaries:s,configuration:i},c,y);if(!b||!b.extractedContentMap){a(`${u(`Compiler:`,l.GREY_DARK)} No extractable text found in ${d(g(o,t))}`,{isVerbose:!0});return}return await T(b.extractedContentMap,t,r,{configuration:i,baseDir:o,appLogger:a},c),{transformedCode:b.transformedCode}},D=(e,t,n)=>{let r=n?.configuration??p(n?.configOptions),i=f(r),{baseDir:a}=r.system,o=n?.unmergedDictionaries??v(r),s=!n?.declarationOnly,m=h(e),y=_();if(m===`.vue`&&!x)try{x=y(`@intlayer/vue-compiler`)}catch{}if(m===`.svelte`&&!S)try{S=y(`@intlayer/svelte-compiler`)}catch{}let b=w(e,t,n,{vueCompiler:x,svelteCompiler:S,unmergedDictionaries:o,configuration:r},s);if(b instanceof Promise)throw Error(`Synchronous extraction failed: External compiler returned a Promise for ${c(g(a,e))}`);if(b?.extractedContentMap){let{extractedContentMap:t,transformedCode:r}=b;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(`${u(`Compiler:`,l.GREY_DARK)} No extractable text found in ${d(g(a,e))}`,{isVerbose:!0})};export{E as extractContent,D as extractContentSync};
1
+ import{extractDictionaryKey as e,extractDictionaryKeyFromPath as t}from"./utils/extractDictionaryKey.mjs";import{writeContentHelper as n}from"./contentWriter.mjs";import{ATTRIBUTES_TO_EXTRACT as r}from"./utils/constants.mjs";import{generateKey as i}from"./utils/generateKey.mjs";import{shouldExtract as a}from"./utils/shouldExtract.mjs";import{extractTsContent as o}from"./babelProcessor.mjs";import{processTsxFile as s}from"./processTsxFile.mjs";import{ANSIColors as c,colorize as l,colorizePath as u,getAppLogger as d}from"@intlayer/config/logger";import{getConfiguration as f}from"@intlayer/config/node";import{readFileSync as p}from"node:fs";import{extname as m,relative as h}from"node:path";import{getProjectRequire as g}from"@intlayer/config/utils";import{getUnmergedDictionaries as _}from"@intlayer/unmerged-dictionaries-entry";import{detectFormatCommand as v}from"@intlayer/chokidar/cli";import{execSync as y}from"node:child_process";let b=null,x=null;const S=(e,t)=>{if(t)return{extractedContentMap:{[e]:t.extractedContent},transformedCode:t.code}},C=(n,l,d,f,h,g)=>{let _=d?.code??p(n,`utf-8`),v=g??e(n,_,f.configuration.compiler.dictionaryKeyPrefix),y=m(n),{vueCompiler:b,svelteCompiler:x,unmergedDictionaries:C,configuration:w}=f,T={generateKey:i,shouldExtract:a,attributesToExtract:r,extractDictionaryKeyFromPath:t,extractTsContent:(e,t,n,r,i)=>o(e,t,n,r,i,C)};if(y===`.vue`){if(!b)throw Error(`Please install ${u(`@intlayer/vue-compiler`,c.YELLOW)} to process Vue files.`);let e=b.processVueFile(n,v,l,T,h);if(e)return S(v,e)}if(y===`.svelte`){if(!x)throw Error(`Please install ${u(`@intlayer/svelte-compiler`,c.YELLOW)} to process Svelte files.`);let e=x.processSvelteFile(n,v,l,T,h);if(e)return S(v,e)}if([`.tsx`,`.jsx`,`.ts`,`.js`,`.cjs`,`.mjs`].includes(y)){let e=s(n,v,l,w,h,C,_);if(e)return{extractedContentMap:e.extractedContent,transformedCode:e.modifiedCode}}},w=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=h(a,await n(s,r,t,i));o(`${l(`Compiler:`,c.GREY_DARK)} Created content file: ${u(e)}`)}if(s){let e=v(i);if(e)try{y(e.replace(`{{file}}`,t),{stdio:`inherit`,cwd:a})}catch(e){console.error(e)}o(`${l(`Compiler:`,c.GREY_DARK)} Updated component: ${u(h(a,t))}`)}},T=(e,t)=>{let n=t?.configuration??f(t?.configOptions),r=d(n),{baseDir:i}=n.system;return{configuration:n,appLogger:r,baseDir:i,unmergedDictionaries:t?.unmergedDictionaries??_(n),saveComponent:!t?.declarationOnly,componentExtension:m(e)}},E=async(t,n,r)=>{let{configuration:i,appLogger:a,baseDir:o,unmergedDictionaries:s,saveComponent:d,componentExtension:f}=T(t,r);if(f===`.vue`&&!b)try{b=await import(`@intlayer/vue-compiler`)}catch{a(`${l(`Compiler:`,c.GREY_DARK)} Install ${u(`@intlayer/vue-compiler`,c.YELLOW)} to process Vue files.`)}if(f===`.svelte`&&!x)try{x=await import(`@intlayer/svelte-compiler`)}catch{a(`${l(`Compiler:`,c.GREY_DARK)} Install ${u(`@intlayer/svelte-compiler`,c.YELLOW)} to process Svelte files.`)}let m=e(t,r?.code??p(t,`utf-8`),i.compiler.dictionaryKeyPrefix),g=C(t,n,r,{vueCompiler:b,svelteCompiler:x,unmergedDictionaries:s,configuration:i},d,m);if(!g||!g.extractedContentMap){a(`${l(`Compiler:`,c.GREY_DARK)} No extractable text found in ${u(h(o,t))}`,{isVerbose:!0});return}return await w(g.extractedContentMap,t,r,{configuration:i,baseDir:o,appLogger:a},d),{transformedCode:g.transformedCode,extractedContentMap:g.extractedContentMap}},D=(e,t,n)=>{let{configuration:r,appLogger:i,baseDir:a,unmergedDictionaries:o,saveComponent:s,componentExtension:d}=T(e,n),f=g();if(d===`.vue`&&!b)try{b=f(`@intlayer/vue-compiler`)}catch{i(`${l(`Compiler:`,c.GREY_DARK)} Install ${u(`@intlayer/vue-compiler`,c.YELLOW)} to process Vue files.`)}if(d===`.svelte`&&!x)try{x=f(`@intlayer/svelte-compiler`)}catch{i(`${l(`Compiler:`,c.GREY_DARK)} Install ${u(`@intlayer/svelte-compiler`,c.YELLOW)} to process Svelte files.`)}let p=C(e,t,n,{vueCompiler:b,svelteCompiler:x,unmergedDictionaries:o,configuration:r},s);if(!p?.extractedContentMap){i(`${l(`Compiler:`,c.GREY_DARK)} No extractable text found in ${u(h(a,e))}`,{isVerbose:!0});return}let{extractedContentMap:m,transformedCode:_}=p;if(n?.onExtract)for(let[t,r]of Object.entries(m))n.onExtract({key:t,content:r,filePath:e});return{transformedCode:_,extractedContentMap:m}};export{E as extractContent,D as extractContentSync};
2
2
  //# sourceMappingURL=extractContent.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractContent.mjs","names":[],"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 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":"o+BAqEA,IAAI,EAAkC,KAClC,EAAwC,KAO5C,MAAM,GACJ,EACA,IACsC,CACjC,KAEL,MAAO,CACL,oBAAqB,EAAG,GAAe,EAAI,iBAAkB,CAC7D,gBAAiB,EAAI,KACtB,EAUG,GACJ,EACA,EACA,EACA,EACA,EACA,IAIe,CACf,IAAM,EAAW,GAAS,MAAQ,EAAa,EAAU,QAAQ,CAC3D,EACJ,GACA,EACE,EACA,EACA,EAAa,cAAc,SAAS,oBACrC,CACG,EAAM,EAAQ,EAAS,CAEvB,CAAE,cAAa,iBAAgB,uBAAsB,iBACzD,EAEI,EAAiD,CACrD,cACA,gBACA,oBAAqB,EACrB,+BACA,kBAAmB,EAAK,EAAM,EAAM,EAAQ,IAC1C,EACE,EACA,EACA,EACA,EACA,EACA,EACD,CACJ,CAED,GAAI,IAAQ,OAAQ,CAClB,GAAI,CAAC,EACH,MAAU,MACR,kBAAkB,EAAa,yBAA0B,EAAW,OAAO,CAAC,wBAC7E,CAGH,IAAM,EAAM,EAAY,eACtB,EACA,EACA,EACA,EACA,EACD,CAED,GAAI,EACF,OAAO,EAAqB,EAAc,EAAI,CAIlD,GAAI,IAAQ,UAAW,CACrB,GAAI,CAAC,EACH,MAAU,MACR,kBAAkB,EAAa,4BAA6B,EAAW,OAAO,CAAC,2BAChF,CAGH,IAAM,EAAM,EAAe,kBACzB,EACA,EACA,EACA,EACA,EACD,CAED,GAAI,EACF,OAAO,EAAqB,EAAc,EAAI,CAIlD,GAAI,CAAC,OAAQ,OAAQ,MAAO,MAAO,OAAQ,OAAO,CAAC,SAAS,EAAI,CAAE,CAChE,IAAM,EAAS,EACb,EACA,EACA,EACA,EACA,EACA,EACA,EACD,CAED,GAAI,EACF,MAAO,CACL,oBAAqB,EAAO,iBAC5B,gBAAiB,EAAO,aACzB,GAOD,EAA8B,MAClC,EACA,EACA,EACA,CACE,gBACA,UACA,aAMF,IACG,CACH,GAAI,GAAS,UACX,IAAK,GAAM,CAAC,EAAK,KAAY,OAAO,QAAQ,EAAoB,CAC9D,MAAM,EAAQ,UAAU,CAAE,MAAK,UAAS,WAAU,CAAC,CAMvD,GAFqB,CAAC,GAAS,UAAY,CAAC,GAAS,UAGnD,IAAK,GAAM,CAAC,EAAK,KAAY,OAAO,QAAQ,EAAoB,CAAE,CAQhE,IAAM,EAA0B,EAAS,EAPjB,MAAM,EAC5B,EACA,EACA,EACA,EACD,CAEiE,CAClE,EACE,GAAG,EAAS,YAAa,EAAW,UAAU,CAAC,yBAAyB,EAAa,EAAwB,GAC9G,CAIL,GAAI,EAAe,CACjB,IAAM,EAAgB,EAAoB,EAAc,CAExD,GAAI,EACF,GAAI,CACF,EAAS,EAAc,QAAQ,WAAY,EAAS,CAAE,CACpD,MAAO,UACP,IAAK,EACN,CAAC,OACK,EAAO,CACd,QAAQ,MAAM,EAAM,CAIxB,EACE,GAAG,EAAS,YAAa,EAAW,UAAU,CAAC,sBAAsB,EAAa,EAAS,EAAS,EAAS,CAAC,GAC/G,GAIQ,EAAiB,MAC5B,EACA,EACA,IAC4D,CAC5D,IAAM,EACJ,GAAS,eAAiB,EAAiB,GAAS,cAAc,CAC9D,EAAY,EAAa,EAAc,CAEvC,CAAE,WAAY,EAAc,OAC5B,EACJ,GAAS,sBAAwB,EAAwB,EAAc,CACnE,EAAgB,CAAC,GAAS,gBAC1B,EAAqB,EAAQ,EAAS,CAExC,IAAuB,QAAU,CAAC,IACpC,EAAe,MAAM,OACnB,2BAIA,IAAuB,WAAa,CAAC,IACvC,EAAkB,MAAM,OACtB,8BAKJ,IAAM,EAAgB,EACpB,EAFe,GAAS,MAAQ,EAAa,EAAU,QAAQ,CAI/D,EAAc,SAAS,oBACxB,CAEK,EAAS,MAAM,EACnB,EACA,EACA,EACA,CAAE,cAAa,iBAAgB,uBAAsB,gBAAe,CACpE,EACA,EACD,CAED,GAAI,CAAC,GAAU,CAAC,EAAO,oBAAqB,CAC1C,EACE,GAAG,EAAS,YAAa,EAAW,UAAU,CAAC,gCAAgC,EAAa,EAAS,EAAS,EAAS,CAAC,GACxH,CAAE,UAAW,GAAM,CACpB,CACD,OAWF,OARA,MAAM,EACJ,EAAO,oBACP,EACA,EACA,CAAE,gBAAe,UAAS,YAAW,CACrC,EACD,CAEM,CAAE,gBAAiB,EAAO,gBAAiB,EAGvC,GACX,EACA,EACA,IAMe,CACf,IAAM,EACJ,GAAS,eAAiB,EAAiB,GAAS,cAAc,CAC9D,EAAY,EAAa,EAAc,CACvC,CAAE,WAAY,EAAc,OAC5B,EACJ,GAAS,sBAAwB,EAAwB,EAAc,CACnE,EAAgB,CAAC,GAAS,gBAC1B,EAAqB,EAAQ,EAAS,CAEtC,EAAY,GAAmB,CAErC,GAAI,IAAuB,QAAU,CAAC,EACpC,GAAI,CACF,EAAc,EAAU,yBAAyB,MAC3C,EAIV,GAAI,IAAuB,WAAa,CAAC,EACvC,GAAI,CACF,EAAiB,EAAU,4BAA4B,MACjD,EAKV,IAAM,EAAS,EACb,EACA,EACA,EACA,CAAE,cAAa,iBAAgB,uBAAsB,gBAAe,CACpE,EACD,CAED,GAAI,aAAkB,QACpB,MAAU,MACR,2EAA2E,EAAW,EAAS,EAAS,EAAS,CAAC,GACnH,CAGH,GAAI,GAAQ,oBAAqB,CAC/B,GAAM,CAAE,sBAAqB,mBAAoB,EAEjD,GAAI,GAAS,UACX,IAAK,GAAM,CAAC,EAAK,KAAY,OAAO,QAAQ,EAAoB,CACzD,EAAQ,UAAU,CAAE,MAAK,UAAS,WAAU,CAAC,CAItD,MAAO,CAAE,kBAAiB,iBAAkB,EAAqB,CAGnE,EACE,GAAG,EAAS,YAAa,EAAW,UAAU,CAAC,gCAAgC,EAAa,EAAS,EAAS,EAAS,CAAC,GACxH,CAAE,UAAW,GAAM,CACpB"}
1
+ {"version":3,"file":"extractContent.mjs","names":[],"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 {\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 { 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): InternalExtractResult | 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\ntype ExtractResult = {\n transformedCode: string | null;\n extractedContentMap: Record<string, Record<string, string>>;\n};\n\ntype ExtractContext = {\n configuration: IntlayerConfig;\n appLogger: ReturnType<typeof getAppLogger>;\n baseDir: string;\n unmergedDictionaries: Record<string, unknown>;\n saveComponent: boolean;\n componentExtension: string;\n};\n\nconst buildContext = (\n filePath: string,\n options: ExtractIntlayerOptions | undefined\n): ExtractContext => {\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 return {\n configuration,\n appLogger,\n baseDir,\n unmergedDictionaries,\n saveComponent,\n componentExtension,\n };\n};\n\nexport const extractContent = async (\n filePath: string,\n packageName: PackageName,\n options?: ExtractIntlayerOptions\n): Promise<ExtractResult | undefined> => {\n const {\n configuration,\n appLogger,\n baseDir,\n unmergedDictionaries,\n saveComponent,\n componentExtension,\n } = buildContext(filePath, options);\n\n if (componentExtension === '.vue' && !vueCompiler) {\n try {\n vueCompiler = await import('@intlayer/vue-compiler');\n } catch {\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} Install ${colorizePath('@intlayer/vue-compiler', ANSIColors.YELLOW)} to process Vue files.`\n );\n }\n }\n\n if (componentExtension === '.svelte' && !svelteCompiler) {\n try {\n svelteCompiler = await import('@intlayer/svelte-compiler');\n } catch {\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} Install ${colorizePath('@intlayer/svelte-compiler', ANSIColors.YELLOW)} to process Svelte files.`\n );\n }\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 = 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 await handleExtractionSideEffects(\n result.extractedContentMap,\n filePath,\n options,\n { configuration, baseDir, appLogger },\n saveComponent\n );\n\n return {\n transformedCode: result.transformedCode,\n extractedContentMap: result.extractedContentMap,\n };\n};\n\n/**\n * Synchronous variant of `extractContent` — used by the Babel plugin which\n * runs in a sync transform context (e.g. Next.js / Webpack).\n *\n * Differences from `extractContent`:\n * - Loads external compilers (Vue, Svelte) via `require()` instead of `import()`\n * - Fires `onExtract` callbacks as fire-and-forget (cannot await in sync context)\n * - Does NOT write dictionary files or run the code formatter; callers that\n * need persistence should supply an `onExtract` callback\n */\nexport const extractContentSync = (\n filePath: string,\n packageName: PackageName,\n options?: ExtractIntlayerOptions\n): ExtractResult | undefined => {\n const {\n configuration,\n appLogger,\n baseDir,\n unmergedDictionaries,\n saveComponent,\n componentExtension,\n } = buildContext(filePath, options);\n\n const requireFn = getProjectRequire();\n\n if (componentExtension === '.vue' && !vueCompiler) {\n try {\n vueCompiler = requireFn('@intlayer/vue-compiler') as VueCompiler;\n } catch {\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} Install ${colorizePath('@intlayer/vue-compiler', ANSIColors.YELLOW)} to process Vue files.`\n );\n }\n }\n\n if (componentExtension === '.svelte' && !svelteCompiler) {\n try {\n svelteCompiler = requireFn('@intlayer/svelte-compiler') as SvelteCompiler;\n } catch {\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} Install ${colorizePath('@intlayer/svelte-compiler', ANSIColors.YELLOW)} to process Svelte files.`\n );\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?.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 { 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, extractedContentMap };\n};\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import{SERVER_CAPABLE_PACKAGES as e}from"./utils/constants.mjs";import{getExistingIntlayerInfo as t}from"./utils/getExistingIntlayerInfo.mjs";import{extractBabelContentForComponents as n}from"./babelProcessor.mjs";import{readFileSync as r,writeFileSync as i}from"node:fs";import{detectFormatCommand as a}from"@intlayer/chokidar/cli";import{parse as o}from"@babel/parser";import{execSync as s}from"node:child_process";import c from"@babel/traverse";import*as l from"@babel/types";const u=typeof c==`function`?c:c.default,d=(c,d,f,p,m=!0,h={},g)=>{let _=g??r(c,`utf-8`),v=o(_,{sourceType:`module`,plugins:[`jsx`,`typescript`]}),y=v.program.directives.some(e=>e.value.value===`use client`),b=e.has(f)&&!y?`${f}/server`:f,x=f===`solid-intlayer`,{extractedContent:S,replacements:C,componentsNeedingHooks:w,componentKeyMap:T,componentPaths:E,hookMap:D}=n(v,_,new Set,d,p,c,h);if(Object.keys(S).length===0)return null;let O=[],k=e=>{let n=e;for(;n;){let e=E.find(e=>e.node===n?.node);if(e){let n=t(e);if(n)return n.hook;if(w.has(e))return D.get(e.node)||`useIntlayer`}n=n.parentPath}return`useIntlayer`};for(let{path:e,key:t,type:n,variables:r,childrenToReplace:i}of C){let a=x?`content().${t}`:`content.${t}`,o=k(e)===`getIntlayer`?``:`.value`;if(n===`jsx-text`&&e.isJSXText())O.push({start:e.node.start,end:e.node.end,replacement:`{${a}}`});else if(n===`jsx-attribute`&&e.isJSXAttribute()){let t=e.node.value;t&&O.push({start:t.start,end:t.end,replacement:`{${a}${o}}`})}else if(n===`string-literal`&&e.isStringLiteral())O.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;O.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;O.push({start:t,end:n,replacement:e})}}let A=!1,j=!1;for(let e of w){let n=T.get(e.node),r=t(e);if(r)r.hook===`useIntlayer`&&(A=!0),r.hook===`getIntlayer`&&(j=!0);else{let t=D.get(e.node)||`useIntlayer`;t===`useIntlayer`&&(A=!0),t===`getIntlayer`&&(j=!0);let r=e.get(`body`),i=`\n const content = ${t}('${n}');\n`;if(r.isBlockStatement())O.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=_[t];if(e===`(`){a=t;break}if(e!==` `&&e!==`
1
+ import{SERVER_CAPABLE_PACKAGES as e}from"./utils/constants.mjs";import{getExistingIntlayerInfo as t}from"./utils/getExistingIntlayerInfo.mjs";import{extractBabelContentForComponents as n}from"./babelProcessor.mjs";import{readFileSync as r,writeFileSync as i}from"node:fs";import{detectFormatCommand as a}from"@intlayer/chokidar/cli";import{parse as o}from"@babel/parser";import{execSync as s}from"node:child_process";import c from"@babel/traverse";import*as l from"@babel/types";const u=typeof c==`function`?c:c.default,d=(c,d,f,p,m=!0,h={},g)=>{let _=g??r(c,`utf-8`),v=o(_,{sourceType:`module`,plugins:[`jsx`,`typescript`]}),y=v.program.directives.some(e=>e.value.value===`use client`),b=e.has(f)&&!y?`${f}/server`:f,x=f===`solid-intlayer`,{extractedContent:S,replacements:C,componentsNeedingHooks:w,componentKeyMap:T,componentPaths:E,hookMap:D}=n(v,_,new Set,d,p,c,h);if(Object.keys(S).length===0)return null;let O=[],k=new Map;for(let e of E)k.set(e.node,e);let A=new Map;for(let e of E)A.set(e.node,t(e));let j=e=>{let t=e;for(;t;){if(k.has(t.node))return A.get(t.node);t=t.parentPath}},M=e=>{let t=e;for(;t;){let e=k.get(t.node);if(e){let t=A.get(e.node);if(t)return t.hook;if(w.has(e))return D.get(e.node)||`useIntlayer`}t=t.parentPath}return`useIntlayer`};for(let{path:e,key:t,type:n,variables:r,childrenToReplace:i}of C){let a=j(e),o=a?.variableName??`content`,s=a?.isDestructured?t:x?`${o}().${t}`:`${o}.${t}`,c=M(e)===`getIntlayer`?``:`.value`;if(n===`jsx-text`&&e.isJSXText())O.push({start:e.node.start,end:e.node.end,replacement:`{${s}}`});else if(n===`jsx-attribute`&&e.isJSXAttribute()){let t=e.node.value;t&&O.push({start:t.start,end:t.end,replacement:`{${s}${c}}`})}else if(n===`string-literal`&&e.isStringLiteral())O.push({start:e.node.start,end:e.node.end,replacement:`${s}${c}`});else if(n===`jsx-text-combined`&&i&&i.length>0){let e=`{${s}}`,t=i[0].start,n=i[i.length-1].end;O.push({start:t,end:n,replacement:e})}else if(n===`jsx-insertion`&&r&&i&&i.length>0){let e=`{${s}({ ${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;O.push({start:t,end:n,replacement:e})}}let N=!1,P=!1;for(let e of w){let t=T.get(e.node),n=A.get(e.node);if(n){if(n.hook===`useIntlayer`&&(N=!0),n.hook===`getIntlayer`&&(P=!0),n.isDestructured&&n.objectPatternNode){let t=new Set;for(let{path:n,key:r}of C){let i=n;for(;i;){if(i.node===e.node){t.add(r);break}i=i.parentPath}}let r=[...t].filter(e=>!n.existingDestructuredKeys.includes(e));if(r.length>0){let{objectPatternNode:e}=n,t=e.properties[e.properties.length-1];O.push({start:t.end,end:t.end,replacement:`, ${r.join(`, `)}`})}}}else{let n=D.get(e.node)||`useIntlayer`;n===`useIntlayer`&&(N=!0),n===`getIntlayer`&&(P=!0);let r=e.get(`body`),i=`\n const content = ${n}('${t}');\n`;if(r.isBlockStatement())O.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=_[t];if(e===`(`){a=t;break}if(e!==` `&&e!==`
2
2
  `&&e!==`\r`&&e!==` `)break}if(a!==-1)for(let e=i;e<_.length;e++){let t=_[e];if(t===`)`){o=e;break}if(t!==` `&&t!==`
3
3
  `&&t!==`\r`&&t!==` `)break}a!==-1&&o!==-1?(O.push({start:o,end:o+1,replacement:`)
4
- }`}),O.push({start:a,end:a+1,replacement:`{\n const content = ${t}('${n}');\n return (`})):(O.push({start:i,end:i,replacement:`
5
- }`}),O.push({start:e,end:e,replacement:`{\n const content = ${t}('${n}');\n return `}))}}}let M=(e,t)=>{let n;if(u(v,{ImportDeclaration(e){e.node.source.value===t&&(n=e,e.stop())}}),!n){let n=`import { ${e} } from '${t}';\n`,r=0;if(v.program.body.length>0)r=v.program.body[0].start;else if(v.program.directives&&v.program.directives.length>0){r=v.program.directives[v.program.directives.length-1].end,_[r]===`;`&&r++,O.push({start:r,end:r,replacement:`\n${n}`});return}(r===0||v.program.body.length>0&&r===v.program.body[0].start)&&O.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=_.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?`, `:` `;O.push({start:a,end:a,replacement:`${o}${e} `})}}};A&&M(`useIntlayer`,b),j&&M(`getIntlayer`,`intlayer`),O.sort((e,t)=>t.start===e.start?t.end-e.end:t.start-e.start);let N=_;for(let e of O)N=N.slice(0,e.start)+e.replacement+N.slice(e.end);if(m){i(c,N);let e=a(p);if(e)try{s(e.replace(`{{file}}`,c),{stdio:`inherit`,cwd:p.system.baseDir})}catch(e){console.error(e)}}return{extractedContent:S,modifiedCode:N}};export{d as processTsxFile};
4
+ }`}),O.push({start:a,end:a+1,replacement:`{\n const content = ${n}('${t}');\n return (`})):(O.push({start:i,end:i,replacement:`
5
+ }`}),O.push({start:e,end:e,replacement:`{\n const content = ${n}('${t}');\n return `}))}}}let F=(e,t)=>{let n;if(u(v,{ImportDeclaration(e){e.node.source.value===t&&(n=e,e.stop())}}),!n){let n=`import { ${e} } from '${t}';\n`,r=0;if(v.program.body.length>0)r=v.program.body[0].start;else if(v.program.directives&&v.program.directives.length>0){r=v.program.directives[v.program.directives.length-1].end,_[r]===`;`&&r++,O.push({start:r,end:r,replacement:`\n${n}`});return}(r===0||v.program.body.length>0&&r===v.program.body[0].start)&&O.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=_.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?`, `:` `;O.push({start:a,end:a,replacement:`${o}${e} `})}}};N&&F(`useIntlayer`,b),P&&F(`getIntlayer`,`intlayer`),O.sort((e,t)=>t.start===e.start?t.end-e.end:t.start-e.start);let I=_;for(let e of O)I=I.slice(0,e.start)+e.replacement+I.slice(e.end);if(m){i(c,I);let e=a(p);if(e)try{s(e.replace(`{{file}}`,c),{stdio:`inherit`,cwd:p.system.baseDir})}catch(e){console.error(e)}}return{extractedContent:S,modifiedCode:I}};export{d as processTsxFile};
6
6
  //# sourceMappingURL=processTsxFile.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"processTsxFile.mjs","names":[],"sources":["../../../src/extractContent/processTsxFile.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { parse } from '@babel/parser';\nimport _traverse, { type NodePath } from '@babel/traverse';\nimport * as t from '@babel/types';\nimport { detectFormatCommand } from '@intlayer/chokidar/cli';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { extractBabelContentForComponents } from './babelProcessor';\nimport {\n 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
+ {"version":3,"file":"processTsxFile.mjs","names":[],"sources":["../../../src/extractContent/processTsxFile.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { parse } from '@babel/parser';\nimport _traverse, { type NodePath } from '@babel/traverse';\nimport * as t from '@babel/types';\nimport { detectFormatCommand } from '@intlayer/chokidar/cli';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { extractBabelContentForComponents } from './babelProcessor';\nimport {\n type ExistingIntlayerInfo,\n getExistingIntlayerInfo,\n type PackageName,\n SERVER_CAPABLE_PACKAGES,\n} from './utils';\n\nexport type TextEdit = {\n start: number;\n end: number;\n replacement: string;\n};\n\nconst traverse = (\n typeof _traverse === 'function' ? _traverse : (_traverse as any).default\n) as typeof _traverse;\n\n/**\n * Processes a TSX/JSX/TS/JS file to extract content and inject Intlayer hooks/calls.\n */\nexport const processTsxFile = (\n filePath: string,\n componentKey: string,\n packageName: PackageName,\n configuration: IntlayerConfig,\n save: boolean = true,\n unmergedDictionaries: Record<string, unknown> = {},\n providedFileCode?: string\n): {\n extractedContent: Record<string, Record<string, string>>;\n modifiedCode: string;\n} | null => {\n const fileCode = providedFileCode ?? readFileSync(filePath, 'utf-8');\n\n const ast = parse(fileCode, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\n const hasUseClient = ast.program.directives.some(\n (directive) => directive.value.value === 'use client'\n );\n\n const effectivePackageName =\n SERVER_CAPABLE_PACKAGES.has(packageName) && !hasUseClient\n ? `${packageName}/server`\n : packageName;\n\n const isSolid = packageName === 'solid-intlayer';\n const existingKeys = new Set<string>();\n\n const {\n extractedContent,\n replacements,\n componentsNeedingHooks,\n componentKeyMap,\n componentPaths,\n hookMap,\n } = extractBabelContentForComponents(\n ast,\n fileCode,\n existingKeys,\n componentKey,\n configuration,\n filePath,\n unmergedDictionaries\n );\n\n if (Object.keys(extractedContent).length === 0) return null;\n\n const textEdits: TextEdit[] = [];\n\n // Build a lookup map: component AST node → NodePath (O(1) access)\n const componentNodeToPath = new Map<t.Node, NodePath>();\n for (const componentPath of componentPaths) {\n componentNodeToPath.set(componentPath.node, componentPath);\n }\n\n // Cache getExistingIntlayerInfo results for all component paths (avoids repeated traversals)\n const existingInfoCache = new Map<t.Node, ExistingIntlayerInfo | undefined>();\n for (const componentPath of componentPaths) {\n existingInfoCache.set(\n componentPath.node,\n getExistingIntlayerInfo(componentPath)\n );\n }\n\n /**\n * Walks up the ancestor chain to find the nearest enclosing component's\n * existing Intlayer info (if any).\n */\n const getExistingInfoForPath = (\n path: NodePath\n ): ExistingIntlayerInfo | undefined => {\n let current: NodePath | null = path;\n while (current) {\n if (componentNodeToPath.has(current.node)) {\n return existingInfoCache.get(current.node);\n }\n current = current.parentPath;\n }\n return undefined;\n };\n\n const getProvidingHookType = (\n path: NodePath\n ): 'useIntlayer' | 'getIntlayer' => {\n let current: NodePath | null = path;\n while (current) {\n const componentPath = componentNodeToPath.get(current.node);\n\n if (componentPath) {\n const existingInfo = existingInfoCache.get(componentPath.node);\n\n if (existingInfo) {\n return existingInfo.hook;\n }\n\n if (componentsNeedingHooks.has(componentPath)) {\n return hookMap.get(componentPath.node) || 'useIntlayer';\n }\n }\n current = current.parentPath;\n }\n return 'useIntlayer';\n };\n\n for (const {\n path,\n key,\n type,\n variables,\n childrenToReplace,\n } of replacements) {\n const existingInfo = getExistingInfoForPath(path);\n // When the existing call is destructured (e.g. `const { a } = getIntlayer(...)`),\n // new keys are added directly to that destructuring, so access them by name alone.\n const varName = existingInfo?.variableName ?? 'content';\n const contentAccessCode = existingInfo?.isDestructured\n ? key\n : isSolid\n ? `${varName}().${key}`\n : `${varName}.${key}`;\n const hookType = getProvidingHookType(path);\n const valueSuffix = hookType === 'getIntlayer' ? '' : '.value';\n\n if (type === 'jsx-text' && path.isJSXText()) {\n textEdits.push({\n start: path.node.start!,\n end: path.node.end!,\n replacement: `{${contentAccessCode}}`,\n });\n } else if (type === 'jsx-attribute' && path.isJSXAttribute()) {\n const valNode = path.node.value;\n\n if (valNode) {\n textEdits.push({\n start: valNode.start!,\n end: valNode.end!,\n replacement: `{${contentAccessCode}${valueSuffix}}`,\n });\n }\n } else if (type === 'string-literal' && path.isStringLiteral()) {\n textEdits.push({\n start: path.node.start!,\n end: path.node.end!,\n replacement: `${contentAccessCode}${valueSuffix}`,\n });\n } else if (\n type === 'jsx-text-combined' &&\n childrenToReplace &&\n childrenToReplace.length > 0\n ) {\n const accessStr = `{${contentAccessCode}}`;\n const start = childrenToReplace[0].start!;\n const end = childrenToReplace[childrenToReplace.length - 1].end!;\n textEdits.push({ start, end, replacement: accessStr });\n } else if (\n type === 'jsx-insertion' &&\n variables &&\n childrenToReplace &&\n childrenToReplace.length > 0\n ) {\n const objProps = variables\n .map((variableString) => {\n const [key, variableValue] = variableString\n .split(':')\n .map((part) => part.trim());\n return `${key}: ${variableValue}`;\n })\n .join(', ');\n\n const accessStr = `{${contentAccessCode}({ ${objProps} })}`;\n const start = childrenToReplace[0].start!;\n const end = childrenToReplace[childrenToReplace.length - 1].end!;\n textEdits.push({ start, end, replacement: accessStr });\n }\n }\n\n let needsUseIntlayer = false;\n let needsGetIntlayer = false;\n\n for (const componentPath of componentsNeedingHooks) {\n const finalKey = componentKeyMap.get(componentPath.node)!;\n const existingInfo = existingInfoCache.get(componentPath.node);\n\n if (existingInfo) {\n if (existingInfo.hook === 'useIntlayer') needsUseIntlayer = true;\n\n if (existingInfo.hook === 'getIntlayer') needsGetIntlayer = true;\n\n // When the existing call is destructured, inject any missing keys into\n // the destructuring pattern so they can be accessed by name directly.\n if (existingInfo.isDestructured && existingInfo.objectPatternNode) {\n const neededKeys = new Set<string>();\n\n for (const { path: rPath, key: rKey } of replacements) {\n let current: NodePath | null = rPath;\n\n while (current) {\n if (current.node === componentPath.node) {\n neededKeys.add(rKey);\n break;\n }\n current = current.parentPath;\n }\n }\n\n const missingKeys = [...neededKeys].filter(\n (key) => !existingInfo.existingDestructuredKeys.includes(key)\n );\n\n if (missingKeys.length > 0) {\n const { objectPatternNode } = existingInfo;\n // Insert right after the last property so the space/newline before\n // `}` is naturally preserved: `{ a }` → `{ a, b }`.\n const lastProp =\n objectPatternNode.properties[\n objectPatternNode.properties.length - 1\n ];\n textEdits.push({\n start: lastProp.end!,\n end: lastProp.end!,\n replacement: `, ${missingKeys.join(', ')}`,\n });\n }\n }\n } else {\n const hook = hookMap.get(componentPath.node) || 'useIntlayer';\n\n if (hook === 'useIntlayer') needsUseIntlayer = true;\n\n if (hook === 'getIntlayer') needsGetIntlayer = true;\n\n const bodyPath = componentPath.get('body') as NodePath;\n const hookStatementStr = `\\n const content = ${hook}('${finalKey}');\\n`;\n\n if (bodyPath.isBlockStatement()) {\n textEdits.push({\n start: bodyPath.node.start! + 1,\n end: bodyPath.node.start! + 1,\n replacement: hookStatementStr,\n });\n } else if (bodyPath.isExpression()) {\n const start = bodyPath.node.start!;\n const end = bodyPath.node.end!;\n\n // Detect wrapping parentheses: `() => (expr)` — scan backward from\n // the expression start and forward from its end for matching `(` / `)`.\n let parenStart = -1;\n let parenEnd = -1;\n\n for (let i = start - 1; i >= 0; i--) {\n const char = fileCode[i];\n if (char === '(') {\n parenStart = i;\n break;\n }\n if (char !== ' ' && char !== '\\n' && char !== '\\r' && char !== '\\t')\n break;\n }\n\n if (parenStart !== -1) {\n for (let i = end; i < fileCode.length; i++) {\n const char = fileCode[i];\n if (char === ')') {\n parenEnd = i;\n break;\n }\n if (char !== ' ' && char !== '\\n' && char !== '\\r' && char !== '\\t')\n break;\n }\n }\n\n if (parenStart !== -1 && parenEnd !== -1) {\n // Replace the surrounding `(` … `)` with a block statement. We keep\n // the parentheses as `return (…)` to prevent automatic semicolon\n // insertion when the returned expression starts on a new line.\n textEdits.push({\n start: parenEnd,\n end: parenEnd + 1,\n replacement: `)\\n}`,\n });\n textEdits.push({\n start: parenStart,\n end: parenStart + 1,\n replacement: `{\\n const content = ${hook}('${finalKey}');\\n return (`,\n });\n } else {\n textEdits.push({\n start: end,\n end: end,\n replacement: `\\n}`,\n });\n textEdits.push({\n start: start,\n end: start,\n replacement: `{\\n const content = ${hook}('${finalKey}');\\n return `,\n });\n }\n }\n }\n }\n\n const injectImport = (hookName: string, targetPackage: string) => {\n let existingImportPath: NodePath<t.ImportDeclaration> | undefined;\n\n traverse(ast, {\n ImportDeclaration(path) {\n if (path.node.source.value === targetPackage) {\n existingImportPath = path;\n path.stop();\n }\n },\n });\n\n if (!existingImportPath) {\n const newImportStr = `import { ${hookName} } from '${targetPackage}';\\n`;\n let insertPos = 0;\n\n if (ast.program.body.length > 0) {\n insertPos = ast.program.body[0].start!;\n } else if (ast.program.directives && ast.program.directives.length > 0) {\n insertPos =\n ast.program.directives[ast.program.directives.length - 1].end!;\n\n if (fileCode[insertPos] === ';') insertPos++;\n\n textEdits.push({\n start: insertPos,\n end: insertPos,\n replacement: `\\n${newImportStr}`,\n });\n return;\n }\n\n if (\n insertPos === 0 ||\n (ast.program.body.length > 0 &&\n insertPos === ast.program.body[0].start!)\n ) {\n textEdits.push({\n start: insertPos,\n end: insertPos,\n replacement: newImportStr,\n });\n }\n } else {\n const existingSpecifiers = existingImportPath.node.specifiers;\n const missingImport = !existingSpecifiers.some(\n (specifier) =>\n t.isImportSpecifier(specifier) &&\n t.isIdentifier(specifier.imported) &&\n specifier.imported.name === hookName\n );\n\n if (missingImport) {\n const importCode = fileCode.slice(\n existingImportPath.node.start!,\n existingImportPath.node.end!\n );\n const closingBraceIndex = importCode.lastIndexOf('}');\n\n if (closingBraceIndex !== -1) {\n const isCommaNeeded = !importCode\n .slice(0, closingBraceIndex)\n .trim()\n .endsWith(',');\n const absolutePos =\n existingImportPath.node.start! + closingBraceIndex;\n const prefix = isCommaNeeded ? ', ' : ' ';\n textEdits.push({\n start: absolutePos,\n end: absolutePos,\n replacement: `${prefix}${hookName} `,\n });\n }\n }\n }\n };\n\n if (needsUseIntlayer) injectImport('useIntlayer', effectivePackageName);\n\n if (needsGetIntlayer) injectImport('getIntlayer', 'intlayer');\n\n textEdits.sort((editA, editB) => {\n if (editB.start !== editA.start) return editB.start - editA.start;\n\n return editB.end - editA.end;\n });\n\n let formattedCode = fileCode;\n\n for (const edit of textEdits) {\n formattedCode =\n formattedCode.slice(0, edit.start) +\n edit.replacement +\n formattedCode.slice(edit.end);\n }\n\n if (save) {\n writeFileSync(filePath, formattedCode);\n\n const formatCommand = detectFormatCommand(configuration);\n\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', filePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n }\n\n return { extractedContent, modifiedCode: formattedCode };\n};\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{extractDictionaryKey as e}from"./extractDictionaryKey.mjs";import{getFormatFromExtension as t,resolveRelativePath as n}from"@intlayer/chokidar/utils";import{DefaultValues as r}from"@intlayer/config/node";import{basename as i,dirname as a,extname as o,relative as s,resolve as c}from"node:path";import{parseStringPattern as l}from"@intlayer/config/utils";import{getUnmergedDictionaries as u}from"@intlayer/unmerged-dictionaries-entry";const d=e=>{if(typeof e.compiler?.output==`string`)return t=>l(e.compiler.output,t);if(typeof e.compiler?.output==`function`)return e.compiler.output;if(typeof e.compiler?.outputDir==`string`){let t=c(e.system.baseDir,e.compiler.outputDir);return n=>l(`${t}/{{fileName}}.${e.content.fileExtensions[0].split(`.`)[1]}.json`,n)}return r.Compiler.COMPILER_OUTPUT},f=async(e,r,l,f)=>{let{baseDir:p}=l.system,{defaultLocale:m}=l.internationalization,h=(u(l)??{})[r]?.filter(e=>e.location!==`remote`).filter(e=>e.locale===void 0||e.locale===(f??m));if(h?.[0]?.filePath){let e=h[0].filePath,t=c(p,e);return{absolutePath:t,relativePath:s(p,t),isPerLocale:!1}}let g=d(l),_=o(e),v=i(e,_),y=v.charAt(0).toLowerCase()+v.slice(1),b=t(_),x={key:r,componentDirPath:s(p,a(e)),componentFileName:v,fileName:y,componentFormat:b,componentExtension:_,format:b,locale:m,extension:l.content.fileExtensions[0]},S=n(await g(x),e,p),C=`###########locale###########`,w=(await g({...x,locale:C})).includes(C);return{absolutePath:S,relativePath:s(p,S),isPerLocale:w}},p=async(t,n,r)=>{let i=e(t,n);return{dictionaryKey:i,...await f(t,i,r)}};export{p as extractDictionaryInfo,d as getOutput,f as resolveContentFilePaths};
1
+ import{extractDictionaryKey as e}from"./extractDictionaryKey.mjs";import{getFormatFromExtension as t,resolveRelativePath as n}from"@intlayer/chokidar/utils";import{ANSIColors as r,colorize as i}from"@intlayer/config/logger";import{basename as a,dirname as o,extname as s,relative as c,resolve as l}from"node:path";import{parseStringPattern as u}from"@intlayer/config/utils";import{getUnmergedDictionaries as d}from"@intlayer/unmerged-dictionaries-entry";const f=e=>{if(typeof e.compiler?.output==`string`)return t=>u(e.compiler.output,t);if(typeof e.compiler?.output==`function`)return e.compiler.output;throw Error(`No output configuration found. Add a ${i(`compiler.output`,r.BLUE)} in your configuration.`)},p=async(e,r,i,u)=>{let{baseDir:p}=i.system,{defaultLocale:m}=i.internationalization,h=(d(i)??{})[r]?.filter(e=>e.location!==`remote`).filter(e=>e.locale===void 0||e.locale===(u??m));if(h?.[0]?.filePath){let e=h[0].filePath,t=l(p,e);return{absolutePath:t,relativePath:c(p,t),isPerLocale:!1}}let g=f(i),_=s(e),v=a(e,_),y=v.charAt(0).toLowerCase()+v.slice(1),b=t(_),x={key:r,componentDirPath:c(p,o(e)),componentFileName:v,fileName:y,componentFormat:b,componentExtension:_,format:b,locale:m,extension:i.content.fileExtensions[0]},S=n(await g(x),e,p),C=`###########locale###########`,w=(await g({...x,locale:C})).includes(C);return{absolutePath:S,relativePath:c(p,S),isPerLocale:w}},m=async(t,n,r)=>{let i=e(t,n);return{dictionaryKey:i,...await p(t,i,r)}};export{m as extractDictionaryInfo,f as getOutput,p as resolveContentFilePaths};
2
2
  //# sourceMappingURL=extractDictionaryInfo.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractDictionaryInfo.mjs","names":[],"sources":["../../../../src/extractContent/utils/extractDictionaryInfo.ts"],"sourcesContent":["import { basename, dirname, extname, relative, resolve } from 'node:path';\nimport {\n getFormatFromExtension,\n resolveRelativePath,\n} from '@intlayer/chokidar/utils';\nimport { DefaultValues } from '@intlayer/config/node';\nimport { parseStringPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type {\n FilePathPatternContext,\n FilePathPatternFunction,\n} from '@intlayer/types/filePathPattern';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { extractDictionaryKey } from './extractDictionaryKey';\n\nexport const getOutput = (\n configuration: IntlayerConfig\n): FilePathPatternFunction => {\n if (typeof configuration.compiler?.output === 'string') {\n return (context: FilePathPatternContext) =>\n parseStringPattern(configuration.compiler.output as string, context);\n }\n\n if (typeof configuration.compiler?.output === 'function') {\n return configuration.compiler.output;\n }\n\n if (typeof configuration.compiler?.outputDir === 'string') {\n // Resolve outputDir against baseDir immediately to guarantee a valid absolute path everywhere\n const absoluteOutputDir = resolve(\n configuration.system.baseDir,\n configuration.compiler.outputDir\n );\n\n return (context: FilePathPatternContext) =>\n parseStringPattern(\n `${absoluteOutputDir}/{{fileName}}.${configuration.content.fileExtensions[0].split('.')[1]}.json`,\n context\n );\n }\n\n return DefaultValues.Compiler.COMPILER_OUTPUT;\n};\n\nexport type ResolveContentFilePaths = {\n absolutePath: string;\n relativePath: string;\n isPerLocale: boolean;\n};\n\n/**\n * Resolves the paths for the content files associated with a component.\n * Checks for existing dictionaries first.\n */\nexport const resolveContentFilePaths = async (\n filePath: string,\n componentKey: string,\n configuration: IntlayerConfig,\n locale?: Locale\n): Promise<ResolveContentFilePaths> => {\n const { baseDir } = configuration.system;\n const { defaultLocale } = configuration.internationalization;\n\n const unmergedDictionaries = getUnmergedDictionaries(configuration) ?? {};\n const existingDicts = unmergedDictionaries[componentKey]\n ?.filter(\n (dictionary) =>\n // Remove remote dictionaries (Fix: Check for !== instead of ===)\n dictionary.location !== 'remote'\n )\n .filter(\n (dictionary) =>\n // Check for first locale dictionary sorted by priority that include the targeted locale\n dictionary.locale === undefined ||\n dictionary.locale === (locale ?? defaultLocale)\n );\n\n if (existingDicts?.[0]?.filePath) {\n const existingPath = existingDicts[0].filePath;\n const resolvedAbsolutePath = resolve(baseDir, existingPath);\n\n return {\n absolutePath: resolvedAbsolutePath,\n relativePath: relative(baseDir, resolvedAbsolutePath),\n isPerLocale: false,\n };\n }\n\n const pattern = getOutput(configuration);\n\n const extension = extname(\n filePath\n ) as FilePathPatternContext['componentExtension'];\n const componentName = basename(filePath, extension);\n const uncapitalizedName =\n componentName.charAt(0).toLowerCase() + componentName.slice(1);\n const componentFormat = getFormatFromExtension(\n extension!\n ) as FilePathPatternContext['componentFormat'];\n\n const context: FilePathPatternContext = {\n key: componentKey,\n componentDirPath: relative(baseDir, dirname(filePath)),\n componentFileName: componentName,\n fileName: uncapitalizedName,\n componentFormat,\n componentExtension: extension,\n format: componentFormat!,\n locale: defaultLocale,\n extension: configuration.content.fileExtensions[0],\n };\n\n const rawAbsolutePath = await pattern(context);\n\n // Apply the resolution rules\n const absolutePath = resolveRelativePath(rawAbsolutePath, filePath, baseDir);\n\n const localeIdentifier = '###########locale###########' as Locale;\n\n const rawPerLocalePath = await pattern({\n ...context,\n locale: localeIdentifier,\n });\n const isPerLocale = rawPerLocalePath.includes(localeIdentifier);\n\n return {\n absolutePath,\n relativePath: relative(baseDir, absolutePath),\n isPerLocale,\n };\n};\n\nexport type ExtractDictionaryInfoOptions = {\n configuration?: IntlayerConfig;\n};\n\n/**\n * Extracts the dictionary key and dictionary file path for a given component file.\n */\nexport const extractDictionaryInfo = async (\n filePath: string,\n fileText: string,\n configuration: IntlayerConfig\n): Promise<\n {\n dictionaryKey: string;\n } & ResolveContentFilePaths\n> => {\n const dictionaryKey = extractDictionaryKey(filePath, fileText);\n\n const resolvedPaths = await resolveContentFilePaths(\n filePath,\n dictionaryKey,\n configuration\n );\n\n return {\n dictionaryKey,\n ...resolvedPaths,\n };\n};\n"],"mappings":"ybAgBA,MAAa,EACX,GAC4B,CAC5B,GAAI,OAAO,EAAc,UAAU,QAAW,SAC5C,MAAQ,IACN,EAAmB,EAAc,SAAS,OAAkB,EAAQ,CAGxE,GAAI,OAAO,EAAc,UAAU,QAAW,WAC5C,OAAO,EAAc,SAAS,OAGhC,GAAI,OAAO,EAAc,UAAU,WAAc,SAAU,CAEzD,IAAM,EAAoB,EACxB,EAAc,OAAO,QACrB,EAAc,SAAS,UACxB,CAED,MAAQ,IACN,EACE,GAAG,EAAkB,gBAAgB,EAAc,QAAQ,eAAe,GAAG,MAAM,IAAI,CAAC,GAAG,OAC3F,EACD,CAGL,OAAO,EAAc,SAAS,iBAanB,EAA0B,MACrC,EACA,EACA,EACA,IACqC,CACrC,GAAM,CAAE,WAAY,EAAc,OAC5B,CAAE,iBAAkB,EAAc,qBAGlC,GADuB,EAAwB,EAAc,EAAI,EAAE,EAC9B,IACvC,OACC,GAEC,EAAW,WAAa,SAC3B,CACA,OACE,GAEC,EAAW,SAAW,IAAA,IACtB,EAAW,UAAY,GAAU,GACpC,CAEH,GAAI,IAAgB,IAAI,SAAU,CAChC,IAAM,EAAe,EAAc,GAAG,SAChC,EAAuB,EAAQ,EAAS,EAAa,CAE3D,MAAO,CACL,aAAc,EACd,aAAc,EAAS,EAAS,EAAqB,CACrD,YAAa,GACd,CAGH,IAAM,EAAU,EAAU,EAAc,CAElC,EAAY,EAChB,EACD,CACK,EAAgB,EAAS,EAAU,EAAU,CAC7C,EACJ,EAAc,OAAO,EAAE,CAAC,aAAa,CAAG,EAAc,MAAM,EAAE,CAC1D,EAAkB,EACtB,EACD,CAEK,EAAkC,CACtC,IAAK,EACL,iBAAkB,EAAS,EAAS,EAAQ,EAAS,CAAC,CACtD,kBAAmB,EACnB,SAAU,EACV,kBACA,mBAAoB,EACpB,OAAQ,EACR,OAAQ,EACR,UAAW,EAAc,QAAQ,eAAe,GACjD,CAKK,EAAe,EAHG,MAAM,EAAQ,EAAQ,CAGY,EAAU,EAAQ,CAEtE,EAAmB,+BAMnB,GAJmB,MAAM,EAAQ,CACrC,GAAG,EACH,OAAQ,EACT,CAAC,EACmC,SAAS,EAAiB,CAE/D,MAAO,CACL,eACA,aAAc,EAAS,EAAS,EAAa,CAC7C,cACD,EAUU,EAAwB,MACnC,EACA,EACA,IAKG,CACH,IAAM,EAAgB,EAAqB,EAAU,EAAS,CAQ9D,MAAO,CACL,gBACA,GARoB,MAAM,EAC1B,EACA,EACA,EACD,CAKA"}
1
+ {"version":3,"file":"extractDictionaryInfo.mjs","names":[],"sources":["../../../../src/extractContent/utils/extractDictionaryInfo.ts"],"sourcesContent":["import { basename, dirname, extname, relative, resolve } from 'node:path';\nimport {\n getFormatFromExtension,\n resolveRelativePath,\n} from '@intlayer/chokidar/utils';\nimport { ANSIColors, colorize } from '@intlayer/config/logger';\nimport { parseStringPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type {\n FilePathPatternContext,\n FilePathPatternFunction,\n} from '@intlayer/types/filePathPattern';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { extractDictionaryKey } from './extractDictionaryKey';\n\nexport const getOutput = (\n configuration: IntlayerConfig\n): FilePathPatternFunction => {\n if (typeof configuration.compiler?.output === 'string') {\n return (context: FilePathPatternContext) =>\n parseStringPattern(configuration.compiler.output as string, context);\n }\n\n if (typeof configuration.compiler?.output === 'function') {\n return configuration.compiler.output;\n }\n\n throw new Error(\n `No output configuration found. Add a ${colorize('compiler.output', ANSIColors.BLUE)} in your configuration.`\n );\n};\n\nexport type ResolveContentFilePaths = {\n absolutePath: string;\n relativePath: string;\n isPerLocale: boolean;\n};\n\n/**\n * Resolves the paths for the content files associated with a component.\n * Checks for existing dictionaries first.\n */\nexport const resolveContentFilePaths = async (\n filePath: string,\n componentKey: string,\n configuration: IntlayerConfig,\n locale?: Locale\n): Promise<ResolveContentFilePaths> => {\n const { baseDir } = configuration.system;\n const { defaultLocale } = configuration.internationalization;\n\n const unmergedDictionaries = getUnmergedDictionaries(configuration) ?? {};\n const existingDicts = unmergedDictionaries[componentKey]\n ?.filter(\n (dictionary) =>\n // Remove remote dictionaries (Fix: Check for !== instead of ===)\n dictionary.location !== 'remote'\n )\n .filter(\n (dictionary) =>\n // Check for first locale dictionary sorted by priority that include the targeted locale\n dictionary.locale === undefined ||\n dictionary.locale === (locale ?? defaultLocale)\n );\n\n if (existingDicts?.[0]?.filePath) {\n const existingPath = existingDicts[0].filePath;\n const resolvedAbsolutePath = resolve(baseDir, existingPath);\n\n return {\n absolutePath: resolvedAbsolutePath,\n relativePath: relative(baseDir, resolvedAbsolutePath),\n isPerLocale: false,\n };\n }\n\n const pattern = getOutput(configuration);\n\n const extension = extname(\n filePath\n ) as FilePathPatternContext['componentExtension'];\n const componentName = basename(filePath, extension);\n const uncapitalizedName =\n componentName.charAt(0).toLowerCase() + componentName.slice(1);\n const componentFormat = getFormatFromExtension(\n extension!\n ) as FilePathPatternContext['componentFormat'];\n\n const context: FilePathPatternContext = {\n key: componentKey,\n componentDirPath: relative(baseDir, dirname(filePath)),\n componentFileName: componentName,\n fileName: uncapitalizedName,\n componentFormat,\n componentExtension: extension,\n format: componentFormat!,\n locale: defaultLocale,\n extension: configuration.content.fileExtensions[0],\n };\n\n const rawAbsolutePath = await pattern(context);\n\n // Apply the resolution rules\n const absolutePath = resolveRelativePath(rawAbsolutePath, filePath, baseDir);\n\n const localeIdentifier = '###########locale###########' as Locale;\n\n const rawPerLocalePath = await pattern({\n ...context,\n locale: localeIdentifier,\n });\n const isPerLocale = rawPerLocalePath.includes(localeIdentifier);\n\n return {\n absolutePath,\n relativePath: relative(baseDir, absolutePath),\n isPerLocale,\n };\n};\n\nexport type ExtractDictionaryInfoOptions = {\n configuration?: IntlayerConfig;\n};\n\n/**\n * Extracts the dictionary key and dictionary file path for a given component file.\n */\nexport const extractDictionaryInfo = async (\n filePath: string,\n fileText: string,\n configuration: IntlayerConfig\n): Promise<\n {\n dictionaryKey: string;\n } & ResolveContentFilePaths\n> => {\n const dictionaryKey = extractDictionaryKey(filePath, fileText);\n\n const resolvedPaths = await resolveContentFilePaths(\n filePath,\n dictionaryKey,\n configuration\n );\n\n return {\n dictionaryKey,\n ...resolvedPaths,\n };\n};\n"],"mappings":"scAgBA,MAAa,EACX,GAC4B,CAC5B,GAAI,OAAO,EAAc,UAAU,QAAW,SAC5C,MAAQ,IACN,EAAmB,EAAc,SAAS,OAAkB,EAAQ,CAGxE,GAAI,OAAO,EAAc,UAAU,QAAW,WAC5C,OAAO,EAAc,SAAS,OAGhC,MAAU,MACR,wCAAwC,EAAS,kBAAmB,EAAW,KAAK,CAAC,yBACtF,EAaU,EAA0B,MACrC,EACA,EACA,EACA,IACqC,CACrC,GAAM,CAAE,WAAY,EAAc,OAC5B,CAAE,iBAAkB,EAAc,qBAGlC,GADuB,EAAwB,EAAc,EAAI,EAAE,EAC9B,IACvC,OACC,GAEC,EAAW,WAAa,SAC3B,CACA,OACE,GAEC,EAAW,SAAW,IAAA,IACtB,EAAW,UAAY,GAAU,GACpC,CAEH,GAAI,IAAgB,IAAI,SAAU,CAChC,IAAM,EAAe,EAAc,GAAG,SAChC,EAAuB,EAAQ,EAAS,EAAa,CAE3D,MAAO,CACL,aAAc,EACd,aAAc,EAAS,EAAS,EAAqB,CACrD,YAAa,GACd,CAGH,IAAM,EAAU,EAAU,EAAc,CAElC,EAAY,EAChB,EACD,CACK,EAAgB,EAAS,EAAU,EAAU,CAC7C,EACJ,EAAc,OAAO,EAAE,CAAC,aAAa,CAAG,EAAc,MAAM,EAAE,CAC1D,EAAkB,EACtB,EACD,CAEK,EAAkC,CACtC,IAAK,EACL,iBAAkB,EAAS,EAAS,EAAQ,EAAS,CAAC,CACtD,kBAAmB,EACnB,SAAU,EACV,kBACA,mBAAoB,EACpB,OAAQ,EACR,OAAQ,EACR,UAAW,EAAc,QAAQ,eAAe,GACjD,CAKK,EAAe,EAHG,MAAM,EAAQ,EAAQ,CAGY,EAAU,EAAQ,CAEtE,EAAmB,+BAMnB,GAJmB,MAAM,EAAQ,CACrC,GAAG,EACH,OAAQ,EACT,CAAC,EACmC,SAAS,EAAiB,CAE/D,MAAO,CACL,eACA,aAAc,EAAS,EAAS,EAAa,CAC7C,cACD,EAUU,EAAwB,MACnC,EACA,EACA,IAKG,CACH,IAAM,EAAgB,EAAqB,EAAU,EAAS,CAQ9D,MAAO,CACL,gBACA,GARoB,MAAM,EAC1B,EACA,EACA,EACD,CAKA"}
@@ -1,2 +1,2 @@
1
- import*as e from"@babel/types";const t=t=>{let n;return t.traverse({CallExpression(t){let r=t.node.callee;if(e.isIdentifier(r)&&(r.name===`useIntlayer`||r.name===`getIntlayer`)){let i=t.node.arguments[0];e.isStringLiteral(i)&&(n={key:i.value,hook:r.name},t.stop())}},Function(e){e.skip()}}),n};export{t as getExistingIntlayerInfo};
1
+ import*as e from"@babel/types";const t=t=>{let n;return t.traverse({CallExpression(t){let r=t.node.callee;if(e.isIdentifier(r)&&(r.name===`useIntlayer`||r.name===`getIntlayer`)){let i=t.node.arguments[0];if(e.isStringLiteral(i)){let a=t.parent,o=!1,s=[],c,l=`content`;e.isVariableDeclarator(a)&&(e.isObjectPattern(a.id)?(o=!0,c=a.id,s=a.id.properties.filter(t=>e.isObjectProperty(t)&&e.isIdentifier(t.key)).map(e=>e.key.name)):e.isIdentifier(a.id)&&(l=a.id.name)),n={key:i.value,hook:r.name,variableName:l,isDestructured:o,existingDestructuredKeys:s,objectPatternNode:c},t.stop()}}},Function(e){e.skip()}}),n};export{t as getExistingIntlayerInfo};
2
2
  //# sourceMappingURL=getExistingIntlayerInfo.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"getExistingIntlayerInfo.mjs","names":[],"sources":["../../../../src/extractContent/utils/getExistingIntlayerInfo.ts"],"sourcesContent":["import type { NodePath } from '@babel/traverse';\nimport * as t from '@babel/types';\n\n/**\n * Searches for an existing useIntlayer or getIntlayer call in the function body.\n */\nexport const getExistingIntlayerInfo = (\n path: NodePath\n): { key: string; hook: 'useIntlayer' | 'getIntlayer' } | undefined => {\n let result: { key: string; hook: 'useIntlayer' | 'getIntlayer' } | undefined;\n\n // We only check the direct body of the function, not nested functions\n path.traverse({\n CallExpression(childPath) {\n const callee = childPath.node.callee;\n if (\n t.isIdentifier(callee) &&\n (callee.name === 'useIntlayer' || callee.name === 'getIntlayer')\n ) {\n const arg = childPath.node.arguments[0];\n if (t.isStringLiteral(arg)) {\n result = {\n key: arg.value,\n hook: callee.name as 'useIntlayer' | 'getIntlayer',\n };\n childPath.stop();\n }\n }\n },\n Function(childPath) {\n childPath.skip(); // Don't look inside nested functions\n },\n });\n\n return result;\n};\n"],"mappings":"+BAMA,MAAa,EACX,GACqE,CACrE,IAAI,EAyBJ,OAtBA,EAAK,SAAS,CACZ,eAAe,EAAW,CACxB,IAAM,EAAS,EAAU,KAAK,OAC9B,GACE,EAAE,aAAa,EAAO,GACrB,EAAO,OAAS,eAAiB,EAAO,OAAS,eAClD,CACA,IAAM,EAAM,EAAU,KAAK,UAAU,GACjC,EAAE,gBAAgB,EAAI,GACxB,EAAS,CACP,IAAK,EAAI,MACT,KAAM,EAAO,KACd,CACD,EAAU,MAAM,IAItB,SAAS,EAAW,CAClB,EAAU,MAAM,EAEnB,CAAC,CAEK"}
1
+ {"version":3,"file":"getExistingIntlayerInfo.mjs","names":[],"sources":["../../../../src/extractContent/utils/getExistingIntlayerInfo.ts"],"sourcesContent":["import type { NodePath } from '@babel/traverse';\nimport * as t from '@babel/types';\n\nexport type ExistingIntlayerInfo = {\n key: string;\n hook: 'useIntlayer' | 'getIntlayer';\n /** The variable name used to store the call result (e.g. `t` in `const t = useIntlayer(...)`) */\n variableName: string;\n /** True when the call result is destructured: `const { a, b } = getIntlayer(...)` */\n isDestructured: boolean;\n /** Keys already present in the destructuring pattern (empty when not destructured) */\n existingDestructuredKeys: string[];\n /** The ObjectPattern AST node, present only when `isDestructured` is true */\n objectPatternNode?: t.ObjectPattern;\n};\n\n/**\n * Searches for an existing useIntlayer or getIntlayer call in the function body.\n */\nexport const getExistingIntlayerInfo = (\n path: NodePath\n): ExistingIntlayerInfo | undefined => {\n let result: ExistingIntlayerInfo | undefined;\n\n // We only check the direct body of the function, not nested functions\n path.traverse({\n CallExpression(childPath) {\n const callee = childPath.node.callee;\n\n if (\n t.isIdentifier(callee) &&\n (callee.name === 'useIntlayer' || callee.name === 'getIntlayer')\n ) {\n const arg = childPath.node.arguments[0];\n\n if (t.isStringLiteral(arg)) {\n const parentNode = childPath.parent;\n let isDestructured = false;\n let existingDestructuredKeys: string[] = [];\n let objectPatternNode: t.ObjectPattern | undefined;\n let variableName = 'content';\n\n if (t.isVariableDeclarator(parentNode)) {\n if (t.isObjectPattern(parentNode.id)) {\n isDestructured = true;\n objectPatternNode = parentNode.id;\n existingDestructuredKeys = parentNode.id.properties\n .filter(\n (p): p is t.ObjectProperty =>\n t.isObjectProperty(p) && t.isIdentifier(p.key)\n )\n .map((p) => (p.key as t.Identifier).name);\n } else if (t.isIdentifier(parentNode.id)) {\n variableName = parentNode.id.name;\n }\n }\n\n result = {\n key: arg.value,\n hook: callee.name as 'useIntlayer' | 'getIntlayer',\n variableName,\n isDestructured,\n existingDestructuredKeys,\n objectPatternNode,\n };\n childPath.stop();\n }\n }\n },\n Function(childPath) {\n childPath.skip(); // Don't look inside nested functions\n },\n });\n\n return result;\n};\n"],"mappings":"+BAmBA,MAAa,EACX,GACqC,CACrC,IAAI,EAoDJ,OAjDA,EAAK,SAAS,CACZ,eAAe,EAAW,CACxB,IAAM,EAAS,EAAU,KAAK,OAE9B,GACE,EAAE,aAAa,EAAO,GACrB,EAAO,OAAS,eAAiB,EAAO,OAAS,eAClD,CACA,IAAM,EAAM,EAAU,KAAK,UAAU,GAErC,GAAI,EAAE,gBAAgB,EAAI,CAAE,CAC1B,IAAM,EAAa,EAAU,OACzB,EAAiB,GACjB,EAAqC,EAAE,CACvC,EACA,EAAe,UAEf,EAAE,qBAAqB,EAAW,GAChC,EAAE,gBAAgB,EAAW,GAAG,EAClC,EAAiB,GACjB,EAAoB,EAAW,GAC/B,EAA2B,EAAW,GAAG,WACtC,OACE,GACC,EAAE,iBAAiB,EAAE,EAAI,EAAE,aAAa,EAAE,IAAI,CACjD,CACA,IAAK,GAAO,EAAE,IAAqB,KAAK,EAClC,EAAE,aAAa,EAAW,GAAG,GACtC,EAAe,EAAW,GAAG,OAIjC,EAAS,CACP,IAAK,EAAI,MACT,KAAM,EAAO,KACb,eACA,iBACA,2BACA,oBACD,CACD,EAAU,MAAM,IAItB,SAAS,EAAW,CAClB,EAAU,MAAM,EAEnB,CAAC,CAEK"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolveDictionaryKey.mjs","names":[],"sources":["../../../../src/extractContent/utils/resolveDictionaryKey.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\n\n/**\n * Resolves a unique dictionary key, checking for existing dictionaries and files.\n * Note: this chokidar-specific variant fetches unmergedDictionaries internally\n * from the configuration (unlike the `@intlayer/babel` version which takes it as a parameter).\n */\nexport const resolveDictionaryKey = (\n initialKey: string,\n filePath: string,\n configuration: IntlayerConfig,\n unmergedDictionaries?: Record<string, unknown>,\n usedKeys: Set<string> = new Set()\n): string => {\n const dicts =\n unmergedDictionaries ?? getUnmergedDictionaries(configuration) ?? {};\n\n const { fileExtensions } = configuration.content;\n\n const dirName = dirname(filePath);\n const firstExtension = fileExtensions[0];\n const extension = firstExtension.startsWith('.')\n ? firstExtension\n : `.${firstExtension}`;\n\n let index = 0;\n\n while (index < 100) {\n const keyToTest = index === 0 ? initialKey : `${initialKey}${index}`;\n const dictionaries = dicts[keyToTest] as Dictionary[] | undefined;\n const contentFilePath = join(dirName, `${keyToTest}${extension}`);\n const isKeyUsed = usedKeys.has(keyToTest);\n const hasDictionaries = dictionaries && dictionaries.length > 0;\n const fileExists = existsSync(contentFilePath);\n\n if (!isKeyUsed && !hasDictionaries && !fileExists) {\n return keyToTest;\n }\n index++;\n }\n\n return initialKey;\n};\n"],"mappings":"mKAWA,MAAa,GACX,EACA,EACA,EACA,EACA,EAAwB,IAAI,MACjB,CACX,IAAM,EACJ,GAAwB,EAAwB,EAAc,EAAI,EAAE,CAEhE,CAAE,kBAAmB,EAAc,QAEnC,EAAU,EAAQ,EAAS,CAC3B,EAAiB,EAAe,GAChC,EAAY,EAAe,WAAW,IAAI,CAC5C,EACA,IAAI,IAEJ,EAAQ,EAEZ,KAAO,EAAQ,KAAK,CAClB,IAAM,EAAY,IAAU,EAAI,EAAa,GAAG,IAAa,IACvD,EAAe,EAAM,GACrB,EAAkB,EAAK,EAAS,GAAG,IAAY,IAAY,CAC3D,EAAY,EAAS,IAAI,EAAU,CACnC,EAAkB,GAAgB,EAAa,OAAS,EACxD,EAAa,EAAW,EAAgB,CAE9C,GAAI,CAAC,GAAa,CAAC,GAAmB,CAAC,EACrC,OAAO,EAET,IAGF,OAAO"}
1
+ {"version":3,"file":"resolveDictionaryKey.mjs","names":[],"sources":["../../../../src/extractContent/utils/resolveDictionaryKey.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\n\n/**\n * Resolves a unique dictionary key, checking for existing dictionaries and files.\n * Note: this chokidar-specific variant fetches unmergedDictionaries internally\n * from the configuration (unlike the `@intlayer/babel` version which takes it as a parameter).\n */\nexport const resolveDictionaryKey = (\n initialKey: string,\n filePath: string,\n configuration: IntlayerConfig,\n unmergedDictionaries?: Record<string, unknown>,\n usedKeys: Set<string> = new Set()\n): string => {\n const dicts =\n unmergedDictionaries ?? getUnmergedDictionaries(configuration) ?? {};\n\n const { fileExtensions } = configuration.content;\n\n const dirName = dirname(filePath);\n const firstExtension = fileExtensions[0];\n const extension = firstExtension.startsWith('.')\n ? firstExtension\n : `.${firstExtension}`;\n\n let index = 0;\n\n while (index < 100) {\n const keyToTest = index === 0 ? initialKey : `${initialKey}${index}`;\n const dictionaries = dicts[keyToTest] as Dictionary[] | undefined;\n const contentFilePath = join(dirName, `${keyToTest}${extension}`);\n const isKeyUsed = usedKeys.has(keyToTest);\n const hasDictionaries = dictionaries && dictionaries.length > 0;\n const fileExists = existsSync(contentFilePath);\n\n if (!isKeyUsed && !hasDictionaries && !fileExists) {\n return keyToTest;\n }\n index++;\n }\n\n return initialKey;\n};\n"],"mappings":"mKAWA,MAAa,GACX,EACA,EACA,EACA,EACA,EAAwB,IAAI,MACjB,CACX,IAAM,EACJ,GAAwB,EAAwB,EAAc,EAAI,EAAE,CAEhE,CAAE,kBAAmB,EAAc,QAEnC,EAAU,EAAQ,EAAS,CAC3B,EAAiB,EAAe,GAChC,EAAY,EAAe,WAAW,IAAI,CAC5C,EACA,IAAI,IAEJ,EAAQ,EAEZ,KAAO,EAAQ,KAAK,CAClB,IAAM,EAAY,IAAU,EAAI,EAAa,GAAG,IAAa,IACvD,EAAe,EAAM,GACrB,EAAkB,EAAK,EAAS,GAAG,IAAY,IAAY,CAC3D,EAAY,EAAS,IAAI,EAAU,CACnC,EAAkB,GAAgB,EAAa,OAAS,EACxD,EAAa,EAAW,EAAgB,CAE9C,GAAI,CAAC,GAAa,CAAC,GAAmB,CAAC,EACrC,OAAO,EAET,IAGF,OAAO"}
@@ -1,2 +1,2 @@
1
- import{writeContentHelper as e}from"./extractContent/contentWriter.mjs";import{buildFilesList as t}from"@intlayer/chokidar/utils";import{ANSIColors as n,colorize as r,colorizeKey as i,getAppLogger as a}from"@intlayer/config/logger";import{DefaultValues as o,getConfiguration as s}from"@intlayer/config/node";const c=(c=s(),l=process.env.INTLAYER_IS_DEV_COMMAND)=>{let u=String(l)===`true`,d=u?`dev`:`build`,f=a(c);c.compiler?.enabled===`build-only`&&u&&f(`${r(`Compiler:`,n.GREY_DARK)} i18n function is not inserted in the code in dev mode to optimize build time. (to test i18n in dev mode set compiler.enabled to true)`);let p=c.compiler?.enabled??o.Compiler.COMPILER_ENABLED;p===`build-only`&&(p=d?d===`build`:!0);let m=t({transformPattern:c.build.traversePattern??c.compiler?.transformPattern,excludePattern:[...c.content.fileExtensions.map(e=>`**/*${e}`),...Array.isArray(c.compiler.excludePattern)?c.compiler.excludePattern:[c.compiler.excludePattern]],baseDir:c.system.baseDir});return{enabled:p,configuration:c,filesList:m,onExtract:async({dictionaryKey:t,content:n,filePath:r})=>{try{await e(n,t,r,c)}catch(e){f([`Failed to process extracted content for ${i(t)}:`,e],{level:`error`})}}}};export{c as getExtractPluginOptions};
1
+ import{writeContentHelper as e}from"./extractContent/contentWriter.mjs";import{buildComponentFilesList as t}from"@intlayer/chokidar/utils";import{ANSIColors as n,colorize as r,colorizeKey as i,getAppLogger as a}from"@intlayer/config/logger";import{DefaultValues as o,getConfiguration as s}from"@intlayer/config/node";const c=(c=s(),l=process.env.INTLAYER_IS_DEV_COMMAND)=>{let u=l===`dev`||l===`serve`||l===`true`,d=u?`dev`:`build`,f=a(c);c.compiler?.enabled===`build-only`&&u&&f(`${r(`Compiler:`,n.GREY_DARK)} i18n function is not inserted in the code in dev mode to optimize build time. (to test i18n in dev mode set compiler.enabled to true)`);let p=c.compiler?.enabled??o.Compiler.COMPILER_ENABLED;p===`build-only`&&(p=d?d===`build`:!0);let m=t(c);return{enabled:p,configuration:c,filesList:m,onExtract:async({dictionaryKey:t,content:n,filePath:r})=>{try{await e(n,t,r,c)}catch(e){f([`Failed to process extracted content for ${i(t)}:`,e],{level:`error`})}}}};export{c as getExtractPluginOptions};
2
2
  //# sourceMappingURL=getExtractPluginOptions.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"getExtractPluginOptions.mjs","names":[],"sources":["../../src/getExtractPluginOptions.ts"],"sourcesContent":["import { buildFilesList } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizeKey,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport { DefaultValues, getConfiguration } from '@intlayer/config/node';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { ExtractPluginOptions } from './babel-plugin-intlayer-extract';\nimport { writeContentHelper } from './extractContent/contentWriter';\n\n/**\n * Mode of the compiler\n * - 'dev': Development mode with HMR support\n * - 'build': Production build mode\n */\nexport type CompilerMode = 'dev' | 'build';\n\n/**\n * Get the options for the Intlayer Babel extraction plugin\n * This function loads the Intlayer configuration and sets up the onExtract callback\n * to write dictionaries to the filesystem.\n */\nexport const getExtractPluginOptions = (\n configuration: IntlayerConfig = getConfiguration(),\n isDev = process.env.INTLAYER_IS_DEV_COMMAND\n): ExtractPluginOptions => {\n const isDevBoolean = String(isDev) === 'true';\n\n const compilerMode: CompilerMode = isDevBoolean ? 'dev' : 'build';\n\n const logger = getAppLogger(configuration);\n\n if (configuration.compiler?.enabled === 'build-only' && isDevBoolean) {\n logger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} i18n function is not inserted in the code in dev mode to optimize build time. (to test i18n in dev mode set compiler.enabled to true)`\n );\n }\n\n let enabled =\n configuration.compiler?.enabled ?? DefaultValues.Compiler.COMPILER_ENABLED;\n\n if (enabled === 'build-only') {\n if (compilerMode) {\n enabled = compilerMode === 'build';\n } else {\n // Fallback if mode isn't explicitly provided (e.g. pure babel plugin context)\n enabled = process.env.NODE_ENV === 'production';\n }\n }\n\n const transformPattern =\n configuration.build.traversePattern ??\n configuration.compiler?.transformPattern;\n\n const excludePattern = [\n // Ensure extensions are treated as glob patterns (e.g., **/*.ts)\n ...configuration.content.fileExtensions.map((ext) => `**/*${ext}`),\n\n ...(Array.isArray(configuration.compiler.excludePattern)\n ? configuration.compiler.excludePattern\n : [configuration.compiler.excludePattern]),\n ] as string[];\n\n const filesList = buildFilesList({\n transformPattern,\n excludePattern,\n baseDir: configuration.system.baseDir,\n });\n\n return {\n enabled,\n configuration,\n filesList,\n onExtract: async ({ dictionaryKey, content, filePath }) => {\n try {\n await writeContentHelper(\n content,\n dictionaryKey,\n filePath,\n configuration\n );\n } catch (error) {\n logger(\n [\n `Failed to process extracted content for ${colorizeKey(dictionaryKey)}:`,\n error,\n ],\n { level: 'error' }\n );\n }\n },\n };\n};\n"],"mappings":"oTAwBA,MAAa,GACX,EAAgC,GAAkB,CAClD,EAAQ,QAAQ,IAAI,0BACK,CACzB,IAAM,EAAe,OAAO,EAAM,GAAK,OAEjC,EAA6B,EAAe,MAAQ,QAEpD,EAAS,EAAa,EAAc,CAEtC,EAAc,UAAU,UAAY,cAAgB,GACtD,EACE,GAAG,EAAS,YAAa,EAAW,UAAU,CAAC,wIAChD,CAGH,IAAI,EACF,EAAc,UAAU,SAAW,EAAc,SAAS,iBAExD,IAAY,eACd,AAIE,EAJE,EACQ,IAAiB,QAGjB,IAiBd,IAAM,EAAY,EAAe,CAC/B,iBAbA,EAAc,MAAM,iBACpB,EAAc,UAAU,iBAaxB,eAXqB,CAErB,GAAG,EAAc,QAAQ,eAAe,IAAK,GAAQ,OAAO,IAAM,CAElE,GAAI,MAAM,QAAQ,EAAc,SAAS,eAAe,CACpD,EAAc,SAAS,eACvB,CAAC,EAAc,SAAS,eAAe,CAC5C,CAKC,QAAS,EAAc,OAAO,QAC/B,CAAC,CAEF,MAAO,CACL,UACA,gBACA,YACA,UAAW,MAAO,CAAE,gBAAe,UAAS,cAAe,CACzD,GAAI,CACF,MAAM,EACJ,EACA,EACA,EACA,EACD,OACM,EAAO,CACd,EACE,CACE,2CAA2C,EAAY,EAAc,CAAC,GACtE,EACD,CACD,CAAE,MAAO,QAAS,CACnB,GAGN"}
1
+ {"version":3,"file":"getExtractPluginOptions.mjs","names":[],"sources":["../../src/getExtractPluginOptions.ts"],"sourcesContent":["import { buildComponentFilesList } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizeKey,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport { DefaultValues, getConfiguration } from '@intlayer/config/node';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { ExtractPluginOptions } from './babel-plugin-intlayer-extract';\nimport { writeContentHelper } from './extractContent/contentWriter';\n\n/**\n * Mode of the compiler\n * - 'dev': Development mode with HMR support\n * - 'build': Production build mode\n */\nexport type CompilerMode = 'dev' | 'build';\n\n/**\n * Get the options for the Intlayer Babel extraction plugin\n * This function loads the Intlayer configuration and sets up the onExtract callback\n * to write dictionaries to the filesystem.\n */\nexport const getExtractPluginOptions = (\n configuration: IntlayerConfig = getConfiguration(),\n isDev: CompilerMode | string | undefined = process.env.INTLAYER_IS_DEV_COMMAND\n): ExtractPluginOptions => {\n // Accept 'dev'/'serve' (Vite), boolean true, or the string 'true' (env var)\n const isDevBoolean = isDev === 'dev' || isDev === 'serve' || isDev === 'true';\n\n const compilerMode: CompilerMode = isDevBoolean ? 'dev' : 'build';\n\n const logger = getAppLogger(configuration);\n\n if (configuration.compiler?.enabled === 'build-only' && isDevBoolean) {\n logger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} i18n function is not inserted in the code in dev mode to optimize build time. (to test i18n in dev mode set compiler.enabled to true)`\n );\n }\n\n let enabled =\n configuration.compiler?.enabled ?? DefaultValues.Compiler.COMPILER_ENABLED;\n\n if (enabled === 'build-only') {\n if (compilerMode) {\n enabled = compilerMode === 'build';\n } else {\n // Fallback if mode isn't explicitly provided (e.g. pure babel plugin context)\n enabled = process.env.NODE_ENV === 'production';\n }\n }\n\n const filesList = buildComponentFilesList(configuration);\n\n return {\n enabled,\n configuration,\n filesList,\n onExtract: async ({ dictionaryKey, content, filePath }) => {\n try {\n await writeContentHelper(\n content,\n dictionaryKey,\n filePath,\n configuration\n );\n } catch (error) {\n logger(\n [\n `Failed to process extracted content for ${colorizeKey(dictionaryKey)}:`,\n error,\n ],\n { level: 'error' }\n );\n }\n },\n };\n};\n"],"mappings":"6TAwBA,MAAa,GACX,EAAgC,GAAkB,CAClD,EAA2C,QAAQ,IAAI,0BAC9B,CAEzB,IAAM,EAAe,IAAU,OAAS,IAAU,SAAW,IAAU,OAEjE,EAA6B,EAAe,MAAQ,QAEpD,EAAS,EAAa,EAAc,CAEtC,EAAc,UAAU,UAAY,cAAgB,GACtD,EACE,GAAG,EAAS,YAAa,EAAW,UAAU,CAAC,wIAChD,CAGH,IAAI,EACF,EAAc,UAAU,SAAW,EAAc,SAAS,iBAExD,IAAY,eACd,AAIE,EAJE,EACQ,IAAiB,QAGjB,IAId,IAAM,EAAY,EAAwB,EAAc,CAExD,MAAO,CACL,UACA,gBACA,YACA,UAAW,MAAO,CAAE,gBAAe,UAAS,cAAe,CACzD,GAAI,CACF,MAAM,EACJ,EACA,EACA,EACA,EACD,OACM,EAAO,CACd,EACE,CACE,2CAA2C,EAAY,EAAc,CAAC,GACtE,EACD,CACD,CAAE,MAAO,QAAS,CACnB,GAGN"}
@@ -1,2 +1,2 @@
1
- import{__require as e}from"./_virtual/_rolldown/runtime.mjs";import{getComponentTransformPatternSync as t}from"@intlayer/chokidar/utils";import{getConfiguration as n}from"@intlayer/config/node";import{join as r}from"node:path";const i=t=>{try{let{getDictionaries:n}=e(`@intlayer/dictionaries-entry`),r=n(t);return Object.values(r)}catch{return[]}},a=e=>{let{configOptions:a,dictionaries:o,overrides:s}=e??{},c=n(a),{mainDir:l,dictionariesDir:u,unmergedDictionariesDir:d,dynamicDictionariesDir:f,fetchDictionariesDir:p}=c.system,{importMode:m,optimize:h}=c.build,g=t(c),_=r(l,`dictionaries.mjs`),v=r(l,`unmerged_dictionaries.mjs`),y=r(l,`dynamic_dictionaries.mjs`),b=r(l,`fetch_dictionaries.mjs`),x=[...g,_,v],S=o??i(c),C={};return S.forEach(e=>{C[e.key]=e.importMode??m}),{optimize:h,dictionariesDir:u,dictionariesEntryPath:_,unmergedDictionariesDir:d,unmergedDictionariesEntryPath:v,dynamicDictionariesDir:f,dynamicDictionariesEntryPath:y,fetchDictionariesDir:p,fetchDictionariesEntryPath:b,replaceDictionaryEntry:!0,importMode:m,dictionaryModeMap:C,filesList:x,...s}};export{a as getOptimizePluginOptions};
1
+ import{__require as e}from"./_virtual/_rolldown/runtime.mjs";import{buildComponentFilesList as t}from"@intlayer/chokidar/utils";import{getConfiguration as n}from"@intlayer/config/node";import{join as r}from"node:path";const i=t=>{try{let{getDictionaries:n}=e(`@intlayer/dictionaries-entry`),r=n(t);return Object.values(r)}catch{return[]}},a=e=>{let{configOptions:a,dictionaries:o,overrides:s}=e??{},c=n(a),{mainDir:l,dictionariesDir:u,unmergedDictionariesDir:d,dynamicDictionariesDir:f,fetchDictionariesDir:p}=c.system,{importMode:m,optimize:h}=c.build,g=r(l,`dictionaries.mjs`),_=r(l,`unmerged_dictionaries.mjs`),v=r(l,`dynamic_dictionaries.mjs`),y=r(l,`fetch_dictionaries.mjs`),b=[...t(c),g,_],x=o??i(c),S={};return x.forEach(e=>{S[e.key]=e.importMode??m}),{optimize:h,dictionariesDir:u,dictionariesEntryPath:g,unmergedDictionariesDir:d,unmergedDictionariesEntryPath:_,dynamicDictionariesDir:f,dynamicDictionariesEntryPath:v,fetchDictionariesDir:p,fetchDictionariesEntryPath:y,replaceDictionaryEntry:!0,importMode:m,dictionaryModeMap:S,filesList:b,...s}};export{a as getOptimizePluginOptions};
2
2
  //# sourceMappingURL=getOptimizePluginOptions.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"getOptimizePluginOptions.mjs","names":[],"sources":["../../src/getOptimizePluginOptions.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { getComponentTransformPatternSync } from '@intlayer/chokidar/utils';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { OptimizePluginOptions } from './babel-plugin-intlayer-optimize';\n\ntype GetOptimizePluginOptionsParams = {\n /**\n * Configuration options for loading intlayer config\n */\n configOptions?: GetConfigurationOptions;\n /**\n * Pre-loaded dictionaries (optional - will be loaded if not provided)\n */\n dictionaries?: Dictionary[];\n /**\n * Override specific options\n */\n overrides?: Partial<OptimizePluginOptions>;\n};\n\n/**\n * Load dictionaries from the dictionaries-entry package\n */\nconst loadDictionaries = (config: IntlayerConfig): Dictionary[] => {\n try {\n // Dynamic require to avoid build-time dependency issues\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { getDictionaries } = require('@intlayer/dictionaries-entry');\n const dictionariesRecord = getDictionaries(config) as Record<\n string,\n Dictionary\n >;\n return Object.values(dictionariesRecord);\n } catch {\n // If dictionaries-entry is not available, return empty array\n return [];\n }\n};\n\n/**\n * Get the options for the Intlayer Babel optimization plugin\n * This function loads the Intlayer configuration and returns the paths\n * needed for dictionary optimization and import rewriting.\n */\nexport const getOptimizePluginOptions = (\n params?: GetOptimizePluginOptionsParams\n): OptimizePluginOptions => {\n const {\n configOptions,\n dictionaries: providedDictionaries,\n overrides,\n } = params ?? {};\n\n const config = getConfiguration(configOptions);\n const {\n mainDir,\n dictionariesDir,\n unmergedDictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n } = config.system;\n const { importMode, optimize } = config.build;\n\n // Build files list from traverse pattern\n const filesListPattern = getComponentTransformPatternSync(config);\n\n const dictionariesEntryPath = join(mainDir, 'dictionaries.mjs');\n const unmergedDictionariesEntryPath = join(\n mainDir,\n 'unmerged_dictionaries.mjs'\n );\n const dynamicDictionariesEntryPath = join(\n mainDir,\n 'dynamic_dictionaries.mjs'\n );\n const fetchDictionariesEntryPath = join(mainDir, 'fetch_dictionaries.mjs');\n\n const filesList = [\n ...filesListPattern,\n dictionariesEntryPath, // should add dictionariesEntryPath to replace it by an empty object if import made dynamic\n unmergedDictionariesEntryPath, // should add dictionariesEntryPath to replace it by an empty object if import made dynamic\n ];\n\n // Load dictionaries if not provided\n const dictionaries = providedDictionaries ?? loadDictionaries(config);\n\n const dictionaryModeMap: Record<\n string,\n 'static' | 'dynamic' | 'fetch' | undefined\n > = {};\n\n dictionaries.forEach((dictionary) => {\n dictionaryModeMap[dictionary.key] = dictionary.importMode ?? importMode;\n });\n\n return {\n optimize,\n dictionariesDir,\n dictionariesEntryPath,\n unmergedDictionariesDir,\n unmergedDictionariesEntryPath,\n dynamicDictionariesDir,\n dynamicDictionariesEntryPath,\n fetchDictionariesDir,\n fetchDictionariesEntryPath,\n replaceDictionaryEntry: true,\n importMode,\n dictionaryModeMap,\n filesList,\n ...overrides,\n };\n};\n"],"mappings":"mOA4BA,MAAM,EAAoB,GAAyC,CACjE,GAAI,CAGF,GAAM,CAAE,mBAAA,EAA4B,+BAA+B,CAC7D,EAAqB,EAAgB,EAAO,CAIlD,OAAO,OAAO,OAAO,EAAmB,MAClC,CAEN,MAAO,EAAE,GASA,EACX,GAC0B,CAC1B,GAAM,CACJ,gBACA,aAAc,EACd,aACE,GAAU,EAAE,CAEV,EAAS,EAAiB,EAAc,CACxC,CACJ,UACA,kBACA,0BACA,yBACA,wBACE,EAAO,OACL,CAAE,aAAY,YAAa,EAAO,MAGlC,EAAmB,EAAiC,EAAO,CAE3D,EAAwB,EAAK,EAAS,mBAAmB,CACzD,EAAgC,EACpC,EACA,4BACD,CACK,EAA+B,EACnC,EACA,2BACD,CACK,EAA6B,EAAK,EAAS,yBAAyB,CAEpE,EAAY,CAChB,GAAG,EACH,EACA,EACD,CAGK,EAAe,GAAwB,EAAiB,EAAO,CAE/D,EAGF,EAAE,CAMN,OAJA,EAAa,QAAS,GAAe,CACnC,EAAkB,EAAW,KAAO,EAAW,YAAc,GAC7D,CAEK,CACL,WACA,kBACA,wBACA,0BACA,gCACA,yBACA,+BACA,uBACA,6BACA,uBAAwB,GACxB,aACA,oBACA,YACA,GAAG,EACJ"}
1
+ {"version":3,"file":"getOptimizePluginOptions.mjs","names":[],"sources":["../../src/getOptimizePluginOptions.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { buildComponentFilesList } from '@intlayer/chokidar/utils';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { OptimizePluginOptions } from './babel-plugin-intlayer-optimize';\n\ntype GetOptimizePluginOptionsParams = {\n /**\n * Configuration options for loading intlayer config\n */\n configOptions?: GetConfigurationOptions;\n /**\n * Pre-loaded dictionaries (optional - will be loaded if not provided)\n */\n dictionaries?: Dictionary[];\n /**\n * Override specific options\n */\n overrides?: Partial<OptimizePluginOptions>;\n};\n\n/**\n * Load dictionaries from the dictionaries-entry package\n */\nconst loadDictionaries = (config: IntlayerConfig): Dictionary[] => {\n try {\n // Dynamic require to avoid build-time dependency issues\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { getDictionaries } = require('@intlayer/dictionaries-entry');\n const dictionariesRecord = getDictionaries(config);\n\n return Object.values(dictionariesRecord);\n } catch {\n // If dictionaries-entry is not available, return empty array\n return [];\n }\n};\n\n/**\n * Get the options for the Intlayer Babel optimization plugin\n * This function loads the Intlayer configuration and returns the paths\n * needed for dictionary optimization and import rewriting.\n */\nexport const getOptimizePluginOptions = (\n params?: GetOptimizePluginOptionsParams\n): OptimizePluginOptions => {\n const {\n configOptions,\n dictionaries: providedDictionaries,\n overrides,\n } = params ?? {};\n\n const config = getConfiguration(configOptions);\n const {\n mainDir,\n dictionariesDir,\n unmergedDictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n } = config.system;\n const { importMode, optimize } = config.build;\n\n const dictionariesEntryPath = join(mainDir, 'dictionaries.mjs');\n const unmergedDictionariesEntryPath = join(\n mainDir,\n 'unmerged_dictionaries.mjs'\n );\n const dynamicDictionariesEntryPath = join(\n mainDir,\n 'dynamic_dictionaries.mjs'\n );\n const fetchDictionariesEntryPath = join(mainDir, 'fetch_dictionaries.mjs');\n\n const filesListPattern = buildComponentFilesList(config);\n\n const filesList = [\n ...filesListPattern,\n dictionariesEntryPath, // should add dictionariesEntryPath to replace it by an empty object if import made dynamic\n unmergedDictionariesEntryPath, // should add dictionariesEntryPath to replace it by an empty object if import made dynamic\n ];\n\n // Load dictionaries if not provided\n const dictionaries = providedDictionaries ?? loadDictionaries(config);\n\n const dictionaryModeMap: Record<\n string,\n 'static' | 'dynamic' | 'fetch' | undefined\n > = {};\n\n dictionaries.forEach((dictionary) => {\n dictionaryModeMap[dictionary.key] = dictionary.importMode ?? importMode;\n });\n\n return {\n optimize,\n dictionariesDir,\n dictionariesEntryPath,\n unmergedDictionariesDir,\n unmergedDictionariesEntryPath,\n dynamicDictionariesDir,\n dynamicDictionariesEntryPath,\n fetchDictionariesDir,\n fetchDictionariesEntryPath,\n replaceDictionaryEntry: true,\n importMode,\n dictionaryModeMap,\n filesList,\n ...overrides,\n };\n};\n"],"mappings":"0NA4BA,MAAM,EAAoB,GAAyC,CACjE,GAAI,CAGF,GAAM,CAAE,mBAAA,EAA4B,+BAA+B,CAC7D,EAAqB,EAAgB,EAAO,CAElD,OAAO,OAAO,OAAO,EAAmB,MAClC,CAEN,MAAO,EAAE,GASA,EACX,GAC0B,CAC1B,GAAM,CACJ,gBACA,aAAc,EACd,aACE,GAAU,EAAE,CAEV,EAAS,EAAiB,EAAc,CACxC,CACJ,UACA,kBACA,0BACA,yBACA,wBACE,EAAO,OACL,CAAE,aAAY,YAAa,EAAO,MAElC,EAAwB,EAAK,EAAS,mBAAmB,CACzD,EAAgC,EACpC,EACA,4BACD,CACK,EAA+B,EACnC,EACA,2BACD,CACK,EAA6B,EAAK,EAAS,yBAAyB,CAIpE,EAAY,CAChB,GAHuB,EAAwB,EAAO,CAItD,EACA,EACD,CAGK,EAAe,GAAwB,EAAiB,EAAO,CAE/D,EAGF,EAAE,CAMN,OAJA,EAAa,QAAS,GAAe,CACnC,EAAkB,EAAW,KAAO,EAAW,YAAc,GAC7D,CAEK,CACL,WACA,kBACA,wBACA,0BACA,gCACA,yBACA,+BACA,uBACA,6BACA,uBAAwB,GACxB,aACA,oBACA,YACA,GAAG,EACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"contentWriter.d.ts","names":[],"sources":["../../../src/extractContent/contentWriter.ts"],"mappings":";;;;;;AAY4E;KAMvE,eAAA;EACH,QAAA;EACA,WAAA,EAAa,MAAA;AAAA;;;;KAMV,oBAAA,GAAuB,MAAA,SAAe,eAAA;AANtB;;;;;AAmBrB;AAnBqB,cAmBR,uCAAA,GACX,gBAAA,EAAkB,MAAA,kBAClB,kBAAA,EAAoB,UAAA,SACpB,aAAA,aACC,oBAAA;;;;;;;cAgCU,oCAAA,GACX,gBAAA,EAAkB,MAAA,kBAClB,kBAAA,EAAoB,UAAA,YACnB,MAAA;;;;cA4BU,kBAAA,GACX,gBAAA,EAAkB,MAAA,kBAClB,aAAA,EAAe,aAAA,EACf,QAAA,UACA,aAAA,EAAe,cAAA,KACd,OAAA"}
1
+ {"version":3,"file":"contentWriter.d.ts","names":[],"sources":["../../../src/extractContent/contentWriter.ts"],"mappings":";;;;;;AAY4E;KAyBvE,eAAA;EACH,QAAA;EACA,WAAA,EAAa,MAAA;AAAA;;;;KAMV,oBAAA,GAAuB,MAAA,SAAe,eAAA;AANtB;;;;;AAmBrB;AAnBqB,cAmBR,uCAAA,GACX,gBAAA,EAAkB,MAAA,kBAClB,kBAAA,EAAoB,UAAA,SACpB,aAAA,aACC,oBAAA;;;;;;;cA+CU,oCAAA,GACX,gBAAA,EAAkB,MAAA,kBAClB,kBAAA,EAAoB,UAAA,YACnB,MAAA;;;;cA2CU,kBAAA,GACX,gBAAA,EAAkB,MAAA,kBAClB,aAAA,EAAe,aAAA,EACf,QAAA,UACA,aAAA,EAAe,cAAA,KACd,OAAA"}
@@ -16,13 +16,22 @@ type ExtractIntlayerOptions = {
16
16
  filePath: string;
17
17
  }) => void | Promise<void>;
18
18
  };
19
- declare const extractContent: (filePath: string, packageName: PackageName, options?: ExtractIntlayerOptions) => Promise<{
19
+ type ExtractResult = {
20
20
  transformedCode: string | null;
21
- } | undefined>;
22
- declare const extractContentSync: (filePath: string, packageName: PackageName, options?: ExtractIntlayerOptions) => {
23
- transformedCode: string | null;
24
- extractedContent: Record<string, Record<string, string>>;
25
- } | undefined;
21
+ extractedContentMap: Record<string, Record<string, string>>;
22
+ };
23
+ declare const extractContent: (filePath: string, packageName: PackageName, options?: ExtractIntlayerOptions) => Promise<ExtractResult | undefined>;
24
+ /**
25
+ * Synchronous variant of `extractContent` — used by the Babel plugin which
26
+ * runs in a sync transform context (e.g. Next.js / Webpack).
27
+ *
28
+ * Differences from `extractContent`:
29
+ * - Loads external compilers (Vue, Svelte) via `require()` instead of `import()`
30
+ * - Fires `onExtract` callbacks as fire-and-forget (cannot await in sync context)
31
+ * - Does NOT write dictionary files or run the code formatter; callers that
32
+ * need persistence should supply an `onExtract` callback
33
+ */
34
+ declare const extractContentSync: (filePath: string, packageName: PackageName, options?: ExtractIntlayerOptions) => ExtractResult | undefined;
26
35
  //#endregion
27
36
  export { ExtractIntlayerOptions, extractContent, extractContentSync };
28
37
  //# sourceMappingURL=extractContent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractContent.d.ts","names":[],"sources":["../../../src/extractContent/extractContent.ts"],"mappings":";;;;;KAgCY,sBAAA;EACV,aAAA,GAAgB,uBAAA;EAChB,QAAA;EACA,eAAA;EACA,oBAAA,GAAuB,MAAA;EACvB,aAAA,GAAgB,cAAA;EAChB,IAAA;EACA,SAAA,IAAa,MAAA;IACX,GAAA;IACA,OAAA,EAAS,MAAA;IACT,QAAA;EAAA,aACW,OAAA;AAAA;AAAA,cAsNF,cAAA,GACX,QAAA,UACA,WAAA,EAAa,WAAA,EACb,OAAA,GAAU,sBAAA,KACT,OAAA;EAAU,eAAA;AAAA;AAAA,cA0DA,kBAAA,GACX,QAAA,UACA,WAAA,EAAa,WAAA,EACb,OAAA,GAAU,sBAAA;EAGN,eAAA;EACA,gBAAA,EAAkB,MAAA,SAAe,MAAA;AAAA"}
1
+ {"version":3,"file":"extractContent.d.ts","names":[],"sources":["../../../src/extractContent/extractContent.ts"],"mappings":";;;;;KA8BY,sBAAA;EACV,aAAA,GAAgB,uBAAA;EAChB,QAAA;EACA,eAAA;EACA,oBAAA,GAAuB,MAAA;EACvB,aAAA,GAAgB,cAAA;EAChB,IAAA;EACA,SAAA,IAAa,MAAA;IACX,GAAA;IACA,OAAA,EAAS,MAAA;IACT,QAAA;EAAA,aACW,OAAA;AAAA;AAAA,KAmNV,aAAA;EACH,eAAA;EACA,mBAAA,EAAqB,MAAA,SAAe,MAAA;AAAA;AAAA,cAmCzB,cAAA,GACX,QAAA,UACA,WAAA,EAAa,WAAA,EACb,OAAA,GAAU,sBAAA,KACT,OAAA,CAAQ,aAAA;;;;;;;;;;;cA8EE,kBAAA,GACX,QAAA,UACA,WAAA,EAAa,WAAA,EACb,OAAA,GAAU,sBAAA,KACT,aAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"processTsxFile.d.ts","names":[],"sources":["../../../src/extractContent/processTsxFile.ts"],"mappings":";;;;KAcY,QAAA;EACV,KAAA;EACA,GAAA;EACA,WAAA;AAAA;;;;cAUW,cAAA,GACX,QAAA,UACA,YAAA,UACA,WAAA,EAAa,WAAA,EACb,aAAA,EAAe,cAAA,EACf,IAAA,YACA,oBAAA,GAAsB,MAAA,mBACtB,gBAAA;EAEA,gBAAA,EAAkB,MAAA,SAAe,MAAA;EACjC,YAAA;AAAA"}
1
+ {"version":3,"file":"processTsxFile.d.ts","names":[],"sources":["../../../src/extractContent/processTsxFile.ts"],"mappings":";;;;KAeY,QAAA;EACV,KAAA;EACA,GAAA;EACA,WAAA;AAAA;;;;cAUW,cAAA,GACX,QAAA,UACA,YAAA,UACA,WAAA,EAAa,WAAA,EACb,aAAA,EAAe,cAAA,EACf,IAAA,YACA,oBAAA,GAAsB,MAAA,mBACtB,gBAAA;EAEA,gBAAA,EAAkB,MAAA,SAAe,MAAA;EACjC,YAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"extractDictionaryInfo.d.ts","names":[],"sources":["../../../../src/extractContent/utils/extractDictionaryInfo.ts"],"mappings":";;;;;cAgBa,SAAA,GACX,aAAA,EAAe,cAAA,KACd,uBAAA;AAAA,KA2BS,uBAAA;EACV,YAAA;EACA,YAAA;EACA,WAAA;AAAA;;;;;cAOW,uBAAA,GACX,QAAA,UACA,YAAA,UACA,aAAA,EAAe,cAAA,EACf,MAAA,GAAS,MAAA,KACR,OAAA,CAAQ,uBAAA;AAAA,KAyEC,4BAAA;EACV,aAAA,GAAgB,cAAA;AAAA;;;;cAML,qBAAA,GACX,QAAA,UACA,QAAA,UACA,aAAA,EAAe,cAAA,KACd,OAAA;EAEC,aAAA;AAAA,IACE,uBAAA"}
1
+ {"version":3,"file":"extractDictionaryInfo.d.ts","names":[],"sources":["../../../../src/extractContent/utils/extractDictionaryInfo.ts"],"mappings":";;;;;cAgBa,SAAA,GACX,aAAA,EAAe,cAAA,KACd,uBAAA;AAAA,KAeS,uBAAA;EACV,YAAA;EACA,YAAA;EACA,WAAA;AAAA;;;;;cAOW,uBAAA,GACX,QAAA,UACA,YAAA,UACA,aAAA,EAAe,cAAA,EACf,MAAA,GAAS,MAAA,KACR,OAAA,CAAQ,uBAAA;AAAA,KAyEC,4BAAA;EACV,aAAA,GAAgB,cAAA;AAAA;;;;cAML,qBAAA,GACX,QAAA,UACA,QAAA,UACA,aAAA,EAAe,cAAA,KACd,OAAA;EAEC,aAAA;AAAA,IACE,uBAAA"}
@@ -1,13 +1,19 @@
1
+ import * as t from "@babel/types";
1
2
  import { NodePath } from "@babel/traverse";
2
3
 
3
4
  //#region src/extractContent/utils/getExistingIntlayerInfo.d.ts
5
+ type ExistingIntlayerInfo = {
6
+ key: string;
7
+ hook: 'useIntlayer' | 'getIntlayer'; /** The variable name used to store the call result (e.g. `t` in `const t = useIntlayer(...)`) */
8
+ variableName: string; /** True when the call result is destructured: `const { a, b } = getIntlayer(...)` */
9
+ isDestructured: boolean; /** Keys already present in the destructuring pattern (empty when not destructured) */
10
+ existingDestructuredKeys: string[]; /** The ObjectPattern AST node, present only when `isDestructured` is true */
11
+ objectPatternNode?: t.ObjectPattern;
12
+ };
4
13
  /**
5
14
  * Searches for an existing useIntlayer or getIntlayer call in the function body.
6
15
  */
7
- declare const getExistingIntlayerInfo: (path: NodePath) => {
8
- key: string;
9
- hook: "useIntlayer" | "getIntlayer";
10
- } | undefined;
16
+ declare const getExistingIntlayerInfo: (path: NodePath) => ExistingIntlayerInfo | undefined;
11
17
  //#endregion
12
- export { getExistingIntlayerInfo };
18
+ export { ExistingIntlayerInfo, getExistingIntlayerInfo };
13
19
  //# sourceMappingURL=getExistingIntlayerInfo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getExistingIntlayerInfo.d.ts","names":[],"sources":["../../../../src/extractContent/utils/getExistingIntlayerInfo.ts"],"mappings":";;;;;AAMA;cAAa,uBAAA,GACX,IAAA,EAAM,QAAA;EACH,GAAA;EAAa,IAAA;AAAA"}
1
+ {"version":3,"file":"getExistingIntlayerInfo.d.ts","names":[],"sources":["../../../../src/extractContent/utils/getExistingIntlayerInfo.ts"],"mappings":";;;;KAGY,oBAAA;EACV,GAAA;EACA,IAAA,iCAF8B;EAI9B,YAAA,UAMmC;EAJnC,cAAA,WAJA;EAMA,wBAAA,YAFA;EAIA,iBAAA,GAAoB,CAAA,CAAE,aAAA;AAAA;;;;cAMX,uBAAA,GACX,IAAA,EAAM,QAAA,KACL,oBAAA"}
@@ -4,8 +4,8 @@ import { ExtractDictionaryInfoOptions, ResolveContentFilePaths, extractDictionar
4
4
  import { extractDictionaryKey, extractDictionaryKeyFromPath } from "./extractDictionaryKey.js";
5
5
  import { generateKey } from "./generateKey.js";
6
6
  import { getComponentName } from "./getComponentName.js";
7
- import { getExistingIntlayerInfo } from "./getExistingIntlayerInfo.js";
7
+ import { ExistingIntlayerInfo, getExistingIntlayerInfo } from "./getExistingIntlayerInfo.js";
8
8
  import { getOrGenerateKey } from "./getOrGenerateKey.js";
9
9
  import { resolveDictionaryKey } from "./resolveDictionaryKey.js";
10
10
  import { shouldExtract } from "./shouldExtract.js";
11
- export { ATTRIBUTES_TO_EXTRACT, ExtractDictionaryInfoOptions, PackageName, ResolveContentFilePaths, SERVER_CAPABLE_PACKAGES, detectPackageName, extractDictionaryInfo, extractDictionaryKey, extractDictionaryKeyFromPath, generateKey, getComponentName, getExistingIntlayerInfo, getOrGenerateKey, getOutput, packageList, resolveContentFilePaths, resolveDictionaryKey, shouldExtract };
11
+ export { ATTRIBUTES_TO_EXTRACT, ExistingIntlayerInfo, ExtractDictionaryInfoOptions, PackageName, ResolveContentFilePaths, SERVER_CAPABLE_PACKAGES, detectPackageName, extractDictionaryInfo, extractDictionaryKey, extractDictionaryKeyFromPath, generateKey, getComponentName, getExistingIntlayerInfo, getOrGenerateKey, getOutput, packageList, resolveContentFilePaths, resolveDictionaryKey, shouldExtract };
@@ -13,7 +13,7 @@ type CompilerMode = 'dev' | 'build';
13
13
  * This function loads the Intlayer configuration and sets up the onExtract callback
14
14
  * to write dictionaries to the filesystem.
15
15
  */
16
- declare const getExtractPluginOptions: (configuration?: IntlayerConfig, isDev?: string) => ExtractPluginOptions;
16
+ declare const getExtractPluginOptions: (configuration?: IntlayerConfig, isDev?: CompilerMode | string | undefined) => ExtractPluginOptions;
17
17
  //#endregion
18
18
  export { CompilerMode, getExtractPluginOptions };
19
19
  //# sourceMappingURL=getExtractPluginOptions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getExtractPluginOptions.d.ts","names":[],"sources":["../../src/getExtractPluginOptions.ts"],"mappings":";;;;;;AAiBA;;;KAAY,YAAA;;AAOZ;;;;cAAa,uBAAA,GACX,aAAA,GAAe,cAAA,EACf,KAAA,cACC,oBAAA"}
1
+ {"version":3,"file":"getExtractPluginOptions.d.ts","names":[],"sources":["../../src/getExtractPluginOptions.ts"],"mappings":";;;;;;AAiBA;;;KAAY,YAAA;;AAOZ;;;;cAAa,uBAAA,GACX,aAAA,GAAe,cAAA,EACf,KAAA,GAAO,YAAA,0BACN,oBAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"getOptimizePluginOptions.d.ts","names":[],"sources":["../../src/getOptimizePluginOptions.ts"],"mappings":";;;;;KAUK,8BAAA;;AAFyE;;EAM5E,aAAA,GAAgB,uBAAA;EAAA;;;EAIhB,YAAA,GAAe,UAAA;EAII;;;EAAnB,SAAA,GAAY,OAAA,CAAQ,qBAAA;AAAA;;;;;;cA2BT,wBAAA,GACX,MAAA,GAAS,8BAAA,KACR,qBAAA"}
1
+ {"version":3,"file":"getOptimizePluginOptions.d.ts","names":[],"sources":["../../src/getOptimizePluginOptions.ts"],"mappings":";;;;;KAUK,8BAAA;;AAFyE;;EAM5E,aAAA,GAAgB,uBAAA;EAAA;;;EAIhB,YAAA,GAAe,UAAA;EAII;;;EAAnB,SAAA,GAAY,OAAA,CAAQ,qBAAA;AAAA;;;;;;cAyBT,wBAAA,GACX,MAAA,GAAS,8BAAA,KACR,qBAAA"}