@intlayer/next-intl 9.3.0 → 9.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -24
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +1 -2
- package/dist/cjs/client/NextIntlClientProvider.cjs.map +1 -1
- package/dist/cjs/client/useLocale.cjs.map +1 -1
- package/dist/cjs/getDictionary.cjs +2 -1
- package/dist/cjs/getDictionary.cjs.map +1 -1
- package/dist/cjs/getDictionaryDynamic.cjs +3 -1
- package/dist/cjs/getDictionaryDynamic.cjs.map +1 -1
- package/dist/cjs/middleware.cjs +1 -1
- package/dist/cjs/middleware.cjs.map +1 -1
- package/dist/cjs/navigation/Link.cjs.map +1 -1
- package/dist/cjs/navigation/createNavigation.cjs.map +1 -1
- package/dist/cjs/navigation/hooks.cjs.map +1 -1
- package/dist/cjs/navigation/localizeHref.cjs +2 -1
- package/dist/cjs/navigation/localizeHref.cjs.map +1 -1
- package/dist/cjs/plugin/index.cjs +1 -1
- package/dist/cjs/plugin/index.cjs.map +1 -1
- package/dist/cjs/server/getLocale.cjs.map +1 -1
- package/dist/cjs/server/getMessages.cjs.map +1 -1
- package/dist/cjs/server/getRequestConfig.cjs.map +1 -1
- package/dist/cjs/server/getTranslations.cjs +2 -1
- package/dist/cjs/server/getTranslations.cjs.map +1 -1
- package/dist/cjs/server/helpers.cjs +2 -1
- package/dist/cjs/server/helpers.cjs.map +1 -1
- package/dist/cjs/server/requestLocaleCache.cjs.map +1 -1
- package/dist/cjs/server/setLocale.cjs.map +1 -1
- package/dist/esm/getDictionary.mjs +2 -1
- package/dist/esm/getDictionary.mjs.map +1 -1
- package/dist/esm/getDictionaryDynamic.mjs +3 -1
- package/dist/esm/getDictionaryDynamic.mjs.map +1 -1
- package/dist/esm/middleware.mjs +1 -1
- package/dist/esm/middleware.mjs.map +1 -1
- package/dist/esm/navigation/localizeHref.mjs +2 -1
- package/dist/esm/navigation/localizeHref.mjs.map +1 -1
- package/dist/esm/plugin/index.mjs +1 -1
- package/dist/esm/plugin/index.mjs.map +1 -1
- package/dist/esm/server/getTranslations.mjs +2 -1
- package/dist/esm/server/getTranslations.mjs.map +1 -1
- package/dist/esm/server/helpers.mjs +2 -1
- package/dist/esm/server/helpers.mjs.map +1 -1
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -47,27 +47,27 @@ With **per-locale content files**, **TypeScript autocompletion**, **tree-shakabl
|
|
|
47
47
|
|
|
48
48
|
## Keys benefits of Intlayer:
|
|
49
49
|
|
|
50
|
-
| Feature | Description
|
|
51
|
-
| --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/frameworks.png?raw=true" alt="Feature" width="700"> | **Cross-Frameworks Support**<br><br>Intlayer is compatible with all major frameworks and libraries, including Next.js, React, Vite, Vue.js, Nuxt, Preact, Express, and more.
|
|
53
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/javascript_content_management.jpg?raw=true" alt="Feature" width="700"> | **JavaScript-Powered Content Management**<br><br>Harness the flexibility of JavaScript to define and manage your content efficiently. <br><br> - [Content declaration](https://intlayer.org/doc/concept/content)
|
|
54
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/per_locale_content_declaration_file.png?raw=true" alt="Feature" width="700"> | **Per-Locale Content Declaration File**<br><br>Speed up your development by declaring your content once, before auto generation.<br><br> - [Per-Locale Content Declaration File](https://intlayer.org/doc/concept/per-locale-file)
|
|
55
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/compiler.jpg?raw=true" alt="Feature" width="700"> | **Compiler**<br><br>The Intlayer Compiler extract automatically the content from the components and generate the dictionary files.<br><br> - [Compiler](https://intlayer.org/doc/compiler)
|
|
56
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true" alt="Feature" width="700"> | **Type-Safe Environment**<br><br>Leverage TypeScript to ensure your content definitions and code are error-free, while also benefiting from IDE autocompletion.<br><br> - [TypeScript configuration](https://intlayer.org/doc/environment/vite-and-react#configure-typescript)
|
|
57
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/config_file.png?raw=true" alt="Feature" width="700"> | **Simplified Setup**<br><br>Get up and running quickly with minimal configuration. Adjust settings for internationalization, routing, AI, build, and content handling with ease. <br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs)
|
|
58
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/content_retrieval.png?raw=true" alt="Feature" width="700"> | **Simplified Content Retrieval**<br><br>No need to call your `t` function for each piece of content. Retrieve all your content directly using a single hook.<br><br> - [React integration](https://intlayer.org/doc/environment/create-react-app)
|
|
59
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/server_component.png?raw=true" alt="Feature" width="700"> | **Consistent Server Component Implementation**<br><br>Perfectly suited for Next.js server components, use the same implementation for both client and server components, no need to pass your `t` function across each server component. <br><br> - [Server Components](https://intlayer.org/doc/environment/nextjs#step-7-utilize-content-in-your-code)
|
|
60
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/file_tree.png?raw=true" alt="Feature" width="700"> | **Organized Codebase**<br><br>Keep your codebase more organized: 1 component = 1 dictionary in the same folder. Translations close to their respective components, enhance maintainability and clarity. <br><br> - [How Intlayer works](https://intlayer.org/doc/concept/how-works-intlayer)
|
|
61
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/url_routing.png?raw=true" alt="Feature" width="700"> | **Enhanced Routing**<br><br>Full support of app routing, adapting seamlessly to complex application structures, for Next.js, React, Vite, Vue.js, etc.<br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs)
|
|
62
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/markdown.png?raw=true" alt="Feature" width="700"> | **Markdown Support**<br><br>Import and interpret, locale files and remote Markdown for multilingual content like privacy policies, documentation, etc. Interpret and make Markdown metadata accessible in your code.<br><br> - [Content files](https://intlayer.org/doc/concept/content/file)
|
|
63
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/visual_editor.png?raw=true" alt="Feature" width="700"> | **Free Visual Editor & CMS**<br><br>A free visual editor and CMS are available for content writers, removing the need for a localization platform. Keep your content synchronized using Git, or externalize it totally or partially with the CMS.<br><br> - [Intlayer Editor](https://intlayer.org/doc/concept/editor) <br> - [Intlayer CMS](https://intlayer.org/doc/concept/cms)
|
|
64
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/bundle.png?raw=true" alt="Feature" width="700"> | **Tree-shakable Content**<br><br>Tree-shakable content, reducing the size of the final bundle. Loads content per component, excluding any unused content from your bundle. Supports lazy loading to enhance app loading efficiency. <br><br> - [App build optimization](https://intlayer.org/doc/concept/how-works-intlayer#app-build-optimization)
|
|
65
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/static_rendering.png?raw=true" alt="Feature" width="700"> | **Static Rendering**<br><br>Doesn't block Static Rendering. <br><br> - [Next.js integration](https://intlayer.org/doc/environment/nextjs)
|
|
66
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/AI_translation.png?raw=true" alt="Feature" width="700"> | **AI-Powered Translation**<br><br>Transform your website into 231 languages with just one click using Intlayer's advanced AI-powered translation tools using your own AI provider / API key. <br><br> - [CI/CD integration](https://intlayer.org/doc/concept/ci-cd) <br> - [Intlayer CLI](https://intlayer.org/doc/concept/cli) <br> - [Auto fill](https://intlayer.org/doc/concept/auto-fill)
|
|
67
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/mcp.png?raw=true" alt="Feature" width="700"> | **MCP Server Integration**<br><br>Provides an MCP (Model Context Protocol) server for IDE automation, enabling seamless content management and i18n workflows directly within your development environment. <br><br> - [MCP Server](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/mcp_server.md)
|
|
68
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/vscode_extension.png?raw=true" alt="Feature" width="700"> | **VSCode Extension**<br><br>Intlayer provides a VSCode extension to help you manage your content and translations, building your dictionaries, translating your content, and more. <br><br> - [VSCode Extension](https://intlayer.org/doc/vs-code-extension)
|
|
69
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/interoperability.png?raw=true" alt="Feature" width="700"> | **Interoperability**<br><br>Allow interoperability with react-i18next, next-i18next, next-intl, react-intl, vue-i18n. <br><br> - [Intlayer and react-intl](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [Intlayer and next-intl](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [Intlayer and next-i18next](https://intlayer.org/blog/intlayer-with-next-i18next) <br> - [Intlayer and vue-i18n](https://intlayer.org/blog/intlayer-with-vue-i18n) |
|
|
70
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/benchmark.png?raw=true" alt="Feature" width="700"> | **Performances & Benchmark**<br><br>Uses advanced tree-shaking and dynamic loading to boost performances and keep the solution as light as possible. <br><br> - [Performances & Benchmark](https://intlayer.org/doc/benchmark)
|
|
50
|
+
| Feature | Description |
|
|
51
|
+
| --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/frameworks.png?raw=true" alt="Feature" width="700"> | **Cross-Frameworks Support**<br><br>Intlayer is compatible with all major frameworks and libraries, including Next.js, React, Vite, Vue.js, Nuxt, Preact, Express, and more. |
|
|
53
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/javascript_content_management.jpg?raw=true" alt="Feature" width="700"> | **JavaScript-Powered Content Management**<br><br>Harness the flexibility of JavaScript to define and manage your content efficiently. <br><br> - [Content declaration](https://intlayer.org/doc/concept/content) |
|
|
54
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/per_locale_content_declaration_file.png?raw=true" alt="Feature" width="700"> | **Per-Locale Content Declaration File**<br><br>Speed up your development by declaring your content once, before auto generation.<br><br> - [Per-Locale Content Declaration File](https://intlayer.org/doc/concept/per-locale-file) |
|
|
55
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/compiler.jpg?raw=true" alt="Feature" width="700"> | **Compiler**<br><br>The Intlayer Compiler extract automatically the content from the components and generate the dictionary files.<br><br> - [Compiler](https://intlayer.org/doc/compiler) |
|
|
56
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true" alt="Feature" width="700"> | **Type-Safe Environment**<br><br>Leverage TypeScript to ensure your content definitions and code are error-free, while also benefiting from IDE autocompletion.<br><br> - [TypeScript configuration](https://intlayer.org/doc/environment/vite-and-react#configure-typescript) |
|
|
57
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/config_file.png?raw=true" alt="Feature" width="700"> | **Simplified Setup**<br><br>Get up and running quickly with minimal configuration. Adjust settings for internationalization, routing, AI, build, and content handling with ease. <br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs) |
|
|
58
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/content_retrieval.png?raw=true" alt="Feature" width="700"> | **Simplified Content Retrieval**<br><br>No need to call your `t` function for each piece of content. Retrieve all your content directly using a single hook.<br><br> - [React integration](https://intlayer.org/doc/environment/create-react-app) |
|
|
59
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/server_component.png?raw=true" alt="Feature" width="700"> | **Consistent Server Component Implementation**<br><br>Perfectly suited for Next.js server components, use the same implementation for both client and server components, no need to pass your `t` function across each server component. <br><br> - [Server Components](https://intlayer.org/doc/environment/nextjs#step-7-utilize-content-in-your-code) |
|
|
60
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/file_tree.png?raw=true" alt="Feature" width="700"> | **Organized Codebase**<br><br>Keep your codebase more organized: 1 component = 1 dictionary in the same folder. Translations close to their respective components, enhance maintainability and clarity. <br><br> - [How Intlayer works](https://intlayer.org/doc/concept/how-works-intlayer) |
|
|
61
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/url_routing.png?raw=true" alt="Feature" width="700"> | **Enhanced Routing**<br><br>Full support of app routing, adapting seamlessly to complex application structures, for Next.js, React, Vite, Vue.js, etc.<br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs) |
|
|
62
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/markdown.png?raw=true" alt="Feature" width="700"> | **Markdown Support**<br><br>Import and interpret, locale files and remote Markdown for multilingual content like privacy policies, documentation, etc. Interpret and make Markdown metadata accessible in your code.<br><br> - [Content files](https://intlayer.org/doc/concept/content/file) |
|
|
63
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/visual_editor.png?raw=true" alt="Feature" width="700"> | **Free Visual Editor & CMS**<br><br>A free visual editor and CMS are available for content writers, removing the need for a localization platform. Keep your content synchronized using Git, or externalize it totally or partially with the CMS.<br><br> - [Intlayer Editor](https://intlayer.org/doc/concept/editor) <br> - [Intlayer CMS](https://intlayer.org/doc/concept/cms) |
|
|
64
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/bundle.png?raw=true" alt="Feature" width="700"> | **Tree-shakable Content**<br><br>Tree-shakable content, reducing the size of the final bundle. Loads content per component, excluding any unused content from your bundle. Supports lazy loading to enhance app loading efficiency. <br><br> - [App build optimization](https://intlayer.org/doc/concept/how-works-intlayer#app-build-optimization) |
|
|
65
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/static_rendering.png?raw=true" alt="Feature" width="700"> | **Static Rendering**<br><br>Doesn't block Static Rendering. <br><br> - [Next.js integration](https://intlayer.org/doc/environment/nextjs) |
|
|
66
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/AI_translation.png?raw=true" alt="Feature" width="700"> | **AI-Powered Translation**<br><br>Transform your website into 231 languages with just one click using Intlayer's advanced AI-powered translation tools using your own AI provider / API key. <br><br> - [CI/CD integration](https://intlayer.org/doc/concept/ci-cd) <br> - [Intlayer CLI](https://intlayer.org/doc/concept/cli) <br> - [Auto fill](https://intlayer.org/doc/concept/auto-fill) |
|
|
67
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/mcp.png?raw=true" alt="Feature" width="700"> | **MCP Server Integration**<br><br>Provides an MCP (Model Context Protocol) server for IDE automation, enabling seamless content management and i18n workflows directly within your development environment. <br><br> - [MCP Server](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/mcp_server.md) |
|
|
68
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/vscode_extension.png?raw=true" alt="Feature" width="700"> | **VSCode Extension**<br><br>Intlayer provides a VSCode extension to help you manage your content and translations, building your dictionaries, translating your content, and more. <br><br> - [VSCode Extension](https://intlayer.org/doc/vs-code-extension) |
|
|
69
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/interoperability.png?raw=true" alt="Feature" width="700"> | **Interoperability**<br><br>Allow interoperability with react-i18next, next-i18next, next-intl, react-intl, vue-i18n. <br><br> - [Intlayer and react-intl](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [Intlayer and next-intl](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [Intlayer and next-i18next](https://intlayer.org/blog/intlayer-with-next-i18next) <br> - [Intlayer and vue-i18n](https://intlayer.org/blog/intlayer-with-vue-i18n) <br> - [Intlayer compat adapters](https://intlayer.org/doc/compatibility) |
|
|
70
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/benchmark.png?raw=true" alt="Feature" width="700"> | **Performances & Benchmark**<br><br>Uses advanced tree-shaking and dynamic loading to boost performances and keep the solution as light as possible. <br><br> - [Performances & Benchmark](https://intlayer.org/doc/benchmark) |
|
|
71
71
|
|
|
72
72
|
---
|
|
73
73
|
|
|
@@ -162,7 +162,7 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
|
|
|
162
162
|
<li><a href="https://intlayer.org/doc/concept/cms" rel=''>Intlayer CMS</a></li>
|
|
163
163
|
<li><a href="https://intlayer.org/doc/concept/content" rel=''>Dictionary</a>
|
|
164
164
|
<ul>
|
|
165
|
-
<li><a href="https://intlayer.org/doc/concept/
|
|
165
|
+
<li><a href="https://intlayer.org/doc/concept/per-locale-file" rel=''>Per-Locale Content Declaration File</a></li>
|
|
166
166
|
<li><a href="https://intlayer.org/doc/concept/content/translation" rel=''>Translation</a></li>
|
|
167
167
|
<li><a href="https://intlayer.org/doc/concept/content/enumeration" rel=''>Enumeration</a></li>
|
|
168
168
|
<li><a href="https://intlayer.org/doc/concept/content/condition" rel=''>Condition</a></li>
|
|
@@ -183,7 +183,7 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
|
|
|
183
183
|
<ul>
|
|
184
184
|
<li><a href="https://intlayer.org/doc/environment/nextjs/15" rel=''>Next.js 15</a></li>
|
|
185
185
|
<li><a href="https://intlayer.org/doc/environment/nextjs/14" rel=''>Next.js 14 (App Router)</a></li>
|
|
186
|
-
<li><a href="https://intlayer.org/doc/environment/nextjs/next-with-
|
|
186
|
+
<li><a href="https://intlayer.org/doc/environment/nextjs/next-with-page-router" rel=''>Next.js Page Router</a></li>
|
|
187
187
|
<li><a href="https://intlayer.org/doc/environment/nextjs/compiler" rel=''>Next.js using Compiler</a></li>
|
|
188
188
|
</ul>
|
|
189
189
|
</li>
|
|
@@ -212,7 +212,7 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
|
|
|
212
212
|
<li><a href="https://intlayer.org/doc/environment/sveltekit" rel=''>SvelteKit</a></li>
|
|
213
213
|
<li><a href="https://intlayer.org/doc/environment/vite-and-preact" rel=''>Vite + Preact</a></li>
|
|
214
214
|
<li><a href="https://intlayer.org/doc/environment/vite-and-vue" rel=''>Vite + Vue</a></li>
|
|
215
|
-
<li><a href="https://intlayer.org/doc/environment/
|
|
215
|
+
<li><a href="https://intlayer.org/doc/environment/nuxt-and-vue" rel=''>Vite + Nuxt</a></li>
|
|
216
216
|
<li><a href="https://intlayer.org/doc/environment/vite-and-solid" rel=''>Vite + Solid</a></li>
|
|
217
217
|
<li><a href="https://intlayer.org/doc/environment/angular" rel=''>Angular</a></li>
|
|
218
218
|
<li>
|
|
@@ -19,11 +19,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
19
19
|
}
|
|
20
20
|
return to;
|
|
21
21
|
};
|
|
22
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
23
23
|
value: mod,
|
|
24
24
|
enumerable: true
|
|
25
25
|
}) : target, mod));
|
|
26
26
|
|
|
27
27
|
//#endregion
|
|
28
|
-
|
|
29
28
|
exports.__toESM = __toESM;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NextIntlClientProvider.cjs","names":["CYAN","routing","IntlayerClientProvider"],"sources":["../../../src/client/NextIntlClientProvider.tsx"],"sourcesContent":["'use client';\n\nimport { log, routing } from '@intlayer/config/built';\nimport { CYAN } from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getLocaleFromPath } from '@intlayer/core/localization';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { usePathname } from 'next/navigation';\nimport type { NextIntlClientProvider as _NextIntlClientProvider } from 'next-intl';\nimport { IntlayerClientProvider } from 'next-intlayer';\nimport type { ComponentProps } from 'react';\n\n/**\n * Drop-in for next-intl's `NextIntlClientProvider`.\n * `messages`, `timeZone`, and `now` are accepted for API compatibility\n * but have no effect — Intlayer uses its own compiled dictionaries.\n */\nexport const NextIntlClientProvider: typeof _NextIntlClientProvider = ({\n locale,\n children,\n messages: _messages,\n timeZone: _timeZone,\n now: _now,\n ...rest\n}) => {\n if (\n process.env.NODE_ENV === 'development' &&\n typeof _messages !== 'undefined'\n ) {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize('NextIntlClientProvider', CYAN)} do not pass the messages prop with intlayer. Messages are loaded automatically under the hood for bundle optimization reason`\n );\n }\n\n // next-intl drives the locale from the request: apps render\n // `<NextIntlClientProvider>` without a `locale` prop and the server resolves it\n // from the `[locale]` route segment. As a client component we cannot read the\n // server request here, so when no explicit `locale` is given we derive it from\n // the URL (the same `[locale]` segment) using Intlayer's routing config. This\n // keeps `useLocale`, `Link` and the locale switcher in sync with the URL\n // instead of falling back to the stored cookie / default locale.\n //\n // Only prefix-based routing carries the locale in the path. For `no-prefix` /\n // `search-params` the path has no locale segment, so we leave `locale`\n // undefined and let the provider resolve it from storage (cookie) — deriving\n // from the path there would wrongly clobber the cookie with the default locale.\n const pathname = usePathname();\n const mode = routing?.mode ?? 'prefix-no-default';\n const isPrefixMode = mode === 'prefix-all' || mode === 'prefix-no-default';\n const resolvedLocale =\n locale ?? (isPrefixMode ? getLocaleFromPath(pathname) : undefined);\n\n // `key={resolvedLocale}` remounts the provider when the locale changes via\n // navigation (next-intl switches locale by routing to a locale-prefixed path).\n // This re-seeds the client locale context so client components re-render in\n // the new language instead of keeping the previous one.\n return (\n <IntlayerClientProvider\n key={String(resolvedLocale)}\n locale={resolvedLocale}\n {...rest}\n >\n {children}\n </IntlayerClientProvider>\n );\n};\n\n/**\n *\n */\nexport type NextIntlClientProviderProps = Omit<\n ComponentProps<typeof _NextIntlClientProvider>,\n 'messages'\n> & {\n /**\n * @deprecated\n * has no use case with intlayer. Messages are loaded automatically under the hood for bundle optimization reason\n */\n messages?: never;\n /**\n * locale\n */\n locale: LocalesValues;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,MAAa,0BAA0D,EACrE,QACA,UACA,UAAU,WACV,UAAU,WACV,KAAK,MACL,GAAG,WACC;CACJ,IACE,QAAQ,IAAI,aAAa,iBACzB,OAAO,cAAc,aAGrB,
|
|
1
|
+
{"version":3,"file":"NextIntlClientProvider.cjs","names":["getAppLogger","colorize","CYAN","usePathname","routing","getLocaleFromPath","IntlayerClientProvider"],"sources":["../../../src/client/NextIntlClientProvider.tsx"],"sourcesContent":["'use client';\n\nimport { log, routing } from '@intlayer/config/built';\nimport { CYAN } from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getLocaleFromPath } from '@intlayer/core/localization';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { usePathname } from 'next/navigation';\nimport type { NextIntlClientProvider as _NextIntlClientProvider } from 'next-intl';\nimport { IntlayerClientProvider } from 'next-intlayer';\nimport type { ComponentProps } from 'react';\n\n/**\n * Drop-in for next-intl's `NextIntlClientProvider`.\n * `messages`, `timeZone`, and `now` are accepted for API compatibility\n * but have no effect — Intlayer uses its own compiled dictionaries.\n */\nexport const NextIntlClientProvider: typeof _NextIntlClientProvider = ({\n locale,\n children,\n messages: _messages,\n timeZone: _timeZone,\n now: _now,\n ...rest\n}) => {\n if (\n process.env.NODE_ENV === 'development' &&\n typeof _messages !== 'undefined'\n ) {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize('NextIntlClientProvider', CYAN)} do not pass the messages prop with intlayer. Messages are loaded automatically under the hood for bundle optimization reason`\n );\n }\n\n // next-intl drives the locale from the request: apps render\n // `<NextIntlClientProvider>` without a `locale` prop and the server resolves it\n // from the `[locale]` route segment. As a client component we cannot read the\n // server request here, so when no explicit `locale` is given we derive it from\n // the URL (the same `[locale]` segment) using Intlayer's routing config. This\n // keeps `useLocale`, `Link` and the locale switcher in sync with the URL\n // instead of falling back to the stored cookie / default locale.\n //\n // Only prefix-based routing carries the locale in the path. For `no-prefix` /\n // `search-params` the path has no locale segment, so we leave `locale`\n // undefined and let the provider resolve it from storage (cookie) — deriving\n // from the path there would wrongly clobber the cookie with the default locale.\n const pathname = usePathname();\n const mode = routing?.mode ?? 'prefix-no-default';\n const isPrefixMode = mode === 'prefix-all' || mode === 'prefix-no-default';\n const resolvedLocale =\n locale ?? (isPrefixMode ? getLocaleFromPath(pathname) : undefined);\n\n // `key={resolvedLocale}` remounts the provider when the locale changes via\n // navigation (next-intl switches locale by routing to a locale-prefixed path).\n // This re-seeds the client locale context so client components re-render in\n // the new language instead of keeping the previous one.\n return (\n <IntlayerClientProvider\n key={String(resolvedLocale)}\n locale={resolvedLocale}\n {...rest}\n >\n {children}\n </IntlayerClientProvider>\n );\n};\n\n/**\n *\n */\nexport type NextIntlClientProviderProps = Omit<\n ComponentProps<typeof _NextIntlClientProvider>,\n 'messages'\n> & {\n /**\n * @deprecated\n * has no use case with intlayer. Messages are loaded automatically under the hood for bundle optimization reason\n */\n messages?: never;\n /**\n * locale\n */\n locale: LocalesValues;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,MAAa,0BAA0D,EACrE,QACA,UACA,UAAU,WACV,UAAU,WACV,KAAK,MACL,GAAG,WACC;CACJ,IACE,QAAQ,IAAI,aAAa,iBACzB,OAAO,cAAc,aAGrB,IADkBA,sCAAa,EAAE,gCAAI,CAC7B,CAAC,CACP,OAAGC,kCAAS,0BAA0BC,4BAAI,EAAE,8HAC9C;CAeF,MAAM,eAAWC,6BAAY;CAC7B,MAAM,OAAOC,gCAAS,QAAQ;CAE9B,MAAM,iBACJ,WAFmB,SAAS,gBAAgB,SAAS,0BAE3BC,+CAAkB,QAAQ,IAAI;CAM1D,OACE,2CAACC,sCAAD;EAEE,QAAQ;EACR,GAAI;EAEH;CACqB,GALjB,OAAO,cAAc,CAKJ;AAE5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLocale.cjs","names":[],"sources":["../../../src/client/useLocale.ts"],"sourcesContent":["'use client';\n\nimport type { useLocale as _useLocale } from 'next-intl';\nimport { useLocale as useLocaleIntlayer } from 'next-intlayer';\n\n/**\n * Drop-in for next-intl's `useLocale`.\n */\nexport const useLocale: typeof _useLocale = (): string => {\n const { locale } = useLocaleIntlayer();\n return locale as string;\n};\n"],"mappings":";;;;;;;;;AAQA,MAAa,kBAA6C;CACxD,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"useLocale.cjs","names":["useLocaleIntlayer"],"sources":["../../../src/client/useLocale.ts"],"sourcesContent":["'use client';\n\nimport type { useLocale as _useLocale } from 'next-intl';\nimport { useLocale as useLocaleIntlayer } from 'next-intlayer';\n\n/**\n * Drop-in for next-intl's `useLocale`.\n */\nexport const useLocale: typeof _useLocale = (): string => {\n const { locale } = useLocaleIntlayer();\n return locale as string;\n};\n"],"mappings":";;;;;;;;;AAQA,MAAa,kBAA6C;CACxD,MAAM,EAAE,eAAWA,yBAAkB;CACrC,OAAO;AACT"}
|
|
@@ -26,7 +26,8 @@ const readRestArgument = (rest) => {
|
|
|
26
26
|
const getDictionary = (async (dictionary, rest) => {
|
|
27
27
|
const { namespacePrefix, localeOverride } = readRestArgument(rest);
|
|
28
28
|
const locale = localeOverride ?? await require_server_getLocale.getLocale();
|
|
29
|
-
|
|
29
|
+
const content = (0, next_intlayer.getDictionary)(dictionary, locale);
|
|
30
|
+
return (0, _intlayer_use_intl.createDictionaryTranslator)(locale, content, namespacePrefix);
|
|
30
31
|
});
|
|
31
32
|
|
|
32
33
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDictionary.cjs","names":["getLocale"],"sources":["../../src/getDictionary.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport {\n createDictionaryTranslator,\n type ScopedTranslateFunction,\n type TranslateFunction,\n} from '@intlayer/use-intl';\nimport { getDictionary as getDictionaryBase } from 'next-intlayer';\nimport { getLocale } from './server/getLocale';\n\n/**\n * Trailing argument left by the optimize pass. `getTranslations('ns.scope')`\n * yields the key-prefix remainder as a string, while the object overload\n * `getTranslations({ locale, namespace })` keeps its options object (with the\n * namespace stripped, since the dictionary is now passed directly).\n */\ntype DictionaryTranslatorRest = string | { locale?: LocalesValues };\n\nconst readRestArgument = (\n rest: DictionaryTranslatorRest | undefined\n): { namespacePrefix?: string; localeOverride?: LocalesValues } => {\n if (typeof rest === 'string') return { namespacePrefix: rest };\n return { localeOverride: rest?.locale };\n};\n\n/**\n * Overload set for {@link getDictionary}: a string rest argument is the\n * key-prefix remainder of a nested namespace (relative dot-paths under the\n * scope); otherwise the translator is typed against the dictionary's\n * dot-paths.\n */\ntype GetDictionary = {\n <T extends Dictionary, Prefix extends string>(\n dictionary: T,\n namespacePrefix: Prefix\n ): Promise<ScopedTranslateFunction<T['key'] & DictionaryKeys, Prefix>>;\n <T extends Dictionary>(\n dictionary: T,\n options?: { locale?: LocalesValues }\n ): Promise<TranslateFunction<T['key'] & DictionaryKeys>>;\n};\n\n/**\n * Dictionary-accepting variant of `getTranslations`.\n *\n * Used internally by the build-time optimization: instead of looking up the\n * dictionary at runtime by key, the babel/swc plugin pre-imports the dictionary\n * JSON at build time and passes it directly here. This enables tree-shaking of\n * unused locale content.\n *\n * Runs on the server, where next-intl apps do not mount an\n * `IntlayerServerProvider`. The request locale therefore cannot be read from a\n * server context and is resolved asynchronously from the cookie/header via\n * `getLocale()` (or the explicit `{ locale }` of the object overload).\n * `getTranslations` is always awaited, so an async resolver is a drop-in\n * replacement.\n */\nexport const getDictionary = (async <T extends Dictionary>(\n dictionary: T,\n rest?: DictionaryTranslatorRest\n) => {\n const { namespacePrefix, localeOverride } = readRestArgument(rest);\n const locale = localeOverride ?? ((await getLocale()) as LocalesValues);\n const content = getDictionaryBase(dictionary, locale);\n\n return createDictionaryTranslator(locale, content, namespacePrefix);\n}) as GetDictionary;\n"],"mappings":";;;;;;AAqBA,MAAM,oBACJ,SACiE;CACjE,IAAI,OAAO,SAAS,UAAU,OAAO,EAAE,iBAAiB,KAAK;CAC7D,OAAO,EAAE,gBAAgB,MAAM,OAAO;AACxC;;;;;;;;;;;;;;;;AAkCA,MAAa,iBAAiB,OAC5B,YACA,SACG;CACH,MAAM,EAAE,iBAAiB,mBAAmB,iBAAiB,IAAI;CACjE,MAAM,SAAS,kBAAoB,MAAMA,mCAAU;
|
|
1
|
+
{"version":3,"file":"getDictionary.cjs","names":["getLocale","getDictionaryBase","createDictionaryTranslator"],"sources":["../../src/getDictionary.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport {\n createDictionaryTranslator,\n type ScopedTranslateFunction,\n type TranslateFunction,\n} from '@intlayer/use-intl';\nimport { getDictionary as getDictionaryBase } from 'next-intlayer';\nimport { getLocale } from './server/getLocale';\n\n/**\n * Trailing argument left by the optimize pass. `getTranslations('ns.scope')`\n * yields the key-prefix remainder as a string, while the object overload\n * `getTranslations({ locale, namespace })` keeps its options object (with the\n * namespace stripped, since the dictionary is now passed directly).\n */\ntype DictionaryTranslatorRest = string | { locale?: LocalesValues };\n\nconst readRestArgument = (\n rest: DictionaryTranslatorRest | undefined\n): { namespacePrefix?: string; localeOverride?: LocalesValues } => {\n if (typeof rest === 'string') return { namespacePrefix: rest };\n return { localeOverride: rest?.locale };\n};\n\n/**\n * Overload set for {@link getDictionary}: a string rest argument is the\n * key-prefix remainder of a nested namespace (relative dot-paths under the\n * scope); otherwise the translator is typed against the dictionary's\n * dot-paths.\n */\ntype GetDictionary = {\n <T extends Dictionary, Prefix extends string>(\n dictionary: T,\n namespacePrefix: Prefix\n ): Promise<ScopedTranslateFunction<T['key'] & DictionaryKeys, Prefix>>;\n <T extends Dictionary>(\n dictionary: T,\n options?: { locale?: LocalesValues }\n ): Promise<TranslateFunction<T['key'] & DictionaryKeys>>;\n};\n\n/**\n * Dictionary-accepting variant of `getTranslations`.\n *\n * Used internally by the build-time optimization: instead of looking up the\n * dictionary at runtime by key, the babel/swc plugin pre-imports the dictionary\n * JSON at build time and passes it directly here. This enables tree-shaking of\n * unused locale content.\n *\n * Runs on the server, where next-intl apps do not mount an\n * `IntlayerServerProvider`. The request locale therefore cannot be read from a\n * server context and is resolved asynchronously from the cookie/header via\n * `getLocale()` (or the explicit `{ locale }` of the object overload).\n * `getTranslations` is always awaited, so an async resolver is a drop-in\n * replacement.\n */\nexport const getDictionary = (async <T extends Dictionary>(\n dictionary: T,\n rest?: DictionaryTranslatorRest\n) => {\n const { namespacePrefix, localeOverride } = readRestArgument(rest);\n const locale = localeOverride ?? ((await getLocale()) as LocalesValues);\n const content = getDictionaryBase(dictionary, locale);\n\n return createDictionaryTranslator(locale, content, namespacePrefix);\n}) as GetDictionary;\n"],"mappings":";;;;;;AAqBA,MAAM,oBACJ,SACiE;CACjE,IAAI,OAAO,SAAS,UAAU,OAAO,EAAE,iBAAiB,KAAK;CAC7D,OAAO,EAAE,gBAAgB,MAAM,OAAO;AACxC;;;;;;;;;;;;;;;;AAkCA,MAAa,iBAAiB,OAC5B,YACA,SACG;CACH,MAAM,EAAE,iBAAiB,mBAAmB,iBAAiB,IAAI;CACjE,MAAM,SAAS,kBAAoB,MAAMA,mCAAU;CACnD,MAAM,cAAUC,6BAAkB,YAAY,MAAM;CAEpD,WAAOC,+CAA2B,QAAQ,SAAS,eAAe;AACpE"}
|
|
@@ -11,7 +11,9 @@ let next_intlayer_server = require("next-intlayer/server");
|
|
|
11
11
|
* locale. Used internally by the build-time optimization.
|
|
12
12
|
*/
|
|
13
13
|
const getDictionaryDynamic = (async (dictionaryPromise, key, namespacePrefix) => {
|
|
14
|
-
|
|
14
|
+
const locale = await require_server_getLocale.getLocale();
|
|
15
|
+
const content = await (0, next_intlayer_server.useDictionaryDynamic)(dictionaryPromise, key);
|
|
16
|
+
return (0, _intlayer_use_intl.createDictionaryTranslator)(locale, content, namespacePrefix);
|
|
15
17
|
});
|
|
16
18
|
|
|
17
19
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDictionaryDynamic.cjs","names":["getLocale"],"sources":["../../src/getDictionaryDynamic.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport {\n createDictionaryTranslator,\n type ScopedTranslateFunction,\n type TranslateFunction,\n} from '@intlayer/use-intl';\nimport { useDictionaryDynamic as getDictionaryDynamicBase } from 'next-intlayer/server';\nimport { getLocale } from './server/getLocale';\n\n/**\n * Overload set for {@link getDictionaryDynamic}: without a prefix the\n * translator is typed against the dictionary's dot-paths; with a prefix the\n * keys are relative dot-paths under that scope.\n */\ntype GetDictionaryDynamic = {\n <T extends Dictionary, K extends DictionaryKeys>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K\n ): Promise<TranslateFunction<K>>;\n <T extends Dictionary, K extends DictionaryKeys, Prefix extends string>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K,\n namespacePrefix: Prefix\n ): Promise<ScopedTranslateFunction<K, Prefix>>;\n};\n\n/**\n * Dynamic dictionary-accepting variant of `getTranslations`.\n *\n * Counterpart to {@link getDictionary} for dictionaries imported lazily per\n * locale. Used internally by the build-time optimization.\n */\nexport const getDictionaryDynamic = (async <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K,\n namespacePrefix?: string\n) => {\n const locale = (await getLocale()) as LocalesValues;\n const content = await getDictionaryDynamicBase<T, K>(dictionaryPromise, key);\n\n return createDictionaryTranslator(locale, content, namespacePrefix);\n}) as GetDictionaryDynamic;\n"],"mappings":";;;;;;;;;;;;AAqCA,MAAa,wBAAwB,OAInC,mBACA,KACA,oBACG;
|
|
1
|
+
{"version":3,"file":"getDictionaryDynamic.cjs","names":["getLocale","getDictionaryDynamicBase","createDictionaryTranslator"],"sources":["../../src/getDictionaryDynamic.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport {\n createDictionaryTranslator,\n type ScopedTranslateFunction,\n type TranslateFunction,\n} from '@intlayer/use-intl';\nimport { useDictionaryDynamic as getDictionaryDynamicBase } from 'next-intlayer/server';\nimport { getLocale } from './server/getLocale';\n\n/**\n * Overload set for {@link getDictionaryDynamic}: without a prefix the\n * translator is typed against the dictionary's dot-paths; with a prefix the\n * keys are relative dot-paths under that scope.\n */\ntype GetDictionaryDynamic = {\n <T extends Dictionary, K extends DictionaryKeys>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K\n ): Promise<TranslateFunction<K>>;\n <T extends Dictionary, K extends DictionaryKeys, Prefix extends string>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K,\n namespacePrefix: Prefix\n ): Promise<ScopedTranslateFunction<K, Prefix>>;\n};\n\n/**\n * Dynamic dictionary-accepting variant of `getTranslations`.\n *\n * Counterpart to {@link getDictionary} for dictionaries imported lazily per\n * locale. Used internally by the build-time optimization.\n */\nexport const getDictionaryDynamic = (async <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K,\n namespacePrefix?: string\n) => {\n const locale = (await getLocale()) as LocalesValues;\n const content = await getDictionaryDynamicBase<T, K>(dictionaryPromise, key);\n\n return createDictionaryTranslator(locale, content, namespacePrefix);\n}) as GetDictionaryDynamic;\n"],"mappings":";;;;;;;;;;;;AAqCA,MAAa,wBAAwB,OAInC,mBACA,KACA,oBACG;CACH,MAAM,SAAU,MAAMA,mCAAU;CAChC,MAAM,UAAU,UAAMC,2CAA+B,mBAAmB,GAAG;CAE3E,WAAOC,+CAA2B,QAAQ,SAAS,eAAe;AACpE"}
|
package/dist/cjs/middleware.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.cjs","names":[],"sources":["../../src/middleware.ts"],"sourcesContent":["import type { NextFetchEvent, NextRequest } from 'next/server';\nimport type _createMiddleware from 'next-intl/middleware';\nimport { intlayerMiddleware } from 'next-intlayer/middleware';\n\n/**\n * Drop-in replacement for next-intl's `createMiddleware`.\n *\n * Returns Intlayer's proxy/middleware, which handles locale detection and\n * routing from the Intlayer configuration. The `routing` argument is accepted\n * for API compatibility but ignored — locales come from `intlayer.config`.\n *\n * @example\n * ```ts\n * // proxy.ts (or middleware.ts on Next <= 15)\n * import createMiddleware from 'next-intl/middleware';\n * export default createMiddleware(routing);\n * export const config = { matcher: ['/((?!api|_next|.*\\\\..*).*)'] };\n * ```\n */\nexport const createMiddleware: typeof _createMiddleware =\n (_routing?: unknown) => (request: NextRequest, event?: NextFetchEvent) => {\n const response = intlayerMiddleware(request, event);\n\n if (response) {\n // Intlayer middleware writes the resolved locale to the x-intlayer-locale header\n // We read it and explicitly set the NEXT_LOCALE cookie to maintain compatibility with next-intl\n const resolvedLocale = response.headers.get('x-intlayer-locale');\n if (resolvedLocale) {\n response.cookies.set('NEXT_LOCALE', resolvedLocale, {\n path: '/',\n sameSite: 'lax',\n maxAge: 60 * 60 * 24 * 365,\n });\n }\n }\n\n return response;\n };\n\nexport default createMiddleware;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAmBA,MAAa,oBACV,cAAwB,SAAsB,UAA2B;CACxE,MAAM,
|
|
1
|
+
{"version":3,"file":"middleware.cjs","names":["intlayerMiddleware"],"sources":["../../src/middleware.ts"],"sourcesContent":["import type { NextFetchEvent, NextRequest } from 'next/server';\nimport type _createMiddleware from 'next-intl/middleware';\nimport { intlayerMiddleware } from 'next-intlayer/middleware';\n\n/**\n * Drop-in replacement for next-intl's `createMiddleware`.\n *\n * Returns Intlayer's proxy/middleware, which handles locale detection and\n * routing from the Intlayer configuration. The `routing` argument is accepted\n * for API compatibility but ignored — locales come from `intlayer.config`.\n *\n * @example\n * ```ts\n * // proxy.ts (or middleware.ts on Next <= 15)\n * import createMiddleware from 'next-intl/middleware';\n * export default createMiddleware(routing);\n * export const config = { matcher: ['/((?!api|_next|.*\\\\..*).*)'] };\n * ```\n */\nexport const createMiddleware: typeof _createMiddleware =\n (_routing?: unknown) => (request: NextRequest, event?: NextFetchEvent) => {\n const response = intlayerMiddleware(request, event);\n\n if (response) {\n // Intlayer middleware writes the resolved locale to the x-intlayer-locale header\n // We read it and explicitly set the NEXT_LOCALE cookie to maintain compatibility with next-intl\n const resolvedLocale = response.headers.get('x-intlayer-locale');\n if (resolvedLocale) {\n response.cookies.set('NEXT_LOCALE', resolvedLocale, {\n path: '/',\n sameSite: 'lax',\n maxAge: 60 * 60 * 24 * 365,\n });\n }\n }\n\n return response;\n };\n\nexport default createMiddleware;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAmBA,MAAa,oBACV,cAAwB,SAAsB,UAA2B;CACxE,MAAM,eAAWA,6CAAmB,SAAS,KAAK;CAElD,IAAI,UAAU;EAGZ,MAAM,iBAAiB,SAAS,QAAQ,IAAI,mBAAmB;EAC/D,IAAI,gBACF,SAAS,QAAQ,IAAI,eAAe,gBAAgB;GAClD,MAAM;GACN,UAAU;GACV,QAAQ;EACV,CAAC;CAEL;CAEA,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.cjs","names":["NextLink","localizeHref"],"sources":["../../../src/navigation/Link.tsx"],"sourcesContent":["'use client';\n\nimport NextLink from 'next/link';\nimport { useLocale } from 'next-intlayer';\nimport { type ComponentPropsWithoutRef, forwardRef, type Ref } from 'react';\nimport { localizeHref, type NextIntlHref } from './localizeHref';\n\n/**\n * Props for the compat `Link`: identical to `next/link` except `href` accepts a\n * `next-intl` href and an optional `locale` overrides the current one.\n */\nexport type LinkProps = Omit<\n ComponentPropsWithoutRef<typeof NextLink>,\n 'href' | 'locale'\n> & {\n href: NextIntlHref;\n locale?: string;\n};\n\n/**\n * Drop-in for the `Link` returned by next-intl's `createNavigation`. Prefixes\n * `href` with the active locale (or the `locale` prop) before delegating to\n * `next/link`.\n */\nexport const Link = forwardRef(\n ({ href, locale, ...rest }: LinkProps, ref: Ref<HTMLAnchorElement>) => {\n const { locale: currentLocale } = useLocale();\n const targetLocale = locale ?? (currentLocale as string);\n\n return (\n <NextLink ref={ref} href={localizeHref(href, targetLocale)} {...rest} />\n );\n }\n);\n\nLink.displayName = 'Link';\n"],"mappings":";;;;;;;;;;;;;;;;;AAwBA,MAAa,
|
|
1
|
+
{"version":3,"file":"Link.cjs","names":["forwardRef","useLocale","NextLink","localizeHref"],"sources":["../../../src/navigation/Link.tsx"],"sourcesContent":["'use client';\n\nimport NextLink from 'next/link';\nimport { useLocale } from 'next-intlayer';\nimport { type ComponentPropsWithoutRef, forwardRef, type Ref } from 'react';\nimport { localizeHref, type NextIntlHref } from './localizeHref';\n\n/**\n * Props for the compat `Link`: identical to `next/link` except `href` accepts a\n * `next-intl` href and an optional `locale` overrides the current one.\n */\nexport type LinkProps = Omit<\n ComponentPropsWithoutRef<typeof NextLink>,\n 'href' | 'locale'\n> & {\n href: NextIntlHref;\n locale?: string;\n};\n\n/**\n * Drop-in for the `Link` returned by next-intl's `createNavigation`. Prefixes\n * `href` with the active locale (or the `locale` prop) before delegating to\n * `next/link`.\n */\nexport const Link = forwardRef(\n ({ href, locale, ...rest }: LinkProps, ref: Ref<HTMLAnchorElement>) => {\n const { locale: currentLocale } = useLocale();\n const targetLocale = locale ?? (currentLocale as string);\n\n return (\n <NextLink ref={ref} href={localizeHref(href, targetLocale)} {...rest} />\n );\n }\n);\n\nLink.displayName = 'Link';\n"],"mappings":";;;;;;;;;;;;;;;;;AAwBA,MAAa,WAAOA,mBACjB,EAAE,MAAM,QAAQ,GAAG,QAAmB,QAAgC;CACrE,MAAM,EAAE,QAAQ,sBAAkBC,yBAAU;CAG5C,OACE,2CAACC,mBAAD;EAAe;EAAK,MAAMC,6CAAa,MAHpB,UAAW,aAG2B;EAAG,GAAI;CAAO;AAE3E,CACF;AAEA,KAAK,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNavigation.cjs","names":["localizeHref","Link"],"sources":["../../../src/navigation/createNavigation.ts"],"sourcesContent":["import {\n permanentRedirect as nextPermanentRedirect,\n redirect as nextRedirect,\n} from 'next/navigation';\nimport type { createNavigation as _createNavigation } from 'next-intl/navigation';\nimport { usePathname, useRouter } from './hooks';\nimport { Link } from './Link';\nimport { localizeHref, type NextIntlHref } from './localizeHref';\n\n/** Arguments shared by `getPathname`, `redirect` and `permanentRedirect`. */\ntype LocalizedHrefArgs = { href: NextIntlHref; locale: string };\n\n/** The optional `RedirectType` accepted by `next/navigation`'s redirect APIs. */\ntype RedirectTypeArg = Parameters<typeof nextRedirect>[1];\n\n/**\n * Drop-in replacement for next-intl's `createNavigation`.\n *\n * Returns locale-aware navigation APIs (`Link`, `usePathname`, `useRouter`,\n * `getPathname`, `redirect`, `permanentRedirect`) backed by Intlayer's routing\n * configuration. The `routing` argument is accepted for API compatibility;\n * locales come from the Intlayer configuration.\n *\n * @example\n * ```ts\n * export const { Link, redirect, usePathname, useRouter, getPathname } =\n * createNavigation();\n * ```\n */\nexport const createNavigation: typeof _createNavigation = (\n _routing?: unknown\n) => {\n const getPathname = ({ href, locale }: LocalizedHrefArgs): string =>\n localizeHref(href, locale);\n\n const redirect = (\n { href, locale }: LocalizedHrefArgs,\n type?: RedirectTypeArg\n ) => nextRedirect(localizeHref(href, locale), type);\n\n const permanentRedirect = (\n { href, locale }: LocalizedHrefArgs,\n type?: RedirectTypeArg\n ) => nextPermanentRedirect(localizeHref(href, locale), type);\n\n return {\n Link: Link as ReturnType<typeof _createNavigation>['Link'],\n usePathname,\n useRouter,\n getPathname,\n redirect,\n permanentRedirect,\n } as ReturnType<typeof _createNavigation>;\n};\n\nexport default createNavigation;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA6BA,MAAa,oBACX,aACG;CACH,MAAM,eAAe,EAAE,MAAM,aAC3BA,6CAAa,MAAM,MAAM;CAE3B,MAAM,YACJ,EAAE,MAAM,UACR,
|
|
1
|
+
{"version":3,"file":"createNavigation.cjs","names":["localizeHref","nextRedirect","nextPermanentRedirect","Link"],"sources":["../../../src/navigation/createNavigation.ts"],"sourcesContent":["import {\n permanentRedirect as nextPermanentRedirect,\n redirect as nextRedirect,\n} from 'next/navigation';\nimport type { createNavigation as _createNavigation } from 'next-intl/navigation';\nimport { usePathname, useRouter } from './hooks';\nimport { Link } from './Link';\nimport { localizeHref, type NextIntlHref } from './localizeHref';\n\n/** Arguments shared by `getPathname`, `redirect` and `permanentRedirect`. */\ntype LocalizedHrefArgs = { href: NextIntlHref; locale: string };\n\n/** The optional `RedirectType` accepted by `next/navigation`'s redirect APIs. */\ntype RedirectTypeArg = Parameters<typeof nextRedirect>[1];\n\n/**\n * Drop-in replacement for next-intl's `createNavigation`.\n *\n * Returns locale-aware navigation APIs (`Link`, `usePathname`, `useRouter`,\n * `getPathname`, `redirect`, `permanentRedirect`) backed by Intlayer's routing\n * configuration. The `routing` argument is accepted for API compatibility;\n * locales come from the Intlayer configuration.\n *\n * @example\n * ```ts\n * export const { Link, redirect, usePathname, useRouter, getPathname } =\n * createNavigation();\n * ```\n */\nexport const createNavigation: typeof _createNavigation = (\n _routing?: unknown\n) => {\n const getPathname = ({ href, locale }: LocalizedHrefArgs): string =>\n localizeHref(href, locale);\n\n const redirect = (\n { href, locale }: LocalizedHrefArgs,\n type?: RedirectTypeArg\n ) => nextRedirect(localizeHref(href, locale), type);\n\n const permanentRedirect = (\n { href, locale }: LocalizedHrefArgs,\n type?: RedirectTypeArg\n ) => nextPermanentRedirect(localizeHref(href, locale), type);\n\n return {\n Link: Link as ReturnType<typeof _createNavigation>['Link'],\n usePathname,\n useRouter,\n getPathname,\n redirect,\n permanentRedirect,\n } as ReturnType<typeof _createNavigation>;\n};\n\nexport default createNavigation;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA6BA,MAAa,oBACX,aACG;CACH,MAAM,eAAe,EAAE,MAAM,aAC3BA,6CAAa,MAAM,MAAM;CAE3B,MAAM,YACJ,EAAE,MAAM,UACR,aACGC,0BAAaD,6CAAa,MAAM,MAAM,GAAG,IAAI;CAElD,MAAM,qBACJ,EAAE,MAAM,UACR,aACGE,mCAAsBF,6CAAa,MAAM,MAAM,GAAG,IAAI;CAE3D,OAAO;EACL,MAAMG;EACN;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.cjs","names":["localizeHref"],"sources":["../../../src/navigation/hooks.ts"],"sourcesContent":["'use client';\n\nimport {\n usePathname as useNextPathname,\n useRouter as useNextRouter,\n} from 'next/navigation';\nimport { useLocale } from 'next-intlayer';\nimport { localizeHref, type NextIntlHref } from './localizeHref';\n\n/**\n * Options accepted by the locale-aware router methods: the standard Next.js\n * navigate options plus an optional target `locale`.\n */\ntype NavigateOptions = { locale?: string } & Record<string, unknown>;\n\n/**\n * Drop-in for the `usePathname` returned by next-intl's `createNavigation`.\n * Returns the current pathname with the locale prefix stripped.\n */\nexport const usePathname = (): string => {\n const pathname = useNextPathname();\n const { locale } = useLocale();\n const prefix = `/${locale}`;\n\n if (pathname === prefix) return '/';\n if (pathname.startsWith(`${prefix}/`)) return pathname.slice(prefix.length);\n return pathname;\n};\n\n/**\n * Drop-in for the `useRouter` returned by next-intl's `createNavigation`.\n * Wraps the Next.js router so `push`/`replace`/`prefetch` localize their href\n * (honouring an optional `locale` option) before navigating.\n */\nexport const useRouter = () => {\n const router = useNextRouter();\n const { locale: currentLocale } = useLocale();\n\n const localize = (href: NextIntlHref, locale?: string): string =>\n localizeHref(href, locale ?? (currentLocale as string));\n\n return {\n ...router,\n push: (href: NextIntlHref, options?: NavigateOptions) =>\n router.push(\n localize(href, options?.locale),\n options as Parameters<typeof router.push>[1]\n ),\n replace: (href: NextIntlHref, options?: NavigateOptions) =>\n router.replace(\n localize(href, options?.locale),\n options as Parameters<typeof router.replace>[1]\n ),\n prefetch: (href: NextIntlHref, options?: NavigateOptions) =>\n router.prefetch(localize(href, options?.locale)),\n };\n};\n"],"mappings":";;;;;;;;;;;;AAmBA,MAAa,oBAA4B;CACvC,MAAM,
|
|
1
|
+
{"version":3,"file":"hooks.cjs","names":["useNextPathname","useLocale","useNextRouter","localizeHref"],"sources":["../../../src/navigation/hooks.ts"],"sourcesContent":["'use client';\n\nimport {\n usePathname as useNextPathname,\n useRouter as useNextRouter,\n} from 'next/navigation';\nimport { useLocale } from 'next-intlayer';\nimport { localizeHref, type NextIntlHref } from './localizeHref';\n\n/**\n * Options accepted by the locale-aware router methods: the standard Next.js\n * navigate options plus an optional target `locale`.\n */\ntype NavigateOptions = { locale?: string } & Record<string, unknown>;\n\n/**\n * Drop-in for the `usePathname` returned by next-intl's `createNavigation`.\n * Returns the current pathname with the locale prefix stripped.\n */\nexport const usePathname = (): string => {\n const pathname = useNextPathname();\n const { locale } = useLocale();\n const prefix = `/${locale}`;\n\n if (pathname === prefix) return '/';\n if (pathname.startsWith(`${prefix}/`)) return pathname.slice(prefix.length);\n return pathname;\n};\n\n/**\n * Drop-in for the `useRouter` returned by next-intl's `createNavigation`.\n * Wraps the Next.js router so `push`/`replace`/`prefetch` localize their href\n * (honouring an optional `locale` option) before navigating.\n */\nexport const useRouter = () => {\n const router = useNextRouter();\n const { locale: currentLocale } = useLocale();\n\n const localize = (href: NextIntlHref, locale?: string): string =>\n localizeHref(href, locale ?? (currentLocale as string));\n\n return {\n ...router,\n push: (href: NextIntlHref, options?: NavigateOptions) =>\n router.push(\n localize(href, options?.locale),\n options as Parameters<typeof router.push>[1]\n ),\n replace: (href: NextIntlHref, options?: NavigateOptions) =>\n router.replace(\n localize(href, options?.locale),\n options as Parameters<typeof router.replace>[1]\n ),\n prefetch: (href: NextIntlHref, options?: NavigateOptions) =>\n router.prefetch(localize(href, options?.locale)),\n };\n};\n"],"mappings":";;;;;;;;;;;;AAmBA,MAAa,oBAA4B;CACvC,MAAM,eAAWA,6BAAgB;CACjC,MAAM,EAAE,eAAWC,yBAAU;CAC7B,MAAM,SAAS,IAAI;CAEnB,IAAI,aAAa,QAAQ,OAAO;CAChC,IAAI,SAAS,WAAW,GAAG,OAAO,EAAE,GAAG,OAAO,SAAS,MAAM,OAAO,MAAM;CAC1E,OAAO;AACT;;;;;;AAOA,MAAa,kBAAkB;CAC7B,MAAM,aAASC,2BAAc;CAC7B,MAAM,EAAE,QAAQ,sBAAkBD,yBAAU;CAE5C,MAAM,YAAY,MAAoB,WACpCE,6CAAa,MAAM,UAAW,aAAwB;CAExD,OAAO;EACL,GAAG;EACH,OAAO,MAAoB,YACzB,OAAO,KACL,SAAS,MAAM,SAAS,MAAM,GAC9B,OACF;EACF,UAAU,MAAoB,YAC5B,OAAO,QACL,SAAS,MAAM,SAAS,MAAM,GAC9B,OACF;EACF,WAAW,MAAoB,YAC7B,OAAO,SAAS,SAAS,MAAM,SAAS,MAAM,CAAC;CACnD;AACF"}
|
|
@@ -11,7 +11,8 @@ let _intlayer_core_localization = require("@intlayer/core/localization");
|
|
|
11
11
|
* @returns The localized URL string.
|
|
12
12
|
*/
|
|
13
13
|
const localizeHref = (href, locale) => {
|
|
14
|
-
const
|
|
14
|
+
const pathname = typeof href === "string" ? href : href.pathname;
|
|
15
|
+
const localizedPathname = (0, _intlayer_core_localization.getLocalizedUrl)(pathname, locale);
|
|
15
16
|
if (typeof href === "string" || !href.query) return localizedPathname;
|
|
16
17
|
const searchParams = new URLSearchParams();
|
|
17
18
|
for (const [key, value] of Object.entries(href.query)) if (Array.isArray(value)) for (const entry of value) searchParams.append(key, String(entry));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localizeHref.cjs","names":[],"sources":["../../../src/navigation/localizeHref.ts"],"sourcesContent":["import { getLocalizedUrl } from '@intlayer/core/localization';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\n\n/**\n * A `next-intl` navigation href: either a pathname string or an object with a\n * `pathname` and optional `query`. The `pathnames` (typed routes) feature is\n * accepted for API compatibility but not interpolated.\n */\nexport type NextIntlHref =\n | string\n | {\n pathname: string;\n query?: Record<string, string | number | (string | number)[]>;\n params?: Record<string, string | number | (string | number)[]>;\n };\n\n/**\n * Prefix a `next-intl` href with the given locale using Intlayer's\n * `getLocalizedUrl`, preserving any query parameters.\n *\n * @param href - The target href (string or `{ pathname, query }`).\n * @param locale - The locale to localize the href for.\n * @returns The localized URL string.\n */\nexport const localizeHref = (href: NextIntlHref, locale: string): string => {\n const pathname = typeof href === 'string' ? href : href.pathname;\n const localizedPathname = getLocalizedUrl(pathname, locale as LocalesValues);\n\n if (typeof href === 'string' || !href.query) {\n return localizedPathname;\n }\n\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(href.query)) {\n if (Array.isArray(value)) {\n for (const entry of value) {\n searchParams.append(key, String(entry));\n }\n } else {\n searchParams.append(key, String(value));\n }\n }\n\n const queryString = searchParams.toString();\n return queryString\n ? `${localizedPathname}?${queryString}`\n : localizedPathname;\n};\n"],"mappings":";;;;;;;;;;;;AAwBA,MAAa,gBAAgB,MAAoB,WAA2B;
|
|
1
|
+
{"version":3,"file":"localizeHref.cjs","names":["getLocalizedUrl"],"sources":["../../../src/navigation/localizeHref.ts"],"sourcesContent":["import { getLocalizedUrl } from '@intlayer/core/localization';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\n\n/**\n * A `next-intl` navigation href: either a pathname string or an object with a\n * `pathname` and optional `query`. The `pathnames` (typed routes) feature is\n * accepted for API compatibility but not interpolated.\n */\nexport type NextIntlHref =\n | string\n | {\n pathname: string;\n query?: Record<string, string | number | (string | number)[]>;\n params?: Record<string, string | number | (string | number)[]>;\n };\n\n/**\n * Prefix a `next-intl` href with the given locale using Intlayer's\n * `getLocalizedUrl`, preserving any query parameters.\n *\n * @param href - The target href (string or `{ pathname, query }`).\n * @param locale - The locale to localize the href for.\n * @returns The localized URL string.\n */\nexport const localizeHref = (href: NextIntlHref, locale: string): string => {\n const pathname = typeof href === 'string' ? href : href.pathname;\n const localizedPathname = getLocalizedUrl(pathname, locale as LocalesValues);\n\n if (typeof href === 'string' || !href.query) {\n return localizedPathname;\n }\n\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(href.query)) {\n if (Array.isArray(value)) {\n for (const entry of value) {\n searchParams.append(key, String(entry));\n }\n } else {\n searchParams.append(key, String(value));\n }\n }\n\n const queryString = searchParams.toString();\n return queryString\n ? `${localizedPathname}?${queryString}`\n : localizedPathname;\n};\n"],"mappings":";;;;;;;;;;;;AAwBA,MAAa,gBAAgB,MAAoB,WAA2B;CAC1E,MAAM,WAAW,OAAO,SAAS,WAAW,OAAO,KAAK;CACxD,MAAM,wBAAoBA,6CAAgB,UAAU,MAAuB;CAE3E,IAAI,OAAO,SAAS,YAAY,CAAC,KAAK,OACpC,OAAO;CAGT,MAAM,eAAe,IAAI,gBAAgB;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,KAAK,GAClD,IAAI,MAAM,QAAQ,KAAK,GACrB,KAAK,MAAM,SAAS,OAClB,aAAa,OAAO,KAAK,OAAO,KAAK,CAAC;MAGxC,aAAa,OAAO,KAAK,OAAO,KAAK,CAAC;CAI1C,MAAM,cAAc,aAAa,SAAS;CAC1C,OAAO,cACH,GAAG,kBAAkB,GAAG,gBACxB;AACN"}
|
|
@@ -107,7 +107,7 @@ const createNextIntlPlugin = (_i18nPath) => {
|
|
|
107
107
|
const appLogger = (0, _intlayer_config_logger.getAppLogger)(intlayerConfig);
|
|
108
108
|
(0, _intlayer_engine_utils.runOnce)((0, node_path.join)(intlayerConfig?.system?.baseDir ?? process.cwd(), ".intlayer", "cache", "intlayer-issues-invitation.lock"), () => {
|
|
109
109
|
appLogger([(0, _intlayer_config_logger.colorize)("Please report any issues you met on GitHub:", _intlayer_config_colors.GREY), (0, _intlayer_config_logger.colorize)("https://github.com/aymericzip/intlayer/issues", _intlayer_config_colors.GREY_LIGHT)]);
|
|
110
|
-
}, { cacheTimeoutMs:
|
|
110
|
+
}, { cacheTimeoutMs: 36e5 });
|
|
111
111
|
const customWebpack = nextConfig.webpack;
|
|
112
112
|
const resolvedTargets = ALIAS_ENTRIES.map(({ request, replacement }) => ({
|
|
113
113
|
request,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["sep","NEXT_INTL_CALLERS","ANSIColors"],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\nimport { NEXT_INTL_CALLERS, toSwcExtraCallers } from '@intlayer/config/callers';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { runOnce } from '@intlayer/engine/utils';\nimport type { NextConfig } from 'next';\nimport { withIntlayer } from 'next-intlayer/server';\n\n/**\n * `require` that works in both the CJS and ESM builds of this plugin.\n * `import.meta.url` is rewritten to the module path in the CJS output by the\n * bundler, so `createRequire` resolves correctly in either format.\n */\nconst compatRequire = createRequire(import.meta.url);\n\n/**\n * Maps each original `next-intl` import specifier to the `@intlayer/next-intl`\n * specifier that should serve it instead.\n */\nconst ALIAS_ENTRIES: { request: string; replacement: string }[] = [\n { request: 'next-intl/server', replacement: '@intlayer/next-intl/server' },\n { request: 'next-intl/routing', replacement: '@intlayer/next-intl/routing' },\n {\n request: 'next-intl/navigation',\n replacement: '@intlayer/next-intl/navigation',\n },\n {\n request: 'next-intl/middleware',\n replacement: '@intlayer/next-intl/middleware',\n },\n { request: 'next-intl', replacement: '@intlayer/next-intl' },\n];\n\n/**\n * Split a package specifier into its package name and export subpath.\n *\n * @param specifier - e.g. `@intlayer/next-intl/server` or `next-intl`.\n * @returns `{ packageName, exportKey }` where `exportKey` is the `exports` map\n * key (`.` for the package root).\n */\nconst splitSpecifier = (\n specifier: string\n): { packageName: string; exportKey: string } => {\n const segments = specifier.split('/');\n const packageName = specifier.startsWith('@')\n ? segments.slice(0, 2).join('/')\n : (segments[0] ?? specifier);\n const subpath = specifier.slice(packageName?.length);\n return { packageName, exportKey: subpath === '' ? '.' : `.${subpath}` };\n};\n\n/**\n * Resolve the absolute path of a package export, preferring the ESM (`import`)\n * condition so Turbopack and modern bundlers load the `.mjs` build (which keeps\n * the `\"use client\"` directives) rather than the CommonJS fallback.\n *\n * Both Turbopack and webpack ignore alias values that are bare package\n * specifiers, so the aliases must point at real files.\n *\n * @param specifier - Package specifier, e.g. `@intlayer/next-intl/server`.\n * @returns Absolute path to the resolved module file.\n */\nconst resolveEsmPath = (specifier: string): string => {\n const { packageName, exportKey } = splitSpecifier(specifier);\n const packageJson = compatRequire(`${packageName}/package.json`) as {\n exports?: Record<\n string,\n string | { import?: string; require?: string; default?: string }\n >;\n };\n const packageDir = dirname(\n compatRequire.resolve(`${packageName}/package.json`)\n );\n\n const exportEntry = packageJson.exports?.[exportKey];\n const relativeFile =\n typeof exportEntry === 'string'\n ? exportEntry\n : (exportEntry?.import ?? exportEntry?.require ?? exportEntry?.default);\n\n // Fall back to Node resolution if the exports map is unexpected.\n if (!relativeFile) return compatRequire.resolve(specifier);\n\n return resolve(packageDir, relativeFile);\n};\n\n/**\n * Format an absolute path as a project-root-relative specifier (prefixed with\n * `./` and using forward slashes). Turbopack only honours `resolveAlias` values\n * that are project-root-relative paths — bare specifiers are ignored and\n * absolute paths are misread as root-relative. Mirrors `withIntlayer`'s\n * Turbopack alias formatter.\n *\n * @param absolutePath - Absolute path to the target module file.\n * @returns Relative specifier such as `./node_modules/@intlayer/next-intl/...`.\n */\nconst toTurbopackAlias = (absolutePath: string): string =>\n `./${relative(process.cwd(), absolutePath).split(sep).join('/')}`;\n\n/**\n * SWC extra-caller configs derived from the shared caller registry\n * (`@intlayer/config/callers`) — the single source of truth also consumed by\n * the babel analyzer/optimizer and the LSP.\n */\nconst NEXT_INTL_SWC_CALLERS = toSwcExtraCallers(NEXT_INTL_CALLERS);\n\n/**\n * A Next.js plugin for next-intl compat that wraps next-intlayer's plugin\n * and configures resolve aliases so `next-intl` imports are served by\n * `@intlayer/next-intl`.\n */\nexport const createNextIntlPlugin = (_i18nPath?: string) => {\n return async (nextConfig: NextConfig = {}): Promise<NextConfig> => {\n const intlayerConfig = getConfiguration();\n const appLogger = getAppLogger(intlayerConfig);\n\n runOnce(\n join(\n intlayerConfig?.system?.baseDir ?? process.cwd(),\n '.intlayer',\n 'cache',\n 'intlayer-issues-invitation.lock'\n ),\n () => {\n appLogger([\n colorize(\n 'Please report any issues you met on GitHub:',\n ANSIColors.GREY\n ),\n colorize(\n 'https://github.com/aymericzip/intlayer/issues',\n ANSIColors.GREY_LIGHT\n ),\n ]);\n },\n {\n cacheTimeoutMs: 1000 * 60 * 60, // 1 hour\n }\n );\n\n const customWebpack = nextConfig.webpack;\n\n const resolvedTargets = ALIAS_ENTRIES.map(({ request, replacement }) => ({\n request,\n absolutePath: resolveEsmPath(replacement),\n }));\n\n // Webpack resolves aliases from absolute paths.\n const webpackAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n absolutePath,\n ])\n );\n\n // Turbopack only honours project-root-relative `./` paths.\n const turboAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n toTurbopackAlias(absolutePath),\n ])\n );\n\n const aliasConfig = {\n webpack: (config: any, options: any) => {\n config.resolve.alias = {\n ...config.resolve.alias,\n ...webpackAlias,\n };\n\n if (typeof customWebpack === 'function') {\n return customWebpack(config, options);\n }\n return config;\n },\n };\n\n const mergedConfig: NextConfig = {\n ...nextConfig,\n ...aliasConfig,\n turbopack: {\n ...(nextConfig.turbopack ?? {}),\n resolveAlias: {\n ...(nextConfig.turbopack?.resolveAlias ?? {}),\n ...turboAlias,\n },\n },\n };\n\n // Only inject the NEXT_LOCALE cookie default when the user has not\n // configured their own routing.storage in intlayer.config.ts.\n // This lets users override via intlayer.config.ts while keeping\n // next-intl compatibility (NEXT_LOCALE) as the default.\n let hasUserDefinedStorage = false;\n try {\n hasUserDefinedStorage = !!(\n intlayerConfig?.routing &&\n 'storage' in intlayerConfig.routing &&\n intlayerConfig.routing.storage !== undefined\n );\n } catch {\n // If the config file cannot be read, fall back to the NEXT_LOCALE default.\n }\n\n const configOptions = hasUserDefinedStorage\n ? { swcExtraCallers: NEXT_INTL_SWC_CALLERS }\n : {\n override: {\n routing: {\n storage: [\n { type: 'cookie' as const, name: 'NEXT_LOCALE' },\n { type: 'header' as const, name: 'x-intlayer-locale' },\n ],\n },\n },\n swcExtraCallers: NEXT_INTL_SWC_CALLERS,\n };\n\n return withIntlayer(mergedConfig, configOptions);\n };\n};\n\nexport default createNextIntlPlugin;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAeA,MAAM,4FAA6C;;;;;AAMnD,MAAM,gBAA4D;CAChE;EAAE,SAAS;EAAoB,aAAa;CAA6B;CACzE;EAAE,SAAS;EAAqB,aAAa;CAA8B;CAC3E;EACE,SAAS;EACT,aAAa;CACf;CACA;EACE,SAAS;EACT,aAAa;CACf;CACA;EAAE,SAAS;EAAa,aAAa;CAAsB;AAC7D;;;;;;;;AASA,MAAM,kBACJ,cAC+C;CAC/C,MAAM,WAAW,UAAU,MAAM,GAAG;CACpC,MAAM,cAAc,UAAU,WAAW,GAAG,IACxC,SAAS,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAC5B,SAAS,MAAM;CACpB,MAAM,UAAU,UAAU,MAAM,aAAa,MAAM;CACnD,OAAO;EAAE;EAAa,WAAW,YAAY,KAAK,MAAM,IAAI;CAAU;AACxE;;;;;;;;;;;;AAaA,MAAM,kBAAkB,cAA8B;CACpD,MAAM,EAAE,aAAa,cAAc,eAAe,SAAS;CAC3D,MAAM,cAAc,cAAc,GAAG,YAAY,cAAc;CAM/D,MAAM,oCACJ,cAAc,QAAQ,GAAG,YAAY,cAAc,CACrD;CAEA,MAAM,cAAc,YAAY,UAAU;CAC1C,MAAM,eACJ,OAAO,gBAAgB,WACnB,cACC,aAAa,UAAU,aAAa,WAAW,aAAa;CAGnE,IAAI,CAAC,cAAc,OAAO,cAAc,QAAQ,SAAS;CAEzD,8BAAe,YAAY,YAAY;AACzC;;;;;;;;;;;AAYA,MAAM,oBAAoB,iBACxB,6BAAc,QAAQ,IAAI,GAAG,YAAY,CAAC,CAAC,MAAMA,aAAG,CAAC,CAAC,KAAK,GAAG;;;;;;AAOhE,MAAM,wEAA0CC,0CAAiB;;;;;;AAOjE,MAAa,wBAAwB,cAAuB;CAC1D,OAAO,OAAO,aAAyB,CAAC,MAA2B;EACjE,MAAM,6DAAkC;EACxC,MAAM,sDAAyB,cAAc;EAE7C,wDAEI,gBAAgB,QAAQ,WAAW,QAAQ,IAAI,GAC/C,aACA,SACA,iCACF,SACM;GACJ,UAAU,uCAEN,+CACAC,wBAAW,IACb,yCAEE,iDACAA,wBAAW,UACb,CACF,CAAC;EACH,GACA,EACE,gBAAgB,MAAO,KAAK,GAC9B,CACF;EAEA,MAAM,gBAAgB,WAAW;EAEjC,MAAM,kBAAkB,cAAc,KAAK,EAAE,SAAS,mBAAmB;GACvE;GACA,cAAc,eAAe,WAAW;EAC1C,EAAE;EAGF,MAAM,eAAe,OAAO,YAC1B,gBAAgB,KAAK,EAAE,SAAS,mBAAmB,CACjD,SACA,YACF,CAAC,CACH;EAGA,MAAM,aAAa,OAAO,YACxB,gBAAgB,KAAK,EAAE,SAAS,mBAAmB,CACjD,SACA,iBAAiB,YAAY,CAC/B,CAAC,CACH;EAEA,MAAM,cAAc,EAClB,UAAU,QAAa,YAAiB;GACtC,OAAO,QAAQ,QAAQ;IACrB,GAAG,OAAO,QAAQ;IAClB,GAAG;GACL;GAEA,IAAI,OAAO,kBAAkB,YAC3B,OAAO,cAAc,QAAQ,OAAO;GAEtC,OAAO;EACT,EACF;EAEA,MAAM,eAA2B;GAC/B,GAAG;GACH,GAAG;GACH,WAAW;IACT,GAAI,WAAW,aAAa,CAAC;IAC7B,cAAc;KACZ,GAAI,WAAW,WAAW,gBAAgB,CAAC;KAC3C,GAAG;IACL;GACF;EACF;EAMA,IAAI,wBAAwB;EAC5B,IAAI;GACF,wBAAwB,CAAC,EACvB,gBAAgB,WAChB,aAAa,eAAe,WAC5B,eAAe,QAAQ,YAAY;EAEvC,QAAQ,CAER;EAgBA,8CAAoB,cAdE,wBAClB,EAAE,iBAAiB,sBAAsB,IACzC;GACE,UAAU,EACR,SAAS,EACP,SAAS,CACP;IAAE,MAAM;IAAmB,MAAM;GAAc,GAC/C;IAAE,MAAM;IAAmB,MAAM;GAAoB,CACvD,EACF,EACF;GACA,iBAAiB;EACnB,CAE2C;CACjD;AACF"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["createRequire","dirname","resolve","relative","sep","toSwcExtraCallers","NEXT_INTL_CALLERS","getConfiguration","getAppLogger","join","colorize","ANSIColors","withIntlayer"],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\nimport { NEXT_INTL_CALLERS, toSwcExtraCallers } from '@intlayer/config/callers';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { runOnce } from '@intlayer/engine/utils';\nimport type { NextConfig } from 'next';\nimport { withIntlayer } from 'next-intlayer/server';\n\n/**\n * `require` that works in both the CJS and ESM builds of this plugin.\n * `import.meta.url` is rewritten to the module path in the CJS output by the\n * bundler, so `createRequire` resolves correctly in either format.\n */\nconst compatRequire = createRequire(import.meta.url);\n\n/**\n * Maps each original `next-intl` import specifier to the `@intlayer/next-intl`\n * specifier that should serve it instead.\n */\nconst ALIAS_ENTRIES: { request: string; replacement: string }[] = [\n { request: 'next-intl/server', replacement: '@intlayer/next-intl/server' },\n { request: 'next-intl/routing', replacement: '@intlayer/next-intl/routing' },\n {\n request: 'next-intl/navigation',\n replacement: '@intlayer/next-intl/navigation',\n },\n {\n request: 'next-intl/middleware',\n replacement: '@intlayer/next-intl/middleware',\n },\n { request: 'next-intl', replacement: '@intlayer/next-intl' },\n];\n\n/**\n * Split a package specifier into its package name and export subpath.\n *\n * @param specifier - e.g. `@intlayer/next-intl/server` or `next-intl`.\n * @returns `{ packageName, exportKey }` where `exportKey` is the `exports` map\n * key (`.` for the package root).\n */\nconst splitSpecifier = (\n specifier: string\n): { packageName: string; exportKey: string } => {\n const segments = specifier.split('/');\n const packageName = specifier.startsWith('@')\n ? segments.slice(0, 2).join('/')\n : (segments[0] ?? specifier);\n const subpath = specifier.slice(packageName?.length);\n return { packageName, exportKey: subpath === '' ? '.' : `.${subpath}` };\n};\n\n/**\n * Resolve the absolute path of a package export, preferring the ESM (`import`)\n * condition so Turbopack and modern bundlers load the `.mjs` build (which keeps\n * the `\"use client\"` directives) rather than the CommonJS fallback.\n *\n * Both Turbopack and webpack ignore alias values that are bare package\n * specifiers, so the aliases must point at real files.\n *\n * @param specifier - Package specifier, e.g. `@intlayer/next-intl/server`.\n * @returns Absolute path to the resolved module file.\n */\nconst resolveEsmPath = (specifier: string): string => {\n const { packageName, exportKey } = splitSpecifier(specifier);\n const packageJson = compatRequire(`${packageName}/package.json`) as {\n exports?: Record<\n string,\n string | { import?: string; require?: string; default?: string }\n >;\n };\n const packageDir = dirname(\n compatRequire.resolve(`${packageName}/package.json`)\n );\n\n const exportEntry = packageJson.exports?.[exportKey];\n const relativeFile =\n typeof exportEntry === 'string'\n ? exportEntry\n : (exportEntry?.import ?? exportEntry?.require ?? exportEntry?.default);\n\n // Fall back to Node resolution if the exports map is unexpected.\n if (!relativeFile) return compatRequire.resolve(specifier);\n\n return resolve(packageDir, relativeFile);\n};\n\n/**\n * Format an absolute path as a project-root-relative specifier (prefixed with\n * `./` and using forward slashes). Turbopack only honours `resolveAlias` values\n * that are project-root-relative paths — bare specifiers are ignored and\n * absolute paths are misread as root-relative. Mirrors `withIntlayer`'s\n * Turbopack alias formatter.\n *\n * @param absolutePath - Absolute path to the target module file.\n * @returns Relative specifier such as `./node_modules/@intlayer/next-intl/...`.\n */\nconst toTurbopackAlias = (absolutePath: string): string =>\n `./${relative(process.cwd(), absolutePath).split(sep).join('/')}`;\n\n/**\n * SWC extra-caller configs derived from the shared caller registry\n * (`@intlayer/config/callers`) — the single source of truth also consumed by\n * the babel analyzer/optimizer and the LSP.\n */\nconst NEXT_INTL_SWC_CALLERS = toSwcExtraCallers(NEXT_INTL_CALLERS);\n\n/**\n * A Next.js plugin for next-intl compat that wraps next-intlayer's plugin\n * and configures resolve aliases so `next-intl` imports are served by\n * `@intlayer/next-intl`.\n */\nexport const createNextIntlPlugin = (_i18nPath?: string) => {\n return async (nextConfig: NextConfig = {}): Promise<NextConfig> => {\n const intlayerConfig = getConfiguration();\n const appLogger = getAppLogger(intlayerConfig);\n\n runOnce(\n join(\n intlayerConfig?.system?.baseDir ?? process.cwd(),\n '.intlayer',\n 'cache',\n 'intlayer-issues-invitation.lock'\n ),\n () => {\n appLogger([\n colorize(\n 'Please report any issues you met on GitHub:',\n ANSIColors.GREY\n ),\n colorize(\n 'https://github.com/aymericzip/intlayer/issues',\n ANSIColors.GREY_LIGHT\n ),\n ]);\n },\n {\n cacheTimeoutMs: 1000 * 60 * 60, // 1 hour\n }\n );\n\n const customWebpack = nextConfig.webpack;\n\n const resolvedTargets = ALIAS_ENTRIES.map(({ request, replacement }) => ({\n request,\n absolutePath: resolveEsmPath(replacement),\n }));\n\n // Webpack resolves aliases from absolute paths.\n const webpackAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n absolutePath,\n ])\n );\n\n // Turbopack only honours project-root-relative `./` paths.\n const turboAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n toTurbopackAlias(absolutePath),\n ])\n );\n\n const aliasConfig = {\n webpack: (config: any, options: any) => {\n config.resolve.alias = {\n ...config.resolve.alias,\n ...webpackAlias,\n };\n\n if (typeof customWebpack === 'function') {\n return customWebpack(config, options);\n }\n return config;\n },\n };\n\n const mergedConfig: NextConfig = {\n ...nextConfig,\n ...aliasConfig,\n turbopack: {\n ...(nextConfig.turbopack ?? {}),\n resolveAlias: {\n ...(nextConfig.turbopack?.resolveAlias ?? {}),\n ...turboAlias,\n },\n },\n };\n\n // Only inject the NEXT_LOCALE cookie default when the user has not\n // configured their own routing.storage in intlayer.config.ts.\n // This lets users override via intlayer.config.ts while keeping\n // next-intl compatibility (NEXT_LOCALE) as the default.\n let hasUserDefinedStorage = false;\n try {\n hasUserDefinedStorage = !!(\n intlayerConfig?.routing &&\n 'storage' in intlayerConfig.routing &&\n intlayerConfig.routing.storage !== undefined\n );\n } catch {\n // If the config file cannot be read, fall back to the NEXT_LOCALE default.\n }\n\n const configOptions = hasUserDefinedStorage\n ? { swcExtraCallers: NEXT_INTL_SWC_CALLERS }\n : {\n override: {\n routing: {\n storage: [\n { type: 'cookie' as const, name: 'NEXT_LOCALE' },\n { type: 'header' as const, name: 'x-intlayer-locale' },\n ],\n },\n },\n swcExtraCallers: NEXT_INTL_SWC_CALLERS,\n };\n\n return withIntlayer(mergedConfig, configOptions);\n };\n};\n\nexport default createNextIntlPlugin;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLocale.cjs","names":["getCachedRequestLocale"],"sources":["../../../src/server/getLocale.ts"],"sourcesContent":["import type { getLocale as _getLocale } from 'next-intl/server';\nimport { getLocale as getLocaleIntlayer } from 'next-intlayer/server';\nimport { getCachedRequestLocale } from './requestLocaleCache';\n\n/**\n * Drop-in for next-intl's `getLocale()` server function.\n *\n * Resolution order mirrors next-intl's per-request model:\n *\n * 1. The locale forwarded through `setRequestLocale(locale)` (the `[locale]`\n * route segment) — the source of truth for URL-driven routing. This is what\n * keeps server-rendered content and the locale switcher in sync with the URL\n * instead of a stale cookie.\n * 2. Otherwise Intlayer's own resolution (cookie / header / Accept-Language),\n * for apps that drive the locale from storage rather than the route.\n */\nexport const getLocale: typeof _getLocale = async (): Promise<string> => {\n const requestLocale = getCachedRequestLocale();\n if (requestLocale) return requestLocale as string;\n\n return (await getLocaleIntlayer()) as string;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,MAAa,YAA+B,YAA6B;CACvE,MAAM,gBAAgBA,yDAAuB;CAC7C,IAAI,eAAe,OAAO;CAE1B,OAAQ,
|
|
1
|
+
{"version":3,"file":"getLocale.cjs","names":["getCachedRequestLocale","getLocaleIntlayer"],"sources":["../../../src/server/getLocale.ts"],"sourcesContent":["import type { getLocale as _getLocale } from 'next-intl/server';\nimport { getLocale as getLocaleIntlayer } from 'next-intlayer/server';\nimport { getCachedRequestLocale } from './requestLocaleCache';\n\n/**\n * Drop-in for next-intl's `getLocale()` server function.\n *\n * Resolution order mirrors next-intl's per-request model:\n *\n * 1. The locale forwarded through `setRequestLocale(locale)` (the `[locale]`\n * route segment) — the source of truth for URL-driven routing. This is what\n * keeps server-rendered content and the locale switcher in sync with the URL\n * instead of a stale cookie.\n * 2. Otherwise Intlayer's own resolution (cookie / header / Accept-Language),\n * for apps that drive the locale from storage rather than the route.\n */\nexport const getLocale: typeof _getLocale = async (): Promise<string> => {\n const requestLocale = getCachedRequestLocale();\n if (requestLocale) return requestLocale as string;\n\n return (await getLocaleIntlayer()) as string;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,MAAa,YAA+B,YAA6B;CACvE,MAAM,gBAAgBA,yDAAuB;CAC7C,IAAI,eAAe,OAAO;CAE1B,OAAQ,UAAMC,gCAAkB;AAClC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getMessages.cjs","names":["CYAN"],"sources":["../../../src/server/getMessages.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { CYAN } from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport type { getMessages as _getMessages } from 'next-intl/server';\n\n/**\n * Drop-in replacement for next-intl's `getMessages()` server function.\n *\n * Returns all compiled dictionary content for the current locale as a flat\n * record keyed by dictionary name. Useful when you need to pass messages\n * to a `NextIntlClientProvider`.\n *\n * @example\n * ```ts\n * const messages = await getMessages();\n * ```\n *\n * @deprecated getMessages has no use case with intlayer.\n * Messages are loaded automatically under the hood\n */\nexport const getMessages: typeof _getMessages = async () => {\n if (process.env.NODE_ENV === 'development') {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize('getMessages', CYAN)} has no use case with intlayer. Messages are loaded automatically under the hood for bundle optimization reason`\n );\n }\n\n return {};\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,cAAmC,YAAY;CAC1D,IAAI,QAAQ,IAAI,aAAa,eAE3B,
|
|
1
|
+
{"version":3,"file":"getMessages.cjs","names":["getAppLogger","colorize","CYAN"],"sources":["../../../src/server/getMessages.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { CYAN } from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport type { getMessages as _getMessages } from 'next-intl/server';\n\n/**\n * Drop-in replacement for next-intl's `getMessages()` server function.\n *\n * Returns all compiled dictionary content for the current locale as a flat\n * record keyed by dictionary name. Useful when you need to pass messages\n * to a `NextIntlClientProvider`.\n *\n * @example\n * ```ts\n * const messages = await getMessages();\n * ```\n *\n * @deprecated getMessages has no use case with intlayer.\n * Messages are loaded automatically under the hood\n */\nexport const getMessages: typeof _getMessages = async () => {\n if (process.env.NODE_ENV === 'development') {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize('getMessages', CYAN)} has no use case with intlayer. Messages are loaded automatically under the hood for bundle optimization reason`\n );\n }\n\n return {};\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,cAAmC,YAAY;CAC1D,IAAI,QAAQ,IAAI,aAAa,eAE3B,IADkBA,sCAAa,EAAE,gCAAI,CAC7B,CAAC,CACP,OAAGC,kCAAS,eAAeC,4BAAI,EAAE,gHACnC;CAGF,OAAO,CAAC;AACV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRequestConfig.cjs","names":["CYAN"],"sources":["../../../src/server/getRequestConfig.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { CYAN } from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport type { getRequestConfig as _getRequestConfig } from 'next-intl/server';\n\n/**\n * Drop-in for next-intl's `getRequestConfig`.\n *\n * In next-intl this registers the per-request config (locale + messages) read\n * by its own plugin. With intlayer the locale is resolved from routing /\n * storage and messages come from compiled dictionaries, so the returned config\n * is never consumed — this is an identity passthrough kept so existing\n * `i18n/request.ts` files keep resolving and type-checking.\n *\n * @deprecated getRequestConfig has no use case with intlayer. The locale and\n * messages are resolved automatically; the file can be removed.\n */\nexport const getRequestConfig: typeof _getRequestConfig = (\n createRequestConfig\n) => {\n if (process.env.NODE_ENV === 'development') {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize('getRequestConfig', CYAN)} has no use case with intlayer. The locale and messages are resolved automatically; the i18n/request.ts file can be removed`\n );\n }\n\n return createRequestConfig;\n};\n\nexport default getRequestConfig;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiBA,MAAa,oBACX,wBACG;CACH,IAAI,QAAQ,IAAI,aAAa,eAE3B,
|
|
1
|
+
{"version":3,"file":"getRequestConfig.cjs","names":["getAppLogger","colorize","CYAN"],"sources":["../../../src/server/getRequestConfig.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { CYAN } from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport type { getRequestConfig as _getRequestConfig } from 'next-intl/server';\n\n/**\n * Drop-in for next-intl's `getRequestConfig`.\n *\n * In next-intl this registers the per-request config (locale + messages) read\n * by its own plugin. With intlayer the locale is resolved from routing /\n * storage and messages come from compiled dictionaries, so the returned config\n * is never consumed — this is an identity passthrough kept so existing\n * `i18n/request.ts` files keep resolving and type-checking.\n *\n * @deprecated getRequestConfig has no use case with intlayer. The locale and\n * messages are resolved automatically; the file can be removed.\n */\nexport const getRequestConfig: typeof _getRequestConfig = (\n createRequestConfig\n) => {\n if (process.env.NODE_ENV === 'development') {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize('getRequestConfig', CYAN)} has no use case with intlayer. The locale and messages are resolved automatically; the i18n/request.ts file can be removed`\n );\n }\n\n return createRequestConfig;\n};\n\nexport default getRequestConfig;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiBA,MAAa,oBACX,wBACG;CACH,IAAI,QAAQ,IAAI,aAAa,eAE3B,IADkBA,sCAAa,EAAE,gCAAI,CAC7B,CAAC,CACP,OAAGC,kCAAS,oBAAoBC,4BAAI,EAAE,4HACxC;CAGF,OAAO;AACT"}
|
|
@@ -38,8 +38,9 @@ const getTranslations = (async (namespaceOrOptions) => {
|
|
|
38
38
|
namespace = namespaceOrOptions.namespace;
|
|
39
39
|
localeOverride = namespaceOrOptions.locale;
|
|
40
40
|
} else namespace = namespaceOrOptions;
|
|
41
|
+
const locale = localeOverride ?? await require_server_getLocale.getLocale();
|
|
41
42
|
return (0, _intlayer_use_intl.createTranslator)({
|
|
42
|
-
locale
|
|
43
|
+
locale,
|
|
43
44
|
namespace
|
|
44
45
|
});
|
|
45
46
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTranslations.cjs","names":["getLocale"],"sources":["../../../src/server/getTranslations.ts"],"sourcesContent":["import type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport {\n createTranslator,\n type LooseTranslateFunction,\n type TranslateFunction,\n type TranslateFunctionForNamespace,\n} from '@intlayer/use-intl';\nimport { getLocale } from './getLocale';\n\n/**\n * Options accepted by the options-object overload of {@link getTranslations}.\n */\ntype GetTranslationsOptions<N extends DictionaryKeys> = {\n /** The dictionary namespace to scope translations to. */\n namespace?: N;\n /** Override the locale instead of reading it from the current request. */\n locale?: LocalesValues;\n};\n\n/**\n * Overload set for {@link getTranslations}:\n *\n * 1. A bare dictionary key → fully-typed `t()` (autocompleted dot-paths).\n * 2. An options object `{ namespace?, locale? }` → typed when namespace is\n * a known `DictionaryKeys` value.\n * 3. A nested namespace `'dictionary.sub.scope'` → `t()` accepts relative\n * dot-paths under the scope, typed against the dictionary, matching\n * next-intl's scoped-namespace behaviour.\n * 4. No namespace → root scope; the first segment of each key designates\n * the dictionary (`t('about.title')`).\n *\n * The translate function shape (`t`, `t.rich`, `t.markup`, `t.raw`, `t.has`)\n * is shared with `@intlayer/use-intl`.\n */\ntype GetTranslations = {\n <N extends DictionaryKeys>(namespace: N): Promise<TranslateFunction<N>>;\n <N extends DictionaryKeys>(\n options: GetTranslationsOptions<N>\n ): Promise<TranslateFunction<N>>;\n <N extends `${string}.${string}`>(\n namespace: N\n ): Promise<TranslateFunctionForNamespace<N>>;\n (): Promise<LooseTranslateFunction>;\n};\n\n/**\n * Drop-in for next-intl's server `getTranslations()`.\n *\n * Messages support ICU MessageFormat syntax: simple arguments (`{name}`),\n * plural (`{count, plural, one {…} other {…}}`, `#`), select, and formatted\n * arguments (`{value, number}`). Rich text is available through `t.rich()`\n * and `t.markup()`.\n *\n * Resolves the active locale from the current request (or the `locale` option)\n * and delegates to `@intlayer/use-intl`'s `createTranslator`, the same runtime\n * that backs the client `useTranslations`.\n *\n * @example\n * ```ts\n * // Bare namespace — fully typed dot-paths\n * const t = await getTranslations('about');\n * return <h1>{t('counter.label')}</h1>;\n *\n * // ICU plural\n * t('items', { count: 3 });\n *\n * // Options object with locale override\n * const t = await getTranslations({ namespace: 'about', locale: 'fr' });\n *\n * // Rich text\n * t.rich('terms', { link: (chunks) => <a href=\"/terms\">{chunks}</a> });\n * ```\n */\nexport const getTranslations: GetTranslations = (async (\n namespaceOrOptions?: string | GetTranslationsOptions<DictionaryKeys>\n) => {\n let namespace: string | undefined;\n let localeOverride: LocalesValues | undefined;\n\n if (typeof namespaceOrOptions === 'object' && namespaceOrOptions !== null) {\n namespace = namespaceOrOptions.namespace;\n localeOverride = namespaceOrOptions.locale;\n } else {\n namespace = namespaceOrOptions as string | undefined;\n }\n\n const locale = localeOverride ?? (await getLocale());\n\n return createTranslator({ locale: locale as LocalesValues, namespace });\n}) as GetTranslations;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4EA,MAAa,mBAAoC,OAC/C,uBACG;CACH,IAAI;CACJ,IAAI;CAEJ,IAAI,OAAO,uBAAuB,YAAY,uBAAuB,MAAM;EACzE,YAAY,mBAAmB;EAC/B,iBAAiB,mBAAmB;CACtC,OACE,YAAY;
|
|
1
|
+
{"version":3,"file":"getTranslations.cjs","names":["getLocale","createTranslator"],"sources":["../../../src/server/getTranslations.ts"],"sourcesContent":["import type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport {\n createTranslator,\n type LooseTranslateFunction,\n type TranslateFunction,\n type TranslateFunctionForNamespace,\n} from '@intlayer/use-intl';\nimport { getLocale } from './getLocale';\n\n/**\n * Options accepted by the options-object overload of {@link getTranslations}.\n */\ntype GetTranslationsOptions<N extends DictionaryKeys> = {\n /** The dictionary namespace to scope translations to. */\n namespace?: N;\n /** Override the locale instead of reading it from the current request. */\n locale?: LocalesValues;\n};\n\n/**\n * Overload set for {@link getTranslations}:\n *\n * 1. A bare dictionary key → fully-typed `t()` (autocompleted dot-paths).\n * 2. An options object `{ namespace?, locale? }` → typed when namespace is\n * a known `DictionaryKeys` value.\n * 3. A nested namespace `'dictionary.sub.scope'` → `t()` accepts relative\n * dot-paths under the scope, typed against the dictionary, matching\n * next-intl's scoped-namespace behaviour.\n * 4. No namespace → root scope; the first segment of each key designates\n * the dictionary (`t('about.title')`).\n *\n * The translate function shape (`t`, `t.rich`, `t.markup`, `t.raw`, `t.has`)\n * is shared with `@intlayer/use-intl`.\n */\ntype GetTranslations = {\n <N extends DictionaryKeys>(namespace: N): Promise<TranslateFunction<N>>;\n <N extends DictionaryKeys>(\n options: GetTranslationsOptions<N>\n ): Promise<TranslateFunction<N>>;\n <N extends `${string}.${string}`>(\n namespace: N\n ): Promise<TranslateFunctionForNamespace<N>>;\n (): Promise<LooseTranslateFunction>;\n};\n\n/**\n * Drop-in for next-intl's server `getTranslations()`.\n *\n * Messages support ICU MessageFormat syntax: simple arguments (`{name}`),\n * plural (`{count, plural, one {…} other {…}}`, `#`), select, and formatted\n * arguments (`{value, number}`). Rich text is available through `t.rich()`\n * and `t.markup()`.\n *\n * Resolves the active locale from the current request (or the `locale` option)\n * and delegates to `@intlayer/use-intl`'s `createTranslator`, the same runtime\n * that backs the client `useTranslations`.\n *\n * @example\n * ```ts\n * // Bare namespace — fully typed dot-paths\n * const t = await getTranslations('about');\n * return <h1>{t('counter.label')}</h1>;\n *\n * // ICU plural\n * t('items', { count: 3 });\n *\n * // Options object with locale override\n * const t = await getTranslations({ namespace: 'about', locale: 'fr' });\n *\n * // Rich text\n * t.rich('terms', { link: (chunks) => <a href=\"/terms\">{chunks}</a> });\n * ```\n */\nexport const getTranslations: GetTranslations = (async (\n namespaceOrOptions?: string | GetTranslationsOptions<DictionaryKeys>\n) => {\n let namespace: string | undefined;\n let localeOverride: LocalesValues | undefined;\n\n if (typeof namespaceOrOptions === 'object' && namespaceOrOptions !== null) {\n namespace = namespaceOrOptions.namespace;\n localeOverride = namespaceOrOptions.locale;\n } else {\n namespace = namespaceOrOptions as string | undefined;\n }\n\n const locale = localeOverride ?? (await getLocale());\n\n return createTranslator({ locale: locale as LocalesValues, namespace });\n}) as GetTranslations;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4EA,MAAa,mBAAoC,OAC/C,uBACG;CACH,IAAI;CACJ,IAAI;CAEJ,IAAI,OAAO,uBAAuB,YAAY,uBAAuB,MAAM;EACzE,YAAY,mBAAmB;EAC/B,iBAAiB,mBAAmB;CACtC,OACE,YAAY;CAGd,MAAM,SAAS,kBAAmB,MAAMA,mCAAU;CAElD,WAAOC,qCAAiB;EAAU;EAAyB;CAAU,CAAC;AACxE"}
|
|
@@ -9,7 +9,8 @@ let _intlayer_use_intl = require("@intlayer/use-intl");
|
|
|
9
9
|
* built by `@intlayer/use-intl`'s `createFormatter`.
|
|
10
10
|
*/
|
|
11
11
|
const getFormatter = (async (options) => {
|
|
12
|
-
|
|
12
|
+
const locale = options?.locale ?? await require_server_getLocale.getLocale();
|
|
13
|
+
return (0, _intlayer_use_intl.createFormatter)({ locale });
|
|
13
14
|
});
|
|
14
15
|
/**
|
|
15
16
|
* Drop-in for next-intl's server `getNow()`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.cjs","names":["getLocale"],"sources":["../../../src/server/helpers.ts"],"sourcesContent":["import { createFormatter } from '@intlayer/use-intl';\nimport type {\n getFormatter as _getFormatter,\n getNow as _getNow,\n getTimeZone as _getTimeZone,\n} from 'next-intl/server';\nimport { getLocale } from './getLocale';\n\n/**\n * Drop-in for next-intl's server `getFormatter()`.\n * Returns locale-aware formatters backed by the native `Intl.*` APIs,\n * built by `@intlayer/use-intl`'s `createFormatter`.\n */\nexport const getFormatter: typeof _getFormatter = (async (options?: {\n locale?: string;\n}) => {\n const locale = options?.locale ?? (await getLocale());\n return createFormatter({ locale: locale as string });\n}) as typeof _getFormatter;\n\n/**\n * Drop-in for next-intl's server `getNow()`.\n * Returns the current `Date`.\n */\nexport const getNow: typeof _getNow = (async () =>\n new Date()) as typeof _getNow;\n\n/**\n * Drop-in for next-intl's server `getTimeZone()`.\n * Returns the system time zone resolved from `Intl.DateTimeFormat`.\n */\nexport const getTimeZone: typeof _getTimeZone = (async () =>\n Intl.DateTimeFormat().resolvedOptions().timeZone) as typeof _getTimeZone;\n"],"mappings":";;;;;;;;;;AAaA,MAAa,gBAAsC,OAAO,YAEpD;
|
|
1
|
+
{"version":3,"file":"helpers.cjs","names":["getLocale","createFormatter"],"sources":["../../../src/server/helpers.ts"],"sourcesContent":["import { createFormatter } from '@intlayer/use-intl';\nimport type {\n getFormatter as _getFormatter,\n getNow as _getNow,\n getTimeZone as _getTimeZone,\n} from 'next-intl/server';\nimport { getLocale } from './getLocale';\n\n/**\n * Drop-in for next-intl's server `getFormatter()`.\n * Returns locale-aware formatters backed by the native `Intl.*` APIs,\n * built by `@intlayer/use-intl`'s `createFormatter`.\n */\nexport const getFormatter: typeof _getFormatter = (async (options?: {\n locale?: string;\n}) => {\n const locale = options?.locale ?? (await getLocale());\n return createFormatter({ locale: locale as string });\n}) as typeof _getFormatter;\n\n/**\n * Drop-in for next-intl's server `getNow()`.\n * Returns the current `Date`.\n */\nexport const getNow: typeof _getNow = (async () =>\n new Date()) as typeof _getNow;\n\n/**\n * Drop-in for next-intl's server `getTimeZone()`.\n * Returns the system time zone resolved from `Intl.DateTimeFormat`.\n */\nexport const getTimeZone: typeof _getTimeZone = (async () =>\n Intl.DateTimeFormat().resolvedOptions().timeZone) as typeof _getTimeZone;\n"],"mappings":";;;;;;;;;;AAaA,MAAa,gBAAsC,OAAO,YAEpD;CACJ,MAAM,SAAS,SAAS,UAAW,MAAMA,mCAAU;CACnD,WAAOC,oCAAgB,EAAU,OAAiB,CAAC;AACrD;;;;;AAMA,MAAa,UAA0B,4BACrC,IAAI,KAAK;;;;;AAMX,MAAa,eAAoC,YAC/C,KAAK,eAAe,CAAC,CAAC,gBAAgB,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestLocaleCache.cjs","names":[],"sources":["../../../src/server/requestLocaleCache.ts"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { cache } from 'react';\n\n/**\n * Request-scoped holder for the locale provided through {@link setRequestLocale}.\n *\n * next-intl resolves the active locale per request from the `[locale]` route\n * segment, which the app forwards via `setRequestLocale(locale)`. React's\n * `cache()` gives a per-request singleton (the same trick next-intl uses in its\n * own `RequestLocaleCache`), so the value set in the layout/page is readable by\n * the other server APIs (`getLocale`, `getTranslations`, …) during the same\n * render.\n *\n * @see https://github.com/vercel/next.js/discussions/58862\n */\nconst getRequestLocaleHolder = cache((): { locale?: LocalesValues } => ({\n locale: undefined,\n}));\n\n/**\n * Read the locale stored for the current request, or `undefined` when\n * `setRequestLocale` has not been called.\n */\nexport const getCachedRequestLocale = (): LocalesValues | undefined =>\n getRequestLocaleHolder().locale;\n\n/**\n * Store the locale for the current request. Called by `setRequestLocale`.\n *\n * @param locale - The locale resolved from the `[locale]` route segment.\n */\nexport const setCachedRequestLocale = (locale: LocalesValues): void => {\n getRequestLocaleHolder().locale = locale;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAM,
|
|
1
|
+
{"version":3,"file":"requestLocaleCache.cjs","names":["cache"],"sources":["../../../src/server/requestLocaleCache.ts"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { cache } from 'react';\n\n/**\n * Request-scoped holder for the locale provided through {@link setRequestLocale}.\n *\n * next-intl resolves the active locale per request from the `[locale]` route\n * segment, which the app forwards via `setRequestLocale(locale)`. React's\n * `cache()` gives a per-request singleton (the same trick next-intl uses in its\n * own `RequestLocaleCache`), so the value set in the layout/page is readable by\n * the other server APIs (`getLocale`, `getTranslations`, …) during the same\n * render.\n *\n * @see https://github.com/vercel/next.js/discussions/58862\n */\nconst getRequestLocaleHolder = cache((): { locale?: LocalesValues } => ({\n locale: undefined,\n}));\n\n/**\n * Read the locale stored for the current request, or `undefined` when\n * `setRequestLocale` has not been called.\n */\nexport const getCachedRequestLocale = (): LocalesValues | undefined =>\n getRequestLocaleHolder().locale;\n\n/**\n * Store the locale for the current request. Called by `setRequestLocale`.\n *\n * @param locale - The locale resolved from the `[locale]` route segment.\n */\nexport const setCachedRequestLocale = (locale: LocalesValues): void => {\n getRequestLocaleHolder().locale = locale;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAM,6BAAyBA,oBAAyC,EACtE,QAAQ,OACV,EAAE;;;;;AAMF,MAAa,+BACX,uBAAuB,CAAC,CAAC;;;;;;AAO3B,MAAa,0BAA0B,WAAgC;CACrE,uBAAuB,CAAC,CAAC,SAAS;AACpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setLocale.cjs","names":[],"sources":["../../../src/server/setLocale.ts"],"sourcesContent":["import { setLocaleInStorageServer } from '@intlayer/core/utils';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { cookies } from 'next/headers.js';\n\n/**\n * Drop-in replacement for next-intl's `setLocale()` server action.\n *\n * Writes the locale to whichever cookie(s) the active `routing.storage`\n * configuration specifies. When `createNextIntlPlugin` is used (the default),\n * this is `NEXT_LOCALE`; when the user has configured a custom storage in\n * `intlayer.config.ts`, that name is used instead.\n *\n * Must be called inside a Server Action.\n *\n * @example\n * ```ts\n * 'use server';\n * await setLocale('fr');\n * ```\n */\nexport const setLocale = async (locale: string): Promise<void> => {\n const cookieStore = await cookies();\n\n setLocaleInStorageServer(locale as LocalesValues, {\n setCookieStore: (name, value, attributes) => {\n cookieStore.set(name, value, {\n ...(attributes ?? {}),\n path: attributes?.path ?? '/',\n sameSite: (attributes?.sameSite as 'lax') ?? 'lax',\n httpOnly: attributes?.httpOnly ?? false,\n secure: attributes?.secure ?? process.env.NODE_ENV === 'production',\n });\n },\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,YAAY,OAAO,WAAkC;CAChE,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"setLocale.cjs","names":["cookies"],"sources":["../../../src/server/setLocale.ts"],"sourcesContent":["import { setLocaleInStorageServer } from '@intlayer/core/utils';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { cookies } from 'next/headers.js';\n\n/**\n * Drop-in replacement for next-intl's `setLocale()` server action.\n *\n * Writes the locale to whichever cookie(s) the active `routing.storage`\n * configuration specifies. When `createNextIntlPlugin` is used (the default),\n * this is `NEXT_LOCALE`; when the user has configured a custom storage in\n * `intlayer.config.ts`, that name is used instead.\n *\n * Must be called inside a Server Action.\n *\n * @example\n * ```ts\n * 'use server';\n * await setLocale('fr');\n * ```\n */\nexport const setLocale = async (locale: string): Promise<void> => {\n const cookieStore = await cookies();\n\n setLocaleInStorageServer(locale as LocalesValues, {\n setCookieStore: (name, value, attributes) => {\n cookieStore.set(name, value, {\n ...(attributes ?? {}),\n path: attributes?.path ?? '/',\n sameSite: (attributes?.sameSite as 'lax') ?? 'lax',\n httpOnly: attributes?.httpOnly ?? false,\n secure: attributes?.secure ?? process.env.NODE_ENV === 'production',\n });\n },\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,YAAY,OAAO,WAAkC;CAChE,MAAM,cAAc,UAAMA,yBAAQ;CAElC,mDAAyB,QAAyB,EAChD,iBAAiB,MAAM,OAAO,eAAe;EAC3C,YAAY,IAAI,MAAM,OAAO;GAC3B,GAAI,cAAc,CAAC;GACnB,MAAM,YAAY,QAAQ;GAC1B,UAAW,YAAY,YAAsB;GAC7C,UAAU,YAAY,YAAY;GAClC,QAAQ,YAAY,UAAU,QAAQ,IAAI,aAAa;EACzD,CAAC;CACH,EACF,CAAC;AACH"}
|
|
@@ -25,7 +25,8 @@ const readRestArgument = (rest) => {
|
|
|
25
25
|
const getDictionary = (async (dictionary, rest) => {
|
|
26
26
|
const { namespacePrefix, localeOverride } = readRestArgument(rest);
|
|
27
27
|
const locale = localeOverride ?? await getLocale();
|
|
28
|
-
|
|
28
|
+
const content = getDictionary$1(dictionary, locale);
|
|
29
|
+
return createDictionaryTranslator(locale, content, namespacePrefix);
|
|
29
30
|
});
|
|
30
31
|
|
|
31
32
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDictionary.mjs","names":["getDictionaryBase"],"sources":["../../src/getDictionary.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport {\n createDictionaryTranslator,\n type ScopedTranslateFunction,\n type TranslateFunction,\n} from '@intlayer/use-intl';\nimport { getDictionary as getDictionaryBase } from 'next-intlayer';\nimport { getLocale } from './server/getLocale';\n\n/**\n * Trailing argument left by the optimize pass. `getTranslations('ns.scope')`\n * yields the key-prefix remainder as a string, while the object overload\n * `getTranslations({ locale, namespace })` keeps its options object (with the\n * namespace stripped, since the dictionary is now passed directly).\n */\ntype DictionaryTranslatorRest = string | { locale?: LocalesValues };\n\nconst readRestArgument = (\n rest: DictionaryTranslatorRest | undefined\n): { namespacePrefix?: string; localeOverride?: LocalesValues } => {\n if (typeof rest === 'string') return { namespacePrefix: rest };\n return { localeOverride: rest?.locale };\n};\n\n/**\n * Overload set for {@link getDictionary}: a string rest argument is the\n * key-prefix remainder of a nested namespace (relative dot-paths under the\n * scope); otherwise the translator is typed against the dictionary's\n * dot-paths.\n */\ntype GetDictionary = {\n <T extends Dictionary, Prefix extends string>(\n dictionary: T,\n namespacePrefix: Prefix\n ): Promise<ScopedTranslateFunction<T['key'] & DictionaryKeys, Prefix>>;\n <T extends Dictionary>(\n dictionary: T,\n options?: { locale?: LocalesValues }\n ): Promise<TranslateFunction<T['key'] & DictionaryKeys>>;\n};\n\n/**\n * Dictionary-accepting variant of `getTranslations`.\n *\n * Used internally by the build-time optimization: instead of looking up the\n * dictionary at runtime by key, the babel/swc plugin pre-imports the dictionary\n * JSON at build time and passes it directly here. This enables tree-shaking of\n * unused locale content.\n *\n * Runs on the server, where next-intl apps do not mount an\n * `IntlayerServerProvider`. The request locale therefore cannot be read from a\n * server context and is resolved asynchronously from the cookie/header via\n * `getLocale()` (or the explicit `{ locale }` of the object overload).\n * `getTranslations` is always awaited, so an async resolver is a drop-in\n * replacement.\n */\nexport const getDictionary = (async <T extends Dictionary>(\n dictionary: T,\n rest?: DictionaryTranslatorRest\n) => {\n const { namespacePrefix, localeOverride } = readRestArgument(rest);\n const locale = localeOverride ?? ((await getLocale()) as LocalesValues);\n const content = getDictionaryBase(dictionary, locale);\n\n return createDictionaryTranslator(locale, content, namespacePrefix);\n}) as GetDictionary;\n"],"mappings":";;;;;AAqBA,MAAM,oBACJ,SACiE;CACjE,IAAI,OAAO,SAAS,UAAU,OAAO,EAAE,iBAAiB,KAAK;CAC7D,OAAO,EAAE,gBAAgB,MAAM,OAAO;AACxC;;;;;;;;;;;;;;;;AAkCA,MAAa,iBAAiB,OAC5B,YACA,SACG;CACH,MAAM,EAAE,iBAAiB,mBAAmB,iBAAiB,IAAI;CACjE,MAAM,SAAS,kBAAoB,MAAM,UAAU;
|
|
1
|
+
{"version":3,"file":"getDictionary.mjs","names":["getDictionaryBase"],"sources":["../../src/getDictionary.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport {\n createDictionaryTranslator,\n type ScopedTranslateFunction,\n type TranslateFunction,\n} from '@intlayer/use-intl';\nimport { getDictionary as getDictionaryBase } from 'next-intlayer';\nimport { getLocale } from './server/getLocale';\n\n/**\n * Trailing argument left by the optimize pass. `getTranslations('ns.scope')`\n * yields the key-prefix remainder as a string, while the object overload\n * `getTranslations({ locale, namespace })` keeps its options object (with the\n * namespace stripped, since the dictionary is now passed directly).\n */\ntype DictionaryTranslatorRest = string | { locale?: LocalesValues };\n\nconst readRestArgument = (\n rest: DictionaryTranslatorRest | undefined\n): { namespacePrefix?: string; localeOverride?: LocalesValues } => {\n if (typeof rest === 'string') return { namespacePrefix: rest };\n return { localeOverride: rest?.locale };\n};\n\n/**\n * Overload set for {@link getDictionary}: a string rest argument is the\n * key-prefix remainder of a nested namespace (relative dot-paths under the\n * scope); otherwise the translator is typed against the dictionary's\n * dot-paths.\n */\ntype GetDictionary = {\n <T extends Dictionary, Prefix extends string>(\n dictionary: T,\n namespacePrefix: Prefix\n ): Promise<ScopedTranslateFunction<T['key'] & DictionaryKeys, Prefix>>;\n <T extends Dictionary>(\n dictionary: T,\n options?: { locale?: LocalesValues }\n ): Promise<TranslateFunction<T['key'] & DictionaryKeys>>;\n};\n\n/**\n * Dictionary-accepting variant of `getTranslations`.\n *\n * Used internally by the build-time optimization: instead of looking up the\n * dictionary at runtime by key, the babel/swc plugin pre-imports the dictionary\n * JSON at build time and passes it directly here. This enables tree-shaking of\n * unused locale content.\n *\n * Runs on the server, where next-intl apps do not mount an\n * `IntlayerServerProvider`. The request locale therefore cannot be read from a\n * server context and is resolved asynchronously from the cookie/header via\n * `getLocale()` (or the explicit `{ locale }` of the object overload).\n * `getTranslations` is always awaited, so an async resolver is a drop-in\n * replacement.\n */\nexport const getDictionary = (async <T extends Dictionary>(\n dictionary: T,\n rest?: DictionaryTranslatorRest\n) => {\n const { namespacePrefix, localeOverride } = readRestArgument(rest);\n const locale = localeOverride ?? ((await getLocale()) as LocalesValues);\n const content = getDictionaryBase(dictionary, locale);\n\n return createDictionaryTranslator(locale, content, namespacePrefix);\n}) as GetDictionary;\n"],"mappings":";;;;;AAqBA,MAAM,oBACJ,SACiE;CACjE,IAAI,OAAO,SAAS,UAAU,OAAO,EAAE,iBAAiB,KAAK;CAC7D,OAAO,EAAE,gBAAgB,MAAM,OAAO;AACxC;;;;;;;;;;;;;;;;AAkCA,MAAa,iBAAiB,OAC5B,YACA,SACG;CACH,MAAM,EAAE,iBAAiB,mBAAmB,iBAAiB,IAAI;CACjE,MAAM,SAAS,kBAAoB,MAAM,UAAU;CACnD,MAAM,UAAUA,gBAAkB,YAAY,MAAM;CAEpD,OAAO,2BAA2B,QAAQ,SAAS,eAAe;AACpE"}
|
|
@@ -10,7 +10,9 @@ import { useDictionaryDynamic } from "next-intlayer/server";
|
|
|
10
10
|
* locale. Used internally by the build-time optimization.
|
|
11
11
|
*/
|
|
12
12
|
const getDictionaryDynamic = (async (dictionaryPromise, key, namespacePrefix) => {
|
|
13
|
-
|
|
13
|
+
const locale = await getLocale$1();
|
|
14
|
+
const content = await useDictionaryDynamic(dictionaryPromise, key);
|
|
15
|
+
return createDictionaryTranslator(locale, content, namespacePrefix);
|
|
14
16
|
});
|
|
15
17
|
|
|
16
18
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDictionaryDynamic.mjs","names":["getLocale","getDictionaryDynamicBase"],"sources":["../../src/getDictionaryDynamic.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport {\n createDictionaryTranslator,\n type ScopedTranslateFunction,\n type TranslateFunction,\n} from '@intlayer/use-intl';\nimport { useDictionaryDynamic as getDictionaryDynamicBase } from 'next-intlayer/server';\nimport { getLocale } from './server/getLocale';\n\n/**\n * Overload set for {@link getDictionaryDynamic}: without a prefix the\n * translator is typed against the dictionary's dot-paths; with a prefix the\n * keys are relative dot-paths under that scope.\n */\ntype GetDictionaryDynamic = {\n <T extends Dictionary, K extends DictionaryKeys>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K\n ): Promise<TranslateFunction<K>>;\n <T extends Dictionary, K extends DictionaryKeys, Prefix extends string>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K,\n namespacePrefix: Prefix\n ): Promise<ScopedTranslateFunction<K, Prefix>>;\n};\n\n/**\n * Dynamic dictionary-accepting variant of `getTranslations`.\n *\n * Counterpart to {@link getDictionary} for dictionaries imported lazily per\n * locale. Used internally by the build-time optimization.\n */\nexport const getDictionaryDynamic = (async <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K,\n namespacePrefix?: string\n) => {\n const locale = (await getLocale()) as LocalesValues;\n const content = await getDictionaryDynamicBase<T, K>(dictionaryPromise, key);\n\n return createDictionaryTranslator(locale, content, namespacePrefix);\n}) as GetDictionaryDynamic;\n"],"mappings":";;;;;;;;;;;AAqCA,MAAa,wBAAwB,OAInC,mBACA,KACA,oBACG;
|
|
1
|
+
{"version":3,"file":"getDictionaryDynamic.mjs","names":["getLocale","getDictionaryDynamicBase"],"sources":["../../src/getDictionaryDynamic.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport {\n createDictionaryTranslator,\n type ScopedTranslateFunction,\n type TranslateFunction,\n} from '@intlayer/use-intl';\nimport { useDictionaryDynamic as getDictionaryDynamicBase } from 'next-intlayer/server';\nimport { getLocale } from './server/getLocale';\n\n/**\n * Overload set for {@link getDictionaryDynamic}: without a prefix the\n * translator is typed against the dictionary's dot-paths; with a prefix the\n * keys are relative dot-paths under that scope.\n */\ntype GetDictionaryDynamic = {\n <T extends Dictionary, K extends DictionaryKeys>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K\n ): Promise<TranslateFunction<K>>;\n <T extends Dictionary, K extends DictionaryKeys, Prefix extends string>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K,\n namespacePrefix: Prefix\n ): Promise<ScopedTranslateFunction<K, Prefix>>;\n};\n\n/**\n * Dynamic dictionary-accepting variant of `getTranslations`.\n *\n * Counterpart to {@link getDictionary} for dictionaries imported lazily per\n * locale. Used internally by the build-time optimization.\n */\nexport const getDictionaryDynamic = (async <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K,\n namespacePrefix?: string\n) => {\n const locale = (await getLocale()) as LocalesValues;\n const content = await getDictionaryDynamicBase<T, K>(dictionaryPromise, key);\n\n return createDictionaryTranslator(locale, content, namespacePrefix);\n}) as GetDictionaryDynamic;\n"],"mappings":";;;;;;;;;;;AAqCA,MAAa,wBAAwB,OAInC,mBACA,KACA,oBACG;CACH,MAAM,SAAU,MAAMA,YAAU;CAChC,MAAM,UAAU,MAAMC,qBAA+B,mBAAmB,GAAG;CAE3E,OAAO,2BAA2B,QAAQ,SAAS,eAAe;AACpE"}
|
package/dist/esm/middleware.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.mjs","names":[],"sources":["../../src/middleware.ts"],"sourcesContent":["import type { NextFetchEvent, NextRequest } from 'next/server';\nimport type _createMiddleware from 'next-intl/middleware';\nimport { intlayerMiddleware } from 'next-intlayer/middleware';\n\n/**\n * Drop-in replacement for next-intl's `createMiddleware`.\n *\n * Returns Intlayer's proxy/middleware, which handles locale detection and\n * routing from the Intlayer configuration. The `routing` argument is accepted\n * for API compatibility but ignored — locales come from `intlayer.config`.\n *\n * @example\n * ```ts\n * // proxy.ts (or middleware.ts on Next <= 15)\n * import createMiddleware from 'next-intl/middleware';\n * export default createMiddleware(routing);\n * export const config = { matcher: ['/((?!api|_next|.*\\\\..*).*)'] };\n * ```\n */\nexport const createMiddleware: typeof _createMiddleware =\n (_routing?: unknown) => (request: NextRequest, event?: NextFetchEvent) => {\n const response = intlayerMiddleware(request, event);\n\n if (response) {\n // Intlayer middleware writes the resolved locale to the x-intlayer-locale header\n // We read it and explicitly set the NEXT_LOCALE cookie to maintain compatibility with next-intl\n const resolvedLocale = response.headers.get('x-intlayer-locale');\n if (resolvedLocale) {\n response.cookies.set('NEXT_LOCALE', resolvedLocale, {\n path: '/',\n sameSite: 'lax',\n maxAge: 60 * 60 * 24 * 365,\n });\n }\n }\n\n return response;\n };\n\nexport default createMiddleware;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmBA,MAAa,oBACV,cAAwB,SAAsB,UAA2B;CACxE,MAAM,WAAW,mBAAmB,SAAS,KAAK;CAElD,IAAI,UAAU;EAGZ,MAAM,iBAAiB,SAAS,QAAQ,IAAI,mBAAmB;EAC/D,IAAI,gBACF,SAAS,QAAQ,IAAI,eAAe,gBAAgB;GAClD,MAAM;GACN,UAAU;GACV,QAAQ
|
|
1
|
+
{"version":3,"file":"middleware.mjs","names":[],"sources":["../../src/middleware.ts"],"sourcesContent":["import type { NextFetchEvent, NextRequest } from 'next/server';\nimport type _createMiddleware from 'next-intl/middleware';\nimport { intlayerMiddleware } from 'next-intlayer/middleware';\n\n/**\n * Drop-in replacement for next-intl's `createMiddleware`.\n *\n * Returns Intlayer's proxy/middleware, which handles locale detection and\n * routing from the Intlayer configuration. The `routing` argument is accepted\n * for API compatibility but ignored — locales come from `intlayer.config`.\n *\n * @example\n * ```ts\n * // proxy.ts (or middleware.ts on Next <= 15)\n * import createMiddleware from 'next-intl/middleware';\n * export default createMiddleware(routing);\n * export const config = { matcher: ['/((?!api|_next|.*\\\\..*).*)'] };\n * ```\n */\nexport const createMiddleware: typeof _createMiddleware =\n (_routing?: unknown) => (request: NextRequest, event?: NextFetchEvent) => {\n const response = intlayerMiddleware(request, event);\n\n if (response) {\n // Intlayer middleware writes the resolved locale to the x-intlayer-locale header\n // We read it and explicitly set the NEXT_LOCALE cookie to maintain compatibility with next-intl\n const resolvedLocale = response.headers.get('x-intlayer-locale');\n if (resolvedLocale) {\n response.cookies.set('NEXT_LOCALE', resolvedLocale, {\n path: '/',\n sameSite: 'lax',\n maxAge: 60 * 60 * 24 * 365,\n });\n }\n }\n\n return response;\n };\n\nexport default createMiddleware;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmBA,MAAa,oBACV,cAAwB,SAAsB,UAA2B;CACxE,MAAM,WAAW,mBAAmB,SAAS,KAAK;CAElD,IAAI,UAAU;EAGZ,MAAM,iBAAiB,SAAS,QAAQ,IAAI,mBAAmB;EAC/D,IAAI,gBACF,SAAS,QAAQ,IAAI,eAAe,gBAAgB;GAClD,MAAM;GACN,UAAU;GACV,QAAQ;EACV,CAAC;CAEL;CAEA,OAAO;AACT"}
|
|
@@ -10,7 +10,8 @@ import { getLocalizedUrl } from "@intlayer/core/localization";
|
|
|
10
10
|
* @returns The localized URL string.
|
|
11
11
|
*/
|
|
12
12
|
const localizeHref = (href, locale) => {
|
|
13
|
-
const
|
|
13
|
+
const pathname = typeof href === "string" ? href : href.pathname;
|
|
14
|
+
const localizedPathname = getLocalizedUrl(pathname, locale);
|
|
14
15
|
if (typeof href === "string" || !href.query) return localizedPathname;
|
|
15
16
|
const searchParams = new URLSearchParams();
|
|
16
17
|
for (const [key, value] of Object.entries(href.query)) if (Array.isArray(value)) for (const entry of value) searchParams.append(key, String(entry));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localizeHref.mjs","names":[],"sources":["../../../src/navigation/localizeHref.ts"],"sourcesContent":["import { getLocalizedUrl } from '@intlayer/core/localization';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\n\n/**\n * A `next-intl` navigation href: either a pathname string or an object with a\n * `pathname` and optional `query`. The `pathnames` (typed routes) feature is\n * accepted for API compatibility but not interpolated.\n */\nexport type NextIntlHref =\n | string\n | {\n pathname: string;\n query?: Record<string, string | number | (string | number)[]>;\n params?: Record<string, string | number | (string | number)[]>;\n };\n\n/**\n * Prefix a `next-intl` href with the given locale using Intlayer's\n * `getLocalizedUrl`, preserving any query parameters.\n *\n * @param href - The target href (string or `{ pathname, query }`).\n * @param locale - The locale to localize the href for.\n * @returns The localized URL string.\n */\nexport const localizeHref = (href: NextIntlHref, locale: string): string => {\n const pathname = typeof href === 'string' ? href : href.pathname;\n const localizedPathname = getLocalizedUrl(pathname, locale as LocalesValues);\n\n if (typeof href === 'string' || !href.query) {\n return localizedPathname;\n }\n\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(href.query)) {\n if (Array.isArray(value)) {\n for (const entry of value) {\n searchParams.append(key, String(entry));\n }\n } else {\n searchParams.append(key, String(value));\n }\n }\n\n const queryString = searchParams.toString();\n return queryString\n ? `${localizedPathname}?${queryString}`\n : localizedPathname;\n};\n"],"mappings":";;;;;;;;;;;AAwBA,MAAa,gBAAgB,MAAoB,WAA2B;
|
|
1
|
+
{"version":3,"file":"localizeHref.mjs","names":[],"sources":["../../../src/navigation/localizeHref.ts"],"sourcesContent":["import { getLocalizedUrl } from '@intlayer/core/localization';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\n\n/**\n * A `next-intl` navigation href: either a pathname string or an object with a\n * `pathname` and optional `query`. The `pathnames` (typed routes) feature is\n * accepted for API compatibility but not interpolated.\n */\nexport type NextIntlHref =\n | string\n | {\n pathname: string;\n query?: Record<string, string | number | (string | number)[]>;\n params?: Record<string, string | number | (string | number)[]>;\n };\n\n/**\n * Prefix a `next-intl` href with the given locale using Intlayer's\n * `getLocalizedUrl`, preserving any query parameters.\n *\n * @param href - The target href (string or `{ pathname, query }`).\n * @param locale - The locale to localize the href for.\n * @returns The localized URL string.\n */\nexport const localizeHref = (href: NextIntlHref, locale: string): string => {\n const pathname = typeof href === 'string' ? href : href.pathname;\n const localizedPathname = getLocalizedUrl(pathname, locale as LocalesValues);\n\n if (typeof href === 'string' || !href.query) {\n return localizedPathname;\n }\n\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(href.query)) {\n if (Array.isArray(value)) {\n for (const entry of value) {\n searchParams.append(key, String(entry));\n }\n } else {\n searchParams.append(key, String(value));\n }\n }\n\n const queryString = searchParams.toString();\n return queryString\n ? `${localizedPathname}?${queryString}`\n : localizedPathname;\n};\n"],"mappings":";;;;;;;;;;;AAwBA,MAAa,gBAAgB,MAAoB,WAA2B;CAC1E,MAAM,WAAW,OAAO,SAAS,WAAW,OAAO,KAAK;CACxD,MAAM,oBAAoB,gBAAgB,UAAU,MAAuB;CAE3E,IAAI,OAAO,SAAS,YAAY,CAAC,KAAK,OACpC,OAAO;CAGT,MAAM,eAAe,IAAI,gBAAgB;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,KAAK,GAClD,IAAI,MAAM,QAAQ,KAAK,GACrB,KAAK,MAAM,SAAS,OAClB,aAAa,OAAO,KAAK,OAAO,KAAK,CAAC;MAGxC,aAAa,OAAO,KAAK,OAAO,KAAK,CAAC;CAI1C,MAAM,cAAc,aAAa,SAAS;CAC1C,OAAO,cACH,GAAG,kBAAkB,GAAG,gBACxB;AACN"}
|
|
@@ -104,7 +104,7 @@ const createNextIntlPlugin = (_i18nPath) => {
|
|
|
104
104
|
const appLogger = getAppLogger(intlayerConfig);
|
|
105
105
|
runOnce(join(intlayerConfig?.system?.baseDir ?? process.cwd(), ".intlayer", "cache", "intlayer-issues-invitation.lock"), () => {
|
|
106
106
|
appLogger([colorize("Please report any issues you met on GitHub:", ANSIColors.GREY), colorize("https://github.com/aymericzip/intlayer/issues", ANSIColors.GREY_LIGHT)]);
|
|
107
|
-
}, { cacheTimeoutMs:
|
|
107
|
+
}, { cacheTimeoutMs: 36e5 });
|
|
108
108
|
const customWebpack = nextConfig.webpack;
|
|
109
109
|
const resolvedTargets = ALIAS_ENTRIES.map(({ request, replacement }) => ({
|
|
110
110
|
request,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\nimport { NEXT_INTL_CALLERS, toSwcExtraCallers } from '@intlayer/config/callers';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { runOnce } from '@intlayer/engine/utils';\nimport type { NextConfig } from 'next';\nimport { withIntlayer } from 'next-intlayer/server';\n\n/**\n * `require` that works in both the CJS and ESM builds of this plugin.\n * `import.meta.url` is rewritten to the module path in the CJS output by the\n * bundler, so `createRequire` resolves correctly in either format.\n */\nconst compatRequire = createRequire(import.meta.url);\n\n/**\n * Maps each original `next-intl` import specifier to the `@intlayer/next-intl`\n * specifier that should serve it instead.\n */\nconst ALIAS_ENTRIES: { request: string; replacement: string }[] = [\n { request: 'next-intl/server', replacement: '@intlayer/next-intl/server' },\n { request: 'next-intl/routing', replacement: '@intlayer/next-intl/routing' },\n {\n request: 'next-intl/navigation',\n replacement: '@intlayer/next-intl/navigation',\n },\n {\n request: 'next-intl/middleware',\n replacement: '@intlayer/next-intl/middleware',\n },\n { request: 'next-intl', replacement: '@intlayer/next-intl' },\n];\n\n/**\n * Split a package specifier into its package name and export subpath.\n *\n * @param specifier - e.g. `@intlayer/next-intl/server` or `next-intl`.\n * @returns `{ packageName, exportKey }` where `exportKey` is the `exports` map\n * key (`.` for the package root).\n */\nconst splitSpecifier = (\n specifier: string\n): { packageName: string; exportKey: string } => {\n const segments = specifier.split('/');\n const packageName = specifier.startsWith('@')\n ? segments.slice(0, 2).join('/')\n : (segments[0] ?? specifier);\n const subpath = specifier.slice(packageName?.length);\n return { packageName, exportKey: subpath === '' ? '.' : `.${subpath}` };\n};\n\n/**\n * Resolve the absolute path of a package export, preferring the ESM (`import`)\n * condition so Turbopack and modern bundlers load the `.mjs` build (which keeps\n * the `\"use client\"` directives) rather than the CommonJS fallback.\n *\n * Both Turbopack and webpack ignore alias values that are bare package\n * specifiers, so the aliases must point at real files.\n *\n * @param specifier - Package specifier, e.g. `@intlayer/next-intl/server`.\n * @returns Absolute path to the resolved module file.\n */\nconst resolveEsmPath = (specifier: string): string => {\n const { packageName, exportKey } = splitSpecifier(specifier);\n const packageJson = compatRequire(`${packageName}/package.json`) as {\n exports?: Record<\n string,\n string | { import?: string; require?: string; default?: string }\n >;\n };\n const packageDir = dirname(\n compatRequire.resolve(`${packageName}/package.json`)\n );\n\n const exportEntry = packageJson.exports?.[exportKey];\n const relativeFile =\n typeof exportEntry === 'string'\n ? exportEntry\n : (exportEntry?.import ?? exportEntry?.require ?? exportEntry?.default);\n\n // Fall back to Node resolution if the exports map is unexpected.\n if (!relativeFile) return compatRequire.resolve(specifier);\n\n return resolve(packageDir, relativeFile);\n};\n\n/**\n * Format an absolute path as a project-root-relative specifier (prefixed with\n * `./` and using forward slashes). Turbopack only honours `resolveAlias` values\n * that are project-root-relative paths — bare specifiers are ignored and\n * absolute paths are misread as root-relative. Mirrors `withIntlayer`'s\n * Turbopack alias formatter.\n *\n * @param absolutePath - Absolute path to the target module file.\n * @returns Relative specifier such as `./node_modules/@intlayer/next-intl/...`.\n */\nconst toTurbopackAlias = (absolutePath: string): string =>\n `./${relative(process.cwd(), absolutePath).split(sep).join('/')}`;\n\n/**\n * SWC extra-caller configs derived from the shared caller registry\n * (`@intlayer/config/callers`) — the single source of truth also consumed by\n * the babel analyzer/optimizer and the LSP.\n */\nconst NEXT_INTL_SWC_CALLERS = toSwcExtraCallers(NEXT_INTL_CALLERS);\n\n/**\n * A Next.js plugin for next-intl compat that wraps next-intlayer's plugin\n * and configures resolve aliases so `next-intl` imports are served by\n * `@intlayer/next-intl`.\n */\nexport const createNextIntlPlugin = (_i18nPath?: string) => {\n return async (nextConfig: NextConfig = {}): Promise<NextConfig> => {\n const intlayerConfig = getConfiguration();\n const appLogger = getAppLogger(intlayerConfig);\n\n runOnce(\n join(\n intlayerConfig?.system?.baseDir ?? process.cwd(),\n '.intlayer',\n 'cache',\n 'intlayer-issues-invitation.lock'\n ),\n () => {\n appLogger([\n colorize(\n 'Please report any issues you met on GitHub:',\n ANSIColors.GREY\n ),\n colorize(\n 'https://github.com/aymericzip/intlayer/issues',\n ANSIColors.GREY_LIGHT\n ),\n ]);\n },\n {\n cacheTimeoutMs: 1000 * 60 * 60, // 1 hour\n }\n );\n\n const customWebpack = nextConfig.webpack;\n\n const resolvedTargets = ALIAS_ENTRIES.map(({ request, replacement }) => ({\n request,\n absolutePath: resolveEsmPath(replacement),\n }));\n\n // Webpack resolves aliases from absolute paths.\n const webpackAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n absolutePath,\n ])\n );\n\n // Turbopack only honours project-root-relative `./` paths.\n const turboAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n toTurbopackAlias(absolutePath),\n ])\n );\n\n const aliasConfig = {\n webpack: (config: any, options: any) => {\n config.resolve.alias = {\n ...config.resolve.alias,\n ...webpackAlias,\n };\n\n if (typeof customWebpack === 'function') {\n return customWebpack(config, options);\n }\n return config;\n },\n };\n\n const mergedConfig: NextConfig = {\n ...nextConfig,\n ...aliasConfig,\n turbopack: {\n ...(nextConfig.turbopack ?? {}),\n resolveAlias: {\n ...(nextConfig.turbopack?.resolveAlias ?? {}),\n ...turboAlias,\n },\n },\n };\n\n // Only inject the NEXT_LOCALE cookie default when the user has not\n // configured their own routing.storage in intlayer.config.ts.\n // This lets users override via intlayer.config.ts while keeping\n // next-intl compatibility (NEXT_LOCALE) as the default.\n let hasUserDefinedStorage = false;\n try {\n hasUserDefinedStorage = !!(\n intlayerConfig?.routing &&\n 'storage' in intlayerConfig.routing &&\n intlayerConfig.routing.storage !== undefined\n );\n } catch {\n // If the config file cannot be read, fall back to the NEXT_LOCALE default.\n }\n\n const configOptions = hasUserDefinedStorage\n ? { swcExtraCallers: NEXT_INTL_SWC_CALLERS }\n : {\n override: {\n routing: {\n storage: [\n { type: 'cookie' as const, name: 'NEXT_LOCALE' },\n { type: 'header' as const, name: 'x-intlayer-locale' },\n ],\n },\n },\n swcExtraCallers: NEXT_INTL_SWC_CALLERS,\n };\n\n return withIntlayer(mergedConfig, configOptions);\n };\n};\n\nexport default createNextIntlPlugin;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\nimport { NEXT_INTL_CALLERS, toSwcExtraCallers } from '@intlayer/config/callers';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { runOnce } from '@intlayer/engine/utils';\nimport type { NextConfig } from 'next';\nimport { withIntlayer } from 'next-intlayer/server';\n\n/**\n * `require` that works in both the CJS and ESM builds of this plugin.\n * `import.meta.url` is rewritten to the module path in the CJS output by the\n * bundler, so `createRequire` resolves correctly in either format.\n */\nconst compatRequire = createRequire(import.meta.url);\n\n/**\n * Maps each original `next-intl` import specifier to the `@intlayer/next-intl`\n * specifier that should serve it instead.\n */\nconst ALIAS_ENTRIES: { request: string; replacement: string }[] = [\n { request: 'next-intl/server', replacement: '@intlayer/next-intl/server' },\n { request: 'next-intl/routing', replacement: '@intlayer/next-intl/routing' },\n {\n request: 'next-intl/navigation',\n replacement: '@intlayer/next-intl/navigation',\n },\n {\n request: 'next-intl/middleware',\n replacement: '@intlayer/next-intl/middleware',\n },\n { request: 'next-intl', replacement: '@intlayer/next-intl' },\n];\n\n/**\n * Split a package specifier into its package name and export subpath.\n *\n * @param specifier - e.g. `@intlayer/next-intl/server` or `next-intl`.\n * @returns `{ packageName, exportKey }` where `exportKey` is the `exports` map\n * key (`.` for the package root).\n */\nconst splitSpecifier = (\n specifier: string\n): { packageName: string; exportKey: string } => {\n const segments = specifier.split('/');\n const packageName = specifier.startsWith('@')\n ? segments.slice(0, 2).join('/')\n : (segments[0] ?? specifier);\n const subpath = specifier.slice(packageName?.length);\n return { packageName, exportKey: subpath === '' ? '.' : `.${subpath}` };\n};\n\n/**\n * Resolve the absolute path of a package export, preferring the ESM (`import`)\n * condition so Turbopack and modern bundlers load the `.mjs` build (which keeps\n * the `\"use client\"` directives) rather than the CommonJS fallback.\n *\n * Both Turbopack and webpack ignore alias values that are bare package\n * specifiers, so the aliases must point at real files.\n *\n * @param specifier - Package specifier, e.g. `@intlayer/next-intl/server`.\n * @returns Absolute path to the resolved module file.\n */\nconst resolveEsmPath = (specifier: string): string => {\n const { packageName, exportKey } = splitSpecifier(specifier);\n const packageJson = compatRequire(`${packageName}/package.json`) as {\n exports?: Record<\n string,\n string | { import?: string; require?: string; default?: string }\n >;\n };\n const packageDir = dirname(\n compatRequire.resolve(`${packageName}/package.json`)\n );\n\n const exportEntry = packageJson.exports?.[exportKey];\n const relativeFile =\n typeof exportEntry === 'string'\n ? exportEntry\n : (exportEntry?.import ?? exportEntry?.require ?? exportEntry?.default);\n\n // Fall back to Node resolution if the exports map is unexpected.\n if (!relativeFile) return compatRequire.resolve(specifier);\n\n return resolve(packageDir, relativeFile);\n};\n\n/**\n * Format an absolute path as a project-root-relative specifier (prefixed with\n * `./` and using forward slashes). Turbopack only honours `resolveAlias` values\n * that are project-root-relative paths — bare specifiers are ignored and\n * absolute paths are misread as root-relative. Mirrors `withIntlayer`'s\n * Turbopack alias formatter.\n *\n * @param absolutePath - Absolute path to the target module file.\n * @returns Relative specifier such as `./node_modules/@intlayer/next-intl/...`.\n */\nconst toTurbopackAlias = (absolutePath: string): string =>\n `./${relative(process.cwd(), absolutePath).split(sep).join('/')}`;\n\n/**\n * SWC extra-caller configs derived from the shared caller registry\n * (`@intlayer/config/callers`) — the single source of truth also consumed by\n * the babel analyzer/optimizer and the LSP.\n */\nconst NEXT_INTL_SWC_CALLERS = toSwcExtraCallers(NEXT_INTL_CALLERS);\n\n/**\n * A Next.js plugin for next-intl compat that wraps next-intlayer's plugin\n * and configures resolve aliases so `next-intl` imports are served by\n * `@intlayer/next-intl`.\n */\nexport const createNextIntlPlugin = (_i18nPath?: string) => {\n return async (nextConfig: NextConfig = {}): Promise<NextConfig> => {\n const intlayerConfig = getConfiguration();\n const appLogger = getAppLogger(intlayerConfig);\n\n runOnce(\n join(\n intlayerConfig?.system?.baseDir ?? process.cwd(),\n '.intlayer',\n 'cache',\n 'intlayer-issues-invitation.lock'\n ),\n () => {\n appLogger([\n colorize(\n 'Please report any issues you met on GitHub:',\n ANSIColors.GREY\n ),\n colorize(\n 'https://github.com/aymericzip/intlayer/issues',\n ANSIColors.GREY_LIGHT\n ),\n ]);\n },\n {\n cacheTimeoutMs: 1000 * 60 * 60, // 1 hour\n }\n );\n\n const customWebpack = nextConfig.webpack;\n\n const resolvedTargets = ALIAS_ENTRIES.map(({ request, replacement }) => ({\n request,\n absolutePath: resolveEsmPath(replacement),\n }));\n\n // Webpack resolves aliases from absolute paths.\n const webpackAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n absolutePath,\n ])\n );\n\n // Turbopack only honours project-root-relative `./` paths.\n const turboAlias = Object.fromEntries(\n resolvedTargets.map(({ request, absolutePath }) => [\n request,\n toTurbopackAlias(absolutePath),\n ])\n );\n\n const aliasConfig = {\n webpack: (config: any, options: any) => {\n config.resolve.alias = {\n ...config.resolve.alias,\n ...webpackAlias,\n };\n\n if (typeof customWebpack === 'function') {\n return customWebpack(config, options);\n }\n return config;\n },\n };\n\n const mergedConfig: NextConfig = {\n ...nextConfig,\n ...aliasConfig,\n turbopack: {\n ...(nextConfig.turbopack ?? {}),\n resolveAlias: {\n ...(nextConfig.turbopack?.resolveAlias ?? {}),\n ...turboAlias,\n },\n },\n };\n\n // Only inject the NEXT_LOCALE cookie default when the user has not\n // configured their own routing.storage in intlayer.config.ts.\n // This lets users override via intlayer.config.ts while keeping\n // next-intl compatibility (NEXT_LOCALE) as the default.\n let hasUserDefinedStorage = false;\n try {\n hasUserDefinedStorage = !!(\n intlayerConfig?.routing &&\n 'storage' in intlayerConfig.routing &&\n intlayerConfig.routing.storage !== undefined\n );\n } catch {\n // If the config file cannot be read, fall back to the NEXT_LOCALE default.\n }\n\n const configOptions = hasUserDefinedStorage\n ? { swcExtraCallers: NEXT_INTL_SWC_CALLERS }\n : {\n override: {\n routing: {\n storage: [\n { type: 'cookie' as const, name: 'NEXT_LOCALE' },\n { type: 'header' as const, name: 'x-intlayer-locale' },\n ],\n },\n },\n swcExtraCallers: NEXT_INTL_SWC_CALLERS,\n };\n\n return withIntlayer(mergedConfig, configOptions);\n };\n};\n\nexport default createNextIntlPlugin;\n"],"mappings":"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"}
|
|
@@ -37,8 +37,9 @@ const getTranslations = (async (namespaceOrOptions) => {
|
|
|
37
37
|
namespace = namespaceOrOptions.namespace;
|
|
38
38
|
localeOverride = namespaceOrOptions.locale;
|
|
39
39
|
} else namespace = namespaceOrOptions;
|
|
40
|
+
const locale = localeOverride ?? await getLocale();
|
|
40
41
|
return createTranslator({
|
|
41
|
-
locale
|
|
42
|
+
locale,
|
|
42
43
|
namespace
|
|
43
44
|
});
|
|
44
45
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTranslations.mjs","names":[],"sources":["../../../src/server/getTranslations.ts"],"sourcesContent":["import type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport {\n createTranslator,\n type LooseTranslateFunction,\n type TranslateFunction,\n type TranslateFunctionForNamespace,\n} from '@intlayer/use-intl';\nimport { getLocale } from './getLocale';\n\n/**\n * Options accepted by the options-object overload of {@link getTranslations}.\n */\ntype GetTranslationsOptions<N extends DictionaryKeys> = {\n /** The dictionary namespace to scope translations to. */\n namespace?: N;\n /** Override the locale instead of reading it from the current request. */\n locale?: LocalesValues;\n};\n\n/**\n * Overload set for {@link getTranslations}:\n *\n * 1. A bare dictionary key → fully-typed `t()` (autocompleted dot-paths).\n * 2. An options object `{ namespace?, locale? }` → typed when namespace is\n * a known `DictionaryKeys` value.\n * 3. A nested namespace `'dictionary.sub.scope'` → `t()` accepts relative\n * dot-paths under the scope, typed against the dictionary, matching\n * next-intl's scoped-namespace behaviour.\n * 4. No namespace → root scope; the first segment of each key designates\n * the dictionary (`t('about.title')`).\n *\n * The translate function shape (`t`, `t.rich`, `t.markup`, `t.raw`, `t.has`)\n * is shared with `@intlayer/use-intl`.\n */\ntype GetTranslations = {\n <N extends DictionaryKeys>(namespace: N): Promise<TranslateFunction<N>>;\n <N extends DictionaryKeys>(\n options: GetTranslationsOptions<N>\n ): Promise<TranslateFunction<N>>;\n <N extends `${string}.${string}`>(\n namespace: N\n ): Promise<TranslateFunctionForNamespace<N>>;\n (): Promise<LooseTranslateFunction>;\n};\n\n/**\n * Drop-in for next-intl's server `getTranslations()`.\n *\n * Messages support ICU MessageFormat syntax: simple arguments (`{name}`),\n * plural (`{count, plural, one {…} other {…}}`, `#`), select, and formatted\n * arguments (`{value, number}`). Rich text is available through `t.rich()`\n * and `t.markup()`.\n *\n * Resolves the active locale from the current request (or the `locale` option)\n * and delegates to `@intlayer/use-intl`'s `createTranslator`, the same runtime\n * that backs the client `useTranslations`.\n *\n * @example\n * ```ts\n * // Bare namespace — fully typed dot-paths\n * const t = await getTranslations('about');\n * return <h1>{t('counter.label')}</h1>;\n *\n * // ICU plural\n * t('items', { count: 3 });\n *\n * // Options object with locale override\n * const t = await getTranslations({ namespace: 'about', locale: 'fr' });\n *\n * // Rich text\n * t.rich('terms', { link: (chunks) => <a href=\"/terms\">{chunks}</a> });\n * ```\n */\nexport const getTranslations: GetTranslations = (async (\n namespaceOrOptions?: string | GetTranslationsOptions<DictionaryKeys>\n) => {\n let namespace: string | undefined;\n let localeOverride: LocalesValues | undefined;\n\n if (typeof namespaceOrOptions === 'object' && namespaceOrOptions !== null) {\n namespace = namespaceOrOptions.namespace;\n localeOverride = namespaceOrOptions.locale;\n } else {\n namespace = namespaceOrOptions as string | undefined;\n }\n\n const locale = localeOverride ?? (await getLocale());\n\n return createTranslator({ locale: locale as LocalesValues, namespace });\n}) as GetTranslations;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4EA,MAAa,mBAAoC,OAC/C,uBACG;CACH,IAAI;CACJ,IAAI;CAEJ,IAAI,OAAO,uBAAuB,YAAY,uBAAuB,MAAM;EACzE,YAAY,mBAAmB;EAC/B,iBAAiB,mBAAmB;CACtC,OACE,YAAY;
|
|
1
|
+
{"version":3,"file":"getTranslations.mjs","names":[],"sources":["../../../src/server/getTranslations.ts"],"sourcesContent":["import type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport {\n createTranslator,\n type LooseTranslateFunction,\n type TranslateFunction,\n type TranslateFunctionForNamespace,\n} from '@intlayer/use-intl';\nimport { getLocale } from './getLocale';\n\n/**\n * Options accepted by the options-object overload of {@link getTranslations}.\n */\ntype GetTranslationsOptions<N extends DictionaryKeys> = {\n /** The dictionary namespace to scope translations to. */\n namespace?: N;\n /** Override the locale instead of reading it from the current request. */\n locale?: LocalesValues;\n};\n\n/**\n * Overload set for {@link getTranslations}:\n *\n * 1. A bare dictionary key → fully-typed `t()` (autocompleted dot-paths).\n * 2. An options object `{ namespace?, locale? }` → typed when namespace is\n * a known `DictionaryKeys` value.\n * 3. A nested namespace `'dictionary.sub.scope'` → `t()` accepts relative\n * dot-paths under the scope, typed against the dictionary, matching\n * next-intl's scoped-namespace behaviour.\n * 4. No namespace → root scope; the first segment of each key designates\n * the dictionary (`t('about.title')`).\n *\n * The translate function shape (`t`, `t.rich`, `t.markup`, `t.raw`, `t.has`)\n * is shared with `@intlayer/use-intl`.\n */\ntype GetTranslations = {\n <N extends DictionaryKeys>(namespace: N): Promise<TranslateFunction<N>>;\n <N extends DictionaryKeys>(\n options: GetTranslationsOptions<N>\n ): Promise<TranslateFunction<N>>;\n <N extends `${string}.${string}`>(\n namespace: N\n ): Promise<TranslateFunctionForNamespace<N>>;\n (): Promise<LooseTranslateFunction>;\n};\n\n/**\n * Drop-in for next-intl's server `getTranslations()`.\n *\n * Messages support ICU MessageFormat syntax: simple arguments (`{name}`),\n * plural (`{count, plural, one {…} other {…}}`, `#`), select, and formatted\n * arguments (`{value, number}`). Rich text is available through `t.rich()`\n * and `t.markup()`.\n *\n * Resolves the active locale from the current request (or the `locale` option)\n * and delegates to `@intlayer/use-intl`'s `createTranslator`, the same runtime\n * that backs the client `useTranslations`.\n *\n * @example\n * ```ts\n * // Bare namespace — fully typed dot-paths\n * const t = await getTranslations('about');\n * return <h1>{t('counter.label')}</h1>;\n *\n * // ICU plural\n * t('items', { count: 3 });\n *\n * // Options object with locale override\n * const t = await getTranslations({ namespace: 'about', locale: 'fr' });\n *\n * // Rich text\n * t.rich('terms', { link: (chunks) => <a href=\"/terms\">{chunks}</a> });\n * ```\n */\nexport const getTranslations: GetTranslations = (async (\n namespaceOrOptions?: string | GetTranslationsOptions<DictionaryKeys>\n) => {\n let namespace: string | undefined;\n let localeOverride: LocalesValues | undefined;\n\n if (typeof namespaceOrOptions === 'object' && namespaceOrOptions !== null) {\n namespace = namespaceOrOptions.namespace;\n localeOverride = namespaceOrOptions.locale;\n } else {\n namespace = namespaceOrOptions as string | undefined;\n }\n\n const locale = localeOverride ?? (await getLocale());\n\n return createTranslator({ locale: locale as LocalesValues, namespace });\n}) as GetTranslations;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4EA,MAAa,mBAAoC,OAC/C,uBACG;CACH,IAAI;CACJ,IAAI;CAEJ,IAAI,OAAO,uBAAuB,YAAY,uBAAuB,MAAM;EACzE,YAAY,mBAAmB;EAC/B,iBAAiB,mBAAmB;CACtC,OACE,YAAY;CAGd,MAAM,SAAS,kBAAmB,MAAM,UAAU;CAElD,OAAO,iBAAiB;EAAU;EAAyB;CAAU,CAAC;AACxE"}
|
|
@@ -8,7 +8,8 @@ import { createFormatter } from "@intlayer/use-intl";
|
|
|
8
8
|
* built by `@intlayer/use-intl`'s `createFormatter`.
|
|
9
9
|
*/
|
|
10
10
|
const getFormatter = (async (options) => {
|
|
11
|
-
|
|
11
|
+
const locale = options?.locale ?? await getLocale();
|
|
12
|
+
return createFormatter({ locale });
|
|
12
13
|
});
|
|
13
14
|
/**
|
|
14
15
|
* Drop-in for next-intl's server `getNow()`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.mjs","names":[],"sources":["../../../src/server/helpers.ts"],"sourcesContent":["import { createFormatter } from '@intlayer/use-intl';\nimport type {\n getFormatter as _getFormatter,\n getNow as _getNow,\n getTimeZone as _getTimeZone,\n} from 'next-intl/server';\nimport { getLocale } from './getLocale';\n\n/**\n * Drop-in for next-intl's server `getFormatter()`.\n * Returns locale-aware formatters backed by the native `Intl.*` APIs,\n * built by `@intlayer/use-intl`'s `createFormatter`.\n */\nexport const getFormatter: typeof _getFormatter = (async (options?: {\n locale?: string;\n}) => {\n const locale = options?.locale ?? (await getLocale());\n return createFormatter({ locale: locale as string });\n}) as typeof _getFormatter;\n\n/**\n * Drop-in for next-intl's server `getNow()`.\n * Returns the current `Date`.\n */\nexport const getNow: typeof _getNow = (async () =>\n new Date()) as typeof _getNow;\n\n/**\n * Drop-in for next-intl's server `getTimeZone()`.\n * Returns the system time zone resolved from `Intl.DateTimeFormat`.\n */\nexport const getTimeZone: typeof _getTimeZone = (async () =>\n Intl.DateTimeFormat().resolvedOptions().timeZone) as typeof _getTimeZone;\n"],"mappings":";;;;;;;;;AAaA,MAAa,gBAAsC,OAAO,YAEpD;
|
|
1
|
+
{"version":3,"file":"helpers.mjs","names":[],"sources":["../../../src/server/helpers.ts"],"sourcesContent":["import { createFormatter } from '@intlayer/use-intl';\nimport type {\n getFormatter as _getFormatter,\n getNow as _getNow,\n getTimeZone as _getTimeZone,\n} from 'next-intl/server';\nimport { getLocale } from './getLocale';\n\n/**\n * Drop-in for next-intl's server `getFormatter()`.\n * Returns locale-aware formatters backed by the native `Intl.*` APIs,\n * built by `@intlayer/use-intl`'s `createFormatter`.\n */\nexport const getFormatter: typeof _getFormatter = (async (options?: {\n locale?: string;\n}) => {\n const locale = options?.locale ?? (await getLocale());\n return createFormatter({ locale: locale as string });\n}) as typeof _getFormatter;\n\n/**\n * Drop-in for next-intl's server `getNow()`.\n * Returns the current `Date`.\n */\nexport const getNow: typeof _getNow = (async () =>\n new Date()) as typeof _getNow;\n\n/**\n * Drop-in for next-intl's server `getTimeZone()`.\n * Returns the system time zone resolved from `Intl.DateTimeFormat`.\n */\nexport const getTimeZone: typeof _getTimeZone = (async () =>\n Intl.DateTimeFormat().resolvedOptions().timeZone) as typeof _getTimeZone;\n"],"mappings":";;;;;;;;;AAaA,MAAa,gBAAsC,OAAO,YAEpD;CACJ,MAAM,SAAS,SAAS,UAAW,MAAM,UAAU;CACnD,OAAO,gBAAgB,EAAU,OAAiB,CAAC;AACrD;;;;;AAMA,MAAa,UAA0B,4BACrC,IAAI,KAAK;;;;;AAMX,MAAa,eAAoC,YAC/C,KAAK,eAAe,CAAC,CAAC,gBAAgB,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/next-intl",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "next-intl API adapter for intlayer — useTranslations, useLocale, getTranslations, getLocale, NextIntlClientProvider backed by next-intlayer",
|
|
6
6
|
"keywords": [
|
|
@@ -110,14 +110,14 @@
|
|
|
110
110
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
111
111
|
},
|
|
112
112
|
"dependencies": {
|
|
113
|
-
"@intlayer/config": "9.3.
|
|
114
|
-
"@intlayer/core": "9.3.
|
|
115
|
-
"@intlayer/dictionaries-entry": "9.3.
|
|
116
|
-
"@intlayer/engine": "9.3.
|
|
117
|
-
"@intlayer/types": "9.3.
|
|
118
|
-
"@intlayer/use-intl": "9.3.
|
|
119
|
-
"next-intlayer": "9.3.
|
|
120
|
-
"react-intlayer": "9.3.
|
|
113
|
+
"@intlayer/config": "9.3.1",
|
|
114
|
+
"@intlayer/core": "9.3.1",
|
|
115
|
+
"@intlayer/dictionaries-entry": "9.3.1",
|
|
116
|
+
"@intlayer/engine": "9.3.1",
|
|
117
|
+
"@intlayer/types": "9.3.1",
|
|
118
|
+
"@intlayer/use-intl": "9.3.1",
|
|
119
|
+
"next-intlayer": "9.3.1",
|
|
120
|
+
"react-intlayer": "9.3.1"
|
|
121
121
|
},
|
|
122
122
|
"devDependencies": {
|
|
123
123
|
"@types/node": "26.2.0",
|