@intlayer/vue-compiler 9.3.0 → 9.3.2
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.
- package/README.md +24 -24
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +1 -2
- package/dist/cjs/vue-intlayer-extract.cjs +16 -8
- package/dist/cjs/vue-intlayer-extract.cjs.map +1 -1
- package/dist/esm/vue-intlayer-extract.mjs +17 -9
- package/dist/esm/vue-intlayer-extract.mjs.map +1 -1
- package/dist/types/vue-intlayer-extract.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -47,27 +47,27 @@ With **per-locale content files**, **TypeScript autocompletion**, **tree-shakabl
|
|
|
47
47
|
|
|
48
48
|
## Keys benefits of Intlayer:
|
|
49
49
|
|
|
50
|
-
| Feature | Description
|
|
51
|
-
| --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/frameworks.png?raw=true" alt="Feature" width="700"> | **Cross-Frameworks Support**<br><br>Intlayer is compatible with all major frameworks and libraries, including Next.js, React, Vite, Vue.js, Nuxt, Preact, Express, and more.
|
|
53
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/javascript_content_management.jpg?raw=true" alt="Feature" width="700"> | **JavaScript-Powered Content Management**<br><br>Harness the flexibility of JavaScript to define and manage your content efficiently. <br><br> - [Content declaration](https://intlayer.org/doc/concept/content)
|
|
54
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/per_locale_content_declaration_file.png?raw=true" alt="Feature" width="700"> | **Per-Locale Content Declaration File**<br><br>Speed up your development by declaring your content once, before auto generation.<br><br> - [Per-Locale Content Declaration File](https://intlayer.org/doc/concept/per-locale-file)
|
|
55
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/compiler.jpg?raw=true" alt="Feature" width="700"> | **Compiler**<br><br>The Intlayer Compiler extract automatically the content from the components and generate the dictionary files.<br><br> - [Compiler](https://intlayer.org/doc/compiler)
|
|
56
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true" alt="Feature" width="700"> | **Type-Safe Environment**<br><br>Leverage TypeScript to ensure your content definitions and code are error-free, while also benefiting from IDE autocompletion.<br><br> - [TypeScript configuration](https://intlayer.org/doc/environment/vite-and-react#configure-typescript)
|
|
57
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/config_file.png?raw=true" alt="Feature" width="700"> | **Simplified Setup**<br><br>Get up and running quickly with minimal configuration. Adjust settings for internationalization, routing, AI, build, and content handling with ease. <br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs)
|
|
58
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/content_retrieval.png?raw=true" alt="Feature" width="700"> | **Simplified Content Retrieval**<br><br>No need to call your `t` function for each piece of content. Retrieve all your content directly using a single hook.<br><br> - [React integration](https://intlayer.org/doc/environment/create-react-app)
|
|
59
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/server_component.png?raw=true" alt="Feature" width="700"> | **Consistent Server Component Implementation**<br><br>Perfectly suited for Next.js server components, use the same implementation for both client and server components, no need to pass your `t` function across each server component. <br><br> - [Server Components](https://intlayer.org/doc/environment/nextjs#step-7-utilize-content-in-your-code)
|
|
60
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/file_tree.png?raw=true" alt="Feature" width="700"> | **Organized Codebase**<br><br>Keep your codebase more organized: 1 component = 1 dictionary in the same folder. Translations close to their respective components, enhance maintainability and clarity. <br><br> - [How Intlayer works](https://intlayer.org/doc/concept/how-works-intlayer)
|
|
61
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/url_routing.png?raw=true" alt="Feature" width="700"> | **Enhanced Routing**<br><br>Full support of app routing, adapting seamlessly to complex application structures, for Next.js, React, Vite, Vue.js, etc.<br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs)
|
|
62
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/markdown.png?raw=true" alt="Feature" width="700"> | **Markdown Support**<br><br>Import and interpret, locale files and remote Markdown for multilingual content like privacy policies, documentation, etc. Interpret and make Markdown metadata accessible in your code.<br><br> - [Content files](https://intlayer.org/doc/concept/content/file)
|
|
63
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/visual_editor.png?raw=true" alt="Feature" width="700"> | **Free Visual Editor & CMS**<br><br>A free visual editor and CMS are available for content writers, removing the need for a localization platform. Keep your content synchronized using Git, or externalize it totally or partially with the CMS.<br><br> - [Intlayer Editor](https://intlayer.org/doc/concept/editor) <br> - [Intlayer CMS](https://intlayer.org/doc/concept/cms)
|
|
64
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/bundle.png?raw=true" alt="Feature" width="700"> | **Tree-shakable Content**<br><br>Tree-shakable content, reducing the size of the final bundle. Loads content per component, excluding any unused content from your bundle. Supports lazy loading to enhance app loading efficiency. <br><br> - [App build optimization](https://intlayer.org/doc/concept/how-works-intlayer#app-build-optimization)
|
|
65
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/static_rendering.png?raw=true" alt="Feature" width="700"> | **Static Rendering**<br><br>Doesn't block Static Rendering. <br><br> - [Next.js integration](https://intlayer.org/doc/environment/nextjs)
|
|
66
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/AI_translation.png?raw=true" alt="Feature" width="700"> | **AI-Powered Translation**<br><br>Transform your website into 231 languages with just one click using Intlayer's advanced AI-powered translation tools using your own AI provider / API key. <br><br> - [CI/CD integration](https://intlayer.org/doc/concept/ci-cd) <br> - [Intlayer CLI](https://intlayer.org/doc/concept/cli) <br> - [Auto fill](https://intlayer.org/doc/concept/auto-fill)
|
|
67
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/mcp.png?raw=true" alt="Feature" width="700"> | **MCP Server Integration**<br><br>Provides an MCP (Model Context Protocol) server for IDE automation, enabling seamless content management and i18n workflows directly within your development environment. <br><br> - [MCP Server](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/mcp_server.md)
|
|
68
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/vscode_extension.png?raw=true" alt="Feature" width="700"> | **VSCode Extension**<br><br>Intlayer provides a VSCode extension to help you manage your content and translations, building your dictionaries, translating your content, and more. <br><br> - [VSCode Extension](https://intlayer.org/doc/vs-code-extension)
|
|
69
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/interoperability.png?raw=true" alt="Feature" width="700"> | **Interoperability**<br><br>Allow interoperability with react-i18next, next-i18next, next-intl, react-intl, vue-i18n. <br><br> - [Intlayer and react-intl](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [Intlayer and next-intl](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [Intlayer and next-i18next](https://intlayer.org/blog/intlayer-with-next-i18next) <br> - [Intlayer and vue-i18n](https://intlayer.org/blog/intlayer-with-vue-i18n) |
|
|
70
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/benchmark.png?raw=true" alt="Feature" width="700"> | **Performances & Benchmark**<br><br>Uses advanced tree-shaking and dynamic loading to boost performances and keep the solution as light as possible. <br><br> - [Performances & Benchmark](https://intlayer.org/doc/benchmark)
|
|
50
|
+
| Feature | Description |
|
|
51
|
+
| --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/frameworks.png?raw=true" alt="Feature" width="700"> | **Cross-Frameworks Support**<br><br>Intlayer is compatible with all major frameworks and libraries, including Next.js, React, Vite, Vue.js, Nuxt, Preact, Express, and more. |
|
|
53
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/javascript_content_management.jpg?raw=true" alt="Feature" width="700"> | **JavaScript-Powered Content Management**<br><br>Harness the flexibility of JavaScript to define and manage your content efficiently. <br><br> - [Content declaration](https://intlayer.org/doc/concept/content) |
|
|
54
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/per_locale_content_declaration_file.png?raw=true" alt="Feature" width="700"> | **Per-Locale Content Declaration File**<br><br>Speed up your development by declaring your content once, before auto generation.<br><br> - [Per-Locale Content Declaration File](https://intlayer.org/doc/concept/per-locale-file) |
|
|
55
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/compiler.jpg?raw=true" alt="Feature" width="700"> | **Compiler**<br><br>The Intlayer Compiler extract automatically the content from the components and generate the dictionary files.<br><br> - [Compiler](https://intlayer.org/doc/compiler) |
|
|
56
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true" alt="Feature" width="700"> | **Type-Safe Environment**<br><br>Leverage TypeScript to ensure your content definitions and code are error-free, while also benefiting from IDE autocompletion.<br><br> - [TypeScript configuration](https://intlayer.org/doc/environment/vite-and-react#configure-typescript) |
|
|
57
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/config_file.png?raw=true" alt="Feature" width="700"> | **Simplified Setup**<br><br>Get up and running quickly with minimal configuration. Adjust settings for internationalization, routing, AI, build, and content handling with ease. <br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs) |
|
|
58
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/content_retrieval.png?raw=true" alt="Feature" width="700"> | **Simplified Content Retrieval**<br><br>No need to call your `t` function for each piece of content. Retrieve all your content directly using a single hook.<br><br> - [React integration](https://intlayer.org/doc/environment/create-react-app) |
|
|
59
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/server_component.png?raw=true" alt="Feature" width="700"> | **Consistent Server Component Implementation**<br><br>Perfectly suited for Next.js server components, use the same implementation for both client and server components, no need to pass your `t` function across each server component. <br><br> - [Server Components](https://intlayer.org/doc/environment/nextjs#step-7-utilize-content-in-your-code) |
|
|
60
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/file_tree.png?raw=true" alt="Feature" width="700"> | **Organized Codebase**<br><br>Keep your codebase more organized: 1 component = 1 dictionary in the same folder. Translations close to their respective components, enhance maintainability and clarity. <br><br> - [How Intlayer works](https://intlayer.org/doc/concept/how-works-intlayer) |
|
|
61
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/url_routing.png?raw=true" alt="Feature" width="700"> | **Enhanced Routing**<br><br>Full support of app routing, adapting seamlessly to complex application structures, for Next.js, React, Vite, Vue.js, etc.<br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs) |
|
|
62
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/markdown.png?raw=true" alt="Feature" width="700"> | **Markdown Support**<br><br>Import and interpret, locale files and remote Markdown for multilingual content like privacy policies, documentation, etc. Interpret and make Markdown metadata accessible in your code.<br><br> - [Content files](https://intlayer.org/doc/concept/content/file) |
|
|
63
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/visual_editor.png?raw=true" alt="Feature" width="700"> | **Free Visual Editor & CMS**<br><br>A free visual editor and CMS are available for content writers, removing the need for a localization platform. Keep your content synchronized using Git, or externalize it totally or partially with the CMS.<br><br> - [Intlayer Editor](https://intlayer.org/doc/concept/editor) <br> - [Intlayer CMS](https://intlayer.org/doc/concept/cms) |
|
|
64
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/bundle.png?raw=true" alt="Feature" width="700"> | **Tree-shakable Content**<br><br>Tree-shakable content, reducing the size of the final bundle. Loads content per component, excluding any unused content from your bundle. Supports lazy loading to enhance app loading efficiency. <br><br> - [App build optimization](https://intlayer.org/doc/concept/how-works-intlayer#app-build-optimization) |
|
|
65
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/static_rendering.png?raw=true" alt="Feature" width="700"> | **Static Rendering**<br><br>Doesn't block Static Rendering. <br><br> - [Next.js integration](https://intlayer.org/doc/environment/nextjs) |
|
|
66
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/AI_translation.png?raw=true" alt="Feature" width="700"> | **AI-Powered Translation**<br><br>Transform your website into 231 languages with just one click using Intlayer's advanced AI-powered translation tools using your own AI provider / API key. <br><br> - [CI/CD integration](https://intlayer.org/doc/concept/ci-cd) <br> - [Intlayer CLI](https://intlayer.org/doc/concept/cli) <br> - [Auto fill](https://intlayer.org/doc/concept/auto-fill) |
|
|
67
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/mcp.png?raw=true" alt="Feature" width="700"> | **MCP Server Integration**<br><br>Provides an MCP (Model Context Protocol) server for IDE automation, enabling seamless content management and i18n workflows directly within your development environment. <br><br> - [MCP Server](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/mcp_server.md) |
|
|
68
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/vscode_extension.png?raw=true" alt="Feature" width="700"> | **VSCode Extension**<br><br>Intlayer provides a VSCode extension to help you manage your content and translations, building your dictionaries, translating your content, and more. <br><br> - [VSCode Extension](https://intlayer.org/doc/vs-code-extension) |
|
|
69
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/interoperability.png?raw=true" alt="Feature" width="700"> | **Interoperability**<br><br>Allow interoperability with react-i18next, next-i18next, next-intl, react-intl, vue-i18n. <br><br> - [Intlayer and react-intl](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [Intlayer and next-intl](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [Intlayer and next-i18next](https://intlayer.org/blog/intlayer-with-next-i18next) <br> - [Intlayer and vue-i18n](https://intlayer.org/blog/intlayer-with-vue-i18n) <br> - [Intlayer compat adapters](https://intlayer.org/doc/compatibility) |
|
|
70
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/benchmark.png?raw=true" alt="Feature" width="700"> | **Performances & Benchmark**<br><br>Uses advanced tree-shaking and dynamic loading to boost performances and keep the solution as light as possible. <br><br> - [Performances & Benchmark](https://intlayer.org/doc/benchmark) |
|
|
71
71
|
|
|
72
72
|
---
|
|
73
73
|
|
|
@@ -162,7 +162,7 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
|
|
|
162
162
|
<li><a href="https://intlayer.org/doc/concept/cms" rel=''>Intlayer CMS</a></li>
|
|
163
163
|
<li><a href="https://intlayer.org/doc/concept/content" rel=''>Dictionary</a>
|
|
164
164
|
<ul>
|
|
165
|
-
<li><a href="https://intlayer.org/doc/concept/
|
|
165
|
+
<li><a href="https://intlayer.org/doc/concept/per-locale-file" rel=''>Per-Locale Content Declaration File</a></li>
|
|
166
166
|
<li><a href="https://intlayer.org/doc/concept/content/translation" rel=''>Translation</a></li>
|
|
167
167
|
<li><a href="https://intlayer.org/doc/concept/content/enumeration" rel=''>Enumeration</a></li>
|
|
168
168
|
<li><a href="https://intlayer.org/doc/concept/content/condition" rel=''>Condition</a></li>
|
|
@@ -183,7 +183,7 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
|
|
|
183
183
|
<ul>
|
|
184
184
|
<li><a href="https://intlayer.org/doc/environment/nextjs/15" rel=''>Next.js 15</a></li>
|
|
185
185
|
<li><a href="https://intlayer.org/doc/environment/nextjs/14" rel=''>Next.js 14 (App Router)</a></li>
|
|
186
|
-
<li><a href="https://intlayer.org/doc/environment/nextjs/next-with-
|
|
186
|
+
<li><a href="https://intlayer.org/doc/environment/nextjs/next-with-page-router" rel=''>Next.js Page Router</a></li>
|
|
187
187
|
<li><a href="https://intlayer.org/doc/environment/nextjs/compiler" rel=''>Next.js using Compiler</a></li>
|
|
188
188
|
</ul>
|
|
189
189
|
</li>
|
|
@@ -212,7 +212,7 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
|
|
|
212
212
|
<li><a href="https://intlayer.org/doc/environment/sveltekit" rel=''>SvelteKit</a></li>
|
|
213
213
|
<li><a href="https://intlayer.org/doc/environment/vite-and-preact" rel=''>Vite + Preact</a></li>
|
|
214
214
|
<li><a href="https://intlayer.org/doc/environment/vite-and-vue" rel=''>Vite + Vue</a></li>
|
|
215
|
-
<li><a href="https://intlayer.org/doc/environment/
|
|
215
|
+
<li><a href="https://intlayer.org/doc/environment/nuxt-and-vue" rel=''>Vite + Nuxt</a></li>
|
|
216
216
|
<li><a href="https://intlayer.org/doc/environment/vite-and-solid" rel=''>Vite + Solid</a></li>
|
|
217
217
|
<li><a href="https://intlayer.org/doc/environment/angular" rel=''>Angular</a></li>
|
|
218
218
|
<li>
|
|
@@ -19,11 +19,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
19
19
|
}
|
|
20
20
|
return to;
|
|
21
21
|
};
|
|
22
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
23
23
|
value: mod,
|
|
24
24
|
enumerable: true
|
|
25
25
|
}) : target, mod));
|
|
26
26
|
|
|
27
27
|
//#endregion
|
|
28
|
-
|
|
29
28
|
exports.__toESM = __toESM;
|
|
@@ -19,10 +19,14 @@ magic_string = require_runtime.__toESM(magic_string);
|
|
|
19
19
|
const detectExistingIntlayerCall = (scriptText, absoluteOffset) => {
|
|
20
20
|
let info = null;
|
|
21
21
|
try {
|
|
22
|
-
const ast = (0, _babel_core.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const ast = (0, _babel_core.parseSync)(scriptText, {
|
|
23
|
+
configFile: false,
|
|
24
|
+
babelrc: false,
|
|
25
|
+
parserOpts: {
|
|
26
|
+
sourceType: "module",
|
|
27
|
+
plugins: ["typescript", "jsx"]
|
|
28
|
+
}
|
|
29
|
+
});
|
|
26
30
|
if (!ast) return null;
|
|
27
31
|
(0, _babel_core.traverse)(ast, { CallExpression(path) {
|
|
28
32
|
const callee = path.node.callee;
|
|
@@ -192,10 +196,14 @@ const intlayerVueExtract = (code, filename, options = {}) => {
|
|
|
192
196
|
const scriptText = scriptBlock.content;
|
|
193
197
|
const offset = scriptBlock.loc.start.offset;
|
|
194
198
|
try {
|
|
195
|
-
const ast = (0, _babel_core.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
+
const ast = (0, _babel_core.parseSync)(scriptText, {
|
|
200
|
+
configFile: false,
|
|
201
|
+
babelrc: false,
|
|
202
|
+
parserOpts: {
|
|
203
|
+
sourceType: "module",
|
|
204
|
+
plugins: ["typescript", "jsx"]
|
|
205
|
+
}
|
|
206
|
+
});
|
|
199
207
|
if (ast) (0, _babel_core.traverse)(ast, { StringLiteral(path) {
|
|
200
208
|
if (path.parentPath.isImportDeclaration()) return;
|
|
201
209
|
if (path.parentPath.isExportDeclaration()) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue-intlayer-extract.cjs","names":["t","DEFAULT_LOCALE","vueSfc","MagicString"],"sources":["../../src/vue-intlayer-extract.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { parse 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 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 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,6BAAiB,YAAY,EACjC,YAAY;GAAE,YAAY;GAAU,SAAS,CAAC,cAAc,KAAK;EAAE,EACrE,CAAC;EAED,IAAI,CAAC,KAAK,OAAO;EAEjB,0BAAS,KAAK,EACZ,eAAe,MAAW;GACxB,MAAM,SAAS,KAAK,KAAK;GAEzB,IACE,CAACA,kBAAE,aAAa,MAAM,KACrB,OAAO,SAAS,iBAAiB,OAAO,SAAS,eAElD;GAEF,MAAM,SAAS,KAAK;GAEpB,IAAIA,kBAAE,qBAAqB,MAAM,KAAKA,kBAAE,gBAAgB,OAAO,EAAE,GAAG;IAClE,MAAM,aAAa,OAAO,GAAG;IAC7B,MAAM,2BAA2B,WAC9B,QACE,aACCA,kBAAE,iBAAiB,QAAQ,KAAKA,kBAAE,aAAa,SAAS,GAAG,CAC/D,CAAC,CACA,KAAK,aAAmB,SAAS,IAAY,IAAc;IAC9D,MAAM,WAAW,WAAW,WAAW,SAAS;IAEhD,OAAO;KACL,gBAAgB;KAChB,cAAc;KACd;KACA,yBAAyB,kBAAkB,OAAO,GAAG,MAAO;KAC5D,qBAAqB,iBAAiB,SAAS;IACjD;GACF,OAME,OAAO;IACL,gBAAgB;IAChB,cANAA,kBAAE,qBAAqB,MAAM,KAAKA,kBAAE,aAAa,OAAO,EAAE,IACtD,OAAO,GAAG,OACV;IAKJ,0BAA0B,CAAC;IAC3B,yBAAyB;IACzB,qBAAqB;GACvB;GAGF,KAAK,KAAK;EACZ,EACF,CAAC;CACH,QAAQ,CAER;CAEA,OAAO;AACT;AA+BA,MAAa,qBACX,UACA,cACY;CACZ,IAAI,CAAC,UAAU,OAAO;CACtB,IAAI,CAAC,aAAa,UAAU,WAAW,GAAG,OAAO;CAEjD,MAAM,qBAAqB,SAAS,QAAQ,OAAO,GAAG;CACtD,OAAO,UAAU,MAAM,MAAM;EAE3B,OADoB,EAAE,QAAQ,OAAO,GACpB,MAAM;CACzB,CAAC;AACH;AAkCA,MAAM,aAAa;CACjB,MAAM;CACN,SAAS;CACT,WAAW;CACX,eAAe;AACjB;AAEA,MAAa,sBACX,MACA,UACA,UAAgC,CAAC,MAC8B;CAC/D,MAAM,EACJ,gBAAgBC,+CAChB,cAAc,gBACd,WACA,eACA,WACA,eAAe,qBACf,sBAAsB,CAAC,GACvB,8BACA,gBACE;CAEJ,IAAI,CAAC,kBAAkB,UAAU,SAAS,GAAG,OAAO;CACpD,IAAI,CAAC,SAAS,SAAS,MAAM,GAAG,OAAO;CAEvC,IAAI;CAEJ,IAAI;EACF,WAAWC,0BAAO;CACpB,QAAQ;EACN,QAAQ,KAAK,8CAA8C;EAC3D,OAAO;CACT;CAEA,MAAM,MAAM,SAAS,IAAI;CACzB,MAAM,QAAQ,IAAIC,qBAAY,IAAI;CAElC,MAAM,mBAAqC,CAAC;CAC5C,MAAM,+BAAe,IAAI,IAAY;CACrC,MAAM,gBACJ,uBAAuB,+BAA+B,QAAQ,KAAK;CACrE,MAAM,eAA8B,CAAC;CAIrC,MAAM,cAAc,IAAI,WAAW,eAAe,IAAI,WAAW;CACjE,MAAM,mBAAmB,cACrB,2BACE,YAAY,SACZ,YAAY,IAAI,MAAM,MACxB,IACA;CAEJ,MAAM,iBAAiB,kBAAkB,kBAAkB;CAC3D,MAAM,UAAU,kBAAkB,gBAAgB;CAGlD,IAAI,IAAI,WAAW,UAAU;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,6BAAiB,YAAY,EACjC,YAAY;IACV,YAAY;IACZ,SAAS,CAAC,cAAc,KAAK;GAC/B,EACF,CAAC;GAED,IAAI,KACF,0BAAS,KAAK,EACZ,cAAc,MAAW;IACvB,IAAI,KAAK,WAAW,oBAAoB,GAAG;IAE3C,IAAI,KAAK,WAAW,oBAAoB,GAAG;IAE3C,IAAI,KAAK,WAAW,kBAAkB,GAAG;IAEzC,IAAI,KAAK,WAAW,iBAAiB,KAAK,KAAK,QAAQ,OACrD;IAEF,IAAI,KAAK,WAAW,iBAAiB,GAAG;KACtC,MAAM,SAAS,KAAK,WAAW,KAAK;KAEpC,IACEH,kBAAE,mBAAmB,MAAM,KAC3BA,kBAAE,aAAa,OAAO,MAAM,KAC5B,OAAO,OAAO,SAAS,WAEvB;KAEF,IACEA,kBAAE,aAAa,MAAM,MACpB,OAAO,SAAS,iBAAiB,OAAO,SAAS,MAElD;KAEF,IAAI,OAAO,SAAS,UAAU;KAE9B,IAAIA,kBAAE,aAAa,MAAM,KAAK,OAAO,SAAS,WAAW;IAC3D;IAEA,MAAM,OAAO,KAAK,KAAK;IAEvB,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,0CAA6B,UAAU,OAAO;CAC3D,IAAI,mBAA2C,CAAC;CAEhD,MAAM,SAAS,mBAAmB,MAAM,UAAU;EAChD;EACA,eAAe;EACf,eAAe,MAAM;EACrB,aAAa,MAAM;EACnB,8BAA8B,MAAM;EACpC,qBAAqB,MAAM;EAC3B,YAAY,kBAAkB;GAC5B,mBAAmB,cAAc;EACnC;CACF,CAAC;CAED,IAAI,CAAC,QAAQ,OAAO;CAEpB,IAAI,MACF,2BAAc,UAAU,OAAO,IAAI;CAGrC,OAAO;EACL;EACA,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF"}
|
|
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,5 +1,5 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
-
import {
|
|
2
|
+
import { parseSync, traverse, types } from "@babel/core";
|
|
3
3
|
import { DEFAULT_LOCALE } from "@intlayer/config/defaultValues";
|
|
4
4
|
import vueSfc from "@vue/compiler-sfc";
|
|
5
5
|
import MagicString from "magic-string";
|
|
@@ -15,10 +15,14 @@ import MagicString from "magic-string";
|
|
|
15
15
|
const detectExistingIntlayerCall = (scriptText, absoluteOffset) => {
|
|
16
16
|
let info = null;
|
|
17
17
|
try {
|
|
18
|
-
const ast =
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
const ast = parseSync(scriptText, {
|
|
19
|
+
configFile: false,
|
|
20
|
+
babelrc: false,
|
|
21
|
+
parserOpts: {
|
|
22
|
+
sourceType: "module",
|
|
23
|
+
plugins: ["typescript", "jsx"]
|
|
24
|
+
}
|
|
25
|
+
});
|
|
22
26
|
if (!ast) return null;
|
|
23
27
|
traverse(ast, { CallExpression(path) {
|
|
24
28
|
const callee = path.node.callee;
|
|
@@ -188,10 +192,14 @@ const intlayerVueExtract = (code, filename, options = {}) => {
|
|
|
188
192
|
const scriptText = scriptBlock.content;
|
|
189
193
|
const offset = scriptBlock.loc.start.offset;
|
|
190
194
|
try {
|
|
191
|
-
const ast =
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
+
const ast = parseSync(scriptText, {
|
|
196
|
+
configFile: false,
|
|
197
|
+
babelrc: false,
|
|
198
|
+
parserOpts: {
|
|
199
|
+
sourceType: "module",
|
|
200
|
+
plugins: ["typescript", "jsx"]
|
|
201
|
+
}
|
|
202
|
+
});
|
|
195
203
|
if (ast) traverse(ast, { StringLiteral(path) {
|
|
196
204
|
if (path.parentPath.isImportDeclaration()) return;
|
|
197
205
|
if (path.parentPath.isExportDeclaration()) return;
|
|
@@ -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 { parse 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 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 parserOpts: {\n sourceType: 'module',\n plugins: ['typescript', 'jsx'],\n },\n });\n\n if (ast) {\n traverse(ast, {\n StringLiteral(path: any) {\n if (path.parentPath.isImportDeclaration()) return;\n\n if (path.parentPath.isExportDeclaration()) return;\n\n if (path.parentPath.isImportSpecifier()) return;\n\n if (path.parentPath.isObjectProperty() && path.key === 'key')\n return;\n\n if (path.parentPath.isCallExpression()) {\n const callee = path.parentPath.node.callee;\n\n if (\n t.isMemberExpression(callee) &&\n t.isIdentifier(callee.object) &&\n callee.object.name === 'console'\n )\n return;\n\n if (\n t.isIdentifier(callee) &&\n (callee.name === 'useIntlayer' || callee.name === 't')\n )\n return;\n\n if (callee.type === 'Import') return;\n\n if (t.isIdentifier(callee) && callee.name === 'require') return;\n }\n\n const text = path.node.value;\n\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n\n if (path.node.start != null && path.node.end != null) {\n const ref = isDestructured ? key : `${varName}.${key}`;\n replacements.push({\n start: offset + path.node.start,\n end: offset + path.node.end,\n replacement: ref,\n key,\n value: text.trim(),\n });\n }\n }\n },\n });\n }\n } catch (e) {\n console.warn(\n `Vue extraction: Failed to parse script content for ${filename}`,\n e\n );\n }\n }\n\n // Abort if nothing was extracted\n if (replacements.length === 0) return null;\n\n // Apply Replacements in Reverse Order\n replacements.sort((a, b) => b.start - a.start);\n\n for (const { start, end, replacement, key, value } of replacements) {\n magic.overwrite(start, end, replacement);\n extractedContent[key] = value;\n }\n\n // When the existing call is destructured, inject only the missing keys into\n // the ObjectPattern — no new `content` variable is needed.\n if (\n existingCallInfo?.isDestructured &&\n existingCallInfo.closingBraceAbsolutePos >= 0\n ) {\n const missingKeys = Object.keys(extractedContent).filter(\n (k) => !existingCallInfo.existingDestructuredKeys.includes(k)\n );\n\n if (missingKeys.length > 0) {\n // Insert right after the last property so the space/newline before `}`\n // is naturally preserved: `{ a }` → `{ a, b }`.\n magic.appendLeft(\n existingCallInfo.lastPropAbsoluteEnd,\n `, ${missingKeys.join(', ')}`\n );\n }\n }\n\n // Inject necessary imports and setup (only when no existing call was detected)\n const finalScriptContent = scriptBlock?.content ?? '';\n\n const hasUseIntlayerImport =\n /import\\s*{[^}]*useIntlayer[^}]*}\\s*from\\s*['\"][^'\"]+['\"]/.test(\n finalScriptContent\n ) ||\n /import\\s+useIntlayer\\s+from\\s*['\"][^'\"]+['\"]/.test(finalScriptContent);\n\n // An existing call (destructured or not) means no new declaration is needed.\n const hasContentDeclaration =\n existingCallInfo !== null ||\n /const\\s+content\\s*=\\s*useIntlayer\\s*\\(/.test(finalScriptContent);\n\n const importStmt = hasUseIntlayerImport\n ? ''\n : `import { useIntlayer } from '${packageName}';`;\n const contentDecl = hasContentDeclaration\n ? ''\n : `const content = useIntlayer('${dictionaryKey}');`;\n\n const injectionParts = [importStmt, contentDecl].filter(Boolean);\n\n if (injectionParts.length > 0) {\n const injection = `\\n${injectionParts.join('\\n')}\\n`;\n\n if (sfc.descriptor.scriptSetup) {\n magic.appendLeft(sfc.descriptor.scriptSetup.loc.start.offset, injection);\n } else if (sfc.descriptor.script) {\n magic.appendLeft(sfc.descriptor.script.loc.start.offset, injection);\n } else {\n magic.prepend(\n `<script setup>\\n${importStmt}\\n${contentDecl}\\n</script>\\n`\n );\n }\n }\n\n if (onExtract) {\n onExtract({\n dictionaryKey,\n filePath: filename,\n content: { ...extractedContent },\n locale: defaultLocale,\n });\n }\n\n return {\n code: magic.toString(),\n map: magic.generateMap({ source: filename, includeContent: true }),\n extracted: true,\n };\n};\n\ntype Tools = {\n generateKey: (text: string, existingKeys: Set<string>) => string;\n shouldExtract: (text: string) => boolean;\n extractDictionaryKeyFromPath: (path: string) => string;\n attributesToExtract: readonly string[];\n extractTsContent: any;\n};\n\nexport const processVueFile = (\n filePath: string,\n _componentKey: string,\n packageName: string,\n tools: Tools,\n save: boolean = true,\n providedCode?: string\n): {\n extractedContent: Record<string, string>;\n code: string;\n map?: any;\n} | null => {\n const code = providedCode ?? readFileSync(filePath, 'utf-8');\n let extractedContent: Record<string, string> = {};\n\n const result = intlayerVueExtract(code, filePath, {\n packageName,\n dictionaryKey: _componentKey,\n shouldExtract: tools.shouldExtract,\n generateKey: tools.generateKey,\n extractDictionaryKeyFromPath: tools.extractDictionaryKeyFromPath,\n attributesToExtract: tools.attributesToExtract,\n onExtract: (extractResult) => {\n extractedContent = extractResult.content;\n },\n });\n\n if (!result) return null;\n\n if (save) {\n writeFileSync(filePath, result.code);\n }\n\n return {\n extractedContent,\n code: result.code,\n map: result.map,\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vue-intlayer-extract.mjs","names":["babelParse","t"],"sources":["../../src/vue-intlayer-extract.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { parseSync as babelParse, types as t, traverse } from '@babel/core';\nimport { DEFAULT_LOCALE } from '@intlayer/config/defaultValues';\nimport 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 +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":";;KA8FY,mBAAmB;KAEnB;EACV;EACA;EACA,SAAS;EACT,QAAQ;;KAGE;EACV,gBAAgB;EAChB;EACA;EACA,iBAAiB;EACjB,aAAa,QAAQ;EACrB;EACA;EACA,gCAAgC;EAChC,eAAe,cAAc,cAAc;;cAWhC,oBAAiB,8BACA;cAoDjB,qBAAkB,cACjB,kBACI,UACP;EACN;EAAc;EAAe;;KAkX7B;EACH,cAAc,cAAc,cAAc;EAC1C,gBAAgB;EAChB,+BAA+B;EAC/B;EACA;;cAGW,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.
|
|
3
|
+
"version": "9.3.2",
|
|
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": [
|
|
@@ -78,8 +78,8 @@
|
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
80
|
"@babel/core": "8.0.1",
|
|
81
|
-
"@intlayer/config": "9.3.
|
|
82
|
-
"@intlayer/types": "9.3.
|
|
81
|
+
"@intlayer/config": "9.3.2",
|
|
82
|
+
"@intlayer/types": "9.3.2",
|
|
83
83
|
"@vue/compiler-sfc": ">=3.0.0",
|
|
84
84
|
"fast-glob": "3.3.3",
|
|
85
85
|
"magic-string": "1.1.0"
|