@intlayer/babel 7.5.0-canary.1 → 7.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
2
  let node_path = require("node:path");
3
- let __intlayer_chokidar = require("@intlayer/chokidar");
3
+ let _intlayer_chokidar = require("@intlayer/chokidar");
4
4
 
5
5
  //#region src/babel-plugin-intlayer-extract.ts
6
6
  /**
@@ -121,8 +121,8 @@ const intlayerExtractBabelPlugin = (babel) => {
121
121
  JSXText(path, state) {
122
122
  if (!state._isIncluded) return;
123
123
  const text = path.node.value;
124
- if ((state.opts.shouldExtract ?? __intlayer_chokidar.shouldExtract)(text)) {
125
- const key = (0, __intlayer_chokidar.generateKey)(text, state._existingKeys);
124
+ if ((state.opts.shouldExtract ?? _intlayer_chokidar.shouldExtract)(text)) {
125
+ const key = (0, _intlayer_chokidar.generateKey)(text, state._existingKeys);
126
126
  state._existingKeys.add(key);
127
127
  state._extractedContent[key] = text.replace(/\s+/g, " ").trim();
128
128
  const funcParent = path.getFunctionParent();
@@ -135,14 +135,14 @@ const intlayerExtractBabelPlugin = (babel) => {
135
135
  const name = path.node.name;
136
136
  if (!t.isJSXIdentifier(name)) return;
137
137
  const attrName = name.name;
138
- if (!__intlayer_chokidar.ATTRIBUTES_TO_EXTRACT.includes(attrName)) return;
138
+ if (!_intlayer_chokidar.ATTRIBUTES_TO_EXTRACT.includes(attrName)) return;
139
139
  const value = path.node.value;
140
140
  let text = null;
141
141
  if (t.isStringLiteral(value)) text = value.value;
142
142
  else if (t.isJSXExpressionContainer(value) && t.isStringLiteral(value.expression)) text = value.expression.value;
143
143
  if (text === null) return;
144
- if ((state.opts.shouldExtract ?? __intlayer_chokidar.shouldExtract)(text)) {
145
- const key = (0, __intlayer_chokidar.generateKey)(text, state._existingKeys);
144
+ if ((state.opts.shouldExtract ?? _intlayer_chokidar.shouldExtract)(text)) {
145
+ const key = (0, _intlayer_chokidar.generateKey)(text, state._existingKeys);
146
146
  state._existingKeys.add(key);
147
147
  state._extractedContent[key] = text.trim();
148
148
  const funcParent = path.getFunctionParent();
@@ -166,8 +166,8 @@ const intlayerExtractBabelPlugin = (babel) => {
166
166
  if (t.isIdentifier(callee) && callee.name === "require") return;
167
167
  }
168
168
  const text = path.node.value;
169
- if ((state.opts.shouldExtract ?? __intlayer_chokidar.shouldExtract)(text)) {
170
- const key = (0, __intlayer_chokidar.generateKey)(text, state._existingKeys);
169
+ if ((state.opts.shouldExtract ?? _intlayer_chokidar.shouldExtract)(text)) {
170
+ const key = (0, _intlayer_chokidar.generateKey)(text, state._existingKeys);
171
171
  state._existingKeys.add(key);
172
172
  state._extractedContent[key] = text.trim();
173
173
  const funcParent = path.getFunctionParent();
@@ -1 +1 @@
1
- {"version":3,"file":"babel-plugin-intlayer-extract.cjs","names":["defaultShouldExtract","ATTRIBUTES_TO_EXTRACT","text: string | null"],"sources":["../../src/babel-plugin-intlayer-extract.ts"],"sourcesContent":["import { basename, dirname, extname } from 'node:path';\nimport type { NodePath, PluginObj, PluginPass } from '@babel/core';\nimport type * as BabelTypes from '@babel/types';\nimport {\n ATTRIBUTES_TO_EXTRACT,\n shouldExtract as defaultShouldExtract,\n generateKey,\n} from '@intlayer/chokidar';\n\ntype ExtractedContent = Record<string, string>;\n\n/**\n * Extracted content result from a file transformation\n */\nexport type ExtractResult = {\n /** Dictionary key derived from the file path */\n dictionaryKey: string;\n /** File path that was processed */\n filePath: string;\n /** Extracted content key-value pairs */\n content: ExtractedContent;\n /** Default locale used */\n locale: string;\n};\n\n/**\n * Options for the extraction Babel plugin\n */\nexport type ExtractPluginOptions = {\n /**\n * The default locale for the extracted content\n */\n defaultLocale?: string;\n /**\n * The package to import useIntlayer from\n * @default 'react-intlayer'\n */\n packageName?: string;\n /**\n * Files list to traverse. If provided, only files in this list will be processed.\n */\n filesList?: string[];\n /**\n * Custom function to determine if a string should be extracted\n */\n shouldExtract?: (text: string) => boolean;\n /**\n * Callback function called when content is extracted from a file.\n * This allows the compiler to capture the extracted content and write it to files.\n * The dictionary will be updated: new keys added, unused keys removed.\n */\n onExtract?: (result: ExtractResult) => void;\n};\n\ntype State = PluginPass & {\n opts: ExtractPluginOptions;\n /** Extracted content from this file */\n _extractedContent?: ExtractedContent;\n /** Set of existing keys to avoid duplicates */\n _existingKeys?: Set<string>;\n /** The dictionary key for this file */\n _dictionaryKey?: string;\n /** whether the current file is included in the filesList */\n _isIncluded?: boolean;\n /** Whether this file has JSX (React component) */\n _hasJSX?: boolean;\n /** Whether we already have useIntlayer imported */\n _hasUseIntlayerImport?: boolean;\n /** The local name for useIntlayer (in case it's aliased) */\n _useIntlayerLocalName?: string;\n /** Whether we already have getIntlayer imported */\n _hasGetIntlayerImport?: boolean;\n /** The local name for getIntlayer (in case it's aliased) */\n _getIntlayerLocalName?: string;\n /** The variable name to use for content (content or _compContent if content is already used) */\n _contentVarName?: string;\n /** Set of function start positions that have extracted content (only inject hooks into these) */\n _functionsWithExtractedContent?: Set<number>;\n};\n\n/* ────────────────────────────────────────── helpers ─────────────────────── */\n\n/**\n * Extract dictionary key from file path\n */\nconst extractDictionaryKeyFromPath = (filePath: string): string => {\n const ext = extname(filePath);\n let baseName = basename(filePath, ext);\n\n if (baseName === 'index') {\n baseName = basename(dirname(filePath));\n }\n\n // Convert to kebab-case\n const key = baseName\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n\n return `comp-${key}`;\n};\n\n/* ────────────────────────────────────────── plugin ──────────────────────── */\n\n/**\n * Autonomous Babel plugin that extracts content and transforms JSX to use useIntlayer.\n *\n * This plugin:\n * 1. Scans files for extractable text (JSX text, attributes)\n * 2. Auto-injects useIntlayer import and hook call\n * 3. Reports extracted content via onExtract callback (for the compiler to write dictionaries)\n * 4. Replaces extractable strings with content references\n *\n * ## Input\n * ```tsx\n * export const MyComponent = () => {\n * return <div>Hello World</div>;\n * };\n * ```\n *\n * ## Output\n * ```tsx\n * import { useIntlayer } from 'react-intlayer';\n *\n * export const MyComponent = () => {\n * const content = useIntlayer('comp-my-component');\n * return <div>{content.helloWorld}</div>;\n * };\n * ```\n *\n * ## When useIntlayer is already present\n *\n * If the component already has a `content` variable from an existing `useIntlayer` call,\n * the plugin will use `_compContent` to avoid naming conflicts:\n *\n * ### Input\n * ```tsx\n * export const Page = () => {\n * const content = useIntlayer('page');\n * return <div>{content.title} - Hello World</div>;\n * };\n * ```\n *\n * ### Output\n * ```tsx\n * export const Page = () => {\n * const _compContent = useIntlayer('comp-page');\n * const content = useIntlayer('page');\n * return <div>{content.title} - {_compContent.helloWorld}</div>;\n * };\n * ```\n *\n * The extracted content is reported via the `onExtract` callback, allowing the\n * compiler to write the dictionary to disk separately:\n * ```json\n * // my-component.content.json (written by compiler)\n * {\n * \"key\": \"comp-my-component\",\n * \"content\": {\n * \"helloWorld\": { \"nodeType\": \"translation\", \"translation\": { \"en\": \"Hello World\" } }\n * }\n * }\n * ```\n */\nexport const intlayerExtractBabelPlugin = (babel: {\n types: typeof BabelTypes;\n}): PluginObj<State> => {\n const { types: t } = babel;\n\n return {\n name: 'babel-plugin-intlayer-extract',\n\n pre() {\n this._extractedContent = {};\n this._existingKeys = new Set();\n this._functionsWithExtractedContent = new Set();\n this._isIncluded = true;\n this._hasJSX = false;\n this._hasUseIntlayerImport = false;\n this._useIntlayerLocalName = 'useIntlayer';\n this._hasGetIntlayerImport = false;\n this._getIntlayerLocalName = 'getIntlayer';\n this._contentVarName = 'content'; // Will be updated in Program.enter if 'content' is already used\n\n const filename = this.file.opts.filename;\n\n // If filesList is provided, check if current file is included\n if (this.opts.filesList && filename) {\n // Normalize paths for comparison (handle potential path separator issues)\n const normalizedFilename = filename.replace(/\\\\/g, '/');\n const isIncluded = this.opts.filesList.some((f) => {\n const normalizedF = f.replace(/\\\\/g, '/');\n return normalizedF === normalizedFilename;\n });\n\n if (!isIncluded) {\n this._isIncluded = false;\n return;\n }\n }\n\n // Extract dictionary key from filename\n if (filename) {\n this._dictionaryKey = extractDictionaryKeyFromPath(filename);\n }\n },\n\n visitor: {\n /* Check if useIntlayer is already imported */\n ImportDeclaration(path, state) {\n if (!state._isIncluded) return;\n\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n const importedName = t.isIdentifier(spec.imported)\n ? spec.imported.name\n : (spec.imported as BabelTypes.StringLiteral).value;\n\n if (importedName === 'useIntlayer') {\n state._hasUseIntlayerImport = true;\n state._useIntlayerLocalName = spec.local.name;\n }\n if (importedName === 'getIntlayer') {\n state._hasGetIntlayerImport = true;\n state._getIntlayerLocalName = spec.local.name;\n }\n }\n },\n\n /* Detect JSX elements to know this is a component file */\n JSXElement(_path, state) {\n if (!state._isIncluded) return;\n state._hasJSX = true;\n },\n\n /* Extract JSX text content */\n JSXText(path, state) {\n if (!state._isIncluded) return;\n\n const text = path.node.value;\n const shouldExtract = state.opts.shouldExtract ?? defaultShouldExtract;\n\n if (shouldExtract(text)) {\n const key = generateKey(text, state._existingKeys!);\n state._existingKeys!.add(key);\n\n // Collect extracted content\n state._extractedContent![key] = text.replace(/\\s+/g, ' ').trim();\n\n // Track which function has extracted content\n const funcParent = path.getFunctionParent();\n if (funcParent?.node.start != null) {\n state._functionsWithExtractedContent!.add(funcParent.node.start);\n }\n\n // Replace with {content.key} or {_compContent.key}\n path.replaceWith(\n t.jsxExpressionContainer(\n t.memberExpression(\n t.identifier(state._contentVarName!),\n t.identifier(key),\n false\n )\n )\n );\n }\n },\n\n /* Extract JSX attributes */\n JSXAttribute(path, state) {\n if (!state._isIncluded) return;\n\n const name = path.node.name;\n\n if (!t.isJSXIdentifier(name)) return;\n\n const attrName = name.name;\n if (!ATTRIBUTES_TO_EXTRACT.includes(attrName)) return;\n\n const value = path.node.value;\n\n // Handle both direct StringLiteral and JSXExpressionContainer with StringLiteral\n // Case 1: attr=\"value\" -> value is StringLiteral\n // Case 2: attr={\"value\"} -> value is JSXExpressionContainer containing StringLiteral\n let text: string | null = null;\n\n if (t.isStringLiteral(value)) {\n text = value.value;\n } else if (\n t.isJSXExpressionContainer(value) &&\n t.isStringLiteral(value.expression)\n ) {\n text = value.expression.value;\n }\n\n if (text === null) return;\n\n const shouldExtract = state.opts.shouldExtract ?? defaultShouldExtract;\n\n if (shouldExtract(text)) {\n const key = generateKey(text, state._existingKeys!);\n state._existingKeys!.add(key);\n\n // Collect extracted content\n state._extractedContent![key] = text.trim();\n\n // Track which function has extracted content\n const funcParent = path.getFunctionParent();\n if (funcParent?.node.start != null) {\n state._functionsWithExtractedContent!.add(funcParent.node.start);\n }\n\n // Replace with {content.key.value} or {_compContent.key.value}\n path.node.value = t.jsxExpressionContainer(\n t.memberExpression(\n t.memberExpression(\n t.identifier(state._contentVarName!),\n t.identifier(key),\n false\n ),\n t.identifier('value'),\n false\n )\n );\n }\n },\n\n /* Extract String Literals in code (variables, props, etc.) */\n StringLiteral(path, state) {\n if (!state._isIncluded) return;\n if (path.parentPath.isJSXAttribute()) return; // Already handled\n if (path.parentPath.isImportDeclaration()) return;\n if (path.parentPath.isExportDeclaration()) return;\n if (path.parentPath.isImportSpecifier()) return;\n // Check if it is a key in an object property\n if (path.parentPath.isObjectProperty() && path.key === 'key') return;\n\n // Check if it is a call expression to console or useIntlayer\n if (path.parentPath.isCallExpression()) {\n const callee = path.parentPath.node.callee;\n\n // Check for console.log/error/etc\n if (\n t.isMemberExpression(callee) &&\n t.isIdentifier(callee.object) &&\n callee.object.name === 'console'\n ) {\n return;\n }\n\n // Check for useIntlayer('key')\n if (\n t.isIdentifier(callee) &&\n callee.name === state._useIntlayerLocalName\n ) {\n return;\n }\n\n // Check for getIntlayer('key')\n if (\n t.isIdentifier(callee) &&\n callee.name === state._getIntlayerLocalName\n ) {\n return;\n }\n\n // Check for dynamic import import()\n if (callee.type === 'Import') return;\n\n // Check for require()\n if (t.isIdentifier(callee) && callee.name === 'require') return;\n }\n\n const text = path.node.value;\n const shouldExtract = state.opts.shouldExtract ?? defaultShouldExtract;\n\n if (shouldExtract(text)) {\n const key = generateKey(text, state._existingKeys!);\n state._existingKeys!.add(key);\n\n // Collect extracted content\n state._extractedContent![key] = text.trim();\n\n // Track which function has extracted content\n const funcParent = path.getFunctionParent();\n if (funcParent?.node.start != null) {\n state._functionsWithExtractedContent!.add(funcParent.node.start);\n }\n\n // Replace with content.key or _compContent.key\n path.replaceWith(\n t.memberExpression(\n t.identifier(state._contentVarName!),\n t.identifier(key),\n false\n )\n );\n }\n },\n\n /* Inject useIntlayer hook at program exit */\n Program: {\n enter(programPath, state) {\n if (!state._isIncluded) return;\n\n // Check if 'content' variable is already used in any function\n // If so, we'll use '_compContent' to avoid conflicts\n let contentVarUsed = false;\n\n programPath.traverse({\n VariableDeclarator(varPath) {\n if (\n t.isIdentifier(varPath.node.id) &&\n varPath.node.id.name === 'content'\n ) {\n contentVarUsed = true;\n }\n },\n });\n\n state._contentVarName = contentVarUsed ? '_compContent' : 'content';\n },\n\n exit(programPath, state) {\n if (!state._isIncluded) return;\n\n const extractedKeys = Object.keys(state._extractedContent!);\n const hasExtractedContent = extractedKeys.length > 0;\n\n // If no content was extracted, skip - don't inject useIntlayer for files with no extractable text\n if (!hasExtractedContent) return;\n\n // Only process JSX files (React components)\n if (!state._hasJSX) return;\n\n const defaultLocale = state.opts.defaultLocale;\n const packageName = state.opts.packageName;\n\n // Call the onExtract callback with extracted content\n // This will update the dictionary, adding new keys and removing unused ones\n if (\n state.opts.onExtract &&\n state._dictionaryKey &&\n hasExtractedContent\n ) {\n state.opts.onExtract({\n dictionaryKey: state._dictionaryKey,\n filePath: state.file.opts.filename!,\n content: { ...state._extractedContent! },\n locale: defaultLocale!,\n });\n }\n\n // Track what we need to inject\n let needsUseIntlayer = false;\n let needsGetIntlayer = false;\n\n // Now inject hooks only into functions that have extracted content\n const functionsWithContent = state._functionsWithExtractedContent!;\n\n programPath.traverse({\n // Handle function declarations\n FunctionDeclaration(funcPath) {\n // Only inject if this function has extracted content\n if (\n funcPath.node.start != null &&\n functionsWithContent.has(funcPath.node.start)\n ) {\n const type = injectHookIntoFunction(funcPath, state, t);\n if (type === 'hook') needsUseIntlayer = true;\n if (type === 'core') needsGetIntlayer = true;\n }\n },\n\n // Handle arrow functions and function expressions in variable declarations\n VariableDeclarator(varPath) {\n const init = varPath.node.init;\n if (\n t.isArrowFunctionExpression(init) ||\n t.isFunctionExpression(init)\n ) {\n // Only inject if this function has extracted content\n if (\n init.start != null &&\n functionsWithContent.has(init.start)\n ) {\n const type = injectHookIntoArrowOrExpression(\n varPath as NodePath<BabelTypes.VariableDeclarator>,\n init,\n state,\n t\n );\n if (type === 'hook') needsUseIntlayer = true;\n if (type === 'core') needsGetIntlayer = true;\n }\n }\n },\n });\n\n // Add imports if needed\n if (needsUseIntlayer || needsGetIntlayer) {\n const bodyPaths = programPath.get(\n 'body'\n ) as NodePath<BabelTypes.Statement>[];\n\n // Find the best position for import (after directives but before other imports)\n let importInsertPos = 0;\n for (const stmtPath of bodyPaths) {\n const stmt = stmtPath.node;\n if (\n t.isExpressionStatement(stmt) &&\n t.isStringLiteral(stmt.expression)\n ) {\n importInsertPos += 1;\n continue;\n }\n break;\n }\n\n // Inject useIntlayer import\n if (needsUseIntlayer && !state._hasUseIntlayerImport) {\n const importDeclaration = t.importDeclaration(\n [\n t.importSpecifier(\n t.identifier('useIntlayer'),\n t.identifier('useIntlayer')\n ),\n ],\n t.stringLiteral(packageName!)\n );\n programPath.node.body.splice(\n importInsertPos,\n 0,\n importDeclaration\n );\n // adjust position for next import\n importInsertPos++;\n }\n\n // Inject getIntlayer import\n if (needsGetIntlayer && !state._hasGetIntlayerImport) {\n const importDeclaration = t.importDeclaration(\n [\n t.importSpecifier(\n t.identifier('getIntlayer'),\n t.identifier('getIntlayer')\n ),\n ],\n t.stringLiteral(packageName!)\n );\n programPath.node.body.splice(\n importInsertPos,\n 0,\n importDeclaration\n );\n }\n }\n },\n },\n },\n };\n};\n\n/**\n * Inject useIntlayer hook into a function declaration\n * Returns 'hook' if useIntlayer was injected (or needed), 'core' if getIntlayer was injected, or null.\n */\nconst injectHookIntoFunction = (\n funcPath: NodePath<BabelTypes.FunctionDeclaration>,\n state: State,\n t: typeof BabelTypes\n): 'hook' | 'core' | null => {\n const body = funcPath.node.body;\n if (!t.isBlockStatement(body)) return null;\n\n // Check if this function returns JSX\n let returnsJSX = false;\n funcPath.traverse({\n ReturnStatement(returnPath) {\n const arg = returnPath.node.argument;\n if (t.isJSXElement(arg) || t.isJSXFragment(arg)) {\n returnsJSX = true;\n }\n },\n });\n\n const contentVarName = state._contentVarName!;\n\n if (returnsJSX) {\n // Inject useIntlayer\n\n // Check if hook with this specific variable name is already injected\n const hasHook = body.body.some(\n (stmt) =>\n t.isVariableDeclaration(stmt) &&\n stmt.declarations.some(\n (decl) =>\n t.isIdentifier(decl.id) &&\n decl.id.name === contentVarName &&\n t.isCallExpression(decl.init) &&\n t.isIdentifier(decl.init.callee) &&\n decl.init.callee.name === state._useIntlayerLocalName\n )\n );\n\n if (hasHook) return 'hook';\n\n // Inject: const content = useIntlayer('dictionary-key');\n const hookCall = t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(contentVarName),\n t.callExpression(t.identifier(state._useIntlayerLocalName!), [\n t.stringLiteral(state._dictionaryKey!),\n ])\n ),\n ]);\n\n body.body.unshift(hookCall);\n return 'hook';\n } else {\n // Inject getIntlayer\n\n // Check if getIntlayer call with this variable name is already injected\n const hasCall = body.body.some(\n (stmt) =>\n t.isVariableDeclaration(stmt) &&\n stmt.declarations.some(\n (decl) =>\n t.isIdentifier(decl.id) &&\n decl.id.name === contentVarName &&\n t.isCallExpression(decl.init) &&\n t.isIdentifier(decl.init.callee) &&\n decl.init.callee.name === state._getIntlayerLocalName\n )\n );\n\n if (hasCall) return 'core';\n\n // Inject: const content = getIntlayer('dictionary-key');\n const call = t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(contentVarName),\n t.callExpression(t.identifier(state._getIntlayerLocalName!), [\n t.stringLiteral(state._dictionaryKey!),\n ])\n ),\n ]);\n\n body.body.unshift(call);\n return 'core';\n }\n};\n\n/**\n * Inject useIntlayer hook into an arrow function or function expression\n */\nconst injectHookIntoArrowOrExpression = (\n varPath: NodePath<BabelTypes.VariableDeclarator>,\n init: BabelTypes.ArrowFunctionExpression | BabelTypes.FunctionExpression,\n state: State,\n t: typeof BabelTypes\n): 'hook' | 'core' | null => {\n const body = init.body;\n const contentVarName = state._contentVarName!;\n\n // If the body is JSX directly (implicit return), wrap it in a block\n if (t.isJSXElement(body) || t.isJSXFragment(body)) {\n // Transform: () => <div>...</div>\n // To: () => { const content = useIntlayer('key'); return <div>...</div>; }\n const hookCall = t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(contentVarName),\n t.callExpression(t.identifier(state._useIntlayerLocalName!), [\n t.stringLiteral(state._dictionaryKey!),\n ])\n ),\n ]);\n\n const returnStmt = t.returnStatement(body);\n init.body = t.blockStatement([hookCall, returnStmt]);\n return 'hook';\n }\n\n if (!t.isBlockStatement(body)) {\n // Transform: () => \"string\"\n // To: () => { const content = getIntlayer('key'); return \"string\"; }\n const call = t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(contentVarName),\n t.callExpression(t.identifier(state._getIntlayerLocalName!), [\n t.stringLiteral(state._dictionaryKey!),\n ])\n ),\n ]);\n\n const returnStmt = t.returnStatement(body);\n init.body = t.blockStatement([call, returnStmt]);\n return 'core';\n }\n\n // Check if this function returns JSX\n let returnsJSX = false;\n varPath.traverse({\n ReturnStatement(returnPath) {\n const arg = returnPath.node.argument;\n if (t.isJSXElement(arg) || t.isJSXFragment(arg)) {\n returnsJSX = true;\n }\n },\n });\n\n if (returnsJSX) {\n // Inject useIntlayer\n const hasHook = body.body.some(\n (stmt) =>\n t.isVariableDeclaration(stmt) &&\n stmt.declarations.some(\n (decl) =>\n t.isIdentifier(decl.id) &&\n decl.id.name === contentVarName &&\n t.isCallExpression(decl.init) &&\n t.isIdentifier(decl.init.callee) &&\n decl.init.callee.name === state._useIntlayerLocalName\n )\n );\n\n if (hasHook) return 'hook';\n\n const hookCall = t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(contentVarName),\n t.callExpression(t.identifier(state._useIntlayerLocalName!), [\n t.stringLiteral(state._dictionaryKey!),\n ])\n ),\n ]);\n\n body.body.unshift(hookCall);\n return 'hook';\n } else {\n // Inject getIntlayer\n const hasCall = body.body.some(\n (stmt) =>\n t.isVariableDeclaration(stmt) &&\n stmt.declarations.some(\n (decl) =>\n t.isIdentifier(decl.id) &&\n decl.id.name === contentVarName &&\n t.isCallExpression(decl.init) &&\n t.isIdentifier(decl.init.callee) &&\n decl.init.callee.name === state._getIntlayerLocalName\n )\n );\n\n if (hasCall) return 'core';\n\n const call = t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(contentVarName),\n t.callExpression(t.identifier(state._getIntlayerLocalName!), [\n t.stringLiteral(state._dictionaryKey!),\n ])\n ),\n ]);\n\n body.body.unshift(call);\n return 'core';\n }\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"babel-plugin-intlayer-extract.cjs","names":["defaultShouldExtract","ATTRIBUTES_TO_EXTRACT","text: string | null"],"sources":["../../src/babel-plugin-intlayer-extract.ts"],"sourcesContent":["import { basename, dirname, extname } from 'node:path';\nimport type { NodePath, PluginObj, PluginPass } from '@babel/core';\nimport type * as BabelTypes from '@babel/types';\nimport {\n ATTRIBUTES_TO_EXTRACT,\n shouldExtract as defaultShouldExtract,\n generateKey,\n} from '@intlayer/chokidar';\n\ntype ExtractedContent = Record<string, string>;\n\n/**\n * Extracted content result from a file transformation\n */\nexport type ExtractResult = {\n /** Dictionary key derived from the file path */\n dictionaryKey: string;\n /** File path that was processed */\n filePath: string;\n /** Extracted content key-value pairs */\n content: ExtractedContent;\n /** Default locale used */\n locale: string;\n};\n\n/**\n * Options for the extraction Babel plugin\n */\nexport type ExtractPluginOptions = {\n /**\n * The default locale for the extracted content\n */\n defaultLocale?: string;\n /**\n * The package to import useIntlayer from\n * @default 'react-intlayer'\n */\n packageName?: string;\n /**\n * Files list to traverse. If provided, only files in this list will be processed.\n */\n filesList?: string[];\n /**\n * Custom function to determine if a string should be extracted\n */\n shouldExtract?: (text: string) => boolean;\n /**\n * Callback function called when content is extracted from a file.\n * This allows the compiler to capture the extracted content and write it to files.\n * The dictionary will be updated: new keys added, unused keys removed.\n */\n onExtract?: (result: ExtractResult) => void;\n};\n\ntype State = PluginPass & {\n opts: ExtractPluginOptions;\n /** Extracted content from this file */\n _extractedContent?: ExtractedContent;\n /** Set of existing keys to avoid duplicates */\n _existingKeys?: Set<string>;\n /** The dictionary key for this file */\n _dictionaryKey?: string;\n /** whether the current file is included in the filesList */\n _isIncluded?: boolean;\n /** Whether this file has JSX (React component) */\n _hasJSX?: boolean;\n /** Whether we already have useIntlayer imported */\n _hasUseIntlayerImport?: boolean;\n /** The local name for useIntlayer (in case it's aliased) */\n _useIntlayerLocalName?: string;\n /** Whether we already have getIntlayer imported */\n _hasGetIntlayerImport?: boolean;\n /** The local name for getIntlayer (in case it's aliased) */\n _getIntlayerLocalName?: string;\n /** The variable name to use for content (content or _compContent if content is already used) */\n _contentVarName?: string;\n /** Set of function start positions that have extracted content (only inject hooks into these) */\n _functionsWithExtractedContent?: Set<number>;\n};\n\n/* ────────────────────────────────────────── helpers ─────────────────────── */\n\n/**\n * Extract dictionary key from file path\n */\nconst extractDictionaryKeyFromPath = (filePath: string): string => {\n const ext = extname(filePath);\n let baseName = basename(filePath, ext);\n\n if (baseName === 'index') {\n baseName = basename(dirname(filePath));\n }\n\n // Convert to kebab-case\n const key = baseName\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n\n return `comp-${key}`;\n};\n\n/* ────────────────────────────────────────── plugin ──────────────────────── */\n\n/**\n * Autonomous Babel plugin that extracts content and transforms JSX to use useIntlayer.\n *\n * This plugin:\n * 1. Scans files for extractable text (JSX text, attributes)\n * 2. Auto-injects useIntlayer import and hook call\n * 3. Reports extracted content via onExtract callback (for the compiler to write dictionaries)\n * 4. Replaces extractable strings with content references\n *\n * ## Input\n * ```tsx\n * export const MyComponent = () => {\n * return <div>Hello World</div>;\n * };\n * ```\n *\n * ## Output\n * ```tsx\n * import { useIntlayer } from 'react-intlayer';\n *\n * export const MyComponent = () => {\n * const content = useIntlayer('comp-my-component');\n * return <div>{content.helloWorld}</div>;\n * };\n * ```\n *\n * ## When useIntlayer is already present\n *\n * If the component already has a `content` variable from an existing `useIntlayer` call,\n * the plugin will use `_compContent` to avoid naming conflicts:\n *\n * ### Input\n * ```tsx\n * export const Page = () => {\n * const content = useIntlayer('page');\n * return <div>{content.title} - Hello World</div>;\n * };\n * ```\n *\n * ### Output\n * ```tsx\n * export const Page = () => {\n * const _compContent = useIntlayer('comp-page');\n * const content = useIntlayer('page');\n * return <div>{content.title} - {_compContent.helloWorld}</div>;\n * };\n * ```\n *\n * The extracted content is reported via the `onExtract` callback, allowing the\n * compiler to write the dictionary to disk separately:\n * ```json\n * // my-component.content.json (written by compiler)\n * {\n * \"key\": \"comp-my-component\",\n * \"content\": {\n * \"helloWorld\": { \"nodeType\": \"translation\", \"translation\": { \"en\": \"Hello World\" } }\n * }\n * }\n * ```\n */\nexport const intlayerExtractBabelPlugin = (babel: {\n types: typeof BabelTypes;\n}): PluginObj<State> => {\n const { types: t } = babel;\n\n return {\n name: 'babel-plugin-intlayer-extract',\n\n pre() {\n this._extractedContent = {};\n this._existingKeys = new Set();\n this._functionsWithExtractedContent = new Set();\n this._isIncluded = true;\n this._hasJSX = false;\n this._hasUseIntlayerImport = false;\n this._useIntlayerLocalName = 'useIntlayer';\n this._hasGetIntlayerImport = false;\n this._getIntlayerLocalName = 'getIntlayer';\n this._contentVarName = 'content'; // Will be updated in Program.enter if 'content' is already used\n\n const filename = this.file.opts.filename;\n\n // If filesList is provided, check if current file is included\n if (this.opts.filesList && filename) {\n // Normalize paths for comparison (handle potential path separator issues)\n const normalizedFilename = filename.replace(/\\\\/g, '/');\n const isIncluded = this.opts.filesList.some((f) => {\n const normalizedF = f.replace(/\\\\/g, '/');\n return normalizedF === normalizedFilename;\n });\n\n if (!isIncluded) {\n this._isIncluded = false;\n return;\n }\n }\n\n // Extract dictionary key from filename\n if (filename) {\n this._dictionaryKey = extractDictionaryKeyFromPath(filename);\n }\n },\n\n visitor: {\n /* Check if useIntlayer is already imported */\n ImportDeclaration(path, state) {\n if (!state._isIncluded) return;\n\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n const importedName = t.isIdentifier(spec.imported)\n ? spec.imported.name\n : (spec.imported as BabelTypes.StringLiteral).value;\n\n if (importedName === 'useIntlayer') {\n state._hasUseIntlayerImport = true;\n state._useIntlayerLocalName = spec.local.name;\n }\n if (importedName === 'getIntlayer') {\n state._hasGetIntlayerImport = true;\n state._getIntlayerLocalName = spec.local.name;\n }\n }\n },\n\n /* Detect JSX elements to know this is a component file */\n JSXElement(_path, state) {\n if (!state._isIncluded) return;\n state._hasJSX = true;\n },\n\n /* Extract JSX text content */\n JSXText(path, state) {\n if (!state._isIncluded) return;\n\n const text = path.node.value;\n const shouldExtract = state.opts.shouldExtract ?? defaultShouldExtract;\n\n if (shouldExtract(text)) {\n const key = generateKey(text, state._existingKeys!);\n state._existingKeys!.add(key);\n\n // Collect extracted content\n state._extractedContent![key] = text.replace(/\\s+/g, ' ').trim();\n\n // Track which function has extracted content\n const funcParent = path.getFunctionParent();\n if (funcParent?.node.start != null) {\n state._functionsWithExtractedContent!.add(funcParent.node.start);\n }\n\n // Replace with {content.key} or {_compContent.key}\n path.replaceWith(\n t.jsxExpressionContainer(\n t.memberExpression(\n t.identifier(state._contentVarName!),\n t.identifier(key),\n false\n )\n )\n );\n }\n },\n\n /* Extract JSX attributes */\n JSXAttribute(path, state) {\n if (!state._isIncluded) return;\n\n const name = path.node.name;\n\n if (!t.isJSXIdentifier(name)) return;\n\n const attrName = name.name;\n if (!ATTRIBUTES_TO_EXTRACT.includes(attrName)) return;\n\n const value = path.node.value;\n\n // Handle both direct StringLiteral and JSXExpressionContainer with StringLiteral\n // Case 1: attr=\"value\" -> value is StringLiteral\n // Case 2: attr={\"value\"} -> value is JSXExpressionContainer containing StringLiteral\n let text: string | null = null;\n\n if (t.isStringLiteral(value)) {\n text = value.value;\n } else if (\n t.isJSXExpressionContainer(value) &&\n t.isStringLiteral(value.expression)\n ) {\n text = value.expression.value;\n }\n\n if (text === null) return;\n\n const shouldExtract = state.opts.shouldExtract ?? defaultShouldExtract;\n\n if (shouldExtract(text)) {\n const key = generateKey(text, state._existingKeys!);\n state._existingKeys!.add(key);\n\n // Collect extracted content\n state._extractedContent![key] = text.trim();\n\n // Track which function has extracted content\n const funcParent = path.getFunctionParent();\n if (funcParent?.node.start != null) {\n state._functionsWithExtractedContent!.add(funcParent.node.start);\n }\n\n // Replace with {content.key.value} or {_compContent.key.value}\n path.node.value = t.jsxExpressionContainer(\n t.memberExpression(\n t.memberExpression(\n t.identifier(state._contentVarName!),\n t.identifier(key),\n false\n ),\n t.identifier('value'),\n false\n )\n );\n }\n },\n\n /* Extract String Literals in code (variables, props, etc.) */\n StringLiteral(path, state) {\n if (!state._isIncluded) return;\n if (path.parentPath.isJSXAttribute()) return; // Already handled\n if (path.parentPath.isImportDeclaration()) return;\n if (path.parentPath.isExportDeclaration()) return;\n if (path.parentPath.isImportSpecifier()) return;\n // Check if it is a key in an object property\n if (path.parentPath.isObjectProperty() && path.key === 'key') return;\n\n // Check if it is a call expression to console or useIntlayer\n if (path.parentPath.isCallExpression()) {\n const callee = path.parentPath.node.callee;\n\n // Check for console.log/error/etc\n if (\n t.isMemberExpression(callee) &&\n t.isIdentifier(callee.object) &&\n callee.object.name === 'console'\n ) {\n return;\n }\n\n // Check for useIntlayer('key')\n if (\n t.isIdentifier(callee) &&\n callee.name === state._useIntlayerLocalName\n ) {\n return;\n }\n\n // Check for getIntlayer('key')\n if (\n t.isIdentifier(callee) &&\n callee.name === state._getIntlayerLocalName\n ) {\n return;\n }\n\n // Check for dynamic import import()\n if (callee.type === 'Import') return;\n\n // Check for require()\n if (t.isIdentifier(callee) && callee.name === 'require') return;\n }\n\n const text = path.node.value;\n const shouldExtract = state.opts.shouldExtract ?? defaultShouldExtract;\n\n if (shouldExtract(text)) {\n const key = generateKey(text, state._existingKeys!);\n state._existingKeys!.add(key);\n\n // Collect extracted content\n state._extractedContent![key] = text.trim();\n\n // Track which function has extracted content\n const funcParent = path.getFunctionParent();\n if (funcParent?.node.start != null) {\n state._functionsWithExtractedContent!.add(funcParent.node.start);\n }\n\n // Replace with content.key or _compContent.key\n path.replaceWith(\n t.memberExpression(\n t.identifier(state._contentVarName!),\n t.identifier(key),\n false\n )\n );\n }\n },\n\n /* Inject useIntlayer hook at program exit */\n Program: {\n enter(programPath, state) {\n if (!state._isIncluded) return;\n\n // Check if 'content' variable is already used in any function\n // If so, we'll use '_compContent' to avoid conflicts\n let contentVarUsed = false;\n\n programPath.traverse({\n VariableDeclarator(varPath) {\n if (\n t.isIdentifier(varPath.node.id) &&\n varPath.node.id.name === 'content'\n ) {\n contentVarUsed = true;\n }\n },\n });\n\n state._contentVarName = contentVarUsed ? '_compContent' : 'content';\n },\n\n exit(programPath, state) {\n if (!state._isIncluded) return;\n\n const extractedKeys = Object.keys(state._extractedContent!);\n const hasExtractedContent = extractedKeys.length > 0;\n\n // If no content was extracted, skip - don't inject useIntlayer for files with no extractable text\n if (!hasExtractedContent) return;\n\n // Only process JSX files (React components)\n if (!state._hasJSX) return;\n\n const defaultLocale = state.opts.defaultLocale;\n const packageName = state.opts.packageName;\n\n // Call the onExtract callback with extracted content\n // This will update the dictionary, adding new keys and removing unused ones\n if (\n state.opts.onExtract &&\n state._dictionaryKey &&\n hasExtractedContent\n ) {\n state.opts.onExtract({\n dictionaryKey: state._dictionaryKey,\n filePath: state.file.opts.filename!,\n content: { ...state._extractedContent! },\n locale: defaultLocale!,\n });\n }\n\n // Track what we need to inject\n let needsUseIntlayer = false;\n let needsGetIntlayer = false;\n\n // Now inject hooks only into functions that have extracted content\n const functionsWithContent = state._functionsWithExtractedContent!;\n\n programPath.traverse({\n // Handle function declarations\n FunctionDeclaration(funcPath) {\n // Only inject if this function has extracted content\n if (\n funcPath.node.start != null &&\n functionsWithContent.has(funcPath.node.start)\n ) {\n const type = injectHookIntoFunction(funcPath, state, t);\n if (type === 'hook') needsUseIntlayer = true;\n if (type === 'core') needsGetIntlayer = true;\n }\n },\n\n // Handle arrow functions and function expressions in variable declarations\n VariableDeclarator(varPath) {\n const init = varPath.node.init;\n if (\n t.isArrowFunctionExpression(init) ||\n t.isFunctionExpression(init)\n ) {\n // Only inject if this function has extracted content\n if (\n init.start != null &&\n functionsWithContent.has(init.start)\n ) {\n const type = injectHookIntoArrowOrExpression(\n varPath as NodePath<BabelTypes.VariableDeclarator>,\n init,\n state,\n t\n );\n if (type === 'hook') needsUseIntlayer = true;\n if (type === 'core') needsGetIntlayer = true;\n }\n }\n },\n });\n\n // Add imports if needed\n if (needsUseIntlayer || needsGetIntlayer) {\n const bodyPaths = programPath.get(\n 'body'\n ) as NodePath<BabelTypes.Statement>[];\n\n // Find the best position for import (after directives but before other imports)\n let importInsertPos = 0;\n for (const stmtPath of bodyPaths) {\n const stmt = stmtPath.node;\n if (\n t.isExpressionStatement(stmt) &&\n t.isStringLiteral(stmt.expression)\n ) {\n importInsertPos += 1;\n continue;\n }\n break;\n }\n\n // Inject useIntlayer import\n if (needsUseIntlayer && !state._hasUseIntlayerImport) {\n const importDeclaration = t.importDeclaration(\n [\n t.importSpecifier(\n t.identifier('useIntlayer'),\n t.identifier('useIntlayer')\n ),\n ],\n t.stringLiteral(packageName!)\n );\n programPath.node.body.splice(\n importInsertPos,\n 0,\n importDeclaration\n );\n // adjust position for next import\n importInsertPos++;\n }\n\n // Inject getIntlayer import\n if (needsGetIntlayer && !state._hasGetIntlayerImport) {\n const importDeclaration = t.importDeclaration(\n [\n t.importSpecifier(\n t.identifier('getIntlayer'),\n t.identifier('getIntlayer')\n ),\n ],\n t.stringLiteral(packageName!)\n );\n programPath.node.body.splice(\n importInsertPos,\n 0,\n importDeclaration\n );\n }\n }\n },\n },\n },\n };\n};\n\n/**\n * Inject useIntlayer hook into a function declaration\n * Returns 'hook' if useIntlayer was injected (or needed), 'core' if getIntlayer was injected, or null.\n */\nconst injectHookIntoFunction = (\n funcPath: NodePath<BabelTypes.FunctionDeclaration>,\n state: State,\n t: typeof BabelTypes\n): 'hook' | 'core' | null => {\n const body = funcPath.node.body;\n if (!t.isBlockStatement(body)) return null;\n\n // Check if this function returns JSX\n let returnsJSX = false;\n funcPath.traverse({\n ReturnStatement(returnPath) {\n const arg = returnPath.node.argument;\n if (t.isJSXElement(arg) || t.isJSXFragment(arg)) {\n returnsJSX = true;\n }\n },\n });\n\n const contentVarName = state._contentVarName!;\n\n if (returnsJSX) {\n // Inject useIntlayer\n\n // Check if hook with this specific variable name is already injected\n const hasHook = body.body.some(\n (stmt) =>\n t.isVariableDeclaration(stmt) &&\n stmt.declarations.some(\n (decl) =>\n t.isIdentifier(decl.id) &&\n decl.id.name === contentVarName &&\n t.isCallExpression(decl.init) &&\n t.isIdentifier(decl.init.callee) &&\n decl.init.callee.name === state._useIntlayerLocalName\n )\n );\n\n if (hasHook) return 'hook';\n\n // Inject: const content = useIntlayer('dictionary-key');\n const hookCall = t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(contentVarName),\n t.callExpression(t.identifier(state._useIntlayerLocalName!), [\n t.stringLiteral(state._dictionaryKey!),\n ])\n ),\n ]);\n\n body.body.unshift(hookCall);\n return 'hook';\n } else {\n // Inject getIntlayer\n\n // Check if getIntlayer call with this variable name is already injected\n const hasCall = body.body.some(\n (stmt) =>\n t.isVariableDeclaration(stmt) &&\n stmt.declarations.some(\n (decl) =>\n t.isIdentifier(decl.id) &&\n decl.id.name === contentVarName &&\n t.isCallExpression(decl.init) &&\n t.isIdentifier(decl.init.callee) &&\n decl.init.callee.name === state._getIntlayerLocalName\n )\n );\n\n if (hasCall) return 'core';\n\n // Inject: const content = getIntlayer('dictionary-key');\n const call = t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(contentVarName),\n t.callExpression(t.identifier(state._getIntlayerLocalName!), [\n t.stringLiteral(state._dictionaryKey!),\n ])\n ),\n ]);\n\n body.body.unshift(call);\n return 'core';\n }\n};\n\n/**\n * Inject useIntlayer hook into an arrow function or function expression\n */\nconst injectHookIntoArrowOrExpression = (\n varPath: NodePath<BabelTypes.VariableDeclarator>,\n init: BabelTypes.ArrowFunctionExpression | BabelTypes.FunctionExpression,\n state: State,\n t: typeof BabelTypes\n): 'hook' | 'core' | null => {\n const body = init.body;\n const contentVarName = state._contentVarName!;\n\n // If the body is JSX directly (implicit return), wrap it in a block\n if (t.isJSXElement(body) || t.isJSXFragment(body)) {\n // Transform: () => <div>...</div>\n // To: () => { const content = useIntlayer('key'); return <div>...</div>; }\n const hookCall = t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(contentVarName),\n t.callExpression(t.identifier(state._useIntlayerLocalName!), [\n t.stringLiteral(state._dictionaryKey!),\n ])\n ),\n ]);\n\n const returnStmt = t.returnStatement(body);\n init.body = t.blockStatement([hookCall, returnStmt]);\n return 'hook';\n }\n\n if (!t.isBlockStatement(body)) {\n // Transform: () => \"string\"\n // To: () => { const content = getIntlayer('key'); return \"string\"; }\n const call = t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(contentVarName),\n t.callExpression(t.identifier(state._getIntlayerLocalName!), [\n t.stringLiteral(state._dictionaryKey!),\n ])\n ),\n ]);\n\n const returnStmt = t.returnStatement(body);\n init.body = t.blockStatement([call, returnStmt]);\n return 'core';\n }\n\n // Check if this function returns JSX\n let returnsJSX = false;\n varPath.traverse({\n ReturnStatement(returnPath) {\n const arg = returnPath.node.argument;\n if (t.isJSXElement(arg) || t.isJSXFragment(arg)) {\n returnsJSX = true;\n }\n },\n });\n\n if (returnsJSX) {\n // Inject useIntlayer\n const hasHook = body.body.some(\n (stmt) =>\n t.isVariableDeclaration(stmt) &&\n stmt.declarations.some(\n (decl) =>\n t.isIdentifier(decl.id) &&\n decl.id.name === contentVarName &&\n t.isCallExpression(decl.init) &&\n t.isIdentifier(decl.init.callee) &&\n decl.init.callee.name === state._useIntlayerLocalName\n )\n );\n\n if (hasHook) return 'hook';\n\n const hookCall = t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(contentVarName),\n t.callExpression(t.identifier(state._useIntlayerLocalName!), [\n t.stringLiteral(state._dictionaryKey!),\n ])\n ),\n ]);\n\n body.body.unshift(hookCall);\n return 'hook';\n } else {\n // Inject getIntlayer\n const hasCall = body.body.some(\n (stmt) =>\n t.isVariableDeclaration(stmt) &&\n stmt.declarations.some(\n (decl) =>\n t.isIdentifier(decl.id) &&\n decl.id.name === contentVarName &&\n t.isCallExpression(decl.init) &&\n t.isIdentifier(decl.init.callee) &&\n decl.init.callee.name === state._getIntlayerLocalName\n )\n );\n\n if (hasCall) return 'core';\n\n const call = t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(contentVarName),\n t.callExpression(t.identifier(state._getIntlayerLocalName!), [\n t.stringLiteral(state._dictionaryKey!),\n ])\n ),\n ]);\n\n body.body.unshift(call);\n return 'core';\n }\n};\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
2
  let node_path = require("node:path");
3
- let __intlayer_chokidar = require("@intlayer/chokidar");
4
- let __intlayer_config = require("@intlayer/config");
3
+ let _intlayer_chokidar = require("@intlayer/chokidar");
4
+ let _intlayer_config = require("@intlayer/config");
5
5
 
6
6
  //#region src/babel-plugin-intlayer-optimize.ts
7
7
  const PACKAGE_LIST = [
@@ -47,7 +47,7 @@ const DYNAMIC_IMPORT_FUNCTION = { useIntlayer: "useDictionaryDynamic" };
47
47
  * with user-defined ones.
48
48
  */
49
49
  const makeIdent = (key, t) => {
50
- const hash = (0, __intlayer_chokidar.getFileHash)(key);
50
+ const hash = (0, _intlayer_chokidar.getFileHash)(key);
51
51
  return t.identifier(`_${hash}`);
52
52
  };
53
53
  const computeImport = (fromFile, dictionariesDir, dynamicDictionariesDir, fetchDictionariesDir, key, importMode) => {
@@ -55,7 +55,7 @@ const computeImport = (fromFile, dictionariesDir, dynamicDictionariesDir, fetchD
55
55
  if (importMode === "live") relativePath = (0, node_path.join)(fetchDictionariesDir, `${key}.mjs`);
56
56
  if (importMode === "dynamic") relativePath = (0, node_path.join)(dynamicDictionariesDir, `${key}.mjs`);
57
57
  let rel = (0, node_path.relative)((0, node_path.dirname)(fromFile), relativePath);
58
- rel = (0, __intlayer_config.normalizePath)(rel);
58
+ rel = (0, _intlayer_config.normalizePath)(rel);
59
59
  if (!rel.startsWith("./") && !rel.startsWith("../")) rel = `./${rel}`;
60
60
  return rel;
61
61
  };
@@ -223,7 +223,7 @@ const intlayerOptimizeBabelPlugin = (babel) => {
223
223
  if (perCallMode === "live") {
224
224
  let dynamicIdent = state._newDynamicImports?.get(key);
225
225
  if (!dynamicIdent) {
226
- const hash = (0, __intlayer_chokidar.getFileHash)(key);
226
+ const hash = (0, _intlayer_chokidar.getFileHash)(key);
227
227
  dynamicIdent = t.identifier(`_${hash}_fetch`);
228
228
  state._newDynamicImports?.set(key, dynamicIdent);
229
229
  }
@@ -232,7 +232,7 @@ const intlayerOptimizeBabelPlugin = (babel) => {
232
232
  } else if (perCallMode === "dynamic") {
233
233
  let dynamicIdent = state._newDynamicImports?.get(key);
234
234
  if (!dynamicIdent) {
235
- const hash = (0, __intlayer_chokidar.getFileHash)(key);
235
+ const hash = (0, _intlayer_chokidar.getFileHash)(key);
236
236
  dynamicIdent = t.identifier(`_${hash}_dyn`);
237
237
  state._newDynamicImports?.set(key, dynamicIdent);
238
238
  }
@@ -1 +1 @@
1
- {"version":3,"file":"babel-plugin-intlayer-optimize.cjs","names":["helperMap: Record<string, string>","perCallMode: 'static' | 'dynamic' | 'live'","ident: BabelTypes.Identifier","imports: BabelTypes.ImportDeclaration[]"],"sources":["../../src/babel-plugin-intlayer-optimize.ts"],"sourcesContent":["import { dirname, join, relative } from 'node:path';\nimport type { NodePath, PluginObj, PluginPass } from '@babel/core';\nimport type * as BabelTypes from '@babel/types';\nimport { getFileHash } from '@intlayer/chokidar';\nimport { normalizePath } from '@intlayer/config';\n\n/* ────────────────────────────────────────── constants ───────────────────── */\n\nconst PACKAGE_LIST = [\n 'intlayer',\n '@intlayer/core',\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'svelte-intlayer',\n 'vue-intlayer',\n 'angular-intlayer',\n 'preact-intlayer',\n 'solid-intlayer',\n];\n\nconst CALLER_LIST = ['useIntlayer', 'getIntlayer'] as const;\n\n/**\n * Packages that support dynamic import\n */\nconst PACKAGE_LIST_DYNAMIC = [\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'preact-intlayer',\n 'vue-intlayer',\n 'solid-intlayer',\n 'svelte-intlayer',\n 'angular-intlayer',\n] as const;\n\nconst STATIC_IMPORT_FUNCTION = {\n getIntlayer: 'getDictionary',\n useIntlayer: 'useDictionary',\n} as const;\n\nconst DYNAMIC_IMPORT_FUNCTION = {\n useIntlayer: 'useDictionaryDynamic',\n} as const;\n\n/* ────────────────────────────────────────── types ───────────────────────── */\n\n/**\n * Options for the optimization Babel plugin\n */\nexport type OptimizePluginOptions = {\n /**\n * If false, the plugin will not apply any transformation.\n */\n optimize?: boolean;\n /**\n * The path to the dictionaries directory.\n */\n dictionariesDir: string;\n /**\n * The path to the dictionaries entry file.\n */\n dictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries entry file.\n */\n unmergedDictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries directory.\n */\n unmergedDictionariesDir: string;\n /**\n * The path to the dictionaries directory.\n */\n dynamicDictionariesDir: string;\n /**\n * The path to the dynamic dictionaries entry file.\n */\n dynamicDictionariesEntryPath: string;\n /**\n * The path to the fetch dictionaries directory.\n */\n fetchDictionariesDir: string;\n /**\n * The path to the fetch dictionaries entry file.\n */\n fetchDictionariesEntryPath: string;\n /**\n * If true, the plugin will replace the dictionary entry file with `export default {}`.\n */\n replaceDictionaryEntry: boolean;\n /**\n * If true, the plugin will activate the dynamic import of the dictionaries. It will rely on Suspense to load the dictionaries.\n */\n importMode: 'static' | 'dynamic' | 'live';\n /**\n * Activate the live sync of the dictionaries.\n * If `importMode` is `live`, the plugin will activate the live sync of the dictionaries.\n */\n liveSyncKeys: string[];\n /**\n * Files list to traverse.\n */\n filesList: string[];\n};\n\ntype State = PluginPass & {\n opts: OptimizePluginOptions;\n /** map key → generated ident (per-file) for static imports */\n _newStaticImports?: Map<string, BabelTypes.Identifier>;\n /** map key → generated ident (per-file) for dynamic imports */\n _newDynamicImports?: Map<string, BabelTypes.Identifier>;\n /** whether the current file imported *any* intlayer package */\n _hasValidImport?: boolean;\n /** whether the current file *is* the dictionaries entry file */\n _isDictEntry?: boolean;\n /** whether dynamic helpers are active for this file */\n _useDynamicHelpers?: boolean;\n /** whether the current file is included in the filesList */\n _isIncluded?: boolean;\n};\n\n/* ────────────────────────────────────────── helpers ─────────────────────── */\n\n/**\n * Replicates the xxHash64 → Base-62 algorithm used by the SWC version\n * and prefixes an underscore so the generated identifiers never collide\n * with user-defined ones.\n */\nconst makeIdent = (\n key: string,\n t: typeof BabelTypes\n): BabelTypes.Identifier => {\n const hash = getFileHash(key);\n return t.identifier(`_${hash}`);\n};\n\nconst computeImport = (\n fromFile: string,\n dictionariesDir: string,\n dynamicDictionariesDir: string,\n fetchDictionariesDir: string,\n key: string,\n importMode: 'static' | 'dynamic' | 'live'\n): string => {\n let relativePath = join(dictionariesDir, `${key}.json`);\n\n if (importMode === 'live') {\n relativePath = join(fetchDictionariesDir, `${key}.mjs`);\n }\n\n if (importMode === 'dynamic') {\n relativePath = join(dynamicDictionariesDir, `${key}.mjs`);\n }\n\n let rel = relative(dirname(fromFile), relativePath);\n\n // Fix windows path\n rel = normalizePath(rel);\n\n // Fix relative path\n if (!rel.startsWith('./') && !rel.startsWith('../')) {\n rel = `./${rel}`;\n }\n\n return rel;\n};\n\n/* ────────────────────────────────────────── plugin ──────────────────────── */\n\n/**\n * Babel plugin that transforms Intlayer function calls and auto-imports dictionaries.\n *\n * This plugin transforms calls to `useIntlayer()` and `getIntlayer()` from various Intlayer\n * packages into optimized dictionary access patterns, automatically importing the required\n * dictionary files based on the configured import mode.\n *\n * ## Supported Input Patterns\n *\n * The plugin recognizes these function calls:\n *\n * ```ts\n * // useIntlayer\n * import { useIntlayer } from 'react-intlayer';\n * import { useIntlayer } from 'next-intlayer';\n *\n * // getIntlayer\n * import { getIntlayer } from 'intlayer';\n *\n * // Usage\n * const content = useIntlayer('app');\n * const content = getIntlayer('app');\n * ```\n *\n * ## Transformation Modes\n *\n * ### Static Mode (default: `importMode = \"static\"`)\n *\n * Imports JSON dictionaries directly and replaces function calls with dictionary access:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import { useDictionary as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash);\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Dynamic Mode (`importMode = \"dynamic\"`)\n *\n * Uses dynamic dictionary loading with Suspense support:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Live Mode (`importMode = \"live\"`)\n *\n * Uses live-based dictionary loading for remote dictionaries:\n *\n * **Output if `liveSyncKeys` includes the key:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_fetch from '../../.intlayer/fetch_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_fetch, \"app\");\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * > If `liveSyncKeys` does not include the key, the plugin will fallback to the dynamic impor\n *\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n */\nexport const intlayerOptimizeBabelPlugin = (babel: {\n types: typeof BabelTypes;\n}): PluginObj<State> => {\n const { types: t } = babel;\n\n return {\n name: 'babel-plugin-intlayer-transform',\n\n pre() {\n this._newStaticImports = new Map();\n this._newDynamicImports = new Map();\n this._isIncluded = true;\n this._hasValidImport = false;\n this._isDictEntry = false;\n this._useDynamicHelpers = false;\n\n // If optimize is false, skip processing entirely\n if (this.opts.optimize === false) {\n this._isIncluded = false;\n return;\n }\n\n // If filesList is provided, check if current file is included\n const filename = this.file.opts.filename;\n if (this.opts.filesList && filename) {\n const isIncluded = this.opts.filesList.includes(filename);\n\n if (!isIncluded) {\n // Force _isIncluded to false to skip processing\n this._isIncluded = false;\n return;\n }\n }\n },\n\n visitor: {\n /* If this file *is* the dictionaries entry, short-circuit: export {} */\n Program: {\n enter(programPath, state) {\n // Safe access to filename\n const filename = state.file.opts.filename;\n\n // Check if this is the correct file to transform\n if (\n state.opts.replaceDictionaryEntry &&\n filename === state.opts.dictionariesEntryPath\n ) {\n state._isDictEntry = true;\n\n // Traverse the program to surgically remove/edit specific parts\n programPath.traverse({\n // Remove all import statements (cleaning up 'sssss.json')\n ImportDeclaration(path) {\n path.remove();\n },\n\n // Find the variable definition and empty the object\n VariableDeclarator(path) {\n // We look for: const x = { ... }\n if (t.isObjectExpression(path.node.init)) {\n // Set the object properties to an empty array: {}\n path.node.init.properties = [];\n }\n },\n });\n\n // (Optional) Stop other plugins from processing this file further if needed\n // programPath.stop();\n }\n },\n\n /**\n * After full traversal, process imports and call expressions, then inject the JSON dictionary imports.\n *\n * We do the transformation in Program.exit (via a manual traverse) rather than using\n * top-level ImportDeclaration/CallExpression visitors. This ensures that if another plugin\n * (like babel-plugin-intlayer-extract) adds new useIntlayer calls in its Program.exit,\n * we will see and transform them here because our Program.exit runs after theirs.\n */\n exit(programPath, state) {\n if (state._isDictEntry) return; // nothing else to do – already replaced\n if (!state._isIncluded) return; // early-out if file is not included\n\n // Manual traversal to process imports and call expressions\n // This runs AFTER all other plugins' visitors have completed\n programPath.traverse({\n /* Inspect every intlayer import */\n ImportDeclaration(path) {\n const src = path.node.source.value;\n if (!PACKAGE_LIST.includes(src)) return;\n\n // Mark that we do import from an intlayer package in this file\n state._hasValidImport = true;\n\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n // ⚠️ We now key off *imported* name, *not* local name.\n const importedName = t.isIdentifier(spec.imported)\n ? spec.imported.name\n : (spec.imported as BabelTypes.StringLiteral).value;\n\n const importMode = state.opts.importMode;\n // Determine whether this import should use the dynamic helpers.\n const shouldUseDynamicHelpers =\n (importMode === 'dynamic' || importMode === 'live') &&\n PACKAGE_LIST_DYNAMIC.includes(src as any);\n\n // Remember for later (CallExpression) whether we are using the dynamic helpers\n if (shouldUseDynamicHelpers) {\n state._useDynamicHelpers = true;\n }\n\n let helperMap: Record<string, string>;\n\n if (shouldUseDynamicHelpers) {\n // Use dynamic helpers for useIntlayer when dynamic mode is enabled\n helperMap = {\n ...STATIC_IMPORT_FUNCTION,\n ...DYNAMIC_IMPORT_FUNCTION,\n } as Record<string, string>;\n } else {\n // Use static helpers by default\n helperMap = STATIC_IMPORT_FUNCTION as Record<string, string>;\n }\n\n const newIdentifier = helperMap[importedName];\n\n // Only rewrite when we actually have a mapping for the imported\n // specifier (ignore unrelated named imports).\n if (newIdentifier) {\n // Keep the local alias intact (so calls remain `useIntlayer` /\n // `getIntlayer`), but rewrite the imported identifier so it\n // points to our helper implementation.\n spec.imported = t.identifier(newIdentifier);\n }\n }\n },\n\n /* Replace calls: useIntlayer(\"foo\") → useDictionary(_hash) or useDictionaryDynamic(_hash, \"foo\") */\n CallExpression(path) {\n const callee = path.node.callee;\n if (!t.isIdentifier(callee)) return;\n if (!CALLER_LIST.includes(callee.name as any)) return;\n\n // Ensure we ultimately emit helper imports for files that *invoke*\n // the hooks, even if they didn't import them directly (edge cases with\n // re-exports).\n state._hasValidImport = true;\n\n const arg = path.node.arguments[0];\n if (!arg || !t.isStringLiteral(arg)) return; // must be literal\n\n const key = arg.value;\n const importMode = state.opts.importMode;\n const isUseIntlayer = callee.name === 'useIntlayer';\n const useDynamicHelpers = Boolean(state._useDynamicHelpers);\n\n // Decide per-call mode: 'static' | 'dynamic' | 'live'\n let perCallMode: 'static' | 'dynamic' | 'live' = 'static';\n if (isUseIntlayer && useDynamicHelpers) {\n if (importMode === 'dynamic') {\n perCallMode = 'dynamic';\n } else if (importMode === 'live') {\n const liveKeys = state.opts.liveSyncKeys ?? [];\n perCallMode = liveKeys.includes(key) ? 'live' : 'dynamic';\n }\n }\n\n let ident: BabelTypes.Identifier;\n\n if (perCallMode === 'live') {\n // Use fetch dictionaries entry (live mode for selected keys)\n let dynamicIdent = state._newDynamicImports?.get(key);\n if (!dynamicIdent) {\n const hash = getFileHash(key);\n dynamicIdent = t.identifier(`_${hash}_fetch`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Helper: first argument is the dictionary entry, second is the key\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else if (perCallMode === 'dynamic') {\n // Use dynamic dictionaries entry\n let dynamicIdent = state._newDynamicImports?.get(key);\n if (!dynamicIdent) {\n // Create a unique identifier for dynamic imports by appending a suffix\n const hash = getFileHash(key);\n dynamicIdent = t.identifier(`_${hash}_dyn`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Dynamic helper: first argument is the dictionary, second is the key.\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else {\n // Use static imports for getIntlayer or useIntlayer when not using dynamic helpers\n let staticIdent = state._newStaticImports?.get(key);\n if (!staticIdent) {\n staticIdent = makeIdent(key, t);\n state._newStaticImports?.set(key, staticIdent);\n }\n ident = staticIdent;\n\n // Static helper (useDictionary / getDictionary): replace key with iden\n path.node.arguments[0] = t.identifier(ident.name);\n }\n },\n });\n\n // Early-out if we touched nothing\n if (!state._hasValidImport) return;\n\n const file = state.file.opts.filename!;\n const dictionariesDir = state.opts.dictionariesDir;\n const dynamicDictionariesDir = state.opts.dynamicDictionariesDir;\n const fetchDictionariesDir = state.opts.fetchDictionariesDir;\n const imports: BabelTypes.ImportDeclaration[] = [];\n\n // Generate static JSON imports (getIntlayer always uses JSON dictionaries)\n for (const [key, ident] of state._newStaticImports!) {\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n 'static'\n );\n\n const importDeclarationNode = t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n );\n\n // Add 'type: json' attribute for JSON files\n importDeclarationNode.attributes = [\n t.importAttribute(t.identifier('type'), t.stringLiteral('json')),\n ];\n\n imports.push(importDeclarationNode);\n }\n\n // Generate dynamic/fetch imports (for useIntlayer when using dynamic/live helpers)\n for (const [key, ident] of state._newDynamicImports!) {\n const modeForThisIdent: 'dynamic' | 'live' = ident.name.endsWith(\n '_fetch'\n )\n ? 'live'\n : 'dynamic';\n\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n modeForThisIdent\n );\n imports.push(\n t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n )\n );\n }\n\n if (!imports.length) return;\n\n /* Keep \"use client\" / \"use server\" directives at the very top. */\n const bodyPaths = programPath.get(\n 'body'\n ) as NodePath<BabelTypes.Statement>[];\n let insertPos = 0;\n for (const stmtPath of bodyPaths) {\n const stmt = stmtPath.node;\n if (\n t.isExpressionStatement(stmt) &&\n t.isStringLiteral(stmt.expression) &&\n !stmt.expression.value.startsWith('import') &&\n !stmt.expression.value.startsWith('require')\n ) {\n insertPos += 1;\n } else {\n break;\n }\n }\n\n programPath.node.body.splice(insertPos, 0, ...imports);\n },\n },\n },\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"babel-plugin-intlayer-optimize.cjs","names":["helperMap: Record<string, string>","perCallMode: 'static' | 'dynamic' | 'live'","ident: BabelTypes.Identifier","imports: BabelTypes.ImportDeclaration[]"],"sources":["../../src/babel-plugin-intlayer-optimize.ts"],"sourcesContent":["import { dirname, join, relative } from 'node:path';\nimport type { NodePath, PluginObj, PluginPass } from '@babel/core';\nimport type * as BabelTypes from '@babel/types';\nimport { getFileHash } from '@intlayer/chokidar';\nimport { normalizePath } from '@intlayer/config';\n\n/* ────────────────────────────────────────── constants ───────────────────── */\n\nconst PACKAGE_LIST = [\n 'intlayer',\n '@intlayer/core',\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'svelte-intlayer',\n 'vue-intlayer',\n 'angular-intlayer',\n 'preact-intlayer',\n 'solid-intlayer',\n];\n\nconst CALLER_LIST = ['useIntlayer', 'getIntlayer'] as const;\n\n/**\n * Packages that support dynamic import\n */\nconst PACKAGE_LIST_DYNAMIC = [\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'preact-intlayer',\n 'vue-intlayer',\n 'solid-intlayer',\n 'svelte-intlayer',\n 'angular-intlayer',\n] as const;\n\nconst STATIC_IMPORT_FUNCTION = {\n getIntlayer: 'getDictionary',\n useIntlayer: 'useDictionary',\n} as const;\n\nconst DYNAMIC_IMPORT_FUNCTION = {\n useIntlayer: 'useDictionaryDynamic',\n} as const;\n\n/* ────────────────────────────────────────── types ───────────────────────── */\n\n/**\n * Options for the optimization Babel plugin\n */\nexport type OptimizePluginOptions = {\n /**\n * If false, the plugin will not apply any transformation.\n */\n optimize?: boolean;\n /**\n * The path to the dictionaries directory.\n */\n dictionariesDir: string;\n /**\n * The path to the dictionaries entry file.\n */\n dictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries entry file.\n */\n unmergedDictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries directory.\n */\n unmergedDictionariesDir: string;\n /**\n * The path to the dictionaries directory.\n */\n dynamicDictionariesDir: string;\n /**\n * The path to the dynamic dictionaries entry file.\n */\n dynamicDictionariesEntryPath: string;\n /**\n * The path to the fetch dictionaries directory.\n */\n fetchDictionariesDir: string;\n /**\n * The path to the fetch dictionaries entry file.\n */\n fetchDictionariesEntryPath: string;\n /**\n * If true, the plugin will replace the dictionary entry file with `export default {}`.\n */\n replaceDictionaryEntry: boolean;\n /**\n * If true, the plugin will activate the dynamic import of the dictionaries. It will rely on Suspense to load the dictionaries.\n */\n importMode: 'static' | 'dynamic' | 'live';\n /**\n * Activate the live sync of the dictionaries.\n * If `importMode` is `live`, the plugin will activate the live sync of the dictionaries.\n */\n liveSyncKeys: string[];\n /**\n * Files list to traverse.\n */\n filesList: string[];\n};\n\ntype State = PluginPass & {\n opts: OptimizePluginOptions;\n /** map key → generated ident (per-file) for static imports */\n _newStaticImports?: Map<string, BabelTypes.Identifier>;\n /** map key → generated ident (per-file) for dynamic imports */\n _newDynamicImports?: Map<string, BabelTypes.Identifier>;\n /** whether the current file imported *any* intlayer package */\n _hasValidImport?: boolean;\n /** whether the current file *is* the dictionaries entry file */\n _isDictEntry?: boolean;\n /** whether dynamic helpers are active for this file */\n _useDynamicHelpers?: boolean;\n /** whether the current file is included in the filesList */\n _isIncluded?: boolean;\n};\n\n/* ────────────────────────────────────────── helpers ─────────────────────── */\n\n/**\n * Replicates the xxHash64 → Base-62 algorithm used by the SWC version\n * and prefixes an underscore so the generated identifiers never collide\n * with user-defined ones.\n */\nconst makeIdent = (\n key: string,\n t: typeof BabelTypes\n): BabelTypes.Identifier => {\n const hash = getFileHash(key);\n return t.identifier(`_${hash}`);\n};\n\nconst computeImport = (\n fromFile: string,\n dictionariesDir: string,\n dynamicDictionariesDir: string,\n fetchDictionariesDir: string,\n key: string,\n importMode: 'static' | 'dynamic' | 'live'\n): string => {\n let relativePath = join(dictionariesDir, `${key}.json`);\n\n if (importMode === 'live') {\n relativePath = join(fetchDictionariesDir, `${key}.mjs`);\n }\n\n if (importMode === 'dynamic') {\n relativePath = join(dynamicDictionariesDir, `${key}.mjs`);\n }\n\n let rel = relative(dirname(fromFile), relativePath);\n\n // Fix windows path\n rel = normalizePath(rel);\n\n // Fix relative path\n if (!rel.startsWith('./') && !rel.startsWith('../')) {\n rel = `./${rel}`;\n }\n\n return rel;\n};\n\n/* ────────────────────────────────────────── plugin ──────────────────────── */\n\n/**\n * Babel plugin that transforms Intlayer function calls and auto-imports dictionaries.\n *\n * This plugin transforms calls to `useIntlayer()` and `getIntlayer()` from various Intlayer\n * packages into optimized dictionary access patterns, automatically importing the required\n * dictionary files based on the configured import mode.\n *\n * ## Supported Input Patterns\n *\n * The plugin recognizes these function calls:\n *\n * ```ts\n * // useIntlayer\n * import { useIntlayer } from 'react-intlayer';\n * import { useIntlayer } from 'next-intlayer';\n *\n * // getIntlayer\n * import { getIntlayer } from 'intlayer';\n *\n * // Usage\n * const content = useIntlayer('app');\n * const content = getIntlayer('app');\n * ```\n *\n * ## Transformation Modes\n *\n * ### Static Mode (default: `importMode = \"static\"`)\n *\n * Imports JSON dictionaries directly and replaces function calls with dictionary access:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import { useDictionary as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash);\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Dynamic Mode (`importMode = \"dynamic\"`)\n *\n * Uses dynamic dictionary loading with Suspense support:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Live Mode (`importMode = \"live\"`)\n *\n * Uses live-based dictionary loading for remote dictionaries:\n *\n * **Output if `liveSyncKeys` includes the key:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_fetch from '../../.intlayer/fetch_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_fetch, \"app\");\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * > If `liveSyncKeys` does not include the key, the plugin will fallback to the dynamic impor\n *\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n */\nexport const intlayerOptimizeBabelPlugin = (babel: {\n types: typeof BabelTypes;\n}): PluginObj<State> => {\n const { types: t } = babel;\n\n return {\n name: 'babel-plugin-intlayer-transform',\n\n pre() {\n this._newStaticImports = new Map();\n this._newDynamicImports = new Map();\n this._isIncluded = true;\n this._hasValidImport = false;\n this._isDictEntry = false;\n this._useDynamicHelpers = false;\n\n // If optimize is false, skip processing entirely\n if (this.opts.optimize === false) {\n this._isIncluded = false;\n return;\n }\n\n // If filesList is provided, check if current file is included\n const filename = this.file.opts.filename;\n if (this.opts.filesList && filename) {\n const isIncluded = this.opts.filesList.includes(filename);\n\n if (!isIncluded) {\n // Force _isIncluded to false to skip processing\n this._isIncluded = false;\n return;\n }\n }\n },\n\n visitor: {\n /* If this file *is* the dictionaries entry, short-circuit: export {} */\n Program: {\n enter(programPath, state) {\n // Safe access to filename\n const filename = state.file.opts.filename;\n\n // Check if this is the correct file to transform\n if (\n state.opts.replaceDictionaryEntry &&\n filename === state.opts.dictionariesEntryPath\n ) {\n state._isDictEntry = true;\n\n // Traverse the program to surgically remove/edit specific parts\n programPath.traverse({\n // Remove all import statements (cleaning up 'sssss.json')\n ImportDeclaration(path) {\n path.remove();\n },\n\n // Find the variable definition and empty the object\n VariableDeclarator(path) {\n // We look for: const x = { ... }\n if (t.isObjectExpression(path.node.init)) {\n // Set the object properties to an empty array: {}\n path.node.init.properties = [];\n }\n },\n });\n\n // (Optional) Stop other plugins from processing this file further if needed\n // programPath.stop();\n }\n },\n\n /**\n * After full traversal, process imports and call expressions, then inject the JSON dictionary imports.\n *\n * We do the transformation in Program.exit (via a manual traverse) rather than using\n * top-level ImportDeclaration/CallExpression visitors. This ensures that if another plugin\n * (like babel-plugin-intlayer-extract) adds new useIntlayer calls in its Program.exit,\n * we will see and transform them here because our Program.exit runs after theirs.\n */\n exit(programPath, state) {\n if (state._isDictEntry) return; // nothing else to do – already replaced\n if (!state._isIncluded) return; // early-out if file is not included\n\n // Manual traversal to process imports and call expressions\n // This runs AFTER all other plugins' visitors have completed\n programPath.traverse({\n /* Inspect every intlayer import */\n ImportDeclaration(path) {\n const src = path.node.source.value;\n if (!PACKAGE_LIST.includes(src)) return;\n\n // Mark that we do import from an intlayer package in this file\n state._hasValidImport = true;\n\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n // ⚠️ We now key off *imported* name, *not* local name.\n const importedName = t.isIdentifier(spec.imported)\n ? spec.imported.name\n : (spec.imported as BabelTypes.StringLiteral).value;\n\n const importMode = state.opts.importMode;\n // Determine whether this import should use the dynamic helpers.\n const shouldUseDynamicHelpers =\n (importMode === 'dynamic' || importMode === 'live') &&\n PACKAGE_LIST_DYNAMIC.includes(src as any);\n\n // Remember for later (CallExpression) whether we are using the dynamic helpers\n if (shouldUseDynamicHelpers) {\n state._useDynamicHelpers = true;\n }\n\n let helperMap: Record<string, string>;\n\n if (shouldUseDynamicHelpers) {\n // Use dynamic helpers for useIntlayer when dynamic mode is enabled\n helperMap = {\n ...STATIC_IMPORT_FUNCTION,\n ...DYNAMIC_IMPORT_FUNCTION,\n } as Record<string, string>;\n } else {\n // Use static helpers by default\n helperMap = STATIC_IMPORT_FUNCTION as Record<string, string>;\n }\n\n const newIdentifier = helperMap[importedName];\n\n // Only rewrite when we actually have a mapping for the imported\n // specifier (ignore unrelated named imports).\n if (newIdentifier) {\n // Keep the local alias intact (so calls remain `useIntlayer` /\n // `getIntlayer`), but rewrite the imported identifier so it\n // points to our helper implementation.\n spec.imported = t.identifier(newIdentifier);\n }\n }\n },\n\n /* Replace calls: useIntlayer(\"foo\") → useDictionary(_hash) or useDictionaryDynamic(_hash, \"foo\") */\n CallExpression(path) {\n const callee = path.node.callee;\n if (!t.isIdentifier(callee)) return;\n if (!CALLER_LIST.includes(callee.name as any)) return;\n\n // Ensure we ultimately emit helper imports for files that *invoke*\n // the hooks, even if they didn't import them directly (edge cases with\n // re-exports).\n state._hasValidImport = true;\n\n const arg = path.node.arguments[0];\n if (!arg || !t.isStringLiteral(arg)) return; // must be literal\n\n const key = arg.value;\n const importMode = state.opts.importMode;\n const isUseIntlayer = callee.name === 'useIntlayer';\n const useDynamicHelpers = Boolean(state._useDynamicHelpers);\n\n // Decide per-call mode: 'static' | 'dynamic' | 'live'\n let perCallMode: 'static' | 'dynamic' | 'live' = 'static';\n if (isUseIntlayer && useDynamicHelpers) {\n if (importMode === 'dynamic') {\n perCallMode = 'dynamic';\n } else if (importMode === 'live') {\n const liveKeys = state.opts.liveSyncKeys ?? [];\n perCallMode = liveKeys.includes(key) ? 'live' : 'dynamic';\n }\n }\n\n let ident: BabelTypes.Identifier;\n\n if (perCallMode === 'live') {\n // Use fetch dictionaries entry (live mode for selected keys)\n let dynamicIdent = state._newDynamicImports?.get(key);\n if (!dynamicIdent) {\n const hash = getFileHash(key);\n dynamicIdent = t.identifier(`_${hash}_fetch`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Helper: first argument is the dictionary entry, second is the key\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else if (perCallMode === 'dynamic') {\n // Use dynamic dictionaries entry\n let dynamicIdent = state._newDynamicImports?.get(key);\n if (!dynamicIdent) {\n // Create a unique identifier for dynamic imports by appending a suffix\n const hash = getFileHash(key);\n dynamicIdent = t.identifier(`_${hash}_dyn`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Dynamic helper: first argument is the dictionary, second is the key.\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else {\n // Use static imports for getIntlayer or useIntlayer when not using dynamic helpers\n let staticIdent = state._newStaticImports?.get(key);\n if (!staticIdent) {\n staticIdent = makeIdent(key, t);\n state._newStaticImports?.set(key, staticIdent);\n }\n ident = staticIdent;\n\n // Static helper (useDictionary / getDictionary): replace key with iden\n path.node.arguments[0] = t.identifier(ident.name);\n }\n },\n });\n\n // Early-out if we touched nothing\n if (!state._hasValidImport) return;\n\n const file = state.file.opts.filename!;\n const dictionariesDir = state.opts.dictionariesDir;\n const dynamicDictionariesDir = state.opts.dynamicDictionariesDir;\n const fetchDictionariesDir = state.opts.fetchDictionariesDir;\n const imports: BabelTypes.ImportDeclaration[] = [];\n\n // Generate static JSON imports (getIntlayer always uses JSON dictionaries)\n for (const [key, ident] of state._newStaticImports!) {\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n 'static'\n );\n\n const importDeclarationNode = t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n );\n\n // Add 'type: json' attribute for JSON files\n importDeclarationNode.attributes = [\n t.importAttribute(t.identifier('type'), t.stringLiteral('json')),\n ];\n\n imports.push(importDeclarationNode);\n }\n\n // Generate dynamic/fetch imports (for useIntlayer when using dynamic/live helpers)\n for (const [key, ident] of state._newDynamicImports!) {\n const modeForThisIdent: 'dynamic' | 'live' = ident.name.endsWith(\n '_fetch'\n )\n ? 'live'\n : 'dynamic';\n\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n modeForThisIdent\n );\n imports.push(\n t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n )\n );\n }\n\n if (!imports.length) return;\n\n /* Keep \"use client\" / \"use server\" directives at the very top. */\n const bodyPaths = programPath.get(\n 'body'\n ) as NodePath<BabelTypes.Statement>[];\n let insertPos = 0;\n for (const stmtPath of bodyPaths) {\n const stmt = stmtPath.node;\n if (\n t.isExpressionStatement(stmt) &&\n t.isStringLiteral(stmt.expression) &&\n !stmt.expression.value.startsWith('import') &&\n !stmt.expression.value.startsWith('require')\n ) {\n insertPos += 1;\n } else {\n break;\n }\n }\n\n programPath.node.body.splice(insertPos, 0, ...imports);\n },\n },\n },\n };\n};\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
2
  let node_path = require("node:path");
3
- let __intlayer_chokidar = require("@intlayer/chokidar");
4
- let __intlayer_config = require("@intlayer/config");
3
+ let _intlayer_chokidar = require("@intlayer/chokidar");
4
+ let _intlayer_config = require("@intlayer/config");
5
5
  let node_fs = require("node:fs");
6
6
  let node_fs_promises = require("node:fs/promises");
7
7
 
@@ -12,7 +12,7 @@ let node_fs_promises = require("node:fs/promises");
12
12
  * to write dictionaries to the filesystem.
13
13
  */
14
14
  const getExtractPluginOptions = () => {
15
- const config = (0, __intlayer_config.getConfiguration)();
15
+ const config = (0, _intlayer_config.getConfiguration)();
16
16
  const { baseDir } = config.content;
17
17
  const compilerDir = (0, node_path.join)(baseDir, config.compiler?.outputDir ?? "compiler");
18
18
  /**
@@ -60,8 +60,8 @@ const getExtractPluginOptions = () => {
60
60
  content: mergeWithExistingDictionary(content, await readExistingDictionary((0, node_path.join)(compilerDir, `${dictionaryKey}.content.json`)), locale),
61
61
  filePath: (0, node_path.join)((0, node_path.relative)(baseDir, compilerDir), `${dictionaryKey}.content.json`)
62
62
  };
63
- const writeResult = await (0, __intlayer_chokidar.writeContentDeclaration)(dictionary, config, { newDictionariesPath: (0, node_path.relative)(baseDir, compilerDir) });
64
- await (0, __intlayer_chokidar.buildDictionary)([{
63
+ const writeResult = await (0, _intlayer_chokidar.writeContentDeclaration)(dictionary, config, { newDictionariesPath: (0, node_path.relative)(baseDir, compilerDir) });
64
+ await (0, _intlayer_chokidar.buildDictionary)([{
65
65
  ...dictionary,
66
66
  filePath: (0, node_path.relative)(baseDir, writeResult.path)
67
67
  }], config);
@@ -1 +1 @@
1
- {"version":3,"file":"getExtractPluginOptions.cjs","names":["mergedContent: DictionaryContentMap","dictionary: Dictionary"],"sources":["../../src/getExtractPluginOptions.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport { buildDictionary, writeContentDeclaration } from '@intlayer/chokidar';\nimport { getConfiguration } from '@intlayer/config';\nimport type { Dictionary } from '@intlayer/types';\nimport type {\n ExtractPluginOptions,\n ExtractResult,\n} from './babel-plugin-intlayer-extract';\n\n/**\n * Translation node structure used in dictionaries\n */\ntype TranslationNode = {\n nodeType: 'translation';\n translation: Record<string, string>;\n};\n\n/**\n * Dictionary content structure - map of keys to translation nodes\n */\ntype DictionaryContentMap = Record<string, TranslationNode>;\n\n/**\n * Get the options for the Intlayer Babel extraction plugin\n * This function loads the Intlayer configuration and sets up the onExtract callback\n * to write dictionaries to the filesystem.\n */\nexport const getExtractPluginOptions = (): ExtractPluginOptions => {\n const config = getConfiguration();\n const { baseDir } = config.content;\n const compilerDir = join(baseDir, config.compiler?.outputDir ?? 'compiler');\n\n /**\n * Read existing dictionary file if it exists\n */\n const readExistingDictionary = async (\n dictionaryPath: string\n ): Promise<Dictionary | null> => {\n try {\n if (!existsSync(dictionaryPath)) {\n return null;\n }\n const content = await readFile(dictionaryPath, 'utf-8');\n return JSON.parse(content) as Dictionary;\n } catch {\n return null;\n }\n };\n\n /**\n * Merge extracted content with existing dictionary, preserving translations.\n * - Keys in extracted but not in existing: added with default locale only\n * - Keys in both: preserve existing translations, update default locale value\n * - Keys in existing but not in extracted: removed (no longer in source)\n */\n const mergeWithExistingDictionary = (\n extractedContent: Record<string, string>,\n existingDictionary: Dictionary | null,\n defaultLocale: string\n ): DictionaryContentMap => {\n const mergedContent: DictionaryContentMap = {};\n const existingContent = existingDictionary?.content as\n | DictionaryContentMap\n | undefined;\n\n for (const [key, value] of Object.entries(extractedContent)) {\n const existingEntry = existingContent?.[key];\n\n if (\n existingEntry &&\n existingEntry.nodeType === 'translation' &&\n existingEntry.translation\n ) {\n // Key exists in both - preserve existing translations, update default locale\n mergedContent[key] = {\n nodeType: 'translation',\n translation: {\n ...existingEntry.translation,\n [defaultLocale]: value,\n },\n };\n } else {\n // New key - add with default locale only\n mergedContent[key] = {\n nodeType: 'translation',\n translation: {\n [defaultLocale]: value,\n },\n };\n }\n }\n\n return mergedContent;\n };\n\n const handleExtractedContent = async (result: ExtractResult) => {\n const { dictionaryKey, content, locale } = result;\n\n try {\n const dictionaryPath = join(compilerDir, `${dictionaryKey}.content.json`);\n\n // Read existing dictionary to preserve translations\n const existingDictionary = await readExistingDictionary(dictionaryPath);\n\n // Merge extracted content with existing translations\n const mergedContent = mergeWithExistingDictionary(\n content,\n existingDictionary,\n locale\n );\n\n const dictionary: Dictionary = {\n key: dictionaryKey,\n content: mergedContent,\n filePath: join(\n relative(baseDir, compilerDir),\n `${dictionaryKey}.content.json`\n ),\n };\n\n const writeResult = await writeContentDeclaration(dictionary, config, {\n newDictionariesPath: relative(baseDir, compilerDir),\n });\n\n // Build the dictionary immediately\n const dictionaryToBuild: Dictionary = {\n ...dictionary,\n filePath: relative(baseDir, writeResult.path),\n };\n\n await buildDictionary([dictionaryToBuild], config);\n } catch (error) {\n console.error(\n `[intlayer] Failed to process extracted content for ${dictionaryKey}:`,\n error\n );\n }\n };\n\n return {\n defaultLocale: config.internationalization.defaultLocale,\n // filesList can be passed if needed, but usually handled by include/exclude in build tool\n onExtract: handleExtractedContent,\n };\n};\n"],"mappings":";;;;;;;;;;;;;AA6BA,MAAa,gCAAsD;CACjE,MAAM,kDAA2B;CACjC,MAAM,EAAE,YAAY,OAAO;CAC3B,MAAM,kCAAmB,SAAS,OAAO,UAAU,aAAa,WAAW;;;;CAK3E,MAAM,yBAAyB,OAC7B,mBAC+B;AAC/B,MAAI;AACF,OAAI,yBAAY,eAAe,CAC7B,QAAO;GAET,MAAM,UAAU,qCAAe,gBAAgB,QAAQ;AACvD,UAAO,KAAK,MAAM,QAAQ;UACpB;AACN,UAAO;;;;;;;;;CAUX,MAAM,+BACJ,kBACA,oBACA,kBACyB;EACzB,MAAMA,gBAAsC,EAAE;EAC9C,MAAM,kBAAkB,oBAAoB;AAI5C,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,iBAAiB,EAAE;GAC3D,MAAM,gBAAgB,kBAAkB;AAExC,OACE,iBACA,cAAc,aAAa,iBAC3B,cAAc,YAGd,eAAc,OAAO;IACnB,UAAU;IACV,aAAa;KACX,GAAG,cAAc;MAChB,gBAAgB;KAClB;IACF;OAGD,eAAc,OAAO;IACnB,UAAU;IACV,aAAa,GACV,gBAAgB,OAClB;IACF;;AAIL,SAAO;;CAGT,MAAM,yBAAyB,OAAO,WAA0B;EAC9D,MAAM,EAAE,eAAe,SAAS,WAAW;AAE3C,MAAI;GAaF,MAAMC,aAAyB;IAC7B,KAAK;IACL,SARoB,4BACpB,SAJyB,MAAM,2CAHL,aAAa,GAAG,cAAc,eAAe,CAGF,EAMrE,OACD;IAKC,sDACW,SAAS,YAAY,EAC9B,GAAG,cAAc,eAClB;IACF;GAED,MAAM,cAAc,uDAA8B,YAAY,QAAQ,EACpE,6CAA8B,SAAS,YAAY,EACpD,CAAC;AAQF,kDAAsB,CALgB;IACpC,GAAG;IACH,kCAAmB,SAAS,YAAY,KAAK;IAC9C,CAEwC,EAAE,OAAO;WAC3C,OAAO;AACd,WAAQ,MACN,sDAAsD,cAAc,IACpE,MACD;;;AAIL,QAAO;EACL,eAAe,OAAO,qBAAqB;EAE3C,WAAW;EACZ"}
1
+ {"version":3,"file":"getExtractPluginOptions.cjs","names":["mergedContent: DictionaryContentMap","dictionary: Dictionary"],"sources":["../../src/getExtractPluginOptions.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport { buildDictionary, writeContentDeclaration } from '@intlayer/chokidar';\nimport { getConfiguration } from '@intlayer/config';\nimport type { Dictionary } from '@intlayer/types';\nimport type {\n ExtractPluginOptions,\n ExtractResult,\n} from './babel-plugin-intlayer-extract';\n\n/**\n * Translation node structure used in dictionaries\n */\ntype TranslationNode = {\n nodeType: 'translation';\n translation: Record<string, string>;\n};\n\n/**\n * Dictionary content structure - map of keys to translation nodes\n */\ntype DictionaryContentMap = Record<string, TranslationNode>;\n\n/**\n * Get the options for the Intlayer Babel extraction plugin\n * This function loads the Intlayer configuration and sets up the onExtract callback\n * to write dictionaries to the filesystem.\n */\nexport const getExtractPluginOptions = (): ExtractPluginOptions => {\n const config = getConfiguration();\n const { baseDir } = config.content;\n const compilerDir = join(baseDir, config.compiler?.outputDir ?? 'compiler');\n\n /**\n * Read existing dictionary file if it exists\n */\n const readExistingDictionary = async (\n dictionaryPath: string\n ): Promise<Dictionary | null> => {\n try {\n if (!existsSync(dictionaryPath)) {\n return null;\n }\n const content = await readFile(dictionaryPath, 'utf-8');\n return JSON.parse(content) as Dictionary;\n } catch {\n return null;\n }\n };\n\n /**\n * Merge extracted content with existing dictionary, preserving translations.\n * - Keys in extracted but not in existing: added with default locale only\n * - Keys in both: preserve existing translations, update default locale value\n * - Keys in existing but not in extracted: removed (no longer in source)\n */\n const mergeWithExistingDictionary = (\n extractedContent: Record<string, string>,\n existingDictionary: Dictionary | null,\n defaultLocale: string\n ): DictionaryContentMap => {\n const mergedContent: DictionaryContentMap = {};\n const existingContent = existingDictionary?.content as\n | DictionaryContentMap\n | undefined;\n\n for (const [key, value] of Object.entries(extractedContent)) {\n const existingEntry = existingContent?.[key];\n\n if (\n existingEntry &&\n existingEntry.nodeType === 'translation' &&\n existingEntry.translation\n ) {\n // Key exists in both - preserve existing translations, update default locale\n mergedContent[key] = {\n nodeType: 'translation',\n translation: {\n ...existingEntry.translation,\n [defaultLocale]: value,\n },\n };\n } else {\n // New key - add with default locale only\n mergedContent[key] = {\n nodeType: 'translation',\n translation: {\n [defaultLocale]: value,\n },\n };\n }\n }\n\n return mergedContent;\n };\n\n const handleExtractedContent = async (result: ExtractResult) => {\n const { dictionaryKey, content, locale } = result;\n\n try {\n const dictionaryPath = join(compilerDir, `${dictionaryKey}.content.json`);\n\n // Read existing dictionary to preserve translations\n const existingDictionary = await readExistingDictionary(dictionaryPath);\n\n // Merge extracted content with existing translations\n const mergedContent = mergeWithExistingDictionary(\n content,\n existingDictionary,\n locale\n );\n\n const dictionary: Dictionary = {\n key: dictionaryKey,\n content: mergedContent,\n filePath: join(\n relative(baseDir, compilerDir),\n `${dictionaryKey}.content.json`\n ),\n };\n\n const writeResult = await writeContentDeclaration(dictionary, config, {\n newDictionariesPath: relative(baseDir, compilerDir),\n });\n\n // Build the dictionary immediately\n const dictionaryToBuild: Dictionary = {\n ...dictionary,\n filePath: relative(baseDir, writeResult.path),\n };\n\n await buildDictionary([dictionaryToBuild], config);\n } catch (error) {\n console.error(\n `[intlayer] Failed to process extracted content for ${dictionaryKey}:`,\n error\n );\n }\n };\n\n return {\n defaultLocale: config.internationalization.defaultLocale,\n // filesList can be passed if needed, but usually handled by include/exclude in build tool\n onExtract: handleExtractedContent,\n };\n};\n"],"mappings":";;;;;;;;;;;;;AA6BA,MAAa,gCAAsD;CACjE,MAAM,iDAA2B;CACjC,MAAM,EAAE,YAAY,OAAO;CAC3B,MAAM,kCAAmB,SAAS,OAAO,UAAU,aAAa,WAAW;;;;CAK3E,MAAM,yBAAyB,OAC7B,mBAC+B;AAC/B,MAAI;AACF,OAAI,yBAAY,eAAe,CAC7B,QAAO;GAET,MAAM,UAAU,qCAAe,gBAAgB,QAAQ;AACvD,UAAO,KAAK,MAAM,QAAQ;UACpB;AACN,UAAO;;;;;;;;;CAUX,MAAM,+BACJ,kBACA,oBACA,kBACyB;EACzB,MAAMA,gBAAsC,EAAE;EAC9C,MAAM,kBAAkB,oBAAoB;AAI5C,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,iBAAiB,EAAE;GAC3D,MAAM,gBAAgB,kBAAkB;AAExC,OACE,iBACA,cAAc,aAAa,iBAC3B,cAAc,YAGd,eAAc,OAAO;IACnB,UAAU;IACV,aAAa;KACX,GAAG,cAAc;MAChB,gBAAgB;KAClB;IACF;OAGD,eAAc,OAAO;IACnB,UAAU;IACV,aAAa,GACV,gBAAgB,OAClB;IACF;;AAIL,SAAO;;CAGT,MAAM,yBAAyB,OAAO,WAA0B;EAC9D,MAAM,EAAE,eAAe,SAAS,WAAW;AAE3C,MAAI;GAaF,MAAMC,aAAyB;IAC7B,KAAK;IACL,SARoB,4BACpB,SAJyB,MAAM,2CAHL,aAAa,GAAG,cAAc,eAAe,CAGF,EAMrE,OACD;IAKC,sDACW,SAAS,YAAY,EAC9B,GAAG,cAAc,eAClB;IACF;GAED,MAAM,cAAc,sDAA8B,YAAY,QAAQ,EACpE,6CAA8B,SAAS,YAAY,EACpD,CAAC;AAQF,iDAAsB,CALgB;IACpC,GAAG;IACH,kCAAmB,SAAS,YAAY,KAAK;IAC9C,CAEwC,EAAE,OAAO;WAC3C,OAAO;AACd,WAAQ,MACN,sDAAsD,cAAc,IACpE,MACD;;;AAIL,QAAO;EACL,eAAe,OAAO,qBAAqB;EAE3C,WAAW;EACZ"}
@@ -1,6 +1,6 @@
1
1
  const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
2
  let node_path = require("node:path");
3
- let __intlayer_config = require("@intlayer/config");
3
+ let _intlayer_config = require("@intlayer/config");
4
4
  let fast_glob = require("fast-glob");
5
5
  fast_glob = require_rolldown_runtime.__toESM(fast_glob);
6
6
 
@@ -24,7 +24,7 @@ const loadDictionaries = (config) => {
24
24
  */
25
25
  const getOptimizePluginOptions = (params) => {
26
26
  const { configOptions, dictionaries: providedDictionaries, overrides } = params ?? {};
27
- const config = (0, __intlayer_config.getConfiguration)(configOptions);
27
+ const config = (0, _intlayer_config.getConfiguration)(configOptions);
28
28
  const { mainDir, baseDir, dictionariesDir, unmergedDictionariesDir, dynamicDictionariesDir, fetchDictionariesDir } = config.content;
29
29
  const { importMode, traversePattern, optimize } = config.build;
30
30
  const filesListPattern = fast_glob.default.sync(traversePattern, { cwd: baseDir }).map((file) => {
@@ -1 +1 @@
1
- {"version":3,"file":"getOptimizePluginOptions.cjs","names":["fg"],"sources":["../../src/getOptimizePluginOptions.ts"],"sourcesContent":["import { isAbsolute, join } from 'node:path';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config';\nimport type { Dictionary, IntlayerConfig } from '@intlayer/types';\nimport fg from 'fast-glob';\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 baseDir,\n dictionariesDir,\n unmergedDictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n } = config.content;\n const { importMode, traversePattern, optimize } = config.build;\n\n // Build files list from traverse pattern\n const filesListPattern = fg\n .sync(traversePattern, {\n cwd: baseDir,\n })\n .map((file) => {\n if (isAbsolute(file)) {\n return file;\n }\n return join(baseDir, file);\n });\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 liveSyncKeys = dictionaries\n .filter((dictionary) => dictionary.live)\n .map((dictionary) => dictionary.key);\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 liveSyncKeys,\n filesList,\n ...overrides,\n };\n};\n"],"mappings":";;;;;;;;;;AA2BA,MAAM,oBAAoB,WAAyC;AACjE,KAAI;EAGF,MAAM,EAAE,oBAAoB,QAAQ,+BAA+B;EACnE,MAAM,qBAAqB,gBAAgB,OAAO;AAIlD,SAAO,OAAO,OAAO,mBAAmB;SAClC;AAEN,SAAO,EAAE;;;;;;;;AASb,MAAa,4BACX,WAC0B;CAC1B,MAAM,EACJ,eACA,cAAc,sBACd,cACE,UAAU,EAAE;CAEhB,MAAM,iDAA0B,cAAc;CAC9C,MAAM,EACJ,SACA,SACA,iBACA,yBACA,wBACA,yBACE,OAAO;CACX,MAAM,EAAE,YAAY,iBAAiB,aAAa,OAAO;CAGzD,MAAM,mBAAmBA,kBACtB,KAAK,iBAAiB,EACrB,KAAK,SACN,CAAC,CACD,KAAK,SAAS;AACb,gCAAe,KAAK,CAClB,QAAO;AAET,6BAAY,SAAS,KAAK;GAC1B;CAEJ,MAAM,4CAA6B,SAAS,mBAAmB;CAC/D,MAAM,oDACJ,SACA,4BACD;CACD,MAAM,mDACJ,SACA,2BACD;CACD,MAAM,iDAAkC,SAAS,yBAAyB;CAE1E,MAAM,YAAY;EAChB,GAAG;EACH;EACA;EACD;AASD,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,wBAAwB;EACxB;EACA,eAlBmB,wBAAwB,iBAAiB,OAAO,EAGlE,QAAQ,eAAe,WAAW,KAAK,CACvC,KAAK,eAAe,WAAW,IAAI;EAepC;EACA,GAAG;EACJ"}
1
+ {"version":3,"file":"getOptimizePluginOptions.cjs","names":["fg"],"sources":["../../src/getOptimizePluginOptions.ts"],"sourcesContent":["import { isAbsolute, join } from 'node:path';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config';\nimport type { Dictionary, IntlayerConfig } from '@intlayer/types';\nimport fg from 'fast-glob';\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 baseDir,\n dictionariesDir,\n unmergedDictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n } = config.content;\n const { importMode, traversePattern, optimize } = config.build;\n\n // Build files list from traverse pattern\n const filesListPattern = fg\n .sync(traversePattern, {\n cwd: baseDir,\n })\n .map((file) => {\n if (isAbsolute(file)) {\n return file;\n }\n return join(baseDir, file);\n });\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 liveSyncKeys = dictionaries\n .filter((dictionary) => dictionary.live)\n .map((dictionary) => dictionary.key);\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 liveSyncKeys,\n filesList,\n ...overrides,\n };\n};\n"],"mappings":";;;;;;;;;;AA2BA,MAAM,oBAAoB,WAAyC;AACjE,KAAI;EAGF,MAAM,EAAE,oBAAoB,QAAQ,+BAA+B;EACnE,MAAM,qBAAqB,gBAAgB,OAAO;AAIlD,SAAO,OAAO,OAAO,mBAAmB;SAClC;AAEN,SAAO,EAAE;;;;;;;;AASb,MAAa,4BACX,WAC0B;CAC1B,MAAM,EACJ,eACA,cAAc,sBACd,cACE,UAAU,EAAE;CAEhB,MAAM,gDAA0B,cAAc;CAC9C,MAAM,EACJ,SACA,SACA,iBACA,yBACA,wBACA,yBACE,OAAO;CACX,MAAM,EAAE,YAAY,iBAAiB,aAAa,OAAO;CAGzD,MAAM,mBAAmBA,kBACtB,KAAK,iBAAiB,EACrB,KAAK,SACN,CAAC,CACD,KAAK,SAAS;AACb,gCAAe,KAAK,CAClB,QAAO;AAET,6BAAY,SAAS,KAAK;GAC1B;CAEJ,MAAM,4CAA6B,SAAS,mBAAmB;CAC/D,MAAM,oDACJ,SACA,4BACD;CACD,MAAM,mDACJ,SACA,2BACD;CACD,MAAM,iDAAkC,SAAS,yBAAyB;CAE1E,MAAM,YAAY;EAChB,GAAG;EACH;EACA;EACD;AASD,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,wBAAwB;EACxB;EACA,eAlBmB,wBAAwB,iBAAiB,OAAO,EAGlE,QAAQ,eAAe,WAAW,KAAK,CACvC,KAAK,eAAe,WAAW,IAAI;EAepC;EACA,GAAG;EACJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/babel",
3
- "version": "7.5.0-canary.1",
3
+ "version": "7.5.0",
4
4
  "private": false,
5
5
  "description": "A Babel plugin for Intlayer that transforms declaration files and provides internationalization features during the build process according to the Intlayer configuration.",
6
6
  "keywords": [
@@ -81,28 +81,28 @@
81
81
  "@babel/parser": "7.1.5",
82
82
  "@babel/traverse": "7.28.0",
83
83
  "@babel/types": "7.28.4",
84
- "@intlayer/chokidar": "7.5.0-canary.1",
85
- "@intlayer/config": "7.5.0-canary.1",
86
- "@intlayer/types": "7.5.0-canary.1",
84
+ "@intlayer/chokidar": "7.5.0",
85
+ "@intlayer/config": "7.5.0",
86
+ "@intlayer/types": "7.5.0",
87
87
  "@types/babel__core": "7.20.5",
88
88
  "@types/babel__generator": "7.27.0",
89
89
  "@types/babel__traverse": "7.28.0",
90
90
  "fast-glob": "3.3.3"
91
91
  },
92
92
  "devDependencies": {
93
- "@intlayer/dictionaries-entry": "7.5.0-canary.1",
93
+ "@intlayer/dictionaries-entry": "7.5.0",
94
94
  "@types/crypto-js": "4.2.2",
95
- "@types/node": "25.0.2",
95
+ "@types/node": "25.0.3",
96
96
  "@utils/ts-config": "1.0.4",
97
97
  "@utils/ts-config-types": "1.0.4",
98
98
  "@utils/tsdown-config": "1.0.4",
99
99
  "rimraf": "6.1.2",
100
- "tsdown": "0.18.0",
100
+ "tsdown": "0.18.1",
101
101
  "typescript": "5.9.3",
102
102
  "vitest": "4.0.16"
103
103
  },
104
104
  "peerDependencies": {
105
- "@intlayer/dictionaries-entry": "7.5.0-canary.1"
105
+ "@intlayer/dictionaries-entry": "7.5.0"
106
106
  },
107
107
  "peerDependenciesMeta": {
108
108
  "@intlayer/dictionaries-entry": {