@intlayer/babel 8.1.6 → 8.1.7
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 +37 -28
- package/dist/cjs/babel-plugin-intlayer-optimize.cjs +1 -1
- package/dist/cjs/babel-plugin-intlayer-optimize.cjs.map +1 -1
- package/dist/esm/babel-plugin-intlayer-optimize.mjs +1 -1
- package/dist/esm/babel-plugin-intlayer-optimize.mjs.map +1 -1
- package/dist/types/babel-plugin-intlayer-optimize.d.ts +3 -1
- package/dist/types/babel-plugin-intlayer-optimize.d.ts.map +1 -1
- package/package.json +8 -9
package/README.md
CHANGED
|
@@ -46,25 +46,26 @@ With **per-locale content files**, **TypeScript autocompletion**, **tree-shakabl
|
|
|
46
46
|
|
|
47
47
|
## Keys benefits of Intlayer:
|
|
48
48
|
|
|
49
|
-
| Feature | Description
|
|
50
|
-
| --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
51
|
-
| <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.
|
|
52
|
-
| <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)
|
|
53
|
-
| <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)
|
|
54
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
55
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
56
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
57
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
58
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
59
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
60
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
61
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
62
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
63
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
64
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
65
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
66
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
67
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/
|
|
49
|
+
| Feature | Description |
|
|
50
|
+
| --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
51
|
+
| <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. |
|
|
52
|
+
| <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) |
|
|
53
|
+
| <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) |
|
|
54
|
+
| <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) |
|
|
55
|
+
| <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) |
|
|
56
|
+
| <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) |
|
|
57
|
+
| <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) |
|
|
58
|
+
| <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) |
|
|
59
|
+
| <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) |
|
|
60
|
+
| <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) |
|
|
61
|
+
| <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) |
|
|
62
|
+
| <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) |
|
|
63
|
+
| <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) |
|
|
64
|
+
| <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) |
|
|
65
|
+
| <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) |
|
|
66
|
+
| <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) |
|
|
67
|
+
| <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) |
|
|
68
|
+
| <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) |
|
|
68
69
|
|
|
69
70
|
---
|
|
70
71
|
|
|
@@ -153,6 +154,8 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
|
|
|
153
154
|
<li><a href="https://intlayer.org/doc/concept/how-works-intlayer" rel=''>How Intlayer Works</a></li>
|
|
154
155
|
<li><a href="https://intlayer.org/doc/concept/configuration" rel=''>Configuration</a></li>
|
|
155
156
|
<li><a href="https://intlayer.org/doc/concept/cli" rel=''>Intlayer CLI</a></li>
|
|
157
|
+
<li><a href="https://intlayer.org/doc/compiler" rel=''>Compiler</a></li>
|
|
158
|
+
|
|
156
159
|
<li><a href="https://intlayer.org/doc/concept/editor" rel=''>Intlayer Editor</a></li>
|
|
157
160
|
<li><a href="https://intlayer.org/doc/concept/cms" rel=''>Intlayer CMS</a></li>
|
|
158
161
|
<li><a href="https://intlayer.org/doc/concept/content" rel=''>Dictionary</a>
|
|
@@ -179,17 +182,15 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
|
|
|
179
182
|
<li><a href="https://intlayer.org/doc/environment/nextjs/15" rel=''>Next.js 15</a></li>
|
|
180
183
|
<li><a href="https://intlayer.org/doc/environment/nextjs/14" rel=''>Next.js 14 (App Router)</a></li>
|
|
181
184
|
<li><a href="https://intlayer.org/doc/environment/nextjs/next-with-Page-Router" rel=''>Next.js Page Router</a></li>
|
|
185
|
+
<li><a href="https://intlayer.org/doc/environment/nextjs/compiler" rel=''>Next.js using Compiler</a></li>
|
|
182
186
|
</ul>
|
|
183
187
|
</li>
|
|
184
188
|
<li><a href="https://intlayer.org/doc/environment/create-react-app" rel=''>React CRA</a></li>
|
|
185
|
-
<li><a href="https://intlayer.org/doc/environment/vite-and-react" rel=''>Vite + React</a>
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
</ul>
|
|
190
|
-
</li>
|
|
189
|
+
<li><a href="https://intlayer.org/doc/environment/vite-and-react" rel=''>Vite + React</a></li>
|
|
190
|
+
<li><a href="https://intlayer.org/doc/environment/vite-and-react" rel=''>Vite + React using Compiler</a></li>
|
|
191
|
+
<li><a href="https://intlayer.org/doc/environment/vite-and-react/compiler" rel=''>React-router-v7</a></li>
|
|
192
|
+
<li><a href="https://intlayer.org/doc/environment/vite-and-react/tanstack-start" rel=''>Tanstack start</a></li>
|
|
191
193
|
<li><a href="https://intlayer.org/doc/environment/react-native-and-expo" rel=''>React Native</a></li>
|
|
192
|
-
<li><a href="https://intlayer.org/doc/environment/lynx-and-react" rel=''>Lynx + React</a></li>
|
|
193
194
|
<li><a href="https://intlayer.org/doc/environment/vite-and-svelte" rel=''>Vite + Svelte</a></li>
|
|
194
195
|
<li><a href="https://intlayer.org/doc/environment/sveltekit" rel=''>SvelteKit</a></li>
|
|
195
196
|
<li><a href="https://intlayer.org/doc/environment/vite-and-preact" rel=''>Vite + Preact</a></li>
|
|
@@ -197,8 +198,16 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
|
|
|
197
198
|
<li><a href="https://intlayer.org/doc/environment/vite-and-nuxt" rel=''>Vite + Nuxt</a></li>
|
|
198
199
|
<li><a href="https://intlayer.org/doc/environment/vite-and-solid" rel=''>Vite + Solid</a></li>
|
|
199
200
|
<li><a href="https://intlayer.org/doc/environment/angular" rel=''>Angular</a></li>
|
|
200
|
-
<li
|
|
201
|
-
|
|
201
|
+
<li>
|
|
202
|
+
<a href="https://intlayer.org/doc/environment/express" rel=''>Backend</a>
|
|
203
|
+
<ul>
|
|
204
|
+
<li><a href="https://intlayer.org/doc/environment/express" rel=''>Express</a></li>
|
|
205
|
+
<li><a href="https://intlayer.org/doc/environment/nest" rel=''>NestJS</a></li>
|
|
206
|
+
<li><a href="https://intlayer.org/doc/environment/fastify" rel=''>Fastify</a></li>
|
|
207
|
+
<li><a href="https://intlayer.org/doc/environment/adonisjs" rel=''>AdonisJS</a></li>
|
|
208
|
+
<li><a href="https://intlayer.org/doc/environment/hono" rel=''>Hono</a></li>
|
|
209
|
+
</ul>
|
|
210
|
+
</li>
|
|
202
211
|
</ul>
|
|
203
212
|
</details>
|
|
204
213
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`node:path`),t=require(`@intlayer/chokidar/utils`),n=require(`@intlayer/config/utils`);const r=[`intlayer`,`@intlayer/core`,`react-intlayer`,`react-intlayer/client`,`react-intlayer/server`,`next-intlayer`,`next-intlayer/client`,`next-intlayer/server`,`svelte-intlayer`,`vue-intlayer`,`angular-intlayer`,`preact-intlayer`,`solid-intlayer`],i=[`useIntlayer`,`getIntlayer`],a=[`react-intlayer`,`react-intlayer/client`,`react-intlayer/server`,`next-intlayer`,`next-intlayer/client`,`next-intlayer/server`,`preact-intlayer`,`vue-intlayer`,`solid-intlayer`,`svelte-intlayer`,`angular-intlayer`],o={getIntlayer:`getDictionary`,useIntlayer:`useDictionary`},s={useIntlayer:`useDictionaryDynamic`},c=(e,n)=>{let r=(0,t.getFileHash)(e);return n.identifier(`_${r}`)},l=(t,r,i,a,o,s)=>{let c=(0,e.join)(r,`${o}.json`);s===`fetch`&&(c=(0,e.join)(a,`${o}.mjs`)),s===`dynamic`&&(c=(0,e.join)(i,`${o}.mjs`));let l=(0,e.relative)((0,e.dirname)(t),c);return l=(0,n.normalizePath)(l),!l.startsWith(`./`)&&!l.startsWith(`../`)&&(l=`./${l}`),l},u=e=>{let{types:n}=e;return{name:`babel-plugin-intlayer-transform`,pre(){if(this._newStaticImports=new Map,this._newDynamicImports=new Map,this._isIncluded=!0,this._hasValidImport=!1,this._isDictEntry=!1,this._useDynamicHelpers=!1,this.opts.optimize===!1){this._isIncluded=!1;return}let e=this.file.opts.filename;if(this.opts.filesList&&e&&!this.opts.filesList.includes(e)){this._isIncluded=!1;return}},visitor:{Program:{enter(e,t){let r=t.file.opts.filename;t.opts.replaceDictionaryEntry&&r===t.opts.dictionariesEntryPath&&(t._isDictEntry=!0,e.traverse({ImportDeclaration(e){e.remove()},VariableDeclarator(e){n.isObjectExpression(e.node.init)&&(e.node.init.properties=[])}}))},exit(e,u){if(u._isDictEntry||!u._isIncluded)return;let d=!1;if(e.traverse({CallExpression(e){let t=e.node.callee;if(!n.isIdentifier(t)||t.name!==`useIntlayer`)return;let r=e.node.arguments[0];if(
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`node:path`),t=require(`@intlayer/chokidar/utils`),n=require(`@intlayer/config/utils`);const r=[`intlayer`,`@intlayer/core`,`react-intlayer`,`react-intlayer/client`,`react-intlayer/server`,`next-intlayer`,`next-intlayer/client`,`next-intlayer/server`,`svelte-intlayer`,`vue-intlayer`,`angular-intlayer`,`preact-intlayer`,`solid-intlayer`],i=[`useIntlayer`,`getIntlayer`],a=[`react-intlayer`,`react-intlayer/client`,`react-intlayer/server`,`next-intlayer`,`next-intlayer/client`,`next-intlayer/server`,`preact-intlayer`,`vue-intlayer`,`solid-intlayer`,`svelte-intlayer`,`angular-intlayer`],o={getIntlayer:`getDictionary`,useIntlayer:`useDictionary`},s={useIntlayer:`useDictionaryDynamic`},c=(e,n)=>{let r=(0,t.getFileHash)(e);return n.identifier(`_${r}`)},l=(t,r,i,a,o,s)=>{let c=(0,e.join)(r,`${o}.json`);s===`fetch`&&(c=(0,e.join)(a,`${o}.mjs`)),s===`dynamic`&&(c=(0,e.join)(i,`${o}.mjs`));let l=(0,e.relative)((0,e.dirname)(t),c);return l=(0,n.normalizePath)(l),!l.startsWith(`./`)&&!l.startsWith(`../`)&&(l=`./${l}`),l},u=e=>{let{types:n}=e;return{name:`babel-plugin-intlayer-transform`,pre(){if(this._newStaticImports=new Map,this._newDynamicImports=new Map,this._callerMap=new Map,this._isIncluded=!0,this._hasValidImport=!1,this._isDictEntry=!1,this._useDynamicHelpers=!1,this.opts.optimize===!1){this._isIncluded=!1;return}let e=this.file.opts.filename;if(this.opts.filesList&&e&&!this.opts.filesList.includes(e)){this._isIncluded=!1;return}},visitor:{Program:{enter(e,t){let r=t.file.opts.filename;t.opts.replaceDictionaryEntry&&r===t.opts.dictionariesEntryPath&&(t._isDictEntry=!0,e.traverse({ImportDeclaration(e){e.remove()},VariableDeclarator(e){n.isObjectExpression(e.node.init)&&(e.node.init.properties=[])}}))},exit(e,u){if(u._isDictEntry||!u._isIncluded)return;let d=!1;if(e.traverse({CallExpression(e){let t=e.node.callee;if(!n.isIdentifier(t)||u._callerMap?.get(t.name)!==`useIntlayer`)return;let r=e.node.arguments[0],i;if(r&&n.isStringLiteral(r)?i=r.value:r&&n.isTemplateLiteral(r)&&r.expressions.length===0&&r.quasis.length===1&&(i=r.quasis[0].value.cooked??r.quasis[0].value.raw),!i)return;let a=u.opts.dictionaryModeMap?.[i];(a===`dynamic`||a===`fetch`)&&(d=!0)}}),e.traverse({ImportDeclaration(e){let t=e.node.source.value;if(r.includes(t)){u._hasValidImport=!0;for(let r of e.node.specifiers){if(!n.isImportSpecifier(r))continue;let e=n.isIdentifier(r.imported)?r.imported.name:r.imported.value;i.includes(e)&&u._callerMap?.set(r.local.name,e);let c=u.opts.importMode,l=(c===`dynamic`||c===`fetch`||d)&&a.includes(t);l&&(u._useDynamicHelpers=!0);let f;f=l?{...o,...s}:o;let p=f[e];p&&(r.imported=n.identifier(p))}}},CallExpression(e){let r=e.node.callee;if(!n.isIdentifier(r))return;let i=u._callerMap?.get(r.name);if(!i)return;u._hasValidImport=!0;let a=e.node.arguments[0],o;if(a&&n.isStringLiteral(a)?o=a.value:a&&n.isTemplateLiteral(a)&&a.expressions.length===0&&a.quasis.length===1&&(o=a.quasis[0].value.cooked??a.quasis[0].value.raw),!o)return;let s=u.opts.importMode,l=i===`useIntlayer`,d=!!u._useDynamicHelpers,f=`static`,p=u.opts.dictionaryModeMap?.[o];l&&d?p?f=p:s===`dynamic`?f=`dynamic`:s===`fetch`&&(f=`fetch`):l&&!d&&(p===`dynamic`||p===`fetch`)&&(f=p);let m;if(f===`fetch`){let r=u._newDynamicImports?.get(o);if(!r){let e=(0,t.getFileHash)(o);r=n.identifier(`_${e}_fetch`),u._newDynamicImports?.set(o,r)}m=r,e.node.arguments=[n.identifier(m.name),...e.node.arguments]}else if(f===`dynamic`){let r=u._newDynamicImports?.get(o);if(!r){let e=(0,t.getFileHash)(o);r=n.identifier(`_${e}_dyn`),u._newDynamicImports?.set(o,r)}m=r,e.node.arguments=[n.identifier(m.name),...e.node.arguments]}else{let t=u._newStaticImports?.get(o);t||(t=c(o,n),u._newStaticImports?.set(o,t)),m=t,e.node.arguments[0]=n.identifier(m.name)}}}),!u._hasValidImport)return;let f=u.file.opts.filename,p=u.opts.dictionariesDir,m=u.opts.dynamicDictionariesDir,h=u.opts.fetchDictionariesDir,g=[];for(let[e,t]of u._newStaticImports){let r=l(f,p,m,h,e,`static`),i=n.importDeclaration([n.importDefaultSpecifier(n.identifier(t.name))],n.stringLiteral(r));i.attributes=[n.importAttribute(n.identifier(`type`),n.stringLiteral(`json`))],g.push(i)}for(let[e,t]of u._newDynamicImports){let r=l(f,p,m,h,e,t.name.endsWith(`_fetch`)?`fetch`:`dynamic`);g.push(n.importDeclaration([n.importDefaultSpecifier(n.identifier(t.name))],n.stringLiteral(r)))}if(!g.length)return;let _=e.get(`body`),v=0;for(let e of _){let t=e.node;if(n.isExpressionStatement(t)&&n.isStringLiteral(t.expression)&&!t.expression.value.startsWith(`import`)&&!t.expression.value.startsWith(`require`))v+=1;else break}e.node.body.splice(v,0,...g)}}}}};exports.intlayerOptimizeBabelPlugin=u;
|
|
2
2
|
//# sourceMappingURL=babel-plugin-intlayer-optimize.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"babel-plugin-intlayer-optimize.cjs","names":[],"sources":["../../src/babel-plugin-intlayer-optimize.ts"],"sourcesContent":["import { dirname, join, relative } from 'node:path';\nimport type { NodePath, PluginObj, PluginPass } from '@babel/core';\nimport type * as BabelTypes from '@babel/types';\nimport { getFileHash } from '@intlayer/chokidar/utils';\nimport { normalizePath } from '@intlayer/config/utils';\n\nconst PACKAGE_LIST = [\n 'intlayer',\n '@intlayer/core',\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'svelte-intlayer',\n 'vue-intlayer',\n 'angular-intlayer',\n 'preact-intlayer',\n 'solid-intlayer',\n];\n\nconst CALLER_LIST = ['useIntlayer', 'getIntlayer'] as const;\n\n/**\n * Packages that support dynamic import\n */\nconst PACKAGE_LIST_DYNAMIC = [\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'preact-intlayer',\n 'vue-intlayer',\n 'solid-intlayer',\n 'svelte-intlayer',\n 'angular-intlayer',\n] as const;\n\nconst STATIC_IMPORT_FUNCTION = {\n getIntlayer: 'getDictionary',\n useIntlayer: 'useDictionary',\n} as const;\n\nconst DYNAMIC_IMPORT_FUNCTION = {\n useIntlayer: 'useDictionaryDynamic',\n} as const;\n\n/**\n * Options for the optimization Babel plugin\n */\nexport type OptimizePluginOptions = {\n /**\n * If false, the plugin will not apply any transformation.\n */\n optimize?: boolean;\n /**\n * The path to the dictionaries directory.\n */\n dictionariesDir: string;\n /**\n * The path to the dictionaries entry file.\n */\n dictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries entry file.\n */\n unmergedDictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries directory.\n */\n unmergedDictionariesDir: string;\n /**\n * The path to the dictionaries directory.\n */\n dynamicDictionariesDir: string;\n /**\n * The path to the dynamic dictionaries entry file.\n */\n dynamicDictionariesEntryPath: string;\n /**\n * The path to the fetch dictionaries directory.\n */\n fetchDictionariesDir: string;\n /**\n * The path to the fetch dictionaries entry file.\n */\n fetchDictionariesEntryPath: string;\n /**\n * If true, the plugin will replace the dictionary entry file with `export default {}`.\n */\n replaceDictionaryEntry: boolean;\n /**\n * If true, the plugin will activate the dynamic import of the dictionaries. It will rely on Suspense to load the dictionaries.\n */\n importMode: 'static' | 'dynamic' | 'fetch';\n /**\n * Map of dictionary keys to their specific import mode.\n */\n dictionaryModeMap?: Record<string, 'static' | 'dynamic' | 'fetch'>;\n /**\n * Files list to traverse.\n */\n filesList: string[];\n};\n\ntype State = PluginPass & {\n opts: OptimizePluginOptions;\n /** map key → generated ident (per-file) for static imports */\n _newStaticImports?: Map<string, BabelTypes.Identifier>;\n /** map key → generated ident (per-file) for dynamic imports */\n _newDynamicImports?: Map<string, BabelTypes.Identifier>;\n /** whether the current file imported *any* intlayer package */\n _hasValidImport?: boolean;\n /** whether the current file *is* the dictionaries entry file */\n _isDictEntry?: boolean;\n /** whether dynamic helpers are active for this file */\n _useDynamicHelpers?: boolean;\n /** whether the current file is included in the filesList */\n _isIncluded?: boolean;\n};\n\n/**\n * Replicates the xxHash64 → Base-62 algorithm used by the SWC version\n * and prefixes an underscore so the generated identifiers never collide\n * with user-defined ones.\n */\nconst makeIdent = (\n key: string,\n t: typeof BabelTypes\n): BabelTypes.Identifier => {\n const hash = getFileHash(key);\n return t.identifier(`_${hash}`);\n};\n\nconst computeImport = (\n fromFile: string,\n dictionariesDir: string,\n dynamicDictionariesDir: string,\n fetchDictionariesDir: string,\n key: string,\n importMode: 'static' | 'dynamic' | 'fetch'\n): string => {\n let relativePath = join(dictionariesDir, `${key}.json`);\n\n if (importMode === 'fetch') {\n relativePath = join(fetchDictionariesDir, `${key}.mjs`);\n }\n\n if (importMode === 'dynamic') {\n relativePath = join(dynamicDictionariesDir, `${key}.mjs`);\n }\n\n let rel = relative(dirname(fromFile), relativePath);\n\n // Fix windows path\n rel = normalizePath(rel);\n\n // Fix relative path\n if (!rel.startsWith('./') && !rel.startsWith('../')) {\n rel = `./${rel}`;\n }\n\n return rel;\n};\n\n/**\n * Babel plugin that transforms Intlayer function calls and auto-imports dictionaries.\n *\n * This plugin transforms calls to `useIntlayer()` and `getIntlayer()` from various Intlayer\n * packages into optimized dictionary access patterns, automatically importing the required\n * dictionary files based on the configured import mode.\n *\n * ## Supported Input Patterns\n *\n * The plugin recognizes these function calls:\n *\n * ```ts\n * // useIntlayer\n * import { useIntlayer } from 'react-intlayer';\n * import { useIntlayer } from 'next-intlayer';\n *\n * // getIntlayer\n * import { getIntlayer } from 'intlayer';\n *\n * // Usage\n * const content = useIntlayer('app');\n * const content = getIntlayer('app');\n * ```\n *\n * ## Transformation Modes\n *\n * ### Static Mode (default: `importMode = \"static\"`)\n *\n * Imports JSON dictionaries directly and replaces function calls with dictionary access:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import { useDictionary as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash);\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Dynamic Mode (`importMode = \"dynamic\"`)\n *\n * Uses dynamic dictionary loading with Suspense support:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Live Mode (`importMode = \"live\"`)\n *\n * Uses live-based dictionary loading for remote dictionaries:\n *\n * **Output if `dictionaryModeMap` includes the key with \"live\" value:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_fetch from '../../.intlayer/fetch_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_fetch, \"app\");\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * > If `dictionaryModeMap` does not include the key with \"live\" value, the plugin will fallback to the dynamic impor\n *\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n */\nexport const intlayerOptimizeBabelPlugin = (babel: {\n types: typeof BabelTypes;\n}): PluginObj<State> => {\n const { types: t } = babel;\n\n return {\n name: 'babel-plugin-intlayer-transform',\n\n pre() {\n this._newStaticImports = new Map();\n this._newDynamicImports = new Map();\n this._isIncluded = true;\n this._hasValidImport = false;\n this._isDictEntry = false;\n this._useDynamicHelpers = false;\n\n // If optimize is false, skip processing entirely\n if (this.opts.optimize === false) {\n this._isIncluded = false;\n return;\n }\n\n // If filesList is provided, check if current file is included\n const filename = this.file.opts.filename;\n if (this.opts.filesList && filename) {\n const isIncluded = this.opts.filesList.includes(filename);\n\n if (!isIncluded) {\n // Force _isIncluded to false to skip processing\n this._isIncluded = false;\n return;\n }\n }\n },\n\n visitor: {\n /* If this file *is* the dictionaries entry, short-circuit: export {} */\n Program: {\n enter(programPath, state) {\n // Safe access to filename\n const filename = state.file.opts.filename;\n\n // Check if this is the correct file to transform\n\n if (\n state.opts.replaceDictionaryEntry &&\n filename === state.opts.dictionariesEntryPath\n ) {\n state._isDictEntry = true;\n\n // Traverse the program to surgically remove/edit specific parts\n programPath.traverse({\n // Remove all import statements (cleaning up 'sssss.json')\n ImportDeclaration(path) {\n path.remove();\n },\n\n // Find the variable definition and empty the object\n VariableDeclarator(path) {\n // We look for: const x = { ... }\n\n if (t.isObjectExpression(path.node.init)) {\n // Set the object properties to an empty array: {}\n path.node.init.properties = [];\n }\n },\n });\n\n // (Optional) Stop other plugins from processing this file further if needed\n // programPath.stop();\n }\n },\n\n /**\n * After full traversal, process imports and call expressions, then inject the JSON dictionary imports.\n *\n * We do the transformation in Program.exit (via a manual traverse) rather than using\n * top-level ImportDeclaration/CallExpression visitors. This ensures that if another plugin\n * (like babel-plugin-intlayer-extract) adds new useIntlayer calls in its Program.exit,\n * we will see and transform them here because our Program.exit runs after theirs.\n */\n exit(programPath, state) {\n if (state._isDictEntry) return; // nothing else to do – already replaced\n\n if (!state._isIncluded) return; // early-out if file is not included\n\n // Manual traversal to process imports and call expressions\n // This runs AFTER all other plugins' visitors have completed\n\n // Pre-pass to determine if we should use dynamic helpers\n let fileHasDynamicCall = false;\n programPath.traverse({\n CallExpression(path) {\n const callee = path.node.callee;\n\n if (!t.isIdentifier(callee)) return;\n\n if (callee.name !== 'useIntlayer') return;\n\n const arg = path.node.arguments[0];\n\n if (!arg || !t.isStringLiteral(arg)) return;\n\n const key = arg.value;\n const dictionaryOverrideMode =\n state.opts.dictionaryModeMap?.[key];\n\n if (\n dictionaryOverrideMode === 'dynamic' ||\n dictionaryOverrideMode === 'fetch'\n ) {\n fileHasDynamicCall = true;\n }\n },\n });\n\n programPath.traverse({\n /* Inspect every intlayer import */\n ImportDeclaration(path) {\n const src = path.node.source.value;\n\n if (!PACKAGE_LIST.includes(src)) return;\n\n // Mark that we do import from an intlayer package in this file\n state._hasValidImport = true;\n\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n // ⚠️ We now key off *imported* name, *not* local name.\n const importedName = t.isIdentifier(spec.imported)\n ? spec.imported.name\n : (spec.imported as BabelTypes.StringLiteral).value;\n\n const importMode = state.opts.importMode;\n // Determine whether this import should use the dynamic helpers.\n const shouldUseDynamicHelpers =\n (importMode === 'dynamic' ||\n importMode === 'fetch' ||\n fileHasDynamicCall) &&\n PACKAGE_LIST_DYNAMIC.includes(src as any);\n\n // Remember for later (CallExpression) whether we are using the dynamic helpers\n\n if (shouldUseDynamicHelpers) {\n state._useDynamicHelpers = true;\n }\n\n let helperMap: Record<string, string>;\n\n if (shouldUseDynamicHelpers) {\n // Use dynamic helpers for useIntlayer when dynamic mode is enabled\n helperMap = {\n ...STATIC_IMPORT_FUNCTION,\n ...DYNAMIC_IMPORT_FUNCTION,\n } as Record<string, string>;\n } else {\n // Use static helpers by default\n helperMap = STATIC_IMPORT_FUNCTION as Record<string, string>;\n }\n\n const newIdentifier = helperMap[importedName];\n\n // Only rewrite when we actually have a mapping for the imported\n // specifier (ignore unrelated named imports).\n\n if (newIdentifier) {\n // Keep the local alias intact (so calls remain `useIntlayer` /\n // `getIntlayer`), but rewrite the imported identifier so it\n // points to our helper implementation.\n spec.imported = t.identifier(newIdentifier);\n }\n }\n },\n\n /* Replace calls: useIntlayer(\"foo\") → useDictionary(_hash) or useDictionaryDynamic(_hash, \"foo\") */\n CallExpression(path) {\n const callee = path.node.callee;\n\n if (!t.isIdentifier(callee)) return;\n\n if (!CALLER_LIST.includes(callee.name as any)) return;\n\n // Ensure we ultimately emit helper imports for files that *invoke*\n // the hooks, even if they didn't import them directly (edge cases with\n // re-exports).\n state._hasValidImport = true;\n\n const arg = path.node.arguments[0];\n\n if (!arg || !t.isStringLiteral(arg)) return; // must be literal\n\n const key = arg.value;\n const importMode = state.opts.importMode;\n const isUseIntlayer = callee.name === 'useIntlayer';\n const useDynamicHelpers = Boolean(state._useDynamicHelpers);\n\n // Decide per-call mode: 'static' | 'dynamic' | 'fetch'\n let perCallMode: 'static' | 'dynamic' | 'fetch' = 'static';\n\n const dictionaryOverrideMode =\n state.opts.dictionaryModeMap?.[key];\n\n if (isUseIntlayer && useDynamicHelpers) {\n if (dictionaryOverrideMode) {\n perCallMode = dictionaryOverrideMode;\n } else if (importMode === 'dynamic') {\n perCallMode = 'dynamic';\n } else if (importMode === 'fetch') {\n perCallMode = 'fetch';\n }\n } else if (isUseIntlayer && !useDynamicHelpers) {\n // If dynamic helpers are NOT active (global mode is static),\n // we STILL might want to force dynamic/live for this specific call\n\n if (\n dictionaryOverrideMode === 'dynamic' ||\n dictionaryOverrideMode === 'fetch'\n ) {\n perCallMode = dictionaryOverrideMode;\n }\n }\n\n let ident: BabelTypes.Identifier;\n\n if (perCallMode === 'fetch') {\n // Use fetch dictionaries entry (live mode for selected keys)\n let dynamicIdent = state._newDynamicImports?.get(key);\n\n if (!dynamicIdent) {\n const hash = getFileHash(key);\n dynamicIdent = t.identifier(`_${hash}_fetch`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Helper: first argument is the dictionary entry, second is the key\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else if (perCallMode === 'dynamic') {\n // Use dynamic dictionaries entry\n let dynamicIdent = state._newDynamicImports?.get(key);\n\n if (!dynamicIdent) {\n // Create a unique identifier for dynamic imports by appending a suffix\n const hash = getFileHash(key);\n dynamicIdent = t.identifier(`_${hash}_dyn`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Dynamic helper: first argument is the dictionary, second is the key.\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else {\n // Use static imports for getIntlayer or useIntlayer when not using dynamic helpers\n let staticIdent = state._newStaticImports?.get(key);\n\n if (!staticIdent) {\n staticIdent = makeIdent(key, t);\n state._newStaticImports?.set(key, staticIdent);\n }\n ident = staticIdent;\n\n // Static helper (useDictionary / getDictionary): replace key with iden\n path.node.arguments[0] = t.identifier(ident.name);\n }\n },\n });\n\n // Early-out if we touched nothing\n\n if (!state._hasValidImport) return;\n\n const file = state.file.opts.filename!;\n const dictionariesDir = state.opts.dictionariesDir;\n const dynamicDictionariesDir = state.opts.dynamicDictionariesDir;\n const fetchDictionariesDir = state.opts.fetchDictionariesDir;\n const imports: BabelTypes.ImportDeclaration[] = [];\n\n // Generate static JSON imports (getIntlayer always uses JSON dictionaries)\n for (const [key, ident] of state._newStaticImports!) {\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n 'static'\n );\n\n const importDeclarationNode = t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n );\n\n // Add 'type: json' attribute for JSON files\n importDeclarationNode.attributes = [\n t.importAttribute(t.identifier('type'), t.stringLiteral('json')),\n ];\n\n imports.push(importDeclarationNode);\n }\n\n // Generate dynamic/fetch imports (for useIntlayer when using dynamic/live helpers)\n for (const [key, ident] of state._newDynamicImports!) {\n const modeForThisIdent: 'dynamic' | 'fetch' = ident.name.endsWith(\n '_fetch'\n )\n ? 'fetch'\n : 'dynamic';\n\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n modeForThisIdent\n );\n imports.push(\n t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n )\n );\n }\n\n if (!imports.length) return;\n\n /* Keep \"use client\" / \"use server\" directives at the very top. */\n const bodyPaths = programPath.get(\n 'body'\n ) as NodePath<BabelTypes.Statement>[];\n let insertPos = 0;\n for (const stmtPath of bodyPaths) {\n const stmt = stmtPath.node;\n\n if (\n t.isExpressionStatement(stmt) &&\n t.isStringLiteral(stmt.expression) &&\n !stmt.expression.value.startsWith('import') &&\n !stmt.expression.value.startsWith('require')\n ) {\n insertPos += 1;\n } else {\n break;\n }\n }\n\n programPath.node.body.splice(insertPos, 0, ...imports);\n },\n },\n },\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"babel-plugin-intlayer-optimize.cjs","names":[],"sources":["../../src/babel-plugin-intlayer-optimize.ts"],"sourcesContent":["import { dirname, join, relative } from 'node:path';\nimport type { NodePath, PluginObj, PluginPass } from '@babel/core';\nimport type * as BabelTypes from '@babel/types';\nimport { getFileHash } from '@intlayer/chokidar/utils';\nimport { normalizePath } from '@intlayer/config/utils';\n\nconst PACKAGE_LIST = [\n 'intlayer',\n '@intlayer/core',\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'svelte-intlayer',\n 'vue-intlayer',\n 'angular-intlayer',\n 'preact-intlayer',\n 'solid-intlayer',\n];\n\nconst CALLER_LIST = ['useIntlayer', 'getIntlayer'] as const;\n\n/**\n * Packages that support dynamic import\n */\nconst PACKAGE_LIST_DYNAMIC = [\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'preact-intlayer',\n 'vue-intlayer',\n 'solid-intlayer',\n 'svelte-intlayer',\n 'angular-intlayer',\n] as const;\n\nconst STATIC_IMPORT_FUNCTION = {\n getIntlayer: 'getDictionary',\n useIntlayer: 'useDictionary',\n} as const;\n\nconst DYNAMIC_IMPORT_FUNCTION = {\n useIntlayer: 'useDictionaryDynamic',\n} as const;\n\n/**\n * Options for the optimization Babel plugin\n */\nexport type OptimizePluginOptions = {\n /**\n * If false, the plugin will not apply any transformation.\n */\n optimize?: boolean;\n /**\n * The path to the dictionaries directory.\n */\n dictionariesDir: string;\n /**\n * The path to the dictionaries entry file.\n */\n dictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries entry file.\n */\n unmergedDictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries directory.\n */\n unmergedDictionariesDir: string;\n /**\n * The path to the dictionaries directory.\n */\n dynamicDictionariesDir: string;\n /**\n * The path to the dynamic dictionaries entry file.\n */\n dynamicDictionariesEntryPath: string;\n /**\n * The path to the fetch dictionaries directory.\n */\n fetchDictionariesDir: string;\n /**\n * The path to the fetch dictionaries entry file.\n */\n fetchDictionariesEntryPath: string;\n /**\n * If true, the plugin will replace the dictionary entry file with `export default {}`.\n */\n replaceDictionaryEntry: boolean;\n /**\n * If true, the plugin will activate the dynamic import of the dictionaries. It will rely on Suspense to load the dictionaries.\n */\n importMode: 'static' | 'dynamic' | 'fetch';\n /**\n * Map of dictionary keys to their specific import mode.\n */\n dictionaryModeMap?: Record<string, 'static' | 'dynamic' | 'fetch'>;\n /**\n * Files list to traverse.\n */\n filesList: string[];\n};\n\ntype State = PluginPass & {\n opts: OptimizePluginOptions;\n /** map key → generated ident (per-file) for static imports */\n _newStaticImports?: Map<string, BabelTypes.Identifier>;\n /** map key → generated ident (per-file) for dynamic imports */\n _newDynamicImports?: Map<string, BabelTypes.Identifier>;\n /** whether the current file imported *any* intlayer package */\n _hasValidImport?: boolean;\n /** map from local identifier name to the imported intlayer func name ('useIntlayer' | 'getIntlayer') */\n _callerMap?: Map<string, (typeof CALLER_LIST)[number]>;\n /** whether the current file *is* the dictionaries entry file */\n _isDictEntry?: boolean;\n /** whether dynamic helpers are active for this file */\n _useDynamicHelpers?: boolean;\n /** whether the current file is included in the filesList */\n _isIncluded?: boolean;\n};\n\n/**\n * Replicates the xxHash64 → Base-62 algorithm used by the SWC version\n * and prefixes an underscore so the generated identifiers never collide\n * with user-defined ones.\n */\nconst makeIdent = (\n key: string,\n t: typeof BabelTypes\n): BabelTypes.Identifier => {\n const hash = getFileHash(key);\n return t.identifier(`_${hash}`);\n};\n\nconst computeImport = (\n fromFile: string,\n dictionariesDir: string,\n dynamicDictionariesDir: string,\n fetchDictionariesDir: string,\n key: string,\n importMode: 'static' | 'dynamic' | 'fetch'\n): string => {\n let relativePath = join(dictionariesDir, `${key}.json`);\n\n if (importMode === 'fetch') {\n relativePath = join(fetchDictionariesDir, `${key}.mjs`);\n }\n\n if (importMode === 'dynamic') {\n relativePath = join(dynamicDictionariesDir, `${key}.mjs`);\n }\n\n let rel = relative(dirname(fromFile), relativePath);\n\n // Fix windows path\n rel = normalizePath(rel);\n\n // Fix relative path\n if (!rel.startsWith('./') && !rel.startsWith('../')) {\n rel = `./${rel}`;\n }\n\n return rel;\n};\n\n/**\n * Babel plugin that transforms Intlayer function calls and auto-imports dictionaries.\n *\n * This plugin transforms calls to `useIntlayer()` and `getIntlayer()` from various Intlayer\n * packages into optimized dictionary access patterns, automatically importing the required\n * dictionary files based on the configured import mode.\n *\n * ## Supported Input Patterns\n *\n * The plugin recognizes these function calls:\n *\n * ```ts\n * // useIntlayer\n * import { useIntlayer } from 'react-intlayer';\n * import { useIntlayer } from 'next-intlayer';\n *\n * // getIntlayer\n * import { getIntlayer } from 'intlayer';\n *\n * // Usage\n * const content = useIntlayer('app');\n * const content = getIntlayer('app');\n * ```\n *\n * ## Transformation Modes\n *\n * ### Static Mode (default: `importMode = \"static\"`)\n *\n * Imports JSON dictionaries directly and replaces function calls with dictionary access:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import { useDictionary as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash);\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Dynamic Mode (`importMode = \"dynamic\"`)\n *\n * Uses dynamic dictionary loading with Suspense support:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Live Mode (`importMode = \"live\"`)\n *\n * Uses live-based dictionary loading for remote dictionaries:\n *\n * **Output if `dictionaryModeMap` includes the key with \"live\" value:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_fetch from '../../.intlayer/fetch_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_fetch, \"app\");\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * > If `dictionaryModeMap` does not include the key with \"live\" value, the plugin will fallback to the dynamic impor\n *\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n */\nexport const intlayerOptimizeBabelPlugin = (babel: {\n types: typeof BabelTypes;\n}): PluginObj<State> => {\n const { types: t } = babel;\n\n return {\n name: 'babel-plugin-intlayer-transform',\n\n pre() {\n this._newStaticImports = new Map();\n this._newDynamicImports = new Map();\n this._callerMap = new Map();\n this._isIncluded = true;\n this._hasValidImport = false;\n this._isDictEntry = false;\n this._useDynamicHelpers = false;\n\n // If optimize is false, skip processing entirely\n if (this.opts.optimize === false) {\n this._isIncluded = false;\n return;\n }\n\n // If filesList is provided, check if current file is included\n const filename = this.file.opts.filename;\n if (this.opts.filesList && filename) {\n const isIncluded = this.opts.filesList.includes(filename);\n\n if (!isIncluded) {\n // Force _isIncluded to false to skip processing\n this._isIncluded = false;\n return;\n }\n }\n },\n\n visitor: {\n /* If this file *is* the dictionaries entry, short-circuit: export {} */\n Program: {\n enter(programPath, state) {\n // Safe access to filename\n const filename = state.file.opts.filename;\n\n // Check if this is the correct file to transform\n\n if (\n state.opts.replaceDictionaryEntry &&\n filename === state.opts.dictionariesEntryPath\n ) {\n state._isDictEntry = true;\n\n // Traverse the program to surgically remove/edit specific parts\n programPath.traverse({\n // Remove all import statements (cleaning up 'sssss.json')\n ImportDeclaration(path) {\n path.remove();\n },\n\n // Find the variable definition and empty the object\n VariableDeclarator(path) {\n // We look for: const x = { ... }\n\n if (t.isObjectExpression(path.node.init)) {\n // Set the object properties to an empty array: {}\n path.node.init.properties = [];\n }\n },\n });\n\n // (Optional) Stop other plugins from processing this file further if needed\n // programPath.stop();\n }\n },\n\n /**\n * After full traversal, process imports and call expressions, then inject the JSON dictionary imports.\n *\n * We do the transformation in Program.exit (via a manual traverse) rather than using\n * top-level ImportDeclaration/CallExpression visitors. This ensures that if another plugin\n * (like babel-plugin-intlayer-extract) adds new useIntlayer calls in its Program.exit,\n * we will see and transform them here because our Program.exit runs after theirs.\n */\n exit(programPath, state) {\n if (state._isDictEntry) return; // nothing else to do – already replaced\n\n if (!state._isIncluded) return; // early-out if file is not included\n\n // Manual traversal to process imports and call expressions\n // This runs AFTER all other plugins' visitors have completed\n\n // Pre-pass to determine if we should use dynamic helpers\n let fileHasDynamicCall = false;\n programPath.traverse({\n CallExpression(path) {\n const callee = path.node.callee;\n\n if (!t.isIdentifier(callee)) return;\n\n const originalImportedName = state._callerMap?.get(callee.name);\n if (originalImportedName !== 'useIntlayer') return;\n\n const arg = path.node.arguments[0];\n\n let key: string | undefined;\n\n if (arg && t.isStringLiteral(arg)) {\n key = arg.value;\n } else if (\n arg &&\n t.isTemplateLiteral(arg) &&\n arg.expressions.length === 0 &&\n arg.quasis.length === 1\n ) {\n // If the bundler output is `breadcrumb` instead of 'breadcrumb'\n key = arg.quasis[0].value.cooked ?? arg.quasis[0].value.raw;\n }\n\n if (!key) return;\n const dictionaryOverrideMode =\n state.opts.dictionaryModeMap?.[key];\n\n if (\n dictionaryOverrideMode === 'dynamic' ||\n dictionaryOverrideMode === 'fetch'\n ) {\n fileHasDynamicCall = true;\n }\n },\n });\n\n programPath.traverse({\n /* Inspect every intlayer import */\n ImportDeclaration(path) {\n const src = path.node.source.value;\n\n if (!PACKAGE_LIST.includes(src)) return;\n\n // Mark that we do import from an intlayer package in this file\n state._hasValidImport = true;\n\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n const importedName = t.isIdentifier(spec.imported)\n ? spec.imported.name\n : (spec.imported as BabelTypes.StringLiteral).value;\n\n if (CALLER_LIST.includes(importedName as any)) {\n state._callerMap?.set(\n spec.local.name,\n importedName as (typeof CALLER_LIST)[number]\n );\n }\n\n const importMode = state.opts.importMode;\n // Determine whether this import should use the dynamic helpers.\n const shouldUseDynamicHelpers =\n (importMode === 'dynamic' ||\n importMode === 'fetch' ||\n fileHasDynamicCall) &&\n PACKAGE_LIST_DYNAMIC.includes(src as any);\n\n // Remember for later (CallExpression) whether we are using the dynamic helpers\n\n if (shouldUseDynamicHelpers) {\n state._useDynamicHelpers = true;\n }\n\n let helperMap: Record<string, string>;\n\n if (shouldUseDynamicHelpers) {\n // Use dynamic helpers for useIntlayer when dynamic mode is enabled\n helperMap = {\n ...STATIC_IMPORT_FUNCTION,\n ...DYNAMIC_IMPORT_FUNCTION,\n } as Record<string, string>;\n } else {\n // Use static helpers by default\n helperMap = STATIC_IMPORT_FUNCTION as Record<string, string>;\n }\n\n const newIdentifier = helperMap[importedName];\n\n // Only rewrite when we actually have a mapping for the imported\n // specifier (ignore unrelated named imports).\n\n if (newIdentifier) {\n // Keep the local alias intact (so calls remain `useIntlayer` /\n // `getIntlayer`), but rewrite the imported identifier so it\n // points to our helper implementation.\n spec.imported = t.identifier(newIdentifier);\n }\n }\n },\n\n /* Replace calls: useIntlayer(\"foo\") → useDictionary(_hash) or useDictionaryDynamic(_hash, \"foo\") */\n CallExpression(path) {\n const callee = path.node.callee;\n\n if (!t.isIdentifier(callee)) return;\n\n const originalImportedName = state._callerMap?.get(callee.name);\n if (!originalImportedName) return;\n\n // Ensure we ultimately emit helper imports for files that *invoke*\n // the hooks, even if they didn't import them directly (edge cases with\n // re-exports).\n state._hasValidImport = true;\n\n const arg = path.node.arguments[0];\n\n let key: string | undefined;\n\n if (arg && t.isStringLiteral(arg)) {\n key = arg.value;\n } else if (\n arg &&\n t.isTemplateLiteral(arg) &&\n arg.expressions.length === 0 &&\n arg.quasis.length === 1\n ) {\n // If the bundler output is `breadcrumb` instead of 'breadcrumb'\n key = arg.quasis[0].value.cooked ?? arg.quasis[0].value.raw;\n }\n\n if (!key) return; // must be a static literal\n const importMode = state.opts.importMode;\n const isUseIntlayer = originalImportedName === 'useIntlayer';\n const useDynamicHelpers = Boolean(state._useDynamicHelpers);\n\n // Decide per-call mode: 'static' | 'dynamic' | 'fetch'\n let perCallMode: 'static' | 'dynamic' | 'fetch' = 'static';\n\n const dictionaryOverrideMode =\n state.opts.dictionaryModeMap?.[key];\n\n if (isUseIntlayer && useDynamicHelpers) {\n if (dictionaryOverrideMode) {\n perCallMode = dictionaryOverrideMode;\n } else if (importMode === 'dynamic') {\n perCallMode = 'dynamic';\n } else if (importMode === 'fetch') {\n perCallMode = 'fetch';\n }\n } else if (isUseIntlayer && !useDynamicHelpers) {\n // If dynamic helpers are NOT active (global mode is static),\n // we STILL might want to force dynamic/live for this specific call\n\n if (\n dictionaryOverrideMode === 'dynamic' ||\n dictionaryOverrideMode === 'fetch'\n ) {\n perCallMode = dictionaryOverrideMode;\n }\n }\n\n let ident: BabelTypes.Identifier;\n\n if (perCallMode === 'fetch') {\n // Use fetch dictionaries entry (live mode for selected keys)\n let dynamicIdent = state._newDynamicImports?.get(key);\n\n if (!dynamicIdent) {\n const hash = getFileHash(key);\n dynamicIdent = t.identifier(`_${hash}_fetch`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Helper: first argument is the dictionary entry, second is the key\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else if (perCallMode === 'dynamic') {\n // Use dynamic dictionaries entry\n let dynamicIdent = state._newDynamicImports?.get(key);\n\n if (!dynamicIdent) {\n // Create a unique identifier for dynamic imports by appending a suffix\n const hash = getFileHash(key);\n dynamicIdent = t.identifier(`_${hash}_dyn`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Dynamic helper: first argument is the dictionary, second is the key.\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else {\n // Use static imports for getIntlayer or useIntlayer when not using dynamic helpers\n let staticIdent = state._newStaticImports?.get(key);\n\n if (!staticIdent) {\n staticIdent = makeIdent(key, t);\n state._newStaticImports?.set(key, staticIdent);\n }\n ident = staticIdent;\n\n // Static helper (useDictionary / getDictionary): replace key with iden\n path.node.arguments[0] = t.identifier(ident.name);\n }\n },\n });\n\n // Early-out if we touched nothing\n\n if (!state._hasValidImport) return;\n\n const file = state.file.opts.filename!;\n const dictionariesDir = state.opts.dictionariesDir;\n const dynamicDictionariesDir = state.opts.dynamicDictionariesDir;\n const fetchDictionariesDir = state.opts.fetchDictionariesDir;\n const imports: BabelTypes.ImportDeclaration[] = [];\n\n // Generate static JSON imports (getIntlayer always uses JSON dictionaries)\n for (const [key, ident] of state._newStaticImports!) {\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n 'static'\n );\n\n const importDeclarationNode = t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n );\n\n // Add 'type: json' attribute for JSON files\n importDeclarationNode.attributes = [\n t.importAttribute(t.identifier('type'), t.stringLiteral('json')),\n ];\n\n imports.push(importDeclarationNode);\n }\n\n // Generate dynamic/fetch imports (for useIntlayer when using dynamic/live helpers)\n for (const [key, ident] of state._newDynamicImports!) {\n const modeForThisIdent: 'dynamic' | 'fetch' = ident.name.endsWith(\n '_fetch'\n )\n ? 'fetch'\n : 'dynamic';\n\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n modeForThisIdent\n );\n imports.push(\n t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n )\n );\n }\n\n if (!imports.length) return;\n\n /* Keep \"use client\" / \"use server\" directives at the very top. */\n const bodyPaths = programPath.get(\n 'body'\n ) as NodePath<BabelTypes.Statement>[];\n let insertPos = 0;\n for (const stmtPath of bodyPaths) {\n const stmt = stmtPath.node;\n\n if (\n t.isExpressionStatement(stmt) &&\n t.isStringLiteral(stmt.expression) &&\n !stmt.expression.value.startsWith('import') &&\n !stmt.expression.value.startsWith('require')\n ) {\n insertPos += 1;\n } else {\n break;\n }\n }\n\n programPath.node.body.splice(insertPos, 0, ...imports);\n },\n },\n },\n };\n};\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{dirname as e,join as t,relative as n}from"node:path";import{getFileHash as r}from"@intlayer/chokidar/utils";import{normalizePath as i}from"@intlayer/config/utils";const a=[`intlayer`,`@intlayer/core`,`react-intlayer`,`react-intlayer/client`,`react-intlayer/server`,`next-intlayer`,`next-intlayer/client`,`next-intlayer/server`,`svelte-intlayer`,`vue-intlayer`,`angular-intlayer`,`preact-intlayer`,`solid-intlayer`],o=[`useIntlayer`,`getIntlayer`],s=[`react-intlayer`,`react-intlayer/client`,`react-intlayer/server`,`next-intlayer`,`next-intlayer/client`,`next-intlayer/server`,`preact-intlayer`,`vue-intlayer`,`solid-intlayer`,`svelte-intlayer`,`angular-intlayer`],c={getIntlayer:`getDictionary`,useIntlayer:`useDictionary`},l={useIntlayer:`useDictionaryDynamic`},u=(e,t)=>{let n=r(e);return t.identifier(`_${n}`)},d=(r,a,o,s,c,l)=>{let u=t(a,`${c}.json`);l===`fetch`&&(u=t(s,`${c}.mjs`)),l===`dynamic`&&(u=t(o,`${c}.mjs`));let d=n(e(r),u);return d=i(d),!d.startsWith(`./`)&&!d.startsWith(`../`)&&(d=`./${d}`),d},f=e=>{let{types:t}=e;return{name:`babel-plugin-intlayer-transform`,pre(){if(this._newStaticImports=new Map,this._newDynamicImports=new Map,this._isIncluded=!0,this._hasValidImport=!1,this._isDictEntry=!1,this._useDynamicHelpers=!1,this.opts.optimize===!1){this._isIncluded=!1;return}let e=this.file.opts.filename;if(this.opts.filesList&&e&&!this.opts.filesList.includes(e)){this._isIncluded=!1;return}},visitor:{Program:{enter(e,n){let r=n.file.opts.filename;n.opts.replaceDictionaryEntry&&r===n.opts.dictionariesEntryPath&&(n._isDictEntry=!0,e.traverse({ImportDeclaration(e){e.remove()},VariableDeclarator(e){t.isObjectExpression(e.node.init)&&(e.node.init.properties=[])}}))},exit(e,n){if(n._isDictEntry||!n._isIncluded)return;let i=!1;if(e.traverse({CallExpression(e){let r=e.node.callee;if(!t.isIdentifier(r)||r.name!==`useIntlayer`)return;let a=e.node.arguments[0];if(
|
|
1
|
+
import{dirname as e,join as t,relative as n}from"node:path";import{getFileHash as r}from"@intlayer/chokidar/utils";import{normalizePath as i}from"@intlayer/config/utils";const a=[`intlayer`,`@intlayer/core`,`react-intlayer`,`react-intlayer/client`,`react-intlayer/server`,`next-intlayer`,`next-intlayer/client`,`next-intlayer/server`,`svelte-intlayer`,`vue-intlayer`,`angular-intlayer`,`preact-intlayer`,`solid-intlayer`],o=[`useIntlayer`,`getIntlayer`],s=[`react-intlayer`,`react-intlayer/client`,`react-intlayer/server`,`next-intlayer`,`next-intlayer/client`,`next-intlayer/server`,`preact-intlayer`,`vue-intlayer`,`solid-intlayer`,`svelte-intlayer`,`angular-intlayer`],c={getIntlayer:`getDictionary`,useIntlayer:`useDictionary`},l={useIntlayer:`useDictionaryDynamic`},u=(e,t)=>{let n=r(e);return t.identifier(`_${n}`)},d=(r,a,o,s,c,l)=>{let u=t(a,`${c}.json`);l===`fetch`&&(u=t(s,`${c}.mjs`)),l===`dynamic`&&(u=t(o,`${c}.mjs`));let d=n(e(r),u);return d=i(d),!d.startsWith(`./`)&&!d.startsWith(`../`)&&(d=`./${d}`),d},f=e=>{let{types:t}=e;return{name:`babel-plugin-intlayer-transform`,pre(){if(this._newStaticImports=new Map,this._newDynamicImports=new Map,this._callerMap=new Map,this._isIncluded=!0,this._hasValidImport=!1,this._isDictEntry=!1,this._useDynamicHelpers=!1,this.opts.optimize===!1){this._isIncluded=!1;return}let e=this.file.opts.filename;if(this.opts.filesList&&e&&!this.opts.filesList.includes(e)){this._isIncluded=!1;return}},visitor:{Program:{enter(e,n){let r=n.file.opts.filename;n.opts.replaceDictionaryEntry&&r===n.opts.dictionariesEntryPath&&(n._isDictEntry=!0,e.traverse({ImportDeclaration(e){e.remove()},VariableDeclarator(e){t.isObjectExpression(e.node.init)&&(e.node.init.properties=[])}}))},exit(e,n){if(n._isDictEntry||!n._isIncluded)return;let i=!1;if(e.traverse({CallExpression(e){let r=e.node.callee;if(!t.isIdentifier(r)||n._callerMap?.get(r.name)!==`useIntlayer`)return;let a=e.node.arguments[0],o;if(a&&t.isStringLiteral(a)?o=a.value:a&&t.isTemplateLiteral(a)&&a.expressions.length===0&&a.quasis.length===1&&(o=a.quasis[0].value.cooked??a.quasis[0].value.raw),!o)return;let s=n.opts.dictionaryModeMap?.[o];(s===`dynamic`||s===`fetch`)&&(i=!0)}}),e.traverse({ImportDeclaration(e){let r=e.node.source.value;if(a.includes(r)){n._hasValidImport=!0;for(let a of e.node.specifiers){if(!t.isImportSpecifier(a))continue;let e=t.isIdentifier(a.imported)?a.imported.name:a.imported.value;o.includes(e)&&n._callerMap?.set(a.local.name,e);let u=n.opts.importMode,d=(u===`dynamic`||u===`fetch`||i)&&s.includes(r);d&&(n._useDynamicHelpers=!0);let f;f=d?{...c,...l}:c;let p=f[e];p&&(a.imported=t.identifier(p))}}},CallExpression(e){let i=e.node.callee;if(!t.isIdentifier(i))return;let a=n._callerMap?.get(i.name);if(!a)return;n._hasValidImport=!0;let o=e.node.arguments[0],s;if(o&&t.isStringLiteral(o)?s=o.value:o&&t.isTemplateLiteral(o)&&o.expressions.length===0&&o.quasis.length===1&&(s=o.quasis[0].value.cooked??o.quasis[0].value.raw),!s)return;let c=n.opts.importMode,l=a===`useIntlayer`,d=!!n._useDynamicHelpers,f=`static`,p=n.opts.dictionaryModeMap?.[s];l&&d?p?f=p:c===`dynamic`?f=`dynamic`:c===`fetch`&&(f=`fetch`):l&&!d&&(p===`dynamic`||p===`fetch`)&&(f=p);let m;if(f===`fetch`){let i=n._newDynamicImports?.get(s);if(!i){let e=r(s);i=t.identifier(`_${e}_fetch`),n._newDynamicImports?.set(s,i)}m=i,e.node.arguments=[t.identifier(m.name),...e.node.arguments]}else if(f===`dynamic`){let i=n._newDynamicImports?.get(s);if(!i){let e=r(s);i=t.identifier(`_${e}_dyn`),n._newDynamicImports?.set(s,i)}m=i,e.node.arguments=[t.identifier(m.name),...e.node.arguments]}else{let r=n._newStaticImports?.get(s);r||(r=u(s,t),n._newStaticImports?.set(s,r)),m=r,e.node.arguments[0]=t.identifier(m.name)}}}),!n._hasValidImport)return;let f=n.file.opts.filename,p=n.opts.dictionariesDir,m=n.opts.dynamicDictionariesDir,h=n.opts.fetchDictionariesDir,g=[];for(let[e,r]of n._newStaticImports){let n=d(f,p,m,h,e,`static`),i=t.importDeclaration([t.importDefaultSpecifier(t.identifier(r.name))],t.stringLiteral(n));i.attributes=[t.importAttribute(t.identifier(`type`),t.stringLiteral(`json`))],g.push(i)}for(let[e,r]of n._newDynamicImports){let n=d(f,p,m,h,e,r.name.endsWith(`_fetch`)?`fetch`:`dynamic`);g.push(t.importDeclaration([t.importDefaultSpecifier(t.identifier(r.name))],t.stringLiteral(n)))}if(!g.length)return;let _=e.get(`body`),v=0;for(let e of _){let n=e.node;if(t.isExpressionStatement(n)&&t.isStringLiteral(n.expression)&&!n.expression.value.startsWith(`import`)&&!n.expression.value.startsWith(`require`))v+=1;else break}e.node.body.splice(v,0,...g)}}}}};export{f as intlayerOptimizeBabelPlugin};
|
|
2
2
|
//# sourceMappingURL=babel-plugin-intlayer-optimize.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"babel-plugin-intlayer-optimize.mjs","names":[],"sources":["../../src/babel-plugin-intlayer-optimize.ts"],"sourcesContent":["import { dirname, join, relative } from 'node:path';\nimport type { NodePath, PluginObj, PluginPass } from '@babel/core';\nimport type * as BabelTypes from '@babel/types';\nimport { getFileHash } from '@intlayer/chokidar/utils';\nimport { normalizePath } from '@intlayer/config/utils';\n\nconst PACKAGE_LIST = [\n 'intlayer',\n '@intlayer/core',\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'svelte-intlayer',\n 'vue-intlayer',\n 'angular-intlayer',\n 'preact-intlayer',\n 'solid-intlayer',\n];\n\nconst CALLER_LIST = ['useIntlayer', 'getIntlayer'] as const;\n\n/**\n * Packages that support dynamic import\n */\nconst PACKAGE_LIST_DYNAMIC = [\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'preact-intlayer',\n 'vue-intlayer',\n 'solid-intlayer',\n 'svelte-intlayer',\n 'angular-intlayer',\n] as const;\n\nconst STATIC_IMPORT_FUNCTION = {\n getIntlayer: 'getDictionary',\n useIntlayer: 'useDictionary',\n} as const;\n\nconst DYNAMIC_IMPORT_FUNCTION = {\n useIntlayer: 'useDictionaryDynamic',\n} as const;\n\n/**\n * Options for the optimization Babel plugin\n */\nexport type OptimizePluginOptions = {\n /**\n * If false, the plugin will not apply any transformation.\n */\n optimize?: boolean;\n /**\n * The path to the dictionaries directory.\n */\n dictionariesDir: string;\n /**\n * The path to the dictionaries entry file.\n */\n dictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries entry file.\n */\n unmergedDictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries directory.\n */\n unmergedDictionariesDir: string;\n /**\n * The path to the dictionaries directory.\n */\n dynamicDictionariesDir: string;\n /**\n * The path to the dynamic dictionaries entry file.\n */\n dynamicDictionariesEntryPath: string;\n /**\n * The path to the fetch dictionaries directory.\n */\n fetchDictionariesDir: string;\n /**\n * The path to the fetch dictionaries entry file.\n */\n fetchDictionariesEntryPath: string;\n /**\n * If true, the plugin will replace the dictionary entry file with `export default {}`.\n */\n replaceDictionaryEntry: boolean;\n /**\n * If true, the plugin will activate the dynamic import of the dictionaries. It will rely on Suspense to load the dictionaries.\n */\n importMode: 'static' | 'dynamic' | 'fetch';\n /**\n * Map of dictionary keys to their specific import mode.\n */\n dictionaryModeMap?: Record<string, 'static' | 'dynamic' | 'fetch'>;\n /**\n * Files list to traverse.\n */\n filesList: string[];\n};\n\ntype State = PluginPass & {\n opts: OptimizePluginOptions;\n /** map key → generated ident (per-file) for static imports */\n _newStaticImports?: Map<string, BabelTypes.Identifier>;\n /** map key → generated ident (per-file) for dynamic imports */\n _newDynamicImports?: Map<string, BabelTypes.Identifier>;\n /** whether the current file imported *any* intlayer package */\n _hasValidImport?: boolean;\n /** whether the current file *is* the dictionaries entry file */\n _isDictEntry?: boolean;\n /** whether dynamic helpers are active for this file */\n _useDynamicHelpers?: boolean;\n /** whether the current file is included in the filesList */\n _isIncluded?: boolean;\n};\n\n/**\n * Replicates the xxHash64 → Base-62 algorithm used by the SWC version\n * and prefixes an underscore so the generated identifiers never collide\n * with user-defined ones.\n */\nconst makeIdent = (\n key: string,\n t: typeof BabelTypes\n): BabelTypes.Identifier => {\n const hash = getFileHash(key);\n return t.identifier(`_${hash}`);\n};\n\nconst computeImport = (\n fromFile: string,\n dictionariesDir: string,\n dynamicDictionariesDir: string,\n fetchDictionariesDir: string,\n key: string,\n importMode: 'static' | 'dynamic' | 'fetch'\n): string => {\n let relativePath = join(dictionariesDir, `${key}.json`);\n\n if (importMode === 'fetch') {\n relativePath = join(fetchDictionariesDir, `${key}.mjs`);\n }\n\n if (importMode === 'dynamic') {\n relativePath = join(dynamicDictionariesDir, `${key}.mjs`);\n }\n\n let rel = relative(dirname(fromFile), relativePath);\n\n // Fix windows path\n rel = normalizePath(rel);\n\n // Fix relative path\n if (!rel.startsWith('./') && !rel.startsWith('../')) {\n rel = `./${rel}`;\n }\n\n return rel;\n};\n\n/**\n * Babel plugin that transforms Intlayer function calls and auto-imports dictionaries.\n *\n * This plugin transforms calls to `useIntlayer()` and `getIntlayer()` from various Intlayer\n * packages into optimized dictionary access patterns, automatically importing the required\n * dictionary files based on the configured import mode.\n *\n * ## Supported Input Patterns\n *\n * The plugin recognizes these function calls:\n *\n * ```ts\n * // useIntlayer\n * import { useIntlayer } from 'react-intlayer';\n * import { useIntlayer } from 'next-intlayer';\n *\n * // getIntlayer\n * import { getIntlayer } from 'intlayer';\n *\n * // Usage\n * const content = useIntlayer('app');\n * const content = getIntlayer('app');\n * ```\n *\n * ## Transformation Modes\n *\n * ### Static Mode (default: `importMode = \"static\"`)\n *\n * Imports JSON dictionaries directly and replaces function calls with dictionary access:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import { useDictionary as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash);\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Dynamic Mode (`importMode = \"dynamic\"`)\n *\n * Uses dynamic dictionary loading with Suspense support:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Live Mode (`importMode = \"live\"`)\n *\n * Uses live-based dictionary loading for remote dictionaries:\n *\n * **Output if `dictionaryModeMap` includes the key with \"live\" value:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_fetch from '../../.intlayer/fetch_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_fetch, \"app\");\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * > If `dictionaryModeMap` does not include the key with \"live\" value, the plugin will fallback to the dynamic impor\n *\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n */\nexport const intlayerOptimizeBabelPlugin = (babel: {\n types: typeof BabelTypes;\n}): PluginObj<State> => {\n const { types: t } = babel;\n\n return {\n name: 'babel-plugin-intlayer-transform',\n\n pre() {\n this._newStaticImports = new Map();\n this._newDynamicImports = new Map();\n this._isIncluded = true;\n this._hasValidImport = false;\n this._isDictEntry = false;\n this._useDynamicHelpers = false;\n\n // If optimize is false, skip processing entirely\n if (this.opts.optimize === false) {\n this._isIncluded = false;\n return;\n }\n\n // If filesList is provided, check if current file is included\n const filename = this.file.opts.filename;\n if (this.opts.filesList && filename) {\n const isIncluded = this.opts.filesList.includes(filename);\n\n if (!isIncluded) {\n // Force _isIncluded to false to skip processing\n this._isIncluded = false;\n return;\n }\n }\n },\n\n visitor: {\n /* If this file *is* the dictionaries entry, short-circuit: export {} */\n Program: {\n enter(programPath, state) {\n // Safe access to filename\n const filename = state.file.opts.filename;\n\n // Check if this is the correct file to transform\n\n if (\n state.opts.replaceDictionaryEntry &&\n filename === state.opts.dictionariesEntryPath\n ) {\n state._isDictEntry = true;\n\n // Traverse the program to surgically remove/edit specific parts\n programPath.traverse({\n // Remove all import statements (cleaning up 'sssss.json')\n ImportDeclaration(path) {\n path.remove();\n },\n\n // Find the variable definition and empty the object\n VariableDeclarator(path) {\n // We look for: const x = { ... }\n\n if (t.isObjectExpression(path.node.init)) {\n // Set the object properties to an empty array: {}\n path.node.init.properties = [];\n }\n },\n });\n\n // (Optional) Stop other plugins from processing this file further if needed\n // programPath.stop();\n }\n },\n\n /**\n * After full traversal, process imports and call expressions, then inject the JSON dictionary imports.\n *\n * We do the transformation in Program.exit (via a manual traverse) rather than using\n * top-level ImportDeclaration/CallExpression visitors. This ensures that if another plugin\n * (like babel-plugin-intlayer-extract) adds new useIntlayer calls in its Program.exit,\n * we will see and transform them here because our Program.exit runs after theirs.\n */\n exit(programPath, state) {\n if (state._isDictEntry) return; // nothing else to do – already replaced\n\n if (!state._isIncluded) return; // early-out if file is not included\n\n // Manual traversal to process imports and call expressions\n // This runs AFTER all other plugins' visitors have completed\n\n // Pre-pass to determine if we should use dynamic helpers\n let fileHasDynamicCall = false;\n programPath.traverse({\n CallExpression(path) {\n const callee = path.node.callee;\n\n if (!t.isIdentifier(callee)) return;\n\n if (callee.name !== 'useIntlayer') return;\n\n const arg = path.node.arguments[0];\n\n if (!arg || !t.isStringLiteral(arg)) return;\n\n const key = arg.value;\n const dictionaryOverrideMode =\n state.opts.dictionaryModeMap?.[key];\n\n if (\n dictionaryOverrideMode === 'dynamic' ||\n dictionaryOverrideMode === 'fetch'\n ) {\n fileHasDynamicCall = true;\n }\n },\n });\n\n programPath.traverse({\n /* Inspect every intlayer import */\n ImportDeclaration(path) {\n const src = path.node.source.value;\n\n if (!PACKAGE_LIST.includes(src)) return;\n\n // Mark that we do import from an intlayer package in this file\n state._hasValidImport = true;\n\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n // ⚠️ We now key off *imported* name, *not* local name.\n const importedName = t.isIdentifier(spec.imported)\n ? spec.imported.name\n : (spec.imported as BabelTypes.StringLiteral).value;\n\n const importMode = state.opts.importMode;\n // Determine whether this import should use the dynamic helpers.\n const shouldUseDynamicHelpers =\n (importMode === 'dynamic' ||\n importMode === 'fetch' ||\n fileHasDynamicCall) &&\n PACKAGE_LIST_DYNAMIC.includes(src as any);\n\n // Remember for later (CallExpression) whether we are using the dynamic helpers\n\n if (shouldUseDynamicHelpers) {\n state._useDynamicHelpers = true;\n }\n\n let helperMap: Record<string, string>;\n\n if (shouldUseDynamicHelpers) {\n // Use dynamic helpers for useIntlayer when dynamic mode is enabled\n helperMap = {\n ...STATIC_IMPORT_FUNCTION,\n ...DYNAMIC_IMPORT_FUNCTION,\n } as Record<string, string>;\n } else {\n // Use static helpers by default\n helperMap = STATIC_IMPORT_FUNCTION as Record<string, string>;\n }\n\n const newIdentifier = helperMap[importedName];\n\n // Only rewrite when we actually have a mapping for the imported\n // specifier (ignore unrelated named imports).\n\n if (newIdentifier) {\n // Keep the local alias intact (so calls remain `useIntlayer` /\n // `getIntlayer`), but rewrite the imported identifier so it\n // points to our helper implementation.\n spec.imported = t.identifier(newIdentifier);\n }\n }\n },\n\n /* Replace calls: useIntlayer(\"foo\") → useDictionary(_hash) or useDictionaryDynamic(_hash, \"foo\") */\n CallExpression(path) {\n const callee = path.node.callee;\n\n if (!t.isIdentifier(callee)) return;\n\n if (!CALLER_LIST.includes(callee.name as any)) return;\n\n // Ensure we ultimately emit helper imports for files that *invoke*\n // the hooks, even if they didn't import them directly (edge cases with\n // re-exports).\n state._hasValidImport = true;\n\n const arg = path.node.arguments[0];\n\n if (!arg || !t.isStringLiteral(arg)) return; // must be literal\n\n const key = arg.value;\n const importMode = state.opts.importMode;\n const isUseIntlayer = callee.name === 'useIntlayer';\n const useDynamicHelpers = Boolean(state._useDynamicHelpers);\n\n // Decide per-call mode: 'static' | 'dynamic' | 'fetch'\n let perCallMode: 'static' | 'dynamic' | 'fetch' = 'static';\n\n const dictionaryOverrideMode =\n state.opts.dictionaryModeMap?.[key];\n\n if (isUseIntlayer && useDynamicHelpers) {\n if (dictionaryOverrideMode) {\n perCallMode = dictionaryOverrideMode;\n } else if (importMode === 'dynamic') {\n perCallMode = 'dynamic';\n } else if (importMode === 'fetch') {\n perCallMode = 'fetch';\n }\n } else if (isUseIntlayer && !useDynamicHelpers) {\n // If dynamic helpers are NOT active (global mode is static),\n // we STILL might want to force dynamic/live for this specific call\n\n if (\n dictionaryOverrideMode === 'dynamic' ||\n dictionaryOverrideMode === 'fetch'\n ) {\n perCallMode = dictionaryOverrideMode;\n }\n }\n\n let ident: BabelTypes.Identifier;\n\n if (perCallMode === 'fetch') {\n // Use fetch dictionaries entry (live mode for selected keys)\n let dynamicIdent = state._newDynamicImports?.get(key);\n\n if (!dynamicIdent) {\n const hash = getFileHash(key);\n dynamicIdent = t.identifier(`_${hash}_fetch`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Helper: first argument is the dictionary entry, second is the key\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else if (perCallMode === 'dynamic') {\n // Use dynamic dictionaries entry\n let dynamicIdent = state._newDynamicImports?.get(key);\n\n if (!dynamicIdent) {\n // Create a unique identifier for dynamic imports by appending a suffix\n const hash = getFileHash(key);\n dynamicIdent = t.identifier(`_${hash}_dyn`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Dynamic helper: first argument is the dictionary, second is the key.\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else {\n // Use static imports for getIntlayer or useIntlayer when not using dynamic helpers\n let staticIdent = state._newStaticImports?.get(key);\n\n if (!staticIdent) {\n staticIdent = makeIdent(key, t);\n state._newStaticImports?.set(key, staticIdent);\n }\n ident = staticIdent;\n\n // Static helper (useDictionary / getDictionary): replace key with iden\n path.node.arguments[0] = t.identifier(ident.name);\n }\n },\n });\n\n // Early-out if we touched nothing\n\n if (!state._hasValidImport) return;\n\n const file = state.file.opts.filename!;\n const dictionariesDir = state.opts.dictionariesDir;\n const dynamicDictionariesDir = state.opts.dynamicDictionariesDir;\n const fetchDictionariesDir = state.opts.fetchDictionariesDir;\n const imports: BabelTypes.ImportDeclaration[] = [];\n\n // Generate static JSON imports (getIntlayer always uses JSON dictionaries)\n for (const [key, ident] of state._newStaticImports!) {\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n 'static'\n );\n\n const importDeclarationNode = t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n );\n\n // Add 'type: json' attribute for JSON files\n importDeclarationNode.attributes = [\n t.importAttribute(t.identifier('type'), t.stringLiteral('json')),\n ];\n\n imports.push(importDeclarationNode);\n }\n\n // Generate dynamic/fetch imports (for useIntlayer when using dynamic/live helpers)\n for (const [key, ident] of state._newDynamicImports!) {\n const modeForThisIdent: 'dynamic' | 'fetch' = ident.name.endsWith(\n '_fetch'\n )\n ? 'fetch'\n : 'dynamic';\n\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n modeForThisIdent\n );\n imports.push(\n t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n )\n );\n }\n\n if (!imports.length) return;\n\n /* Keep \"use client\" / \"use server\" directives at the very top. */\n const bodyPaths = programPath.get(\n 'body'\n ) as NodePath<BabelTypes.Statement>[];\n let insertPos = 0;\n for (const stmtPath of bodyPaths) {\n const stmt = stmtPath.node;\n\n if (\n t.isExpressionStatement(stmt) &&\n t.isStringLiteral(stmt.expression) &&\n !stmt.expression.value.startsWith('import') &&\n !stmt.expression.value.startsWith('require')\n ) {\n insertPos += 1;\n } else {\n break;\n }\n }\n\n programPath.node.body.splice(insertPos, 0, ...imports);\n },\n },\n },\n };\n};\n"],"mappings":"0KAMA,MAAM,EAAe,CACnB,WACA,iBACA,iBACA,wBACA,wBACA,gBACA,uBACA,uBACA,kBACA,eACA,mBACA,kBACA,iBACD,CAEK,EAAc,CAAC,cAAe,cAAc,CAK5C,EAAuB,CAC3B,iBACA,wBACA,wBACA,gBACA,uBACA,uBACA,kBACA,eACA,iBACA,kBACA,mBACD,CAEK,EAAyB,CAC7B,YAAa,gBACb,YAAa,gBACd,CAEK,EAA0B,CAC9B,YAAa,uBACd,CAiFK,GACJ,EACA,IAC0B,CAC1B,IAAM,EAAO,EAAY,EAAI,CAC7B,OAAO,EAAE,WAAW,IAAI,IAAO,EAG3B,GACJ,EACA,EACA,EACA,EACA,EACA,IACW,CACX,IAAI,EAAe,EAAK,EAAiB,GAAG,EAAI,OAAO,CAEnD,IAAe,UACjB,EAAe,EAAK,EAAsB,GAAG,EAAI,MAAM,EAGrD,IAAe,YACjB,EAAe,EAAK,EAAwB,GAAG,EAAI,MAAM,EAG3D,IAAI,EAAM,EAAS,EAAQ,EAAS,CAAE,EAAa,CAUnD,MAPA,GAAM,EAAc,EAAI,CAGpB,CAAC,EAAI,WAAW,KAAK,EAAI,CAAC,EAAI,WAAW,MAAM,GACjD,EAAM,KAAK,KAGN,GAqFI,EAA+B,GAEpB,CACtB,GAAM,CAAE,MAAO,GAAM,EAErB,MAAO,CACL,KAAM,kCAEN,KAAM,CASJ,GARA,KAAK,kBAAoB,IAAI,IAC7B,KAAK,mBAAqB,IAAI,IAC9B,KAAK,YAAc,GACnB,KAAK,gBAAkB,GACvB,KAAK,aAAe,GACpB,KAAK,mBAAqB,GAGtB,KAAK,KAAK,WAAa,GAAO,CAChC,KAAK,YAAc,GACnB,OAIF,IAAM,EAAW,KAAK,KAAK,KAAK,SAChC,GAAI,KAAK,KAAK,WAAa,GAGrB,CAFe,KAAK,KAAK,UAAU,SAAS,EAAS,CAExC,CAEf,KAAK,YAAc,GACnB,SAKN,QAAS,CAEP,QAAS,CACP,MAAM,EAAa,EAAO,CAExB,IAAM,EAAW,EAAM,KAAK,KAAK,SAK/B,EAAM,KAAK,wBACX,IAAa,EAAM,KAAK,wBAExB,EAAM,aAAe,GAGrB,EAAY,SAAS,CAEnB,kBAAkB,EAAM,CACtB,EAAK,QAAQ,EAIf,mBAAmB,EAAM,CAGnB,EAAE,mBAAmB,EAAK,KAAK,KAAK,GAEtC,EAAK,KAAK,KAAK,WAAa,EAAE,GAGnC,CAAC,GAeN,KAAK,EAAa,EAAO,CAGvB,GAFI,EAAM,cAEN,CAAC,EAAM,YAAa,OAMxB,IAAI,EAAqB,GA0LzB,GAzLA,EAAY,SAAS,CACnB,eAAe,EAAM,CACnB,IAAM,EAAS,EAAK,KAAK,OAIzB,GAFI,CAAC,EAAE,aAAa,EAAO,EAEvB,EAAO,OAAS,cAAe,OAEnC,IAAM,EAAM,EAAK,KAAK,UAAU,GAEhC,GAAI,CAAC,GAAO,CAAC,EAAE,gBAAgB,EAAI,CAAE,OAErC,IAAM,EAAM,EAAI,MACV,EACJ,EAAM,KAAK,oBAAoB,IAG/B,IAA2B,WAC3B,IAA2B,WAE3B,EAAqB,KAG1B,CAAC,CAEF,EAAY,SAAS,CAEnB,kBAAkB,EAAM,CACtB,IAAM,EAAM,EAAK,KAAK,OAAO,MAExB,KAAa,SAAS,EAAI,CAG/B,GAAM,gBAAkB,GAExB,IAAK,IAAM,KAAQ,EAAK,KAAK,WAAY,CACvC,GAAI,CAAC,EAAE,kBAAkB,EAAK,CAAE,SAGhC,IAAM,EAAe,EAAE,aAAa,EAAK,SAAS,CAC9C,EAAK,SAAS,KACb,EAAK,SAAsC,MAE1C,EAAa,EAAM,KAAK,WAExB,GACH,IAAe,WACd,IAAe,SACf,IACF,EAAqB,SAAS,EAAW,CAIvC,IACF,EAAM,mBAAqB,IAG7B,IAAI,EAEJ,AAQE,EARE,EAEU,CACV,GAAG,EACH,GAAG,EACJ,CAGW,EAGd,IAAM,EAAgB,EAAU,GAK5B,IAIF,EAAK,SAAW,EAAE,WAAW,EAAc,KAMjD,eAAe,EAAM,CACnB,IAAM,EAAS,EAAK,KAAK,OAIzB,GAFI,CAAC,EAAE,aAAa,EAAO,EAEvB,CAAC,EAAY,SAAS,EAAO,KAAY,CAAE,OAK/C,EAAM,gBAAkB,GAExB,IAAM,EAAM,EAAK,KAAK,UAAU,GAEhC,GAAI,CAAC,GAAO,CAAC,EAAE,gBAAgB,EAAI,CAAE,OAErC,IAAM,EAAM,EAAI,MACV,EAAa,EAAM,KAAK,WACxB,EAAgB,EAAO,OAAS,cAChC,EAAoB,EAAQ,EAAM,mBAGpC,EAA8C,SAE5C,EACJ,EAAM,KAAK,oBAAoB,GAE7B,GAAiB,EACf,EACF,EAAc,EACL,IAAe,UACxB,EAAc,UACL,IAAe,UACxB,EAAc,SAEP,GAAiB,CAAC,IAKzB,IAA2B,WAC3B,IAA2B,WAE3B,EAAc,GAIlB,IAAI,EAEJ,GAAI,IAAgB,QAAS,CAE3B,IAAI,EAAe,EAAM,oBAAoB,IAAI,EAAI,CAErD,GAAI,CAAC,EAAc,CACjB,IAAM,EAAO,EAAY,EAAI,CAC7B,EAAe,EAAE,WAAW,IAAI,EAAK,QAAQ,CAC7C,EAAM,oBAAoB,IAAI,EAAK,EAAa,CAElD,EAAQ,EAGR,EAAK,KAAK,UAAY,CACpB,EAAE,WAAW,EAAM,KAAK,CACxB,GAAG,EAAK,KAAK,UACd,SACQ,IAAgB,UAAW,CAEpC,IAAI,EAAe,EAAM,oBAAoB,IAAI,EAAI,CAErD,GAAI,CAAC,EAAc,CAEjB,IAAM,EAAO,EAAY,EAAI,CAC7B,EAAe,EAAE,WAAW,IAAI,EAAK,MAAM,CAC3C,EAAM,oBAAoB,IAAI,EAAK,EAAa,CAElD,EAAQ,EAGR,EAAK,KAAK,UAAY,CACpB,EAAE,WAAW,EAAM,KAAK,CACxB,GAAG,EAAK,KAAK,UACd,KACI,CAEL,IAAI,EAAc,EAAM,mBAAmB,IAAI,EAAI,CAE9C,IACH,EAAc,EAAU,EAAK,EAAE,CAC/B,EAAM,mBAAmB,IAAI,EAAK,EAAY,EAEhD,EAAQ,EAGR,EAAK,KAAK,UAAU,GAAK,EAAE,WAAW,EAAM,KAAK,GAGtD,CAAC,CAIE,CAAC,EAAM,gBAAiB,OAE5B,IAAM,EAAO,EAAM,KAAK,KAAK,SACvB,EAAkB,EAAM,KAAK,gBAC7B,EAAyB,EAAM,KAAK,uBACpC,EAAuB,EAAM,KAAK,qBAClC,EAA0C,EAAE,CAGlD,IAAK,GAAM,CAAC,EAAK,KAAU,EAAM,kBAAoB,CACnD,IAAM,EAAM,EACV,EACA,EACA,EACA,EACA,EACA,SACD,CAEK,EAAwB,EAAE,kBAC9B,CAAC,EAAE,uBAAuB,EAAE,WAAW,EAAM,KAAK,CAAC,CAAC,CACpD,EAAE,cAAc,EAAI,CACrB,CAGD,EAAsB,WAAa,CACjC,EAAE,gBAAgB,EAAE,WAAW,OAAO,CAAE,EAAE,cAAc,OAAO,CAAC,CACjE,CAED,EAAQ,KAAK,EAAsB,CAIrC,IAAK,GAAM,CAAC,EAAK,KAAU,EAAM,mBAAqB,CAOpD,IAAM,EAAM,EACV,EACA,EACA,EACA,EACA,EAX4C,EAAM,KAAK,SACvD,SACD,CACG,QACA,UASH,CACD,EAAQ,KACN,EAAE,kBACA,CAAC,EAAE,uBAAuB,EAAE,WAAW,EAAM,KAAK,CAAC,CAAC,CACpD,EAAE,cAAc,EAAI,CACrB,CACF,CAGH,GAAI,CAAC,EAAQ,OAAQ,OAGrB,IAAM,EAAY,EAAY,IAC5B,OACD,CACG,EAAY,EAChB,IAAK,IAAM,KAAY,EAAW,CAChC,IAAM,EAAO,EAAS,KAEtB,GACE,EAAE,sBAAsB,EAAK,EAC7B,EAAE,gBAAgB,EAAK,WAAW,EAClC,CAAC,EAAK,WAAW,MAAM,WAAW,SAAS,EAC3C,CAAC,EAAK,WAAW,MAAM,WAAW,UAAU,CAE5C,GAAa,OAEb,MAIJ,EAAY,KAAK,KAAK,OAAO,EAAW,EAAG,GAAG,EAAQ,EAEzD,CACF,CACF"}
|
|
1
|
+
{"version":3,"file":"babel-plugin-intlayer-optimize.mjs","names":[],"sources":["../../src/babel-plugin-intlayer-optimize.ts"],"sourcesContent":["import { dirname, join, relative } from 'node:path';\nimport type { NodePath, PluginObj, PluginPass } from '@babel/core';\nimport type * as BabelTypes from '@babel/types';\nimport { getFileHash } from '@intlayer/chokidar/utils';\nimport { normalizePath } from '@intlayer/config/utils';\n\nconst PACKAGE_LIST = [\n 'intlayer',\n '@intlayer/core',\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'svelte-intlayer',\n 'vue-intlayer',\n 'angular-intlayer',\n 'preact-intlayer',\n 'solid-intlayer',\n];\n\nconst CALLER_LIST = ['useIntlayer', 'getIntlayer'] as const;\n\n/**\n * Packages that support dynamic import\n */\nconst PACKAGE_LIST_DYNAMIC = [\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'preact-intlayer',\n 'vue-intlayer',\n 'solid-intlayer',\n 'svelte-intlayer',\n 'angular-intlayer',\n] as const;\n\nconst STATIC_IMPORT_FUNCTION = {\n getIntlayer: 'getDictionary',\n useIntlayer: 'useDictionary',\n} as const;\n\nconst DYNAMIC_IMPORT_FUNCTION = {\n useIntlayer: 'useDictionaryDynamic',\n} as const;\n\n/**\n * Options for the optimization Babel plugin\n */\nexport type OptimizePluginOptions = {\n /**\n * If false, the plugin will not apply any transformation.\n */\n optimize?: boolean;\n /**\n * The path to the dictionaries directory.\n */\n dictionariesDir: string;\n /**\n * The path to the dictionaries entry file.\n */\n dictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries entry file.\n */\n unmergedDictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries directory.\n */\n unmergedDictionariesDir: string;\n /**\n * The path to the dictionaries directory.\n */\n dynamicDictionariesDir: string;\n /**\n * The path to the dynamic dictionaries entry file.\n */\n dynamicDictionariesEntryPath: string;\n /**\n * The path to the fetch dictionaries directory.\n */\n fetchDictionariesDir: string;\n /**\n * The path to the fetch dictionaries entry file.\n */\n fetchDictionariesEntryPath: string;\n /**\n * If true, the plugin will replace the dictionary entry file with `export default {}`.\n */\n replaceDictionaryEntry: boolean;\n /**\n * If true, the plugin will activate the dynamic import of the dictionaries. It will rely on Suspense to load the dictionaries.\n */\n importMode: 'static' | 'dynamic' | 'fetch';\n /**\n * Map of dictionary keys to their specific import mode.\n */\n dictionaryModeMap?: Record<string, 'static' | 'dynamic' | 'fetch'>;\n /**\n * Files list to traverse.\n */\n filesList: string[];\n};\n\ntype State = PluginPass & {\n opts: OptimizePluginOptions;\n /** map key → generated ident (per-file) for static imports */\n _newStaticImports?: Map<string, BabelTypes.Identifier>;\n /** map key → generated ident (per-file) for dynamic imports */\n _newDynamicImports?: Map<string, BabelTypes.Identifier>;\n /** whether the current file imported *any* intlayer package */\n _hasValidImport?: boolean;\n /** map from local identifier name to the imported intlayer func name ('useIntlayer' | 'getIntlayer') */\n _callerMap?: Map<string, (typeof CALLER_LIST)[number]>;\n /** whether the current file *is* the dictionaries entry file */\n _isDictEntry?: boolean;\n /** whether dynamic helpers are active for this file */\n _useDynamicHelpers?: boolean;\n /** whether the current file is included in the filesList */\n _isIncluded?: boolean;\n};\n\n/**\n * Replicates the xxHash64 → Base-62 algorithm used by the SWC version\n * and prefixes an underscore so the generated identifiers never collide\n * with user-defined ones.\n */\nconst makeIdent = (\n key: string,\n t: typeof BabelTypes\n): BabelTypes.Identifier => {\n const hash = getFileHash(key);\n return t.identifier(`_${hash}`);\n};\n\nconst computeImport = (\n fromFile: string,\n dictionariesDir: string,\n dynamicDictionariesDir: string,\n fetchDictionariesDir: string,\n key: string,\n importMode: 'static' | 'dynamic' | 'fetch'\n): string => {\n let relativePath = join(dictionariesDir, `${key}.json`);\n\n if (importMode === 'fetch') {\n relativePath = join(fetchDictionariesDir, `${key}.mjs`);\n }\n\n if (importMode === 'dynamic') {\n relativePath = join(dynamicDictionariesDir, `${key}.mjs`);\n }\n\n let rel = relative(dirname(fromFile), relativePath);\n\n // Fix windows path\n rel = normalizePath(rel);\n\n // Fix relative path\n if (!rel.startsWith('./') && !rel.startsWith('../')) {\n rel = `./${rel}`;\n }\n\n return rel;\n};\n\n/**\n * Babel plugin that transforms Intlayer function calls and auto-imports dictionaries.\n *\n * This plugin transforms calls to `useIntlayer()` and `getIntlayer()` from various Intlayer\n * packages into optimized dictionary access patterns, automatically importing the required\n * dictionary files based on the configured import mode.\n *\n * ## Supported Input Patterns\n *\n * The plugin recognizes these function calls:\n *\n * ```ts\n * // useIntlayer\n * import { useIntlayer } from 'react-intlayer';\n * import { useIntlayer } from 'next-intlayer';\n *\n * // getIntlayer\n * import { getIntlayer } from 'intlayer';\n *\n * // Usage\n * const content = useIntlayer('app');\n * const content = getIntlayer('app');\n * ```\n *\n * ## Transformation Modes\n *\n * ### Static Mode (default: `importMode = \"static\"`)\n *\n * Imports JSON dictionaries directly and replaces function calls with dictionary access:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import { useDictionary as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash);\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Dynamic Mode (`importMode = \"dynamic\"`)\n *\n * Uses dynamic dictionary loading with Suspense support:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Live Mode (`importMode = \"live\"`)\n *\n * Uses live-based dictionary loading for remote dictionaries:\n *\n * **Output if `dictionaryModeMap` includes the key with \"live\" value:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_fetch from '../../.intlayer/fetch_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_fetch, \"app\");\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * > If `dictionaryModeMap` does not include the key with \"live\" value, the plugin will fallback to the dynamic impor\n *\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n */\nexport const intlayerOptimizeBabelPlugin = (babel: {\n types: typeof BabelTypes;\n}): PluginObj<State> => {\n const { types: t } = babel;\n\n return {\n name: 'babel-plugin-intlayer-transform',\n\n pre() {\n this._newStaticImports = new Map();\n this._newDynamicImports = new Map();\n this._callerMap = new Map();\n this._isIncluded = true;\n this._hasValidImport = false;\n this._isDictEntry = false;\n this._useDynamicHelpers = false;\n\n // If optimize is false, skip processing entirely\n if (this.opts.optimize === false) {\n this._isIncluded = false;\n return;\n }\n\n // If filesList is provided, check if current file is included\n const filename = this.file.opts.filename;\n if (this.opts.filesList && filename) {\n const isIncluded = this.opts.filesList.includes(filename);\n\n if (!isIncluded) {\n // Force _isIncluded to false to skip processing\n this._isIncluded = false;\n return;\n }\n }\n },\n\n visitor: {\n /* If this file *is* the dictionaries entry, short-circuit: export {} */\n Program: {\n enter(programPath, state) {\n // Safe access to filename\n const filename = state.file.opts.filename;\n\n // Check if this is the correct file to transform\n\n if (\n state.opts.replaceDictionaryEntry &&\n filename === state.opts.dictionariesEntryPath\n ) {\n state._isDictEntry = true;\n\n // Traverse the program to surgically remove/edit specific parts\n programPath.traverse({\n // Remove all import statements (cleaning up 'sssss.json')\n ImportDeclaration(path) {\n path.remove();\n },\n\n // Find the variable definition and empty the object\n VariableDeclarator(path) {\n // We look for: const x = { ... }\n\n if (t.isObjectExpression(path.node.init)) {\n // Set the object properties to an empty array: {}\n path.node.init.properties = [];\n }\n },\n });\n\n // (Optional) Stop other plugins from processing this file further if needed\n // programPath.stop();\n }\n },\n\n /**\n * After full traversal, process imports and call expressions, then inject the JSON dictionary imports.\n *\n * We do the transformation in Program.exit (via a manual traverse) rather than using\n * top-level ImportDeclaration/CallExpression visitors. This ensures that if another plugin\n * (like babel-plugin-intlayer-extract) adds new useIntlayer calls in its Program.exit,\n * we will see and transform them here because our Program.exit runs after theirs.\n */\n exit(programPath, state) {\n if (state._isDictEntry) return; // nothing else to do – already replaced\n\n if (!state._isIncluded) return; // early-out if file is not included\n\n // Manual traversal to process imports and call expressions\n // This runs AFTER all other plugins' visitors have completed\n\n // Pre-pass to determine if we should use dynamic helpers\n let fileHasDynamicCall = false;\n programPath.traverse({\n CallExpression(path) {\n const callee = path.node.callee;\n\n if (!t.isIdentifier(callee)) return;\n\n const originalImportedName = state._callerMap?.get(callee.name);\n if (originalImportedName !== 'useIntlayer') return;\n\n const arg = path.node.arguments[0];\n\n let key: string | undefined;\n\n if (arg && t.isStringLiteral(arg)) {\n key = arg.value;\n } else if (\n arg &&\n t.isTemplateLiteral(arg) &&\n arg.expressions.length === 0 &&\n arg.quasis.length === 1\n ) {\n // If the bundler output is `breadcrumb` instead of 'breadcrumb'\n key = arg.quasis[0].value.cooked ?? arg.quasis[0].value.raw;\n }\n\n if (!key) return;\n const dictionaryOverrideMode =\n state.opts.dictionaryModeMap?.[key];\n\n if (\n dictionaryOverrideMode === 'dynamic' ||\n dictionaryOverrideMode === 'fetch'\n ) {\n fileHasDynamicCall = true;\n }\n },\n });\n\n programPath.traverse({\n /* Inspect every intlayer import */\n ImportDeclaration(path) {\n const src = path.node.source.value;\n\n if (!PACKAGE_LIST.includes(src)) return;\n\n // Mark that we do import from an intlayer package in this file\n state._hasValidImport = true;\n\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n const importedName = t.isIdentifier(spec.imported)\n ? spec.imported.name\n : (spec.imported as BabelTypes.StringLiteral).value;\n\n if (CALLER_LIST.includes(importedName as any)) {\n state._callerMap?.set(\n spec.local.name,\n importedName as (typeof CALLER_LIST)[number]\n );\n }\n\n const importMode = state.opts.importMode;\n // Determine whether this import should use the dynamic helpers.\n const shouldUseDynamicHelpers =\n (importMode === 'dynamic' ||\n importMode === 'fetch' ||\n fileHasDynamicCall) &&\n PACKAGE_LIST_DYNAMIC.includes(src as any);\n\n // Remember for later (CallExpression) whether we are using the dynamic helpers\n\n if (shouldUseDynamicHelpers) {\n state._useDynamicHelpers = true;\n }\n\n let helperMap: Record<string, string>;\n\n if (shouldUseDynamicHelpers) {\n // Use dynamic helpers for useIntlayer when dynamic mode is enabled\n helperMap = {\n ...STATIC_IMPORT_FUNCTION,\n ...DYNAMIC_IMPORT_FUNCTION,\n } as Record<string, string>;\n } else {\n // Use static helpers by default\n helperMap = STATIC_IMPORT_FUNCTION as Record<string, string>;\n }\n\n const newIdentifier = helperMap[importedName];\n\n // Only rewrite when we actually have a mapping for the imported\n // specifier (ignore unrelated named imports).\n\n if (newIdentifier) {\n // Keep the local alias intact (so calls remain `useIntlayer` /\n // `getIntlayer`), but rewrite the imported identifier so it\n // points to our helper implementation.\n spec.imported = t.identifier(newIdentifier);\n }\n }\n },\n\n /* Replace calls: useIntlayer(\"foo\") → useDictionary(_hash) or useDictionaryDynamic(_hash, \"foo\") */\n CallExpression(path) {\n const callee = path.node.callee;\n\n if (!t.isIdentifier(callee)) return;\n\n const originalImportedName = state._callerMap?.get(callee.name);\n if (!originalImportedName) return;\n\n // Ensure we ultimately emit helper imports for files that *invoke*\n // the hooks, even if they didn't import them directly (edge cases with\n // re-exports).\n state._hasValidImport = true;\n\n const arg = path.node.arguments[0];\n\n let key: string | undefined;\n\n if (arg && t.isStringLiteral(arg)) {\n key = arg.value;\n } else if (\n arg &&\n t.isTemplateLiteral(arg) &&\n arg.expressions.length === 0 &&\n arg.quasis.length === 1\n ) {\n // If the bundler output is `breadcrumb` instead of 'breadcrumb'\n key = arg.quasis[0].value.cooked ?? arg.quasis[0].value.raw;\n }\n\n if (!key) return; // must be a static literal\n const importMode = state.opts.importMode;\n const isUseIntlayer = originalImportedName === 'useIntlayer';\n const useDynamicHelpers = Boolean(state._useDynamicHelpers);\n\n // Decide per-call mode: 'static' | 'dynamic' | 'fetch'\n let perCallMode: 'static' | 'dynamic' | 'fetch' = 'static';\n\n const dictionaryOverrideMode =\n state.opts.dictionaryModeMap?.[key];\n\n if (isUseIntlayer && useDynamicHelpers) {\n if (dictionaryOverrideMode) {\n perCallMode = dictionaryOverrideMode;\n } else if (importMode === 'dynamic') {\n perCallMode = 'dynamic';\n } else if (importMode === 'fetch') {\n perCallMode = 'fetch';\n }\n } else if (isUseIntlayer && !useDynamicHelpers) {\n // If dynamic helpers are NOT active (global mode is static),\n // we STILL might want to force dynamic/live for this specific call\n\n if (\n dictionaryOverrideMode === 'dynamic' ||\n dictionaryOverrideMode === 'fetch'\n ) {\n perCallMode = dictionaryOverrideMode;\n }\n }\n\n let ident: BabelTypes.Identifier;\n\n if (perCallMode === 'fetch') {\n // Use fetch dictionaries entry (live mode for selected keys)\n let dynamicIdent = state._newDynamicImports?.get(key);\n\n if (!dynamicIdent) {\n const hash = getFileHash(key);\n dynamicIdent = t.identifier(`_${hash}_fetch`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Helper: first argument is the dictionary entry, second is the key\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else if (perCallMode === 'dynamic') {\n // Use dynamic dictionaries entry\n let dynamicIdent = state._newDynamicImports?.get(key);\n\n if (!dynamicIdent) {\n // Create a unique identifier for dynamic imports by appending a suffix\n const hash = getFileHash(key);\n dynamicIdent = t.identifier(`_${hash}_dyn`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Dynamic helper: first argument is the dictionary, second is the key.\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else {\n // Use static imports for getIntlayer or useIntlayer when not using dynamic helpers\n let staticIdent = state._newStaticImports?.get(key);\n\n if (!staticIdent) {\n staticIdent = makeIdent(key, t);\n state._newStaticImports?.set(key, staticIdent);\n }\n ident = staticIdent;\n\n // Static helper (useDictionary / getDictionary): replace key with iden\n path.node.arguments[0] = t.identifier(ident.name);\n }\n },\n });\n\n // Early-out if we touched nothing\n\n if (!state._hasValidImport) return;\n\n const file = state.file.opts.filename!;\n const dictionariesDir = state.opts.dictionariesDir;\n const dynamicDictionariesDir = state.opts.dynamicDictionariesDir;\n const fetchDictionariesDir = state.opts.fetchDictionariesDir;\n const imports: BabelTypes.ImportDeclaration[] = [];\n\n // Generate static JSON imports (getIntlayer always uses JSON dictionaries)\n for (const [key, ident] of state._newStaticImports!) {\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n 'static'\n );\n\n const importDeclarationNode = t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n );\n\n // Add 'type: json' attribute for JSON files\n importDeclarationNode.attributes = [\n t.importAttribute(t.identifier('type'), t.stringLiteral('json')),\n ];\n\n imports.push(importDeclarationNode);\n }\n\n // Generate dynamic/fetch imports (for useIntlayer when using dynamic/live helpers)\n for (const [key, ident] of state._newDynamicImports!) {\n const modeForThisIdent: 'dynamic' | 'fetch' = ident.name.endsWith(\n '_fetch'\n )\n ? 'fetch'\n : 'dynamic';\n\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n modeForThisIdent\n );\n imports.push(\n t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n )\n );\n }\n\n if (!imports.length) return;\n\n /* Keep \"use client\" / \"use server\" directives at the very top. */\n const bodyPaths = programPath.get(\n 'body'\n ) as NodePath<BabelTypes.Statement>[];\n let insertPos = 0;\n for (const stmtPath of bodyPaths) {\n const stmt = stmtPath.node;\n\n if (\n t.isExpressionStatement(stmt) &&\n t.isStringLiteral(stmt.expression) &&\n !stmt.expression.value.startsWith('import') &&\n !stmt.expression.value.startsWith('require')\n ) {\n insertPos += 1;\n } else {\n break;\n }\n }\n\n programPath.node.body.splice(insertPos, 0, ...imports);\n },\n },\n },\n };\n};\n"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { PluginObj, PluginPass } from "@babel/core";
|
|
|
2
2
|
import * as BabelTypes from "@babel/types";
|
|
3
3
|
|
|
4
4
|
//#region src/babel-plugin-intlayer-optimize.d.ts
|
|
5
|
+
declare const CALLER_LIST: readonly ["useIntlayer", "getIntlayer"];
|
|
5
6
|
/**
|
|
6
7
|
* Options for the optimization Babel plugin
|
|
7
8
|
*/
|
|
@@ -63,7 +64,8 @@ type State = PluginPass & {
|
|
|
63
64
|
opts: OptimizePluginOptions; /** map key → generated ident (per-file) for static imports */
|
|
64
65
|
_newStaticImports?: Map<string, BabelTypes.Identifier>; /** map key → generated ident (per-file) for dynamic imports */
|
|
65
66
|
_newDynamicImports?: Map<string, BabelTypes.Identifier>; /** whether the current file imported *any* intlayer package */
|
|
66
|
-
_hasValidImport?: boolean; /**
|
|
67
|
+
_hasValidImport?: boolean; /** map from local identifier name to the imported intlayer func name ('useIntlayer' | 'getIntlayer') */
|
|
68
|
+
_callerMap?: Map<string, (typeof CALLER_LIST)[number]>; /** whether the current file *is* the dictionaries entry file */
|
|
67
69
|
_isDictEntry?: boolean; /** whether dynamic helpers are active for this file */
|
|
68
70
|
_useDynamicHelpers?: boolean; /** whether the current file is included in the filesList */
|
|
69
71
|
_isIncluded?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"babel-plugin-intlayer-optimize.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-optimize.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"babel-plugin-intlayer-optimize.d.ts","names":[],"sources":["../../src/babel-plugin-intlayer-optimize.ts"],"mappings":";;;;cAsBM,WAAA;;AApB0C;;KAmDpC,qBAAA;EA/B+C;;AA+B3D;EAIE,QAAA;;;;EAIA,eAAA;EAIA;;;EAAA,qBAAA;EAgBA;;;EAZA,6BAAA;EA4BA;;;EAxBA,uBAAA;EAgCS;;AACT;EA7BA,sBAAA;;;;EAIA,4BAAA;EA8BoB;;;EA1BpB,oBAAA;EAgCa;;;EA5Bb,0BAAA;EAoBA;;;EAhBA,sBAAA;EAkBgC;;;EAdhC,UAAA;EAgBiC;;;EAZjC,iBAAA,GAAoB,MAAA;EAgBP;;;EAZb,SAAA;AAAA;AAAA,KAGG,KAAA,GAAQ,UAAA;EACX,IAAA,EAAM,qBAAA,EA+IK;EA7IX,iBAAA,GAAoB,GAAA,SAAY,UAAA,CAAW,UAAA;EAE3C,kBAAA,GAAqB,GAAA,SAAY,UAAA,CAAW,UAAA,GA6IhC;EA3IZ,eAAA,YA2IW;EAzIX,UAAA,GAAa,GAAA,iBAAoB,WAAA,YAwIjC;EAtIA,YAAA,YAqI0C;EAnI1C,kBAAA,YAqIY;EAnIZ,WAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiIW,2BAAA,GAA+B,KAAA;EAC1C,KAAA,SAAc,UAAA;AAAA,MACZ,SAAA,CAAU,KAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/babel",
|
|
3
|
-
"version": "8.1.
|
|
3
|
+
"version": "8.1.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A Babel plugin for Intlayer that transforms declaration files and provides internationalization features during the build process according to the Intlayer configuration.",
|
|
6
6
|
"keywords": [
|
|
@@ -58,7 +58,6 @@
|
|
|
58
58
|
"./package.json"
|
|
59
59
|
],
|
|
60
60
|
"scripts": {
|
|
61
|
-
"_prepublish": "cp -f ../../../README.md ./README.md",
|
|
62
61
|
"build": "tsdown --config tsdown.config.ts",
|
|
63
62
|
"build:ci": "tsdown --config tsdown.config.ts",
|
|
64
63
|
"clean": "rimraf ./dist .turbo",
|
|
@@ -67,7 +66,7 @@
|
|
|
67
66
|
"format:fix": "biome format --write .",
|
|
68
67
|
"lint": "biome lint .",
|
|
69
68
|
"lint:fix": "biome lint --write .",
|
|
70
|
-
"prepublish": "
|
|
69
|
+
"prepublish": "cp -f ../../../README.md ./README.md",
|
|
71
70
|
"publish": "bun publish || true",
|
|
72
71
|
"publish:canary": "bun publish --access public --tag canary || true",
|
|
73
72
|
"publish:latest": "bun publish --access public --tag latest || true",
|
|
@@ -81,10 +80,10 @@
|
|
|
81
80
|
"@babel/parser": "7.1.5",
|
|
82
81
|
"@babel/traverse": "7.28.0",
|
|
83
82
|
"@babel/types": "7.28.4",
|
|
84
|
-
"@intlayer/chokidar": "8.1.
|
|
85
|
-
"@intlayer/config": "8.1.
|
|
86
|
-
"@intlayer/core": "8.1.
|
|
87
|
-
"@intlayer/types": "8.1.
|
|
83
|
+
"@intlayer/chokidar": "8.1.7",
|
|
84
|
+
"@intlayer/config": "8.1.7",
|
|
85
|
+
"@intlayer/core": "8.1.7",
|
|
86
|
+
"@intlayer/types": "8.1.7",
|
|
88
87
|
"@types/babel__core": "7.20.5",
|
|
89
88
|
"@types/babel__generator": "7.27.0",
|
|
90
89
|
"@types/babel__traverse": "7.28.0",
|
|
@@ -92,7 +91,7 @@
|
|
|
92
91
|
},
|
|
93
92
|
"devDependencies": {
|
|
94
93
|
"@babel/plugin-syntax-jsx": "^7.28.6",
|
|
95
|
-
"@intlayer/dictionaries-entry": "8.1.
|
|
94
|
+
"@intlayer/dictionaries-entry": "8.1.7",
|
|
96
95
|
"@types/crypto-js": "4.2.2",
|
|
97
96
|
"@types/node": "25.3.0",
|
|
98
97
|
"@utils/ts-config": "1.0.4",
|
|
@@ -105,7 +104,7 @@
|
|
|
105
104
|
"vitest": "4.0.18"
|
|
106
105
|
},
|
|
107
106
|
"peerDependencies": {
|
|
108
|
-
"@intlayer/dictionaries-entry": "8.1.
|
|
107
|
+
"@intlayer/dictionaries-entry": "8.1.7"
|
|
109
108
|
},
|
|
110
109
|
"peerDependenciesMeta": {
|
|
111
110
|
"@intlayer/dictionaries-entry": {
|