@intlayer/vue-compiler 9.7.3 → 9.8.0-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,6 +5,7 @@ _vue_compiler_sfc = require_runtime.__toESM(_vue_compiler_sfc);
5
5
  let node_fs = require("node:fs");
6
6
  let _babel_core = require("@babel/core");
7
7
  let _intlayer_config_defaultValues = require("@intlayer/config/defaultValues");
8
+ let _intlayer_config_extract = require("@intlayer/config/extract");
8
9
  let magic_string = require("magic-string");
9
10
  magic_string = require_runtime.__toESM(magic_string);
10
11
 
@@ -73,6 +74,8 @@ const intlayerVueExtract = (code, filename, options = {}) => {
73
74
  const { defaultLocale = _intlayer_config_defaultValues.DEFAULT_LOCALE, packageName = "vue-intlayer", filesList, shouldExtract, onExtract, dictionaryKey: dictionaryKeyOption, attributesToExtract = [], extractDictionaryKeyFromPath, generateKey } = options;
74
75
  if (!shouldProcessFile(filename, filesList)) return null;
75
76
  if (!filename.endsWith(".vue")) return null;
77
+ const ignoreDirectives = (0, _intlayer_config_extract.getExtractionIgnoreDirectives)(code);
78
+ if (ignoreDirectives.isFileIgnored) return null;
76
79
  let parseVue;
77
80
  try {
78
81
  parseVue = _vue_compiler_sfc.default.parse;
@@ -91,10 +94,16 @@ const intlayerVueExtract = (code, filename, options = {}) => {
91
94
  const isDestructured = existingCallInfo?.isDestructured ?? false;
92
95
  const varName = existingCallInfo?.variableName ?? "content";
93
96
  if (sfc.descriptor.template) {
94
- const walkVueAst = (node) => {
97
+ /**
98
+ * Walks the template; `isParentIgnored` is true when an ignore directive
99
+ * covers the opening tag of the enclosing element.
100
+ */
101
+ const walkVueAst = (node, isParentIgnored = false) => {
102
+ const isNodeIgnored = ignoreDirectives.isOffsetIgnored(node.loc.start.offset);
95
103
  if (node.type === NODE_TYPES.TEXT) {
96
104
  const text = node.content ?? "";
97
- if (shouldExtract?.(text) && generateKey) {
105
+ const leadingWhitespaceLength = text.length - text.trimStart().length;
106
+ if (!(isParentIgnored || ignoreDirectives.isOffsetIgnored(node.loc.start.offset + leadingWhitespaceLength)) && shouldExtract?.(text) && generateKey) {
98
107
  const key = generateKey(text, existingKeys);
99
108
  existingKeys.add(key);
100
109
  const ref = isDestructured ? key : `${varName}.${key}`;
@@ -108,7 +117,9 @@ const intlayerVueExtract = (code, filename, options = {}) => {
108
117
  }
109
118
  } else if (node.type === NODE_TYPES.ELEMENT) {
110
119
  const children = node.children ?? [];
111
- if (children.length > 0 && children.some((c) => c.type === NODE_TYPES.INTERPOLATION)) {
120
+ /** Attributes on an ignored tag or line stay untouched. */
121
+ const isPropIgnored = (prop) => isNodeIgnored || ignoreDirectives.isOffsetIgnored(prop.loc.start.offset);
122
+ if (!isNodeIgnored && (children.length ?? 0) > 0 && children.some((child) => child.type === NODE_TYPES.INTERPOLATION)) {
112
123
  const parts = [];
113
124
  let hasSignificantText = false;
114
125
  let isValid = true;
@@ -143,14 +154,14 @@ const intlayerVueExtract = (code, filename, options = {}) => {
143
154
  const firstChild = children[0];
144
155
  const lastChild = children[children.length - 1];
145
156
  replacements.push({
146
- start: firstChild.loc.start.offset,
147
- end: lastChild.loc.end.offset,
157
+ start: firstChild?.loc.start.offset ?? 0,
158
+ end: lastChild?.loc.end.offset ?? 0,
148
159
  replacement,
149
160
  key,
150
161
  value: cleanString
151
162
  });
152
163
  node.props?.forEach((prop) => {
153
- if (prop.type === NODE_TYPES.ATTRIBUTE && attributesToExtract.includes(prop.name) && prop.value) {
164
+ if (prop.type === NODE_TYPES.ATTRIBUTE && attributesToExtract.includes(prop.name) && prop.value && !isPropIgnored(prop)) {
154
165
  const text = prop.value.content;
155
166
  if (shouldExtract?.(text) && generateKey) {
156
167
  const propKey = generateKey(text, existingKeys);
@@ -171,7 +182,7 @@ const intlayerVueExtract = (code, filename, options = {}) => {
171
182
  }
172
183
  }
173
184
  node.props?.forEach((prop) => {
174
- if (prop.type === NODE_TYPES.ATTRIBUTE && attributesToExtract.includes(prop.name) && prop.value) {
185
+ if (prop.type === NODE_TYPES.ATTRIBUTE && attributesToExtract.includes(prop.name) && prop.value && !isPropIgnored(prop)) {
175
186
  const text = prop.value.content;
176
187
  if (shouldExtract?.(text) && generateKey) {
177
188
  const key = generateKey(text, existingKeys);
@@ -188,7 +199,7 @@ const intlayerVueExtract = (code, filename, options = {}) => {
188
199
  }
189
200
  });
190
201
  }
191
- if (node.children) node.children.forEach(walkVueAst);
202
+ if (node.children) node.children.forEach((child) => walkVueAst(child, node.type === NODE_TYPES.ELEMENT ? isNodeIgnored : isParentIgnored));
192
203
  };
193
204
  walkVueAst(sfc.descriptor.template.ast);
194
205
  }
@@ -217,6 +228,7 @@ const intlayerVueExtract = (code, filename, options = {}) => {
217
228
  if (_babel_core.types.isIdentifier(callee) && callee.name === "require") return;
218
229
  }
219
230
  const text = path.node.value;
231
+ if (path.node.start != null && ignoreDirectives.isOffsetIgnored(offset + path.node.start)) return;
220
232
  if (shouldExtract?.(text) && generateKey) {
221
233
  const key = generateKey(text, existingKeys);
222
234
  existingKeys.add(key);
@@ -1 +1 @@
1
- {"version":3,"file":"vue-intlayer-extract.cjs","names":["babelParse","t","DEFAULT_LOCALE","vueSfc","MagicString","readFileSync"],"sources":["../../src/vue-intlayer-extract.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { parseSync as babelParse, types as t, traverse } from '@babel/core';\nimport { DEFAULT_LOCALE } from '@intlayer/config/defaultValues';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport vueSfc from '@vue/compiler-sfc';\nimport MagicString from 'magic-string';\n\ntype ExistingCallInfo = {\n isDestructured: boolean;\n existingDestructuredKeys: string[];\n /** The variable name used to store the call result (e.g. `t` in `const t = useIntlayer(...)`) */\n variableName: string;\n /** Absolute position of `}` in the full file — only valid when `isDestructured` */\n closingBraceAbsolutePos: number;\n /** Absolute position of end of last property — only valid when `isDestructured` */\n lastPropAbsoluteEnd: number;\n} | null;\n\n/**\n * Detects whether the script block already contains a `useIntlayer` /\n * `getIntlayer` call and, if so, whether its result is destructured.\n *\n * @param scriptText Raw text of the script block content.\n * @param absoluteOffset Byte offset of `scriptText[0]` in the full SFC source.\n */\nconst detectExistingIntlayerCall = (\n scriptText: string,\n absoluteOffset: number\n): ExistingCallInfo => {\n let info: ExistingCallInfo = null;\n\n try {\n const ast = babelParse(scriptText, {\n configFile: false,\n babelrc: false,\n parserOpts: { sourceType: 'module', plugins: ['typescript', 'jsx'] },\n });\n\n if (!ast) return null;\n\n traverse(ast, {\n CallExpression(path: any) {\n const callee = path.node.callee;\n\n if (\n !t.isIdentifier(callee) ||\n (callee.name !== 'useIntlayer' && callee.name !== 'getIntlayer')\n )\n return;\n\n const parent = path.parent;\n\n if (t.isVariableDeclarator(parent) && t.isObjectPattern(parent.id)) {\n const properties = parent.id.properties;\n const existingDestructuredKeys = properties\n .filter(\n (property: any): property is typeof t.objectProperty =>\n t.isObjectProperty(property) && t.isIdentifier(property.key)\n )\n .map((property: any) => (property.key as any).name as string);\n const lastProp = properties[properties.length - 1];\n\n info = {\n isDestructured: true,\n variableName: 'content',\n existingDestructuredKeys,\n closingBraceAbsolutePos: absoluteOffset + (parent.id.end! - 1),\n lastPropAbsoluteEnd: absoluteOffset + lastProp.end!,\n };\n } else {\n const variableName =\n t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)\n ? parent.id.name\n : 'content';\n\n info = {\n isDestructured: false,\n variableName,\n existingDestructuredKeys: [],\n closingBraceAbsolutePos: -1,\n lastPropAbsoluteEnd: -1,\n };\n }\n\n path.stop();\n },\n });\n } catch {\n // Silently ignore parse failures — fall back to no-info\n }\n\n return info;\n};\n\nexport type ExtractedContent = Record<string, string>;\n\nexport type ExtractResult = {\n dictionaryKey: string;\n filePath: string;\n content: ExtractedContent;\n locale: Locale;\n};\n\nexport type ExtractPluginOptions = {\n defaultLocale?: Locale;\n packageName?: string;\n filesList?: string[];\n shouldExtract?: (text: string) => boolean;\n onExtract?: (result: ExtractResult) => void;\n dictionaryKey?: string;\n attributesToExtract?: readonly string[];\n extractDictionaryKeyFromPath?: (path: string) => string;\n generateKey?: (text: string, existingKeys: Set<string>) => string;\n};\n\ntype Replacement = {\n start: number;\n end: number;\n replacement: string;\n key: string;\n value: string;\n};\n\nexport const shouldProcessFile = (\n filename: string | undefined,\n filesList?: string[]\n): boolean => {\n if (!filename) return false;\n if (!filesList || filesList.length === 0) return true;\n\n const normalizedFilename = filename.replace(/\\\\/g, '/');\n return filesList.some((f) => {\n const normalizedF = f.replace(/\\\\/g, '/');\n return normalizedF === normalizedFilename;\n });\n};\n\ntype VueParseResult = {\n descriptor: {\n template?: {\n ast: VueAstNode;\n loc: { start: { offset: number }; end: { offset: number } };\n };\n script?: {\n content: string;\n loc: { start: { offset: number }; end: { offset: number } };\n };\n scriptSetup?: {\n content: string;\n loc: { start: { offset: number }; end: { offset: number } };\n };\n };\n};\n\ntype VueAstNode = {\n type: number;\n content?: string;\n children?: VueAstNode[];\n props?: VueAstProp[];\n loc: { start: { offset: number }; end: { offset: number } };\n};\n\ntype VueAstProp = {\n type: number;\n name: string;\n value?: { content: string };\n loc: { start: { offset: number }; end: { offset: number } };\n};\n\nconst NODE_TYPES = {\n TEXT: 2,\n ELEMENT: 1,\n ATTRIBUTE: 6,\n INTERPOLATION: 5,\n};\n\nexport const intlayerVueExtract = (\n code: string,\n filename: string,\n options: ExtractPluginOptions = {}\n): { code: string; map?: unknown; extracted: boolean } | null => {\n const {\n defaultLocale = DEFAULT_LOCALE,\n packageName = 'vue-intlayer',\n filesList,\n shouldExtract,\n onExtract,\n dictionaryKey: dictionaryKeyOption,\n attributesToExtract = [],\n extractDictionaryKeyFromPath,\n generateKey,\n } = options;\n\n if (!shouldProcessFile(filename, filesList)) return null;\n if (!filename.endsWith('.vue')) return null;\n\n let parseVue: (code: string) => VueParseResult;\n\n try {\n parseVue = vueSfc.parse as unknown as (code: string) => VueParseResult;\n } catch {\n console.warn('Vue extraction: @vue/compiler-sfc not found.');\n return null;\n }\n\n const sfc = parseVue(code);\n const magic = new MagicString(code);\n\n const extractedContent: ExtractedContent = {};\n const existingKeys = new Set<string>();\n const dictionaryKey =\n dictionaryKeyOption ?? extractDictionaryKeyFromPath?.(filename) ?? '';\n const replacements: Replacement[] = [];\n\n // Detect existing useIntlayer / getIntlayer call in the script block BEFORE\n // walking the template, so the correct access pattern can be chosen.\n const scriptBlock = sfc.descriptor.scriptSetup ?? sfc.descriptor.script;\n const existingCallInfo = scriptBlock\n ? detectExistingIntlayerCall(\n scriptBlock.content,\n scriptBlock.loc.start.offset\n )\n : null;\n\n const isDestructured = existingCallInfo?.isDestructured ?? false;\n const varName = existingCallInfo?.variableName ?? 'content';\n\n // Walk Vue Template AST\n if (sfc.descriptor.template) {\n const walkVueAst = (node: VueAstNode) => {\n if (node.type === NODE_TYPES.TEXT) {\n const text = node.content ?? '';\n\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n // When the existing call is destructured, access the key directly;\n // otherwise use the `content` variable.\n const ref = isDestructured ? key : `${varName}.${key}`;\n replacements.push({\n start: node.loc.start.offset,\n end: node.loc.end.offset,\n replacement: `{{ ${ref} }}`,\n key,\n value: text.replace(/\\s+/g, ' ').trim(),\n });\n }\n } else if (node.type === NODE_TYPES.ELEMENT) {\n const children = node.children ?? [];\n\n // Try to handle as insertion (mixed TEXT + INTERPOLATION children)\n if (\n children.length > 0 &&\n children.some((c) => c.type === NODE_TYPES.INTERPOLATION)\n ) {\n const parts: {\n type: 'text' | 'var';\n value: string;\n originalExpr: string;\n }[] = [];\n let hasSignificantText = false;\n let isValid = true;\n\n for (const child of children) {\n if (child.type === NODE_TYPES.TEXT) {\n const text = child.content ?? '';\n if (text.trim().length > 0) hasSignificantText = true;\n parts.push({ type: 'text', value: text, originalExpr: '' });\n } else if (child.type === NODE_TYPES.INTERPOLATION) {\n // Extract the expression source between {{ and }}\n const exprCode = code\n .slice(child.loc.start.offset + 2, child.loc.end.offset - 2)\n .trim();\n const varName = exprCode.includes('.')\n ? exprCode\n .split('.')\n .pop()!\n .replace(/[^\\w$]/g, '')\n : exprCode;\n parts.push({\n type: 'var',\n value: varName,\n originalExpr: exprCode,\n });\n } else {\n isValid = false;\n break;\n }\n }\n\n if (\n isValid &&\n hasSignificantText &&\n parts.some((p) => p.type === 'var')\n ) {\n let combined = '';\n for (const p of parts) {\n combined += p.type === 'var' ? `{{${p.value}}}` : p.value;\n }\n const cleanString = combined.replace(/\\s+/g, ' ').trim();\n\n if (shouldExtract?.(cleanString) && generateKey) {\n const key = generateKey(cleanString, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `${varName}.${key}`;\n\n const uniqueVarPairs = [\n ...new Set(\n parts\n .filter((p) => p.type === 'var')\n .map((p) => `${p.value}: ${p.originalExpr}`)\n ),\n ];\n const varArgs = uniqueVarPairs.join(', ');\n const replacement = `{{ ${ref}({ ${varArgs} }) }}`;\n\n const firstChild = children[0];\n const lastChild = children[children.length - 1];\n replacements.push({\n start: firstChild.loc.start.offset,\n end: lastChild.loc.end.offset,\n replacement,\n key,\n value: cleanString,\n });\n\n // Process props but skip children (they are replaced)\n node.props?.forEach((prop) => {\n if (\n prop.type === NODE_TYPES.ATTRIBUTE &&\n (attributesToExtract as readonly string[]).includes(\n prop.name\n ) &&\n prop.value\n ) {\n const text = prop.value.content;\n if (shouldExtract?.(text) && generateKey) {\n const propKey = generateKey(text, existingKeys);\n existingKeys.add(propKey);\n const propRef = isDestructured\n ? propKey\n : `${varName}.${propKey}`;\n replacements.push({\n start: prop.loc.start.offset,\n end: prop.loc.end.offset,\n replacement: `:${prop.name}=\"${propRef}\"`,\n key: propKey,\n value: text.trim(),\n });\n }\n }\n });\n return; // don't recurse into children\n }\n }\n }\n\n // Regular element: handle props\n node.props?.forEach((prop) => {\n if (\n prop.type === NODE_TYPES.ATTRIBUTE &&\n (attributesToExtract as readonly string[]).includes(prop.name) &&\n prop.value\n ) {\n const text = prop.value.content;\n\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `${varName}.${key}`;\n replacements.push({\n start: prop.loc.start.offset,\n end: prop.loc.end.offset,\n replacement: `:${prop.name}=\"${ref}\"`,\n key,\n value: text.trim(),\n });\n }\n }\n });\n }\n\n if (node.children) {\n node.children.forEach(walkVueAst);\n }\n };\n\n walkVueAst(sfc.descriptor.template.ast);\n }\n\n // Extract and Walk Script using Babel\n if (scriptBlock) {\n const scriptText = scriptBlock.content;\n const offset = scriptBlock.loc.start.offset;\n\n try {\n const ast = babelParse(scriptText, {\n configFile: false,\n babelrc: false,\n parserOpts: {\n sourceType: 'module',\n plugins: ['typescript', 'jsx'],\n },\n });\n\n if (ast) {\n traverse(ast, {\n StringLiteral(path: any) {\n if (path.parentPath.isImportDeclaration()) return;\n\n if (path.parentPath.isExportDeclaration()) return;\n\n if (path.parentPath.isImportSpecifier()) return;\n\n if (path.parentPath.isObjectProperty() && path.key === 'key')\n return;\n\n if (path.parentPath.isCallExpression()) {\n const callee = path.parentPath.node.callee;\n\n if (\n t.isMemberExpression(callee) &&\n t.isIdentifier(callee.object) &&\n callee.object.name === 'console'\n )\n return;\n\n if (\n t.isIdentifier(callee) &&\n (callee.name === 'useIntlayer' || callee.name === 't')\n )\n return;\n\n if (callee.type === 'Import') return;\n\n if (t.isIdentifier(callee) && callee.name === 'require') return;\n }\n\n const text = path.node.value;\n\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n\n if (path.node.start != null && path.node.end != null) {\n const ref = isDestructured ? key : `${varName}.${key}`;\n replacements.push({\n start: offset + path.node.start,\n end: offset + path.node.end,\n replacement: ref,\n key,\n value: text.trim(),\n });\n }\n }\n },\n });\n }\n } catch (e) {\n console.warn(\n `Vue extraction: Failed to parse script content for ${filename}`,\n e\n );\n }\n }\n\n // Abort if nothing was extracted\n if (replacements.length === 0) return null;\n\n // Apply Replacements in Reverse Order\n replacements.sort((a, b) => b.start - a.start);\n\n for (const { start, end, replacement, key, value } of replacements) {\n magic.overwrite(start, end, replacement);\n extractedContent[key] = value;\n }\n\n // When the existing call is destructured, inject only the missing keys into\n // the ObjectPattern — no new `content` variable is needed.\n if (\n existingCallInfo?.isDestructured &&\n existingCallInfo.closingBraceAbsolutePos >= 0\n ) {\n const missingKeys = Object.keys(extractedContent).filter(\n (k) => !existingCallInfo.existingDestructuredKeys.includes(k)\n );\n\n if (missingKeys.length > 0) {\n // Insert right after the last property so the space/newline before `}`\n // is naturally preserved: `{ a }` → `{ a, b }`.\n magic.appendLeft(\n existingCallInfo.lastPropAbsoluteEnd,\n `, ${missingKeys.join(', ')}`\n );\n }\n }\n\n // Inject necessary imports and setup (only when no existing call was detected)\n const finalScriptContent = scriptBlock?.content ?? '';\n\n const hasUseIntlayerImport =\n /import\\s*{[^}]*useIntlayer[^}]*}\\s*from\\s*['\"][^'\"]+['\"]/.test(\n finalScriptContent\n ) ||\n /import\\s+useIntlayer\\s+from\\s*['\"][^'\"]+['\"]/.test(finalScriptContent);\n\n // An existing call (destructured or not) means no new declaration is needed.\n const hasContentDeclaration =\n existingCallInfo !== null ||\n /const\\s+content\\s*=\\s*useIntlayer\\s*\\(/.test(finalScriptContent);\n\n const importStmt = hasUseIntlayerImport\n ? ''\n : `import { useIntlayer } from '${packageName}';`;\n const contentDecl = hasContentDeclaration\n ? ''\n : `const content = useIntlayer('${dictionaryKey}');`;\n\n const injectionParts = [importStmt, contentDecl].filter(Boolean);\n\n if (injectionParts.length > 0) {\n const injection = `\\n${injectionParts.join('\\n')}\\n`;\n\n if (sfc.descriptor.scriptSetup) {\n magic.appendLeft(sfc.descriptor.scriptSetup.loc.start.offset, injection);\n } else if (sfc.descriptor.script) {\n magic.appendLeft(sfc.descriptor.script.loc.start.offset, injection);\n } else {\n magic.prepend(\n `<script setup>\\n${importStmt}\\n${contentDecl}\\n</script>\\n`\n );\n }\n }\n\n if (onExtract) {\n onExtract({\n dictionaryKey,\n filePath: filename,\n content: { ...extractedContent },\n locale: defaultLocale,\n });\n }\n\n return {\n code: magic.toString(),\n map: magic.generateMap({ source: filename, includeContent: true }),\n extracted: true,\n };\n};\n\ntype Tools = {\n generateKey: (text: string, existingKeys: Set<string>) => string;\n shouldExtract: (text: string) => boolean;\n extractDictionaryKeyFromPath: (path: string) => string;\n attributesToExtract: readonly string[];\n extractTsContent: any;\n};\n\nexport const processVueFile = (\n filePath: string,\n _componentKey: string,\n packageName: string,\n tools: Tools,\n save: boolean = true,\n providedCode?: string\n): {\n extractedContent: Record<string, string>;\n code: string;\n map?: any;\n} | null => {\n const code = providedCode ?? readFileSync(filePath, 'utf-8');\n let extractedContent: Record<string, string> = {};\n\n const result = intlayerVueExtract(code, filePath, {\n packageName,\n dictionaryKey: _componentKey,\n shouldExtract: tools.shouldExtract,\n generateKey: tools.generateKey,\n extractDictionaryKeyFromPath: tools.extractDictionaryKeyFromPath,\n attributesToExtract: tools.attributesToExtract,\n onExtract: (extractResult) => {\n extractedContent = extractResult.content;\n },\n });\n\n if (!result) return null;\n\n if (save) {\n writeFileSync(filePath, result.code);\n }\n\n return {\n extractedContent,\n code: result.code,\n map: result.map,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"vue-intlayer-extract.cjs","names":["babelParse","t","DEFAULT_LOCALE","getExtractionIgnoreDirectives","vueSfc","MagicString","readFileSync"],"sources":["../../src/vue-intlayer-extract.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { parseSync as babelParse, types as t, traverse } from '@babel/core';\nimport { DEFAULT_LOCALE } from '@intlayer/config/defaultValues';\nimport { getExtractionIgnoreDirectives } from '@intlayer/config/extract';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport vueSfc from '@vue/compiler-sfc';\nimport MagicString from 'magic-string';\n\ntype ExistingCallInfo = {\n isDestructured: boolean;\n existingDestructuredKeys: string[];\n /** The variable name used to store the call result (e.g. `t` in `const t = useIntlayer(...)`) */\n variableName: string;\n /** Absolute position of `}` in the full file — only valid when `isDestructured` */\n closingBraceAbsolutePos: number;\n /** Absolute position of end of last property — only valid when `isDestructured` */\n lastPropAbsoluteEnd: number;\n} | null;\n\n/**\n * Detects whether the script block already contains a `useIntlayer` /\n * `getIntlayer` call and, if so, whether its result is destructured.\n *\n * @param scriptText Raw text of the script block content.\n * @param absoluteOffset Byte offset of `scriptText[0]` in the full SFC source.\n */\nconst detectExistingIntlayerCall = (\n scriptText: string,\n absoluteOffset: number\n): ExistingCallInfo => {\n let info: ExistingCallInfo = null;\n\n try {\n const ast = babelParse(scriptText, {\n configFile: false,\n babelrc: false,\n parserOpts: { sourceType: 'module', plugins: ['typescript', 'jsx'] },\n });\n\n if (!ast) return null;\n\n traverse(ast, {\n CallExpression(path: any) {\n const callee = path.node.callee;\n\n if (\n !t.isIdentifier(callee) ||\n (callee.name !== 'useIntlayer' && callee.name !== 'getIntlayer')\n )\n return;\n\n const parent = path.parent;\n\n if (t.isVariableDeclarator(parent) && t.isObjectPattern(parent.id)) {\n const properties = parent.id.properties;\n const existingDestructuredKeys = properties\n .filter(\n (property: any): property is typeof t.objectProperty =>\n t.isObjectProperty(property) && t.isIdentifier(property.key)\n )\n .map((property: any) => (property.key as any).name as string);\n const lastProp = properties[properties.length - 1];\n\n info = {\n isDestructured: true,\n variableName: 'content',\n existingDestructuredKeys,\n closingBraceAbsolutePos: absoluteOffset + (parent.id.end! - 1),\n lastPropAbsoluteEnd: absoluteOffset + lastProp.end!,\n };\n } else {\n const variableName =\n t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)\n ? parent.id.name\n : 'content';\n\n info = {\n isDestructured: false,\n variableName,\n existingDestructuredKeys: [],\n closingBraceAbsolutePos: -1,\n lastPropAbsoluteEnd: -1,\n };\n }\n\n path.stop();\n },\n });\n } catch {\n // Silently ignore parse failures — fall back to no-info\n }\n\n return info;\n};\n\nexport type ExtractedContent = Record<string, string>;\n\nexport type ExtractResult = {\n dictionaryKey: string;\n filePath: string;\n content: ExtractedContent;\n locale: Locale;\n};\n\nexport type ExtractPluginOptions = {\n defaultLocale?: Locale;\n packageName?: string;\n filesList?: string[];\n shouldExtract?: (text: string) => boolean;\n onExtract?: (result: ExtractResult) => void;\n dictionaryKey?: string;\n attributesToExtract?: readonly string[];\n extractDictionaryKeyFromPath?: (path: string) => string;\n generateKey?: (text: string, existingKeys: Set<string>) => string;\n};\n\ntype Replacement = {\n start: number;\n end: number;\n replacement: string;\n key: string;\n value: string;\n};\n\nexport const shouldProcessFile = (\n filename: string | undefined,\n filesList?: string[]\n): boolean => {\n if (!filename) return false;\n if (!filesList || filesList.length === 0) return true;\n\n const normalizedFilename = filename.replace(/\\\\/g, '/');\n return filesList.some((f) => {\n const normalizedF = f.replace(/\\\\/g, '/');\n return normalizedF === normalizedFilename;\n });\n};\n\ntype VueParseResult = {\n descriptor: {\n template?: {\n ast: VueAstNode;\n loc: { start: { offset: number }; end: { offset: number } };\n };\n script?: {\n content: string;\n loc: { start: { offset: number }; end: { offset: number } };\n };\n scriptSetup?: {\n content: string;\n loc: { start: { offset: number }; end: { offset: number } };\n };\n };\n};\n\ntype VueAstNode = {\n type: number;\n content?: string;\n children?: VueAstNode[];\n props?: VueAstProp[];\n loc: { start: { offset: number }; end: { offset: number } };\n};\n\ntype VueAstProp = {\n type: number;\n name: string;\n value?: { content: string };\n loc: { start: { offset: number }; end: { offset: number } };\n};\n\nconst NODE_TYPES = {\n TEXT: 2,\n ELEMENT: 1,\n ATTRIBUTE: 6,\n INTERPOLATION: 5,\n};\n\nexport const intlayerVueExtract = (\n code: string,\n filename: string,\n options: ExtractPluginOptions = {}\n): { code: string; map?: unknown; extracted: boolean } | null => {\n const {\n defaultLocale = DEFAULT_LOCALE,\n packageName = 'vue-intlayer',\n filesList,\n shouldExtract,\n onExtract,\n dictionaryKey: dictionaryKeyOption,\n attributesToExtract = [],\n extractDictionaryKeyFromPath,\n generateKey,\n } = options;\n\n if (!shouldProcessFile(filename, filesList)) return null;\n if (!filename.endsWith('.vue')) return null;\n\n const ignoreDirectives = getExtractionIgnoreDirectives(code);\n\n if (ignoreDirectives.isFileIgnored) return null;\n\n let parseVue: (code: string) => VueParseResult;\n\n try {\n parseVue = vueSfc.parse as unknown as (code: string) => VueParseResult;\n } catch {\n console.warn('Vue extraction: @vue/compiler-sfc not found.');\n return null;\n }\n\n const sfc = parseVue(code);\n const magic = new MagicString(code);\n\n const extractedContent: ExtractedContent = {};\n const existingKeys = new Set<string>();\n const dictionaryKey =\n dictionaryKeyOption ?? extractDictionaryKeyFromPath?.(filename) ?? '';\n const replacements: Replacement[] = [];\n\n // Detect existing useIntlayer / getIntlayer call in the script block BEFORE\n // walking the template, so the correct access pattern can be chosen.\n const scriptBlock = sfc.descriptor.scriptSetup ?? sfc.descriptor.script;\n const existingCallInfo = scriptBlock\n ? detectExistingIntlayerCall(\n scriptBlock.content,\n scriptBlock.loc.start.offset\n )\n : null;\n\n const isDestructured = existingCallInfo?.isDestructured ?? false;\n const varName = existingCallInfo?.variableName ?? 'content';\n\n // Walk Vue Template AST\n if (sfc.descriptor.template) {\n /**\n * Walks the template; `isParentIgnored` is true when an ignore directive\n * covers the opening tag of the enclosing element.\n */\n const walkVueAst = (node: VueAstNode, isParentIgnored = false) => {\n const isNodeIgnored = ignoreDirectives.isOffsetIgnored(\n node.loc.start.offset\n );\n\n if (node.type === NODE_TYPES.TEXT) {\n const text = node.content ?? '';\n const leadingWhitespaceLength = text.length - text.trimStart().length;\n const isTextIgnored =\n isParentIgnored ||\n ignoreDirectives.isOffsetIgnored(\n node.loc.start.offset + leadingWhitespaceLength\n );\n\n if (!isTextIgnored && shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n // When the existing call is destructured, access the key directly;\n // otherwise use the `content` variable.\n const ref = isDestructured ? key : `${varName}.${key}`;\n replacements.push({\n start: node.loc.start.offset,\n end: node.loc.end.offset,\n replacement: `{{ ${ref} }}`,\n key,\n value: text.replace(/\\s+/g, ' ').trim(),\n });\n }\n } else if (node.type === NODE_TYPES.ELEMENT) {\n const children = node.children ?? [];\n\n /** Attributes on an ignored tag or line stay untouched. */\n const isPropIgnored = (prop: VueAstProp): boolean =>\n isNodeIgnored ||\n ignoreDirectives.isOffsetIgnored(prop.loc.start.offset);\n\n // Try to handle as insertion (mixed TEXT + INTERPOLATION children)\n if (\n !isNodeIgnored &&\n (children.length ?? 0) > 0 &&\n children.some((child) => child.type === NODE_TYPES.INTERPOLATION)\n ) {\n const parts: {\n type: 'text' | 'var';\n value: string;\n originalExpr: string;\n }[] = [];\n let hasSignificantText = false;\n let isValid = true;\n\n for (const child of children) {\n if (child.type === NODE_TYPES.TEXT) {\n const text = child.content ?? '';\n if (text.trim().length > 0) hasSignificantText = true;\n parts.push({ type: 'text', value: text, originalExpr: '' });\n } else if (child.type === NODE_TYPES.INTERPOLATION) {\n // Extract the expression source between {{ and }}\n const exprCode = code\n .slice(child.loc.start.offset + 2, child.loc.end.offset - 2)\n .trim();\n const varName = exprCode.includes('.')\n ? exprCode\n .split('.')\n .pop()!\n .replace(/[^\\w$]/g, '')\n : exprCode;\n parts.push({\n type: 'var',\n value: varName,\n originalExpr: exprCode,\n });\n } else {\n isValid = false;\n break;\n }\n }\n\n if (\n isValid &&\n hasSignificantText &&\n parts.some((p) => p.type === 'var')\n ) {\n let combined = '';\n for (const p of parts) {\n combined += p.type === 'var' ? `{{${p.value}}}` : p.value;\n }\n const cleanString = combined.replace(/\\s+/g, ' ').trim();\n\n if (shouldExtract?.(cleanString) && generateKey) {\n const key = generateKey(cleanString, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `${varName}.${key}`;\n\n const uniqueVarPairs = [\n ...new Set(\n parts\n .filter((p) => p.type === 'var')\n .map((p) => `${p.value}: ${p.originalExpr}`)\n ),\n ];\n const varArgs = uniqueVarPairs.join(', ');\n const replacement = `{{ ${ref}({ ${varArgs} }) }}`;\n\n const firstChild = children[0];\n const lastChild = children[children.length - 1];\n replacements.push({\n start: firstChild?.loc.start.offset ?? 0,\n end: lastChild?.loc.end.offset ?? 0,\n replacement,\n key,\n value: cleanString,\n });\n\n // Process props but skip children (they are replaced)\n node.props?.forEach((prop) => {\n if (\n prop.type === NODE_TYPES.ATTRIBUTE &&\n (attributesToExtract as readonly string[]).includes(\n prop.name\n ) &&\n prop.value &&\n !isPropIgnored(prop)\n ) {\n const text = prop.value.content;\n if (shouldExtract?.(text) && generateKey) {\n const propKey = generateKey(text, existingKeys);\n existingKeys.add(propKey);\n const propRef = isDestructured\n ? propKey\n : `${varName}.${propKey}`;\n replacements.push({\n start: prop.loc.start.offset,\n end: prop.loc.end.offset,\n replacement: `:${prop.name}=\"${propRef}\"`,\n key: propKey,\n value: text.trim(),\n });\n }\n }\n });\n return; // don't recurse into children\n }\n }\n }\n\n // Regular element: handle props\n node.props?.forEach((prop) => {\n if (\n prop.type === NODE_TYPES.ATTRIBUTE &&\n (attributesToExtract as readonly string[]).includes(prop.name) &&\n prop.value &&\n !isPropIgnored(prop)\n ) {\n const text = prop.value.content;\n\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `${varName}.${key}`;\n replacements.push({\n start: prop.loc.start.offset,\n end: prop.loc.end.offset,\n replacement: `:${prop.name}=\"${ref}\"`,\n key,\n value: text.trim(),\n });\n }\n }\n });\n }\n\n if (node.children) {\n node.children.forEach((child) =>\n walkVueAst(\n child,\n node.type === NODE_TYPES.ELEMENT ? isNodeIgnored : isParentIgnored\n )\n );\n }\n };\n\n walkVueAst(sfc.descriptor.template.ast);\n }\n\n // Extract and Walk Script using Babel\n if (scriptBlock) {\n const scriptText = scriptBlock.content;\n const offset = scriptBlock.loc.start.offset;\n\n try {\n const ast = babelParse(scriptText, {\n configFile: false,\n babelrc: false,\n parserOpts: {\n sourceType: 'module',\n plugins: ['typescript', 'jsx'],\n },\n });\n\n if (ast) {\n traverse(ast, {\n StringLiteral(path: any) {\n if (path.parentPath.isImportDeclaration()) return;\n\n if (path.parentPath.isExportDeclaration()) return;\n\n if (path.parentPath.isImportSpecifier()) return;\n\n if (path.parentPath.isObjectProperty() && path.key === 'key')\n return;\n\n if (path.parentPath.isCallExpression()) {\n const callee = path.parentPath.node.callee;\n\n if (\n t.isMemberExpression(callee) &&\n t.isIdentifier(callee.object) &&\n callee.object.name === 'console'\n )\n return;\n\n if (\n t.isIdentifier(callee) &&\n (callee.name === 'useIntlayer' || callee.name === 't')\n )\n return;\n\n if (callee.type === 'Import') return;\n\n if (t.isIdentifier(callee) && callee.name === 'require') return;\n }\n\n const text = path.node.value;\n\n if (\n path.node.start != null &&\n ignoreDirectives.isOffsetIgnored(offset + path.node.start)\n )\n return;\n\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n\n if (path.node.start != null && path.node.end != null) {\n const ref = isDestructured ? key : `${varName}.${key}`;\n replacements.push({\n start: offset + path.node.start,\n end: offset + path.node.end,\n replacement: ref,\n key,\n value: text.trim(),\n });\n }\n }\n },\n });\n }\n } catch (e) {\n console.warn(\n `Vue extraction: Failed to parse script content for ${filename}`,\n e\n );\n }\n }\n\n // Abort if nothing was extracted\n if (replacements.length === 0) return null;\n\n // Apply Replacements in Reverse Order\n replacements.sort((a, b) => b.start - a.start);\n\n for (const { start, end, replacement, key, value } of replacements) {\n magic.overwrite(start, end, replacement);\n extractedContent[key] = value;\n }\n\n // When the existing call is destructured, inject only the missing keys into\n // the ObjectPattern — no new `content` variable is needed.\n if (\n existingCallInfo?.isDestructured &&\n existingCallInfo.closingBraceAbsolutePos >= 0\n ) {\n const missingKeys = Object.keys(extractedContent).filter(\n (k) => !existingCallInfo.existingDestructuredKeys.includes(k)\n );\n\n if (missingKeys.length > 0) {\n // Insert right after the last property so the space/newline before `}`\n // is naturally preserved: `{ a }` → `{ a, b }`.\n magic.appendLeft(\n existingCallInfo.lastPropAbsoluteEnd,\n `, ${missingKeys.join(', ')}`\n );\n }\n }\n\n // Inject necessary imports and setup (only when no existing call was detected)\n const finalScriptContent = scriptBlock?.content ?? '';\n\n const hasUseIntlayerImport =\n /import\\s*{[^}]*useIntlayer[^}]*}\\s*from\\s*['\"][^'\"]+['\"]/.test(\n finalScriptContent\n ) ||\n /import\\s+useIntlayer\\s+from\\s*['\"][^'\"]+['\"]/.test(finalScriptContent);\n\n // An existing call (destructured or not) means no new declaration is needed.\n const hasContentDeclaration =\n existingCallInfo !== null ||\n /const\\s+content\\s*=\\s*useIntlayer\\s*\\(/.test(finalScriptContent);\n\n const importStmt = hasUseIntlayerImport\n ? ''\n : `import { useIntlayer } from '${packageName}';`;\n const contentDecl = hasContentDeclaration\n ? ''\n : `const content = useIntlayer('${dictionaryKey}');`;\n\n const injectionParts = [importStmt, contentDecl].filter(Boolean);\n\n if (injectionParts.length > 0) {\n const injection = `\\n${injectionParts.join('\\n')}\\n`;\n\n if (sfc.descriptor.scriptSetup) {\n magic.appendLeft(sfc.descriptor.scriptSetup.loc.start.offset, injection);\n } else if (sfc.descriptor.script) {\n magic.appendLeft(sfc.descriptor.script.loc.start.offset, injection);\n } else {\n magic.prepend(\n `<script setup>\\n${importStmt}\\n${contentDecl}\\n</script>\\n`\n );\n }\n }\n\n if (onExtract) {\n onExtract({\n dictionaryKey,\n filePath: filename,\n content: { ...extractedContent },\n locale: defaultLocale,\n });\n }\n\n return {\n code: magic.toString(),\n map: magic.generateMap({ source: filename, includeContent: true }),\n extracted: true,\n };\n};\n\ntype Tools = {\n generateKey: (text: string, existingKeys: Set<string>) => string;\n shouldExtract: (text: string) => boolean;\n extractDictionaryKeyFromPath: (path: string) => string;\n attributesToExtract: readonly string[];\n extractTsContent: any;\n};\n\nexport const processVueFile = (\n filePath: string,\n _componentKey: string,\n packageName: string,\n tools: Tools,\n save: boolean = true,\n providedCode?: string\n): {\n extractedContent: Record<string, string>;\n code: string;\n map?: any;\n} | null => {\n const code = providedCode ?? readFileSync(filePath, 'utf-8');\n let extractedContent: Record<string, string> = {};\n\n const result = intlayerVueExtract(code, filePath, {\n packageName,\n dictionaryKey: _componentKey,\n shouldExtract: tools.shouldExtract,\n generateKey: tools.generateKey,\n extractDictionaryKeyFromPath: tools.extractDictionaryKeyFromPath,\n attributesToExtract: tools.attributesToExtract,\n onExtract: (extractResult) => {\n extractedContent = extractResult.content;\n },\n });\n\n if (!result) return null;\n\n if (save) {\n writeFileSync(filePath, result.code);\n }\n\n return {\n extractedContent,\n code: result.code,\n map: result.map,\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA0BA,MAAM,8BACJ,YACA,mBACqB;CACrB,IAAI,OAAyB;CAE7B,IAAI;EACF,MAAM,UAAMA,uBAAW,YAAY;GACjC,YAAY;GACZ,SAAS;GACT,YAAY;IAAE,YAAY;IAAU,SAAS,CAAC,cAAc,KAAK;GAAE;EACrE,CAAC;EAED,IAAI,CAAC,KAAK,OAAO;EAEjB,0BAAS,KAAK,EACZ,eAAe,MAAW;GACxB,MAAM,SAAS,KAAK,KAAK;GAEzB,IACE,CAACC,kBAAE,aAAa,MAAM,KACrB,OAAO,SAAS,iBAAiB,OAAO,SAAS,eAElD;GAEF,MAAM,SAAS,KAAK;GAEpB,IAAIA,kBAAE,qBAAqB,MAAM,KAAKA,kBAAE,gBAAgB,OAAO,EAAE,GAAG;IAClE,MAAM,aAAa,OAAO,GAAG;IAC7B,MAAM,2BAA2B,WAC9B,QACE,aACCA,kBAAE,iBAAiB,QAAQ,KAAKA,kBAAE,aAAa,SAAS,GAAG,CAC/D,CAAC,CACA,KAAK,aAAmB,SAAS,IAAY,IAAc;IAC9D,MAAM,WAAW,WAAW,WAAW,SAAS;IAEhD,OAAO;KACL,gBAAgB;KAChB,cAAc;KACd;KACA,yBAAyB,kBAAkB,OAAO,GAAG,MAAO;KAC5D,qBAAqB,iBAAiB,SAAS;IACjD;GACF,OAME,OAAO;IACL,gBAAgB;IAChB,cANAA,kBAAE,qBAAqB,MAAM,KAAKA,kBAAE,aAAa,OAAO,EAAE,IACtD,OAAO,GAAG,OACV;IAKJ,0BAA0B,CAAC;IAC3B,yBAAyB;IACzB,qBAAqB;GACvB;GAGF,KAAK,KAAK;EACZ,EACF,CAAC;CACH,QAAQ,CAER;CAEA,OAAO;AACT;AA+BA,MAAa,qBACX,UACA,cACY;CACZ,IAAI,CAAC,UAAU,OAAO;CACtB,IAAI,CAAC,aAAa,UAAU,WAAW,GAAG,OAAO;CAEjD,MAAM,qBAAqB,SAAS,QAAQ,OAAO,GAAG;CACtD,OAAO,UAAU,MAAM,MAAM;EAE3B,OADoB,EAAE,QAAQ,OAAO,GACpB,MAAM;CACzB,CAAC;AACH;AAkCA,MAAM,aAAa;CACjB,MAAM;CACN,SAAS;CACT,WAAW;CACX,eAAe;AACjB;AAEA,MAAa,sBACX,MACA,UACA,UAAgC,CAAC,MAC8B;CAC/D,MAAM,EACJ,gBAAgBC,+CAChB,cAAc,gBACd,WACA,eACA,WACA,eAAe,qBACf,sBAAsB,CAAC,GACvB,8BACA,gBACE;CAEJ,IAAI,CAAC,kBAAkB,UAAU,SAAS,GAAG,OAAO;CACpD,IAAI,CAAC,SAAS,SAAS,MAAM,GAAG,OAAO;CAEvC,MAAM,uBAAmBC,wDAA8B,IAAI;CAE3D,IAAI,iBAAiB,eAAe,OAAO;CAE3C,IAAI;CAEJ,IAAI;EACF,WAAWC,0BAAO;CACpB,QAAQ;EACN,QAAQ,KAAK,8CAA8C;EAC3D,OAAO;CACT;CAEA,MAAM,MAAM,SAAS,IAAI;CACzB,MAAM,QAAQ,IAAIC,qBAAY,IAAI;CAElC,MAAM,mBAAqC,CAAC;CAC5C,MAAM,+BAAe,IAAI,IAAY;CACrC,MAAM,gBACJ,uBAAuB,+BAA+B,QAAQ,KAAK;CACrE,MAAM,eAA8B,CAAC;CAIrC,MAAM,cAAc,IAAI,WAAW,eAAe,IAAI,WAAW;CACjE,MAAM,mBAAmB,cACrB,2BACE,YAAY,SACZ,YAAY,IAAI,MAAM,MACxB,IACA;CAEJ,MAAM,iBAAiB,kBAAkB,kBAAkB;CAC3D,MAAM,UAAU,kBAAkB,gBAAgB;CAGlD,IAAI,IAAI,WAAW,UAAU;;;;;EAK3B,MAAM,cAAc,MAAkB,kBAAkB,UAAU;GAChE,MAAM,gBAAgB,iBAAiB,gBACrC,KAAK,IAAI,MAAM,MACjB;GAEA,IAAI,KAAK,SAAS,WAAW,MAAM;IACjC,MAAM,OAAO,KAAK,WAAW;IAC7B,MAAM,0BAA0B,KAAK,SAAS,KAAK,UAAU,CAAC,CAAC;IAO/D,IAAI,EALF,mBACA,iBAAiB,gBACf,KAAK,IAAI,MAAM,SAAS,uBAC1B,MAEoB,gBAAgB,IAAI,KAAK,aAAa;KAC1D,MAAM,MAAM,YAAY,MAAM,YAAY;KAC1C,aAAa,IAAI,GAAG;KAGpB,MAAM,MAAM,iBAAiB,MAAM,GAAG,QAAQ,GAAG;KACjD,aAAa,KAAK;MAChB,OAAO,KAAK,IAAI,MAAM;MACtB,KAAK,KAAK,IAAI,IAAI;MAClB,aAAa,MAAM,IAAI;MACvB;MACA,OAAO,KAAK,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK;KACxC,CAAC;IACH;GACF,OAAO,IAAI,KAAK,SAAS,WAAW,SAAS;IAC3C,MAAM,WAAW,KAAK,YAAY,CAAC;;IAGnC,MAAM,iBAAiB,SACrB,iBACA,iBAAiB,gBAAgB,KAAK,IAAI,MAAM,MAAM;IAGxD,IACE,CAAC,kBACA,SAAS,UAAU,KAAK,KACzB,SAAS,MAAM,UAAU,MAAM,SAAS,WAAW,aAAa,GAChE;KACA,MAAM,QAIA,CAAC;KACP,IAAI,qBAAqB;KACzB,IAAI,UAAU;KAEd,KAAK,MAAM,SAAS,UAClB,IAAI,MAAM,SAAS,WAAW,MAAM;MAClC,MAAM,OAAO,MAAM,WAAW;MAC9B,IAAI,KAAK,KAAK,CAAC,CAAC,SAAS,GAAG,qBAAqB;MACjD,MAAM,KAAK;OAAE,MAAM;OAAQ,OAAO;OAAM,cAAc;MAAG,CAAC;KAC5D,OAAO,IAAI,MAAM,SAAS,WAAW,eAAe;MAElD,MAAM,WAAW,KACd,MAAM,MAAM,IAAI,MAAM,SAAS,GAAG,MAAM,IAAI,IAAI,SAAS,CAAC,CAAC,CAC3D,KAAK;MACR,MAAM,UAAU,SAAS,SAAS,GAAG,IACjC,SACG,MAAM,GAAG,CAAC,CACV,IAAI,CAAC,CACL,QAAQ,WAAW,EAAE,IACxB;MACJ,MAAM,KAAK;OACT,MAAM;OACN,OAAO;OACP,cAAc;MAChB,CAAC;KACH,OAAO;MACL,UAAU;MACV;KACF;KAGF,IACE,WACA,sBACA,MAAM,MAAM,MAAM,EAAE,SAAS,KAAK,GAClC;MACA,IAAI,WAAW;MACf,KAAK,MAAM,KAAK,OACd,YAAY,EAAE,SAAS,QAAQ,KAAK,EAAE,MAAM,MAAM,EAAE;MAEtD,MAAM,cAAc,SAAS,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK;MAEvD,IAAI,gBAAgB,WAAW,KAAK,aAAa;OAC/C,MAAM,MAAM,YAAY,aAAa,YAAY;OACjD,aAAa,IAAI,GAAG;OAWpB,MAAM,cAAc,MAVR,iBAAiB,MAAM,GAAG,QAAQ,GAAG,MAUnB,KADd,CANd,GAAG,IAAI,IACL,MACG,QAAQ,MAAM,EAAE,SAAS,KAAK,CAAC,CAC/B,KAAK,MAAM,GAAG,EAAE,MAAM,IAAI,EAAE,cAAc,CAC/C,CAE2B,CAAC,CAAC,KAAK,IACK,EAAE;OAE3C,MAAM,aAAa,SAAS;OAC5B,MAAM,YAAY,SAAS,SAAS,SAAS;OAC7C,aAAa,KAAK;QAChB,OAAO,YAAY,IAAI,MAAM,UAAU;QACvC,KAAK,WAAW,IAAI,IAAI,UAAU;QAClC;QACA;QACA,OAAO;OACT,CAAC;OAGD,KAAK,OAAO,SAAS,SAAS;QAC5B,IACE,KAAK,SAAS,WAAW,aACxB,oBAA0C,SACzC,KAAK,IACP,KACA,KAAK,SACL,CAAC,cAAc,IAAI,GACnB;SACA,MAAM,OAAO,KAAK,MAAM;SACxB,IAAI,gBAAgB,IAAI,KAAK,aAAa;UACxC,MAAM,UAAU,YAAY,MAAM,YAAY;UAC9C,aAAa,IAAI,OAAO;UACxB,MAAM,UAAU,iBACZ,UACA,GAAG,QAAQ,GAAG;UAClB,aAAa,KAAK;WAChB,OAAO,KAAK,IAAI,MAAM;WACtB,KAAK,KAAK,IAAI,IAAI;WAClB,aAAa,IAAI,KAAK,KAAK,IAAI,QAAQ;WACvC,KAAK;WACL,OAAO,KAAK,KAAK;UACnB,CAAC;SACH;QACF;OACF,CAAC;OACD;MACF;KACF;IACF;IAGA,KAAK,OAAO,SAAS,SAAS;KAC5B,IACE,KAAK,SAAS,WAAW,aACxB,oBAA0C,SAAS,KAAK,IAAI,KAC7D,KAAK,SACL,CAAC,cAAc,IAAI,GACnB;MACA,MAAM,OAAO,KAAK,MAAM;MAExB,IAAI,gBAAgB,IAAI,KAAK,aAAa;OACxC,MAAM,MAAM,YAAY,MAAM,YAAY;OAC1C,aAAa,IAAI,GAAG;OACpB,MAAM,MAAM,iBAAiB,MAAM,GAAG,QAAQ,GAAG;OACjD,aAAa,KAAK;QAChB,OAAO,KAAK,IAAI,MAAM;QACtB,KAAK,KAAK,IAAI,IAAI;QAClB,aAAa,IAAI,KAAK,KAAK,IAAI,IAAI;QACnC;QACA,OAAO,KAAK,KAAK;OACnB,CAAC;MACH;KACF;IACF,CAAC;GACH;GAEA,IAAI,KAAK,UACP,KAAK,SAAS,SAAS,UACrB,WACE,OACA,KAAK,SAAS,WAAW,UAAU,gBAAgB,eACrD,CACF;EAEJ;EAEA,WAAW,IAAI,WAAW,SAAS,GAAG;CACxC;CAGA,IAAI,aAAa;EACf,MAAM,aAAa,YAAY;EAC/B,MAAM,SAAS,YAAY,IAAI,MAAM;EAErC,IAAI;GACF,MAAM,UAAML,uBAAW,YAAY;IACjC,YAAY;IACZ,SAAS;IACT,YAAY;KACV,YAAY;KACZ,SAAS,CAAC,cAAc,KAAK;IAC/B;GACF,CAAC;GAED,IAAI,KACF,0BAAS,KAAK,EACZ,cAAc,MAAW;IACvB,IAAI,KAAK,WAAW,oBAAoB,GAAG;IAE3C,IAAI,KAAK,WAAW,oBAAoB,GAAG;IAE3C,IAAI,KAAK,WAAW,kBAAkB,GAAG;IAEzC,IAAI,KAAK,WAAW,iBAAiB,KAAK,KAAK,QAAQ,OACrD;IAEF,IAAI,KAAK,WAAW,iBAAiB,GAAG;KACtC,MAAM,SAAS,KAAK,WAAW,KAAK;KAEpC,IACEC,kBAAE,mBAAmB,MAAM,KAC3BA,kBAAE,aAAa,OAAO,MAAM,KAC5B,OAAO,OAAO,SAAS,WAEvB;KAEF,IACEA,kBAAE,aAAa,MAAM,MACpB,OAAO,SAAS,iBAAiB,OAAO,SAAS,MAElD;KAEF,IAAI,OAAO,SAAS,UAAU;KAE9B,IAAIA,kBAAE,aAAa,MAAM,KAAK,OAAO,SAAS,WAAW;IAC3D;IAEA,MAAM,OAAO,KAAK,KAAK;IAEvB,IACE,KAAK,KAAK,SAAS,QACnB,iBAAiB,gBAAgB,SAAS,KAAK,KAAK,KAAK,GAEzD;IAEF,IAAI,gBAAgB,IAAI,KAAK,aAAa;KACxC,MAAM,MAAM,YAAY,MAAM,YAAY;KAC1C,aAAa,IAAI,GAAG;KAEpB,IAAI,KAAK,KAAK,SAAS,QAAQ,KAAK,KAAK,OAAO,MAAM;MACpD,MAAM,MAAM,iBAAiB,MAAM,GAAG,QAAQ,GAAG;MACjD,aAAa,KAAK;OAChB,OAAO,SAAS,KAAK,KAAK;OAC1B,KAAK,SAAS,KAAK,KAAK;OACxB,aAAa;OACb;OACA,OAAO,KAAK,KAAK;MACnB,CAAC;KACH;IACF;GACF,EACF,CAAC;EAEL,SAAS,GAAG;GACV,QAAQ,KACN,sDAAsD,YACtD,CACF;EACF;CACF;CAGA,IAAI,aAAa,WAAW,GAAG,OAAO;CAGtC,aAAa,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;CAE7C,KAAK,MAAM,EAAE,OAAO,KAAK,aAAa,KAAK,WAAW,cAAc;EAClE,MAAM,UAAU,OAAO,KAAK,WAAW;EACvC,iBAAiB,OAAO;CAC1B;CAIA,IACE,kBAAkB,kBAClB,iBAAiB,2BAA2B,GAC5C;EACA,MAAM,cAAc,OAAO,KAAK,gBAAgB,CAAC,CAAC,QAC/C,MAAM,CAAC,iBAAiB,yBAAyB,SAAS,CAAC,CAC9D;EAEA,IAAI,YAAY,SAAS,GAGvB,MAAM,WACJ,iBAAiB,qBACjB,KAAK,YAAY,KAAK,IAAI,GAC5B;CAEJ;CAGA,MAAM,qBAAqB,aAAa,WAAW;CAEnD,MAAM,uBACJ,2DAA2D,KACzD,kBACF,KACA,+CAA+C,KAAK,kBAAkB;CAGxE,MAAM,wBACJ,qBAAqB,QACrB,yCAAyC,KAAK,kBAAkB;CAElE,MAAM,aAAa,uBACf,KACA,gCAAgC,YAAY;CAChD,MAAM,cAAc,wBAChB,KACA,gCAAgC,cAAc;CAElD,MAAM,iBAAiB,CAAC,YAAY,WAAW,CAAC,CAAC,OAAO,OAAO;CAE/D,IAAI,eAAe,SAAS,GAAG;EAC7B,MAAM,YAAY,KAAK,eAAe,KAAK,IAAI,EAAE;EAEjD,IAAI,IAAI,WAAW,aACjB,MAAM,WAAW,IAAI,WAAW,YAAY,IAAI,MAAM,QAAQ,SAAS;OAClE,IAAI,IAAI,WAAW,QACxB,MAAM,WAAW,IAAI,WAAW,OAAO,IAAI,MAAM,QAAQ,SAAS;OAElE,MAAM,QACJ,mBAAmB,WAAW,IAAI,YAAY,eAChD;CAEJ;CAEA,IAAI,WACF,UAAU;EACR;EACA,UAAU;EACV,SAAS,EAAE,GAAG,iBAAiB;EAC/B,QAAQ;CACV,CAAC;CAGH,OAAO;EACL,MAAM,MAAM,SAAS;EACrB,KAAK,MAAM,YAAY;GAAE,QAAQ;GAAU,gBAAgB;EAAK,CAAC;EACjE,WAAW;CACb;AACF;AAUA,MAAa,kBACX,UACA,eACA,aACA,OACA,OAAgB,MAChB,iBAKU;CACV,MAAM,OAAO,oBAAgBK,sBAAa,UAAU,OAAO;CAC3D,IAAI,mBAA2C,CAAC;CAEhD,MAAM,SAAS,mBAAmB,MAAM,UAAU;EAChD;EACA,eAAe;EACf,eAAe,MAAM;EACrB,aAAa,MAAM;EACnB,8BAA8B,MAAM;EACpC,qBAAqB,MAAM;EAC3B,YAAY,kBAAkB;GAC5B,mBAAmB,cAAc;EACnC;CACF,CAAC;CAED,IAAI,CAAC,QAAQ,OAAO;CAEpB,IAAI,MACF,2BAAc,UAAU,OAAO,IAAI;CAGrC,OAAO;EACL;EACA,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF"}
@@ -2,6 +2,7 @@ import vueSfc from "@vue/compiler-sfc";
2
2
  import { readFileSync, writeFileSync } from "node:fs";
3
3
  import { parseSync, traverse, types } from "@babel/core";
4
4
  import { DEFAULT_LOCALE } from "@intlayer/config/defaultValues";
5
+ import { getExtractionIgnoreDirectives } from "@intlayer/config/extract";
5
6
  import MagicString from "magic-string";
6
7
 
7
8
  // src/vue-intlayer-extract.ts
@@ -69,6 +70,8 @@ const intlayerVueExtract = (code, filename, options = {}) => {
69
70
  const { defaultLocale = DEFAULT_LOCALE, packageName = "vue-intlayer", filesList, shouldExtract, onExtract, dictionaryKey: dictionaryKeyOption, attributesToExtract = [], extractDictionaryKeyFromPath, generateKey } = options;
70
71
  if (!shouldProcessFile(filename, filesList)) return null;
71
72
  if (!filename.endsWith(".vue")) return null;
73
+ const ignoreDirectives = getExtractionIgnoreDirectives(code);
74
+ if (ignoreDirectives.isFileIgnored) return null;
72
75
  let parseVue;
73
76
  try {
74
77
  parseVue = vueSfc.parse;
@@ -87,10 +90,16 @@ const intlayerVueExtract = (code, filename, options = {}) => {
87
90
  const isDestructured = existingCallInfo?.isDestructured ?? false;
88
91
  const varName = existingCallInfo?.variableName ?? "content";
89
92
  if (sfc.descriptor.template) {
90
- const walkVueAst = (node) => {
93
+ /**
94
+ * Walks the template; `isParentIgnored` is true when an ignore directive
95
+ * covers the opening tag of the enclosing element.
96
+ */
97
+ const walkVueAst = (node, isParentIgnored = false) => {
98
+ const isNodeIgnored = ignoreDirectives.isOffsetIgnored(node.loc.start.offset);
91
99
  if (node.type === NODE_TYPES.TEXT) {
92
100
  const text = node.content ?? "";
93
- if (shouldExtract?.(text) && generateKey) {
101
+ const leadingWhitespaceLength = text.length - text.trimStart().length;
102
+ if (!(isParentIgnored || ignoreDirectives.isOffsetIgnored(node.loc.start.offset + leadingWhitespaceLength)) && shouldExtract?.(text) && generateKey) {
94
103
  const key = generateKey(text, existingKeys);
95
104
  existingKeys.add(key);
96
105
  const ref = isDestructured ? key : `${varName}.${key}`;
@@ -104,7 +113,9 @@ const intlayerVueExtract = (code, filename, options = {}) => {
104
113
  }
105
114
  } else if (node.type === NODE_TYPES.ELEMENT) {
106
115
  const children = node.children ?? [];
107
- if (children.length > 0 && children.some((c) => c.type === NODE_TYPES.INTERPOLATION)) {
116
+ /** Attributes on an ignored tag or line stay untouched. */
117
+ const isPropIgnored = (prop) => isNodeIgnored || ignoreDirectives.isOffsetIgnored(prop.loc.start.offset);
118
+ if (!isNodeIgnored && (children.length ?? 0) > 0 && children.some((child) => child.type === NODE_TYPES.INTERPOLATION)) {
108
119
  const parts = [];
109
120
  let hasSignificantText = false;
110
121
  let isValid = true;
@@ -139,14 +150,14 @@ const intlayerVueExtract = (code, filename, options = {}) => {
139
150
  const firstChild = children[0];
140
151
  const lastChild = children[children.length - 1];
141
152
  replacements.push({
142
- start: firstChild.loc.start.offset,
143
- end: lastChild.loc.end.offset,
153
+ start: firstChild?.loc.start.offset ?? 0,
154
+ end: lastChild?.loc.end.offset ?? 0,
144
155
  replacement,
145
156
  key,
146
157
  value: cleanString
147
158
  });
148
159
  node.props?.forEach((prop) => {
149
- if (prop.type === NODE_TYPES.ATTRIBUTE && attributesToExtract.includes(prop.name) && prop.value) {
160
+ if (prop.type === NODE_TYPES.ATTRIBUTE && attributesToExtract.includes(prop.name) && prop.value && !isPropIgnored(prop)) {
150
161
  const text = prop.value.content;
151
162
  if (shouldExtract?.(text) && generateKey) {
152
163
  const propKey = generateKey(text, existingKeys);
@@ -167,7 +178,7 @@ const intlayerVueExtract = (code, filename, options = {}) => {
167
178
  }
168
179
  }
169
180
  node.props?.forEach((prop) => {
170
- if (prop.type === NODE_TYPES.ATTRIBUTE && attributesToExtract.includes(prop.name) && prop.value) {
181
+ if (prop.type === NODE_TYPES.ATTRIBUTE && attributesToExtract.includes(prop.name) && prop.value && !isPropIgnored(prop)) {
171
182
  const text = prop.value.content;
172
183
  if (shouldExtract?.(text) && generateKey) {
173
184
  const key = generateKey(text, existingKeys);
@@ -184,7 +195,7 @@ const intlayerVueExtract = (code, filename, options = {}) => {
184
195
  }
185
196
  });
186
197
  }
187
- if (node.children) node.children.forEach(walkVueAst);
198
+ if (node.children) node.children.forEach((child) => walkVueAst(child, node.type === NODE_TYPES.ELEMENT ? isNodeIgnored : isParentIgnored));
188
199
  };
189
200
  walkVueAst(sfc.descriptor.template.ast);
190
201
  }
@@ -213,6 +224,7 @@ const intlayerVueExtract = (code, filename, options = {}) => {
213
224
  if (types.isIdentifier(callee) && callee.name === "require") return;
214
225
  }
215
226
  const text = path.node.value;
227
+ if (path.node.start != null && ignoreDirectives.isOffsetIgnored(offset + path.node.start)) return;
216
228
  if (shouldExtract?.(text) && generateKey) {
217
229
  const key = generateKey(text, existingKeys);
218
230
  existingKeys.add(key);
@@ -1 +1 @@
1
- {"version":3,"file":"vue-intlayer-extract.mjs","names":["babelParse","t"],"sources":["../../src/vue-intlayer-extract.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { parseSync as babelParse, types as t, traverse } from '@babel/core';\nimport { DEFAULT_LOCALE } from '@intlayer/config/defaultValues';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport vueSfc from '@vue/compiler-sfc';\nimport MagicString from 'magic-string';\n\ntype ExistingCallInfo = {\n isDestructured: boolean;\n existingDestructuredKeys: string[];\n /** The variable name used to store the call result (e.g. `t` in `const t = useIntlayer(...)`) */\n variableName: string;\n /** Absolute position of `}` in the full file — only valid when `isDestructured` */\n closingBraceAbsolutePos: number;\n /** Absolute position of end of last property — only valid when `isDestructured` */\n lastPropAbsoluteEnd: number;\n} | null;\n\n/**\n * Detects whether the script block already contains a `useIntlayer` /\n * `getIntlayer` call and, if so, whether its result is destructured.\n *\n * @param scriptText Raw text of the script block content.\n * @param absoluteOffset Byte offset of `scriptText[0]` in the full SFC source.\n */\nconst detectExistingIntlayerCall = (\n scriptText: string,\n absoluteOffset: number\n): ExistingCallInfo => {\n let info: ExistingCallInfo = null;\n\n try {\n const ast = babelParse(scriptText, {\n configFile: false,\n babelrc: false,\n parserOpts: { sourceType: 'module', plugins: ['typescript', 'jsx'] },\n });\n\n if (!ast) return null;\n\n traverse(ast, {\n CallExpression(path: any) {\n const callee = path.node.callee;\n\n if (\n !t.isIdentifier(callee) ||\n (callee.name !== 'useIntlayer' && callee.name !== 'getIntlayer')\n )\n return;\n\n const parent = path.parent;\n\n if (t.isVariableDeclarator(parent) && t.isObjectPattern(parent.id)) {\n const properties = parent.id.properties;\n const existingDestructuredKeys = properties\n .filter(\n (property: any): property is typeof t.objectProperty =>\n t.isObjectProperty(property) && t.isIdentifier(property.key)\n )\n .map((property: any) => (property.key as any).name as string);\n const lastProp = properties[properties.length - 1];\n\n info = {\n isDestructured: true,\n variableName: 'content',\n existingDestructuredKeys,\n closingBraceAbsolutePos: absoluteOffset + (parent.id.end! - 1),\n lastPropAbsoluteEnd: absoluteOffset + lastProp.end!,\n };\n } else {\n const variableName =\n t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)\n ? parent.id.name\n : 'content';\n\n info = {\n isDestructured: false,\n variableName,\n existingDestructuredKeys: [],\n closingBraceAbsolutePos: -1,\n lastPropAbsoluteEnd: -1,\n };\n }\n\n path.stop();\n },\n });\n } catch {\n // Silently ignore parse failures — fall back to no-info\n }\n\n return info;\n};\n\nexport type ExtractedContent = Record<string, string>;\n\nexport type ExtractResult = {\n dictionaryKey: string;\n filePath: string;\n content: ExtractedContent;\n locale: Locale;\n};\n\nexport type ExtractPluginOptions = {\n defaultLocale?: Locale;\n packageName?: string;\n filesList?: string[];\n shouldExtract?: (text: string) => boolean;\n onExtract?: (result: ExtractResult) => void;\n dictionaryKey?: string;\n attributesToExtract?: readonly string[];\n extractDictionaryKeyFromPath?: (path: string) => string;\n generateKey?: (text: string, existingKeys: Set<string>) => string;\n};\n\ntype Replacement = {\n start: number;\n end: number;\n replacement: string;\n key: string;\n value: string;\n};\n\nexport const shouldProcessFile = (\n filename: string | undefined,\n filesList?: string[]\n): boolean => {\n if (!filename) return false;\n if (!filesList || filesList.length === 0) return true;\n\n const normalizedFilename = filename.replace(/\\\\/g, '/');\n return filesList.some((f) => {\n const normalizedF = f.replace(/\\\\/g, '/');\n return normalizedF === normalizedFilename;\n });\n};\n\ntype VueParseResult = {\n descriptor: {\n template?: {\n ast: VueAstNode;\n loc: { start: { offset: number }; end: { offset: number } };\n };\n script?: {\n content: string;\n loc: { start: { offset: number }; end: { offset: number } };\n };\n scriptSetup?: {\n content: string;\n loc: { start: { offset: number }; end: { offset: number } };\n };\n };\n};\n\ntype VueAstNode = {\n type: number;\n content?: string;\n children?: VueAstNode[];\n props?: VueAstProp[];\n loc: { start: { offset: number }; end: { offset: number } };\n};\n\ntype VueAstProp = {\n type: number;\n name: string;\n value?: { content: string };\n loc: { start: { offset: number }; end: { offset: number } };\n};\n\nconst NODE_TYPES = {\n TEXT: 2,\n ELEMENT: 1,\n ATTRIBUTE: 6,\n INTERPOLATION: 5,\n};\n\nexport const intlayerVueExtract = (\n code: string,\n filename: string,\n options: ExtractPluginOptions = {}\n): { code: string; map?: unknown; extracted: boolean } | null => {\n const {\n defaultLocale = DEFAULT_LOCALE,\n packageName = 'vue-intlayer',\n filesList,\n shouldExtract,\n onExtract,\n dictionaryKey: dictionaryKeyOption,\n attributesToExtract = [],\n extractDictionaryKeyFromPath,\n generateKey,\n } = options;\n\n if (!shouldProcessFile(filename, filesList)) return null;\n if (!filename.endsWith('.vue')) return null;\n\n let parseVue: (code: string) => VueParseResult;\n\n try {\n parseVue = vueSfc.parse as unknown as (code: string) => VueParseResult;\n } catch {\n console.warn('Vue extraction: @vue/compiler-sfc not found.');\n return null;\n }\n\n const sfc = parseVue(code);\n const magic = new MagicString(code);\n\n const extractedContent: ExtractedContent = {};\n const existingKeys = new Set<string>();\n const dictionaryKey =\n dictionaryKeyOption ?? extractDictionaryKeyFromPath?.(filename) ?? '';\n const replacements: Replacement[] = [];\n\n // Detect existing useIntlayer / getIntlayer call in the script block BEFORE\n // walking the template, so the correct access pattern can be chosen.\n const scriptBlock = sfc.descriptor.scriptSetup ?? sfc.descriptor.script;\n const existingCallInfo = scriptBlock\n ? detectExistingIntlayerCall(\n scriptBlock.content,\n scriptBlock.loc.start.offset\n )\n : null;\n\n const isDestructured = existingCallInfo?.isDestructured ?? false;\n const varName = existingCallInfo?.variableName ?? 'content';\n\n // Walk Vue Template AST\n if (sfc.descriptor.template) {\n const walkVueAst = (node: VueAstNode) => {\n if (node.type === NODE_TYPES.TEXT) {\n const text = node.content ?? '';\n\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n // When the existing call is destructured, access the key directly;\n // otherwise use the `content` variable.\n const ref = isDestructured ? key : `${varName}.${key}`;\n replacements.push({\n start: node.loc.start.offset,\n end: node.loc.end.offset,\n replacement: `{{ ${ref} }}`,\n key,\n value: text.replace(/\\s+/g, ' ').trim(),\n });\n }\n } else if (node.type === NODE_TYPES.ELEMENT) {\n const children = node.children ?? [];\n\n // Try to handle as insertion (mixed TEXT + INTERPOLATION children)\n if (\n children.length > 0 &&\n children.some((c) => c.type === NODE_TYPES.INTERPOLATION)\n ) {\n const parts: {\n type: 'text' | 'var';\n value: string;\n originalExpr: string;\n }[] = [];\n let hasSignificantText = false;\n let isValid = true;\n\n for (const child of children) {\n if (child.type === NODE_TYPES.TEXT) {\n const text = child.content ?? '';\n if (text.trim().length > 0) hasSignificantText = true;\n parts.push({ type: 'text', value: text, originalExpr: '' });\n } else if (child.type === NODE_TYPES.INTERPOLATION) {\n // Extract the expression source between {{ and }}\n const exprCode = code\n .slice(child.loc.start.offset + 2, child.loc.end.offset - 2)\n .trim();\n const varName = exprCode.includes('.')\n ? exprCode\n .split('.')\n .pop()!\n .replace(/[^\\w$]/g, '')\n : exprCode;\n parts.push({\n type: 'var',\n value: varName,\n originalExpr: exprCode,\n });\n } else {\n isValid = false;\n break;\n }\n }\n\n if (\n isValid &&\n hasSignificantText &&\n parts.some((p) => p.type === 'var')\n ) {\n let combined = '';\n for (const p of parts) {\n combined += p.type === 'var' ? `{{${p.value}}}` : p.value;\n }\n const cleanString = combined.replace(/\\s+/g, ' ').trim();\n\n if (shouldExtract?.(cleanString) && generateKey) {\n const key = generateKey(cleanString, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `${varName}.${key}`;\n\n const uniqueVarPairs = [\n ...new Set(\n parts\n .filter((p) => p.type === 'var')\n .map((p) => `${p.value}: ${p.originalExpr}`)\n ),\n ];\n const varArgs = uniqueVarPairs.join(', ');\n const replacement = `{{ ${ref}({ ${varArgs} }) }}`;\n\n const firstChild = children[0];\n const lastChild = children[children.length - 1];\n replacements.push({\n start: firstChild.loc.start.offset,\n end: lastChild.loc.end.offset,\n replacement,\n key,\n value: cleanString,\n });\n\n // Process props but skip children (they are replaced)\n node.props?.forEach((prop) => {\n if (\n prop.type === NODE_TYPES.ATTRIBUTE &&\n (attributesToExtract as readonly string[]).includes(\n prop.name\n ) &&\n prop.value\n ) {\n const text = prop.value.content;\n if (shouldExtract?.(text) && generateKey) {\n const propKey = generateKey(text, existingKeys);\n existingKeys.add(propKey);\n const propRef = isDestructured\n ? propKey\n : `${varName}.${propKey}`;\n replacements.push({\n start: prop.loc.start.offset,\n end: prop.loc.end.offset,\n replacement: `:${prop.name}=\"${propRef}\"`,\n key: propKey,\n value: text.trim(),\n });\n }\n }\n });\n return; // don't recurse into children\n }\n }\n }\n\n // Regular element: handle props\n node.props?.forEach((prop) => {\n if (\n prop.type === NODE_TYPES.ATTRIBUTE &&\n (attributesToExtract as readonly string[]).includes(prop.name) &&\n prop.value\n ) {\n const text = prop.value.content;\n\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `${varName}.${key}`;\n replacements.push({\n start: prop.loc.start.offset,\n end: prop.loc.end.offset,\n replacement: `:${prop.name}=\"${ref}\"`,\n key,\n value: text.trim(),\n });\n }\n }\n });\n }\n\n if (node.children) {\n node.children.forEach(walkVueAst);\n }\n };\n\n walkVueAst(sfc.descriptor.template.ast);\n }\n\n // Extract and Walk Script using Babel\n if (scriptBlock) {\n const scriptText = scriptBlock.content;\n const offset = scriptBlock.loc.start.offset;\n\n try {\n const ast = babelParse(scriptText, {\n configFile: false,\n babelrc: false,\n parserOpts: {\n sourceType: 'module',\n plugins: ['typescript', 'jsx'],\n },\n });\n\n if (ast) {\n traverse(ast, {\n StringLiteral(path: any) {\n if (path.parentPath.isImportDeclaration()) return;\n\n if (path.parentPath.isExportDeclaration()) return;\n\n if (path.parentPath.isImportSpecifier()) return;\n\n if (path.parentPath.isObjectProperty() && path.key === 'key')\n return;\n\n if (path.parentPath.isCallExpression()) {\n const callee = path.parentPath.node.callee;\n\n if (\n t.isMemberExpression(callee) &&\n t.isIdentifier(callee.object) &&\n callee.object.name === 'console'\n )\n return;\n\n if (\n t.isIdentifier(callee) &&\n (callee.name === 'useIntlayer' || callee.name === 't')\n )\n return;\n\n if (callee.type === 'Import') return;\n\n if (t.isIdentifier(callee) && callee.name === 'require') return;\n }\n\n const text = path.node.value;\n\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n\n if (path.node.start != null && path.node.end != null) {\n const ref = isDestructured ? key : `${varName}.${key}`;\n replacements.push({\n start: offset + path.node.start,\n end: offset + path.node.end,\n replacement: ref,\n key,\n value: text.trim(),\n });\n }\n }\n },\n });\n }\n } catch (e) {\n console.warn(\n `Vue extraction: Failed to parse script content for ${filename}`,\n e\n );\n }\n }\n\n // Abort if nothing was extracted\n if (replacements.length === 0) return null;\n\n // Apply Replacements in Reverse Order\n replacements.sort((a, b) => b.start - a.start);\n\n for (const { start, end, replacement, key, value } of replacements) {\n magic.overwrite(start, end, replacement);\n extractedContent[key] = value;\n }\n\n // When the existing call is destructured, inject only the missing keys into\n // the ObjectPattern — no new `content` variable is needed.\n if (\n existingCallInfo?.isDestructured &&\n existingCallInfo.closingBraceAbsolutePos >= 0\n ) {\n const missingKeys = Object.keys(extractedContent).filter(\n (k) => !existingCallInfo.existingDestructuredKeys.includes(k)\n );\n\n if (missingKeys.length > 0) {\n // Insert right after the last property so the space/newline before `}`\n // is naturally preserved: `{ a }` → `{ a, b }`.\n magic.appendLeft(\n existingCallInfo.lastPropAbsoluteEnd,\n `, ${missingKeys.join(', ')}`\n );\n }\n }\n\n // Inject necessary imports and setup (only when no existing call was detected)\n const finalScriptContent = scriptBlock?.content ?? '';\n\n const hasUseIntlayerImport =\n /import\\s*{[^}]*useIntlayer[^}]*}\\s*from\\s*['\"][^'\"]+['\"]/.test(\n finalScriptContent\n ) ||\n /import\\s+useIntlayer\\s+from\\s*['\"][^'\"]+['\"]/.test(finalScriptContent);\n\n // An existing call (destructured or not) means no new declaration is needed.\n const hasContentDeclaration =\n existingCallInfo !== null ||\n /const\\s+content\\s*=\\s*useIntlayer\\s*\\(/.test(finalScriptContent);\n\n const importStmt = hasUseIntlayerImport\n ? ''\n : `import { useIntlayer } from '${packageName}';`;\n const contentDecl = hasContentDeclaration\n ? ''\n : `const content = useIntlayer('${dictionaryKey}');`;\n\n const injectionParts = [importStmt, contentDecl].filter(Boolean);\n\n if (injectionParts.length > 0) {\n const injection = `\\n${injectionParts.join('\\n')}\\n`;\n\n if (sfc.descriptor.scriptSetup) {\n magic.appendLeft(sfc.descriptor.scriptSetup.loc.start.offset, injection);\n } else if (sfc.descriptor.script) {\n magic.appendLeft(sfc.descriptor.script.loc.start.offset, injection);\n } else {\n magic.prepend(\n `<script setup>\\n${importStmt}\\n${contentDecl}\\n</script>\\n`\n );\n }\n }\n\n if (onExtract) {\n onExtract({\n dictionaryKey,\n filePath: filename,\n content: { ...extractedContent },\n locale: defaultLocale,\n });\n }\n\n return {\n code: magic.toString(),\n map: magic.generateMap({ source: filename, includeContent: true }),\n extracted: true,\n };\n};\n\ntype Tools = {\n generateKey: (text: string, existingKeys: Set<string>) => string;\n shouldExtract: (text: string) => boolean;\n extractDictionaryKeyFromPath: (path: string) => string;\n attributesToExtract: readonly string[];\n extractTsContent: any;\n};\n\nexport const processVueFile = (\n filePath: string,\n _componentKey: string,\n packageName: string,\n tools: Tools,\n save: boolean = true,\n providedCode?: string\n): {\n extractedContent: Record<string, string>;\n code: string;\n map?: any;\n} | null => {\n const code = providedCode ?? readFileSync(filePath, 'utf-8');\n let extractedContent: Record<string, string> = {};\n\n const result = intlayerVueExtract(code, filePath, {\n packageName,\n dictionaryKey: _componentKey,\n shouldExtract: tools.shouldExtract,\n generateKey: tools.generateKey,\n extractDictionaryKeyFromPath: tools.extractDictionaryKeyFromPath,\n attributesToExtract: tools.attributesToExtract,\n onExtract: (extractResult) => {\n extractedContent = extractResult.content;\n },\n });\n\n if (!result) return null;\n\n if (save) {\n writeFileSync(filePath, result.code);\n }\n\n return {\n extractedContent,\n code: result.code,\n map: result.map,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"vue-intlayer-extract.mjs","names":["babelParse","t"],"sources":["../../src/vue-intlayer-extract.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { parseSync as babelParse, types as t, traverse } from '@babel/core';\nimport { DEFAULT_LOCALE } from '@intlayer/config/defaultValues';\nimport { getExtractionIgnoreDirectives } from '@intlayer/config/extract';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport vueSfc from '@vue/compiler-sfc';\nimport MagicString from 'magic-string';\n\ntype ExistingCallInfo = {\n isDestructured: boolean;\n existingDestructuredKeys: string[];\n /** The variable name used to store the call result (e.g. `t` in `const t = useIntlayer(...)`) */\n variableName: string;\n /** Absolute position of `}` in the full file — only valid when `isDestructured` */\n closingBraceAbsolutePos: number;\n /** Absolute position of end of last property — only valid when `isDestructured` */\n lastPropAbsoluteEnd: number;\n} | null;\n\n/**\n * Detects whether the script block already contains a `useIntlayer` /\n * `getIntlayer` call and, if so, whether its result is destructured.\n *\n * @param scriptText Raw text of the script block content.\n * @param absoluteOffset Byte offset of `scriptText[0]` in the full SFC source.\n */\nconst detectExistingIntlayerCall = (\n scriptText: string,\n absoluteOffset: number\n): ExistingCallInfo => {\n let info: ExistingCallInfo = null;\n\n try {\n const ast = babelParse(scriptText, {\n configFile: false,\n babelrc: false,\n parserOpts: { sourceType: 'module', plugins: ['typescript', 'jsx'] },\n });\n\n if (!ast) return null;\n\n traverse(ast, {\n CallExpression(path: any) {\n const callee = path.node.callee;\n\n if (\n !t.isIdentifier(callee) ||\n (callee.name !== 'useIntlayer' && callee.name !== 'getIntlayer')\n )\n return;\n\n const parent = path.parent;\n\n if (t.isVariableDeclarator(parent) && t.isObjectPattern(parent.id)) {\n const properties = parent.id.properties;\n const existingDestructuredKeys = properties\n .filter(\n (property: any): property is typeof t.objectProperty =>\n t.isObjectProperty(property) && t.isIdentifier(property.key)\n )\n .map((property: any) => (property.key as any).name as string);\n const lastProp = properties[properties.length - 1];\n\n info = {\n isDestructured: true,\n variableName: 'content',\n existingDestructuredKeys,\n closingBraceAbsolutePos: absoluteOffset + (parent.id.end! - 1),\n lastPropAbsoluteEnd: absoluteOffset + lastProp.end!,\n };\n } else {\n const variableName =\n t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)\n ? parent.id.name\n : 'content';\n\n info = {\n isDestructured: false,\n variableName,\n existingDestructuredKeys: [],\n closingBraceAbsolutePos: -1,\n lastPropAbsoluteEnd: -1,\n };\n }\n\n path.stop();\n },\n });\n } catch {\n // Silently ignore parse failures — fall back to no-info\n }\n\n return info;\n};\n\nexport type ExtractedContent = Record<string, string>;\n\nexport type ExtractResult = {\n dictionaryKey: string;\n filePath: string;\n content: ExtractedContent;\n locale: Locale;\n};\n\nexport type ExtractPluginOptions = {\n defaultLocale?: Locale;\n packageName?: string;\n filesList?: string[];\n shouldExtract?: (text: string) => boolean;\n onExtract?: (result: ExtractResult) => void;\n dictionaryKey?: string;\n attributesToExtract?: readonly string[];\n extractDictionaryKeyFromPath?: (path: string) => string;\n generateKey?: (text: string, existingKeys: Set<string>) => string;\n};\n\ntype Replacement = {\n start: number;\n end: number;\n replacement: string;\n key: string;\n value: string;\n};\n\nexport const shouldProcessFile = (\n filename: string | undefined,\n filesList?: string[]\n): boolean => {\n if (!filename) return false;\n if (!filesList || filesList.length === 0) return true;\n\n const normalizedFilename = filename.replace(/\\\\/g, '/');\n return filesList.some((f) => {\n const normalizedF = f.replace(/\\\\/g, '/');\n return normalizedF === normalizedFilename;\n });\n};\n\ntype VueParseResult = {\n descriptor: {\n template?: {\n ast: VueAstNode;\n loc: { start: { offset: number }; end: { offset: number } };\n };\n script?: {\n content: string;\n loc: { start: { offset: number }; end: { offset: number } };\n };\n scriptSetup?: {\n content: string;\n loc: { start: { offset: number }; end: { offset: number } };\n };\n };\n};\n\ntype VueAstNode = {\n type: number;\n content?: string;\n children?: VueAstNode[];\n props?: VueAstProp[];\n loc: { start: { offset: number }; end: { offset: number } };\n};\n\ntype VueAstProp = {\n type: number;\n name: string;\n value?: { content: string };\n loc: { start: { offset: number }; end: { offset: number } };\n};\n\nconst NODE_TYPES = {\n TEXT: 2,\n ELEMENT: 1,\n ATTRIBUTE: 6,\n INTERPOLATION: 5,\n};\n\nexport const intlayerVueExtract = (\n code: string,\n filename: string,\n options: ExtractPluginOptions = {}\n): { code: string; map?: unknown; extracted: boolean } | null => {\n const {\n defaultLocale = DEFAULT_LOCALE,\n packageName = 'vue-intlayer',\n filesList,\n shouldExtract,\n onExtract,\n dictionaryKey: dictionaryKeyOption,\n attributesToExtract = [],\n extractDictionaryKeyFromPath,\n generateKey,\n } = options;\n\n if (!shouldProcessFile(filename, filesList)) return null;\n if (!filename.endsWith('.vue')) return null;\n\n const ignoreDirectives = getExtractionIgnoreDirectives(code);\n\n if (ignoreDirectives.isFileIgnored) return null;\n\n let parseVue: (code: string) => VueParseResult;\n\n try {\n parseVue = vueSfc.parse as unknown as (code: string) => VueParseResult;\n } catch {\n console.warn('Vue extraction: @vue/compiler-sfc not found.');\n return null;\n }\n\n const sfc = parseVue(code);\n const magic = new MagicString(code);\n\n const extractedContent: ExtractedContent = {};\n const existingKeys = new Set<string>();\n const dictionaryKey =\n dictionaryKeyOption ?? extractDictionaryKeyFromPath?.(filename) ?? '';\n const replacements: Replacement[] = [];\n\n // Detect existing useIntlayer / getIntlayer call in the script block BEFORE\n // walking the template, so the correct access pattern can be chosen.\n const scriptBlock = sfc.descriptor.scriptSetup ?? sfc.descriptor.script;\n const existingCallInfo = scriptBlock\n ? detectExistingIntlayerCall(\n scriptBlock.content,\n scriptBlock.loc.start.offset\n )\n : null;\n\n const isDestructured = existingCallInfo?.isDestructured ?? false;\n const varName = existingCallInfo?.variableName ?? 'content';\n\n // Walk Vue Template AST\n if (sfc.descriptor.template) {\n /**\n * Walks the template; `isParentIgnored` is true when an ignore directive\n * covers the opening tag of the enclosing element.\n */\n const walkVueAst = (node: VueAstNode, isParentIgnored = false) => {\n const isNodeIgnored = ignoreDirectives.isOffsetIgnored(\n node.loc.start.offset\n );\n\n if (node.type === NODE_TYPES.TEXT) {\n const text = node.content ?? '';\n const leadingWhitespaceLength = text.length - text.trimStart().length;\n const isTextIgnored =\n isParentIgnored ||\n ignoreDirectives.isOffsetIgnored(\n node.loc.start.offset + leadingWhitespaceLength\n );\n\n if (!isTextIgnored && shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n // When the existing call is destructured, access the key directly;\n // otherwise use the `content` variable.\n const ref = isDestructured ? key : `${varName}.${key}`;\n replacements.push({\n start: node.loc.start.offset,\n end: node.loc.end.offset,\n replacement: `{{ ${ref} }}`,\n key,\n value: text.replace(/\\s+/g, ' ').trim(),\n });\n }\n } else if (node.type === NODE_TYPES.ELEMENT) {\n const children = node.children ?? [];\n\n /** Attributes on an ignored tag or line stay untouched. */\n const isPropIgnored = (prop: VueAstProp): boolean =>\n isNodeIgnored ||\n ignoreDirectives.isOffsetIgnored(prop.loc.start.offset);\n\n // Try to handle as insertion (mixed TEXT + INTERPOLATION children)\n if (\n !isNodeIgnored &&\n (children.length ?? 0) > 0 &&\n children.some((child) => child.type === NODE_TYPES.INTERPOLATION)\n ) {\n const parts: {\n type: 'text' | 'var';\n value: string;\n originalExpr: string;\n }[] = [];\n let hasSignificantText = false;\n let isValid = true;\n\n for (const child of children) {\n if (child.type === NODE_TYPES.TEXT) {\n const text = child.content ?? '';\n if (text.trim().length > 0) hasSignificantText = true;\n parts.push({ type: 'text', value: text, originalExpr: '' });\n } else if (child.type === NODE_TYPES.INTERPOLATION) {\n // Extract the expression source between {{ and }}\n const exprCode = code\n .slice(child.loc.start.offset + 2, child.loc.end.offset - 2)\n .trim();\n const varName = exprCode.includes('.')\n ? exprCode\n .split('.')\n .pop()!\n .replace(/[^\\w$]/g, '')\n : exprCode;\n parts.push({\n type: 'var',\n value: varName,\n originalExpr: exprCode,\n });\n } else {\n isValid = false;\n break;\n }\n }\n\n if (\n isValid &&\n hasSignificantText &&\n parts.some((p) => p.type === 'var')\n ) {\n let combined = '';\n for (const p of parts) {\n combined += p.type === 'var' ? `{{${p.value}}}` : p.value;\n }\n const cleanString = combined.replace(/\\s+/g, ' ').trim();\n\n if (shouldExtract?.(cleanString) && generateKey) {\n const key = generateKey(cleanString, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `${varName}.${key}`;\n\n const uniqueVarPairs = [\n ...new Set(\n parts\n .filter((p) => p.type === 'var')\n .map((p) => `${p.value}: ${p.originalExpr}`)\n ),\n ];\n const varArgs = uniqueVarPairs.join(', ');\n const replacement = `{{ ${ref}({ ${varArgs} }) }}`;\n\n const firstChild = children[0];\n const lastChild = children[children.length - 1];\n replacements.push({\n start: firstChild?.loc.start.offset ?? 0,\n end: lastChild?.loc.end.offset ?? 0,\n replacement,\n key,\n value: cleanString,\n });\n\n // Process props but skip children (they are replaced)\n node.props?.forEach((prop) => {\n if (\n prop.type === NODE_TYPES.ATTRIBUTE &&\n (attributesToExtract as readonly string[]).includes(\n prop.name\n ) &&\n prop.value &&\n !isPropIgnored(prop)\n ) {\n const text = prop.value.content;\n if (shouldExtract?.(text) && generateKey) {\n const propKey = generateKey(text, existingKeys);\n existingKeys.add(propKey);\n const propRef = isDestructured\n ? propKey\n : `${varName}.${propKey}`;\n replacements.push({\n start: prop.loc.start.offset,\n end: prop.loc.end.offset,\n replacement: `:${prop.name}=\"${propRef}\"`,\n key: propKey,\n value: text.trim(),\n });\n }\n }\n });\n return; // don't recurse into children\n }\n }\n }\n\n // Regular element: handle props\n node.props?.forEach((prop) => {\n if (\n prop.type === NODE_TYPES.ATTRIBUTE &&\n (attributesToExtract as readonly string[]).includes(prop.name) &&\n prop.value &&\n !isPropIgnored(prop)\n ) {\n const text = prop.value.content;\n\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `${varName}.${key}`;\n replacements.push({\n start: prop.loc.start.offset,\n end: prop.loc.end.offset,\n replacement: `:${prop.name}=\"${ref}\"`,\n key,\n value: text.trim(),\n });\n }\n }\n });\n }\n\n if (node.children) {\n node.children.forEach((child) =>\n walkVueAst(\n child,\n node.type === NODE_TYPES.ELEMENT ? isNodeIgnored : isParentIgnored\n )\n );\n }\n };\n\n walkVueAst(sfc.descriptor.template.ast);\n }\n\n // Extract and Walk Script using Babel\n if (scriptBlock) {\n const scriptText = scriptBlock.content;\n const offset = scriptBlock.loc.start.offset;\n\n try {\n const ast = babelParse(scriptText, {\n configFile: false,\n babelrc: false,\n parserOpts: {\n sourceType: 'module',\n plugins: ['typescript', 'jsx'],\n },\n });\n\n if (ast) {\n traverse(ast, {\n StringLiteral(path: any) {\n if (path.parentPath.isImportDeclaration()) return;\n\n if (path.parentPath.isExportDeclaration()) return;\n\n if (path.parentPath.isImportSpecifier()) return;\n\n if (path.parentPath.isObjectProperty() && path.key === 'key')\n return;\n\n if (path.parentPath.isCallExpression()) {\n const callee = path.parentPath.node.callee;\n\n if (\n t.isMemberExpression(callee) &&\n t.isIdentifier(callee.object) &&\n callee.object.name === 'console'\n )\n return;\n\n if (\n t.isIdentifier(callee) &&\n (callee.name === 'useIntlayer' || callee.name === 't')\n )\n return;\n\n if (callee.type === 'Import') return;\n\n if (t.isIdentifier(callee) && callee.name === 'require') return;\n }\n\n const text = path.node.value;\n\n if (\n path.node.start != null &&\n ignoreDirectives.isOffsetIgnored(offset + path.node.start)\n )\n return;\n\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n\n if (path.node.start != null && path.node.end != null) {\n const ref = isDestructured ? key : `${varName}.${key}`;\n replacements.push({\n start: offset + path.node.start,\n end: offset + path.node.end,\n replacement: ref,\n key,\n value: text.trim(),\n });\n }\n }\n },\n });\n }\n } catch (e) {\n console.warn(\n `Vue extraction: Failed to parse script content for ${filename}`,\n e\n );\n }\n }\n\n // Abort if nothing was extracted\n if (replacements.length === 0) return null;\n\n // Apply Replacements in Reverse Order\n replacements.sort((a, b) => b.start - a.start);\n\n for (const { start, end, replacement, key, value } of replacements) {\n magic.overwrite(start, end, replacement);\n extractedContent[key] = value;\n }\n\n // When the existing call is destructured, inject only the missing keys into\n // the ObjectPattern — no new `content` variable is needed.\n if (\n existingCallInfo?.isDestructured &&\n existingCallInfo.closingBraceAbsolutePos >= 0\n ) {\n const missingKeys = Object.keys(extractedContent).filter(\n (k) => !existingCallInfo.existingDestructuredKeys.includes(k)\n );\n\n if (missingKeys.length > 0) {\n // Insert right after the last property so the space/newline before `}`\n // is naturally preserved: `{ a }` → `{ a, b }`.\n magic.appendLeft(\n existingCallInfo.lastPropAbsoluteEnd,\n `, ${missingKeys.join(', ')}`\n );\n }\n }\n\n // Inject necessary imports and setup (only when no existing call was detected)\n const finalScriptContent = scriptBlock?.content ?? '';\n\n const hasUseIntlayerImport =\n /import\\s*{[^}]*useIntlayer[^}]*}\\s*from\\s*['\"][^'\"]+['\"]/.test(\n finalScriptContent\n ) ||\n /import\\s+useIntlayer\\s+from\\s*['\"][^'\"]+['\"]/.test(finalScriptContent);\n\n // An existing call (destructured or not) means no new declaration is needed.\n const hasContentDeclaration =\n existingCallInfo !== null ||\n /const\\s+content\\s*=\\s*useIntlayer\\s*\\(/.test(finalScriptContent);\n\n const importStmt = hasUseIntlayerImport\n ? ''\n : `import { useIntlayer } from '${packageName}';`;\n const contentDecl = hasContentDeclaration\n ? ''\n : `const content = useIntlayer('${dictionaryKey}');`;\n\n const injectionParts = [importStmt, contentDecl].filter(Boolean);\n\n if (injectionParts.length > 0) {\n const injection = `\\n${injectionParts.join('\\n')}\\n`;\n\n if (sfc.descriptor.scriptSetup) {\n magic.appendLeft(sfc.descriptor.scriptSetup.loc.start.offset, injection);\n } else if (sfc.descriptor.script) {\n magic.appendLeft(sfc.descriptor.script.loc.start.offset, injection);\n } else {\n magic.prepend(\n `<script setup>\\n${importStmt}\\n${contentDecl}\\n</script>\\n`\n );\n }\n }\n\n if (onExtract) {\n onExtract({\n dictionaryKey,\n filePath: filename,\n content: { ...extractedContent },\n locale: defaultLocale,\n });\n }\n\n return {\n code: magic.toString(),\n map: magic.generateMap({ source: filename, includeContent: true }),\n extracted: true,\n };\n};\n\ntype Tools = {\n generateKey: (text: string, existingKeys: Set<string>) => string;\n shouldExtract: (text: string) => boolean;\n extractDictionaryKeyFromPath: (path: string) => string;\n attributesToExtract: readonly string[];\n extractTsContent: any;\n};\n\nexport const processVueFile = (\n filePath: string,\n _componentKey: string,\n packageName: string,\n tools: Tools,\n save: boolean = true,\n providedCode?: string\n): {\n extractedContent: Record<string, string>;\n code: string;\n map?: any;\n} | null => {\n const code = providedCode ?? readFileSync(filePath, 'utf-8');\n let extractedContent: Record<string, string> = {};\n\n const result = intlayerVueExtract(code, filePath, {\n packageName,\n dictionaryKey: _componentKey,\n shouldExtract: tools.shouldExtract,\n generateKey: tools.generateKey,\n extractDictionaryKeyFromPath: tools.extractDictionaryKeyFromPath,\n attributesToExtract: tools.attributesToExtract,\n onExtract: (extractResult) => {\n extractedContent = extractResult.content;\n },\n });\n\n if (!result) return null;\n\n if (save) {\n writeFileSync(filePath, result.code);\n }\n\n return {\n extractedContent,\n code: result.code,\n map: result.map,\n };\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"vue-intlayer-extract.d.ts","names":[],"sources":["../../src/vue-intlayer-extract.ts"],"mappings":";YA8FY,mBAAmB;YAEnB;EACV;EACA;EACA,SAAS;EACT,QAAQ;;YAGE;EACV,gBAAgB;EAChB;EACA;EACA,iBAAiB;EACjB,aAAa,QAAQ;EACrB;EACA;EACA,gCAAgC;EAChC,eAAe,cAAc,cAAc;;qBAWhC,oBAAiB,8BACA;qBAoDjB,qBAAkB,cACjB,kBACI,UACP;EACN;EAAc;EAAe;;KAkX7B;EACH,cAAc,cAAc,cAAc;EAC1C,gBAAgB;EAChB,+BAA+B;EAC/B;EACA;;qBAGW,iBAAc,kBACT,uBACK,qBACF,OACZ,OAAK,gBACC;EAGb,kBAAkB;EAClB;EACA"}
1
+ {"version":3,"file":"vue-intlayer-extract.d.ts","names":[],"sources":["../../src/vue-intlayer-extract.ts"],"mappings":";YA+FY,mBAAmB;YAEnB;EACV;EACA;EACA,SAAS;EACT,QAAQ;;YAGE;EACV,gBAAgB;EAChB;EACA;EACA,iBAAiB;EACjB,aAAa,QAAQ;EACrB;EACA;EACA,gCAAgC;EAChC,eAAe,cAAc,cAAc;;qBAWhC,oBAAiB,8BACA;qBAoDjB,qBAAkB,cACjB,kBACI,UACP;EACN;EAAc;EAAe;;KAuZ7B;EACH,cAAc,cAAc,cAAc;EAC1C,gBAAgB;EAChB,+BAA+B;EAC/B;EACA;;qBAGW,iBAAc,kBACT,uBACK,qBACF,OACZ,OAAK,gBACC;EAGb,kBAAkB;EAClB;EACA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/vue-compiler",
3
- "version": "9.7.3",
3
+ "version": "9.8.0-canary.1",
4
4
  "private": false,
5
5
  "description": "Vite-compatible compiler plugin for Vue with Intlayer, providing HMR support, file transformation, and optimized dictionary loading for Vue applications.",
6
6
  "keywords": [
@@ -79,8 +79,8 @@
79
79
  },
80
80
  "dependencies": {
81
81
  "@babel/core": "8.1.0",
82
- "@intlayer/config": "9.7.3",
83
- "@intlayer/types": "9.7.3",
82
+ "@intlayer/config": "9.8.0-canary.1",
83
+ "@intlayer/types": "9.8.0-canary.1",
84
84
  "@vue/compiler-sfc": ">=3.0.0",
85
85
  "fast-glob": "3.3.3",
86
86
  "magic-string": "1.4.5"