@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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
147
|
-
end: lastChild
|
|
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":"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"}
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
143
|
-
end: lastChild
|
|
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":";;;;;;;;;;;;;;AAyBA,MAAM,8BACJ,YACA,mBACqB;CACrB,IAAI,OAAyB;CAE7B,IAAI;EACF,MAAM,MAAMA,UAAW,YAAY;GACjC,YAAY;GACZ,SAAS;GACT,YAAY;IAAE,YAAY;IAAU,SAAS,CAAC,cAAc,KAAK;GAAE;EACrE,CAAC;EAED,IAAI,CAAC,KAAK,OAAO;EAEjB,SAAS,KAAK,EACZ,eAAe,MAAW;GACxB,MAAM,SAAS,KAAK,KAAK;GAEzB,IACE,CAACC,MAAE,aAAa,MAAM,KACrB,OAAO,SAAS,iBAAiB,OAAO,SAAS,eAElD;GAEF,MAAM,SAAS,KAAK;GAEpB,IAAIA,MAAE,qBAAqB,MAAM,KAAKA,MAAE,gBAAgB,OAAO,EAAE,GAAG;IAClE,MAAM,aAAa,OAAO,GAAG;IAC7B,MAAM,2BAA2B,WAC9B,QACE,aACCA,MAAE,iBAAiB,QAAQ,KAAKA,MAAE,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,MAAE,qBAAqB,MAAM,KAAKA,MAAE,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,gBAAgB,gBAChB,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,IAAI;CAEJ,IAAI;EACF,WAAW,OAAO;CACpB,QAAQ;EACN,QAAQ,KAAK,8CAA8C;EAC3D,OAAO;CACT;CAEA,MAAM,MAAM,SAAS,IAAI;CACzB,MAAM,QAAQ,IAAI,YAAY,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;EAC3B,MAAM,cAAc,SAAqB;GACvC,IAAI,KAAK,SAAS,WAAW,MAAM;IACjC,MAAM,OAAO,KAAK,WAAW;IAE7B,IAAI,gBAAgB,IAAI,KAAK,aAAa;KACxC,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,IACE,SAAS,SAAS,KAClB,SAAS,MAAM,MAAM,EAAE,SAAS,WAAW,aAAa,GACxD;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,WAAW,IAAI,MAAM;QAC5B,KAAK,UAAU,IAAI,IAAI;QACvB;QACA;QACA,OAAO;OACT,CAAC;OAGD,KAAK,OAAO,SAAS,SAAS;QAC5B,IACE,KAAK,SAAS,WAAW,aACxB,oBAA0C,SACzC,KAAK,IACP,KACA,KAAK,OACL;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,OACL;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,QAAQ,UAAU;EAEpC;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,MAAMD,UAAW,YAAY;IACjC,YAAY;IACZ,SAAS;IACT,YAAY;KACV,YAAY;KACZ,SAAS,CAAC,cAAc,KAAK;IAC/B;GACF,CAAC;GAED,IAAI,KACF,SAAS,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,MAAE,mBAAmB,MAAM,KAC3BA,MAAE,aAAa,OAAO,MAAM,KAC5B,OAAO,OAAO,SAAS,WAEvB;KAEF,IACEA,MAAE,aAAa,MAAM,MACpB,OAAO,SAAS,iBAAiB,OAAO,SAAS,MAElD;KAEF,IAAI,OAAO,SAAS,UAAU;KAE9B,IAAIA,MAAE,aAAa,MAAM,KAAK,OAAO,SAAS,WAAW;IAC3D;IAEA,MAAM,OAAO,KAAK,KAAK;IAEvB,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,gBAAgB,aAAa,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,cAAc,UAAU,OAAO,IAAI;CAGrC,OAAO;EACL;EACA,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF"}
|
|
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":";;;;;;;;;;;;;;;AA0BA,MAAM,8BACJ,YACA,mBACqB;CACrB,IAAI,OAAyB;CAE7B,IAAI;EACF,MAAM,MAAMA,UAAW,YAAY;GACjC,YAAY;GACZ,SAAS;GACT,YAAY;IAAE,YAAY;IAAU,SAAS,CAAC,cAAc,KAAK;GAAE;EACrE,CAAC;EAED,IAAI,CAAC,KAAK,OAAO;EAEjB,SAAS,KAAK,EACZ,eAAe,MAAW;GACxB,MAAM,SAAS,KAAK,KAAK;GAEzB,IACE,CAACC,MAAE,aAAa,MAAM,KACrB,OAAO,SAAS,iBAAiB,OAAO,SAAS,eAElD;GAEF,MAAM,SAAS,KAAK;GAEpB,IAAIA,MAAE,qBAAqB,MAAM,KAAKA,MAAE,gBAAgB,OAAO,EAAE,GAAG;IAClE,MAAM,aAAa,OAAO,GAAG;IAC7B,MAAM,2BAA2B,WAC9B,QACE,aACCA,MAAE,iBAAiB,QAAQ,KAAKA,MAAE,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,MAAE,qBAAqB,MAAM,KAAKA,MAAE,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,gBAAgB,gBAChB,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,mBAAmB,8BAA8B,IAAI;CAE3D,IAAI,iBAAiB,eAAe,OAAO;CAE3C,IAAI;CAEJ,IAAI;EACF,WAAW,OAAO;CACpB,QAAQ;EACN,QAAQ,KAAK,8CAA8C;EAC3D,OAAO;CACT;CAEA,MAAM,MAAM,SAAS,IAAI;CACzB,MAAM,QAAQ,IAAI,YAAY,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,MAAMD,UAAW,YAAY;IACjC,YAAY;IACZ,SAAS;IACT,YAAY;KACV,YAAY;KACZ,SAAS,CAAC,cAAc,KAAK;IAC/B;GACF,CAAC;GAED,IAAI,KACF,SAAS,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,MAAE,mBAAmB,MAAM,KAC3BA,MAAE,aAAa,OAAO,MAAM,KAC5B,OAAO,OAAO,SAAS,WAEvB;KAEF,IACEA,MAAE,aAAa,MAAM,MACpB,OAAO,SAAS,iBAAiB,OAAO,SAAS,MAElD;KAEF,IAAI,OAAO,SAAS,UAAU;KAE9B,IAAIA,MAAE,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,gBAAgB,aAAa,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,cAAc,UAAU,OAAO,IAAI;CAGrC,OAAO;EACL;EACA,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue-intlayer-extract.d.ts","names":[],"sources":["../../src/vue-intlayer-extract.ts"],"mappings":";
|
|
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.
|
|
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.
|
|
83
|
-
"@intlayer/types": "9.
|
|
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"
|