nuxt-intlayer 8.12.1 → 8.12.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"module.mjs","names":[],"sources":["../../src/module.ts"],"sourcesContent":["import { getConfiguration } from '@intlayer/config/node';\nimport { getPrefix } from '@intlayer/core/localization';\nimport { addPlugin, createResolver, defineNuxtModule } from '@nuxt/kit';\nimport type { NuxtModule } from '@nuxt/schema';\nimport { intlayer, intlayerProxy } from 'vite-intlayer';\n\n/**\n * Nuxt module that integrates Intlayer into Nuxt applications.\n *\n * It handles:\n * 1. Configuring TypeScript to include Intlayer's generated types.\n * 2. Registering runtime plugins for Vue Intlayer and HTML lang management.\n * 3. Extending Vite configuration with Intlayer and Intlayer Proxy plugins.\n * 4. Extending Nuxt pages to support locale-aware routing based on the configuration.\n *\n * @example\n * ```ts\n * // nuxt.config.ts\n * export default defineNuxtConfig({\n * modules: ['nuxt-intlayer'],\n * });\n * ```\n */\nexport const module: NuxtModule = defineNuxtModule({\n meta: {\n name: 'nuxt-intlayer',\n },\n setup(_options, nuxt) {\n const configuration = getConfiguration();\n\n nuxt.options.typescript = nuxt.options.typescript || {};\n nuxt.options.typescript.tsConfig = nuxt.options.typescript.tsConfig || {};\n nuxt.options.typescript.tsConfig.include =\n nuxt.options.typescript.tsConfig.include || [];\n\n if (\n !nuxt.options.typescript.tsConfig.include.includes(\n '../.intlayer/types/**/*.ts'\n )\n ) {\n nuxt.options.typescript.tsConfig.include.push(\n '../.intlayer/types/**/*.ts'\n );\n }\n\n /**\n * -------------------------------------------------\n * RUNTIME PLUGIN REGISTRATION\n * -------------------------------------------------\n * Automatically install `vue-intlayer` on the client\n * so developers don't need to add the plugin manually\n * in every Nuxt project.\n */\n const resolver = createResolver(import.meta.url);\n\n addPlugin({\n src: resolver.resolve('./runtime/intlayer-plugin'),\n mode: 'all',\n });\n\n addPlugin({\n src: resolver.resolve('./runtime/html-lang'),\n mode: 'all',\n });\n\n // // Inject the intlayer middleware plugin into Nuxt's Vite config\n nuxt.hook('vite:extendConfig', (viteConfig, { isServer }) => {\n if (isServer) {\n // We only need the middleware on the server side during development\n // viteConfig.plugins can be undefined at this stage\n (viteConfig.plugins ?? []).push(intlayerProxy());\n }\n\n viteConfig.plugins?.push(intlayer());\n });\n\n // After setting up aliases, extend Nuxt pages with locale-aware routes\n nuxt.hook('pages:extend', (pages) => {\n const {\n internationalization: { locales, defaultLocale },\n routing: { mode },\n } = configuration;\n\n // Build a RegExp string with supported locales (e.g. \"en|fr|de\") to ensure the param only accepts known locales\n const filteredLocales = locales.filter((locale) => {\n const { localePrefix } = getPrefix(locale, {\n mode,\n defaultLocale,\n });\n return localePrefix !== undefined;\n });\n const localeGroupRegex = filteredLocales.map(String).join('|');\n\n // If no locales remain to prefix (e.g., only default locale and prefixDefault is false) skip extension\n if (!localeGroupRegex) return;\n\n // Clone the original page list to avoid infinite loops when pushing\n const originalPages = [...pages];\n\n for (const page of originalPages) {\n // Skip already localised routes (prevent double processing)\n if (page.path.startsWith('/:locale')) continue;\n\n // Determine the paths we need to add depending on prefixDefault flag\n // We always add the dynamic \":locale\" prefixed variant so that `/fr/about` works\n const dynPathPrefix = `/:locale(${localeGroupRegex})`;\n const isIndex = page.path === '/';\n const prefixedPath = isIndex\n ? `${dynPathPrefix}`\n : `${dynPathPrefix}${page.path}`;\n\n // If prefixDefault is false and this is the default locale, we keep the original\n // route (already in pages) and add the dynamic variant which will match non default\n // locales. When prefixDefault is true, we still keep the original route for SSR\n // convenience (middleware will redirect anyway) but also expose locale variants.\n\n // Create a shallow copy of the page with the new path\n pages.push({\n ...page,\n path: prefixedPath,\n name: page.name ? `${page.name}___i18n` : undefined,\n });\n }\n });\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,SAAqB,iBAAiB;CACjD,MAAM,EACJ,MAAM,gBACR;CACA,MAAM,UAAU,MAAM;EACpB,MAAM,gBAAgB,iBAAiB;EAEvC,KAAK,QAAQ,aAAa,KAAK,QAAQ,cAAc,CAAC;EACtD,KAAK,QAAQ,WAAW,WAAW,KAAK,QAAQ,WAAW,YAAY,CAAC;EACxE,KAAK,QAAQ,WAAW,SAAS,UAC/B,KAAK,QAAQ,WAAW,SAAS,WAAW,CAAC;EAE/C,IACE,CAAC,KAAK,QAAQ,WAAW,SAAS,QAAQ,SACxC,4BACF,GAEA,KAAK,QAAQ,WAAW,SAAS,QAAQ,KACvC,4BACF;;;;;;;;;EAWF,MAAM,WAAW,eAAe,OAAO,KAAK,GAAG;EAE/C,UAAU;GACR,KAAK,SAAS,QAAQ,2BAA2B;GACjD,MAAM;EACR,CAAC;EAED,UAAU;GACR,KAAK,SAAS,QAAQ,qBAAqB;GAC3C,MAAM;EACR,CAAC;EAGD,KAAK,KAAK,sBAAsB,YAAY,EAAE,eAAe;GAC3D,IAAI,UAGF,CAAC,WAAW,WAAW,CAAC,GAAG,KAAK,cAAc,CAAC;GAGjD,WAAW,SAAS,KAAK,SAAS,CAAC;EACrC,CAAC;EAGD,KAAK,KAAK,iBAAiB,UAAU;GACnC,MAAM,EACJ,sBAAsB,EAAE,SAAS,iBACjC,SAAS,EAAE,WACT;GAUJ,MAAM,mBAPkB,QAAQ,QAAQ,WAAW;IACjD,MAAM,EAAE,iBAAiB,UAAU,QAAQ;KACzC;KACA;IACF,CAAC;IACD,OAAO,iBAAiB;GAC1B,CACuC,EAAE,IAAI,MAAM,EAAE,KAAK,GAAG;GAG7D,IAAI,CAAC,kBAAkB;GAGvB,MAAM,gBAAgB,CAAC,GAAG,KAAK;GAE/B,KAAK,MAAM,QAAQ,eAAe;IAEhC,IAAI,KAAK,KAAK,WAAW,UAAU,GAAG;IAItC,MAAM,gBAAgB,YAAY,iBAAiB;IAEnD,MAAM,eADU,KAAK,SAAS,MAE1B,GAAG,kBACH,GAAG,gBAAgB,KAAK;IAQ5B,MAAM,KAAK;KACT,GAAG;KACH,MAAM;KACN,MAAM,KAAK,OAAO,GAAG,KAAK,KAAK,WAAW;IAC5C,CAAC;GACH;EACF,CAAC;CACH;AACF,CAAC"}
1
+ {"version":3,"file":"module.mjs","names":[],"sources":["../../src/module.ts"],"sourcesContent":["import { getConfiguration } from '@intlayer/config/node';\nimport { getPrefix } from '@intlayer/core/localization';\nimport { addPlugin, createResolver, defineNuxtModule } from '@nuxt/kit';\nimport type { NuxtModule } from '@nuxt/schema';\nimport { intlayer, intlayerProxy } from 'vite-intlayer';\n\n/**\n * Nuxt module that integrates Intlayer into Nuxt applications.\n *\n * It handles:\n * 1. Configuring TypeScript to include Intlayer's generated types.\n * 2. Registering runtime plugins for Vue Intlayer and HTML lang management.\n * 3. Extending Vite configuration with Intlayer and Intlayer Proxy plugins.\n * 4. Extending Nuxt pages to support locale-aware routing based on the configuration.\n *\n * @example\n * ```ts\n * // nuxt.config.ts\n * export default defineNuxtConfig({\n * modules: ['nuxt-intlayer'],\n * });\n * ```\n */\nexport const module: NuxtModule = defineNuxtModule({\n meta: {\n name: 'nuxt-intlayer',\n },\n setup(_options, nuxt) {\n const configuration = getConfiguration();\n\n nuxt.options.typescript = nuxt.options.typescript || {};\n nuxt.options.typescript.tsConfig = nuxt.options.typescript.tsConfig || {};\n nuxt.options.typescript.tsConfig.include =\n nuxt.options.typescript.tsConfig.include || [];\n\n if (\n !nuxt.options.typescript.tsConfig.include.includes(\n '../.intlayer/types/**/*.ts'\n )\n ) {\n nuxt.options.typescript.tsConfig.include.push(\n '../.intlayer/types/**/*.ts'\n );\n }\n\n /**\n * -------------------------------------------------\n * RUNTIME PLUGIN REGISTRATION\n * -------------------------------------------------\n * Automatically install `vue-intlayer` on the client\n * so developers don't need to add the plugin manually\n * in every Nuxt project.\n */\n const resolver = createResolver(import.meta.url);\n\n addPlugin({\n src: resolver.resolve('./runtime/intlayer-plugin'),\n mode: 'all',\n });\n\n addPlugin({\n src: resolver.resolve('./runtime/html-lang'),\n mode: 'all',\n });\n\n // // Inject the intlayer middleware plugin into Nuxt's Vite config\n nuxt.hook('vite:extendConfig', (viteConfig, { isServer }) => {\n if (isServer) {\n // We only need the middleware on the server side during development\n // viteConfig.plugins can be undefined at this stage\n (viteConfig.plugins ?? []).push(intlayerProxy());\n }\n\n viteConfig.plugins?.push(intlayer());\n });\n\n // After setting up aliases, extend Nuxt pages with locale-aware routes\n nuxt.hook('pages:extend', (pages) => {\n const {\n internationalization: { locales, defaultLocale },\n routing: { mode },\n } = configuration;\n\n // Build a RegExp string with supported locales (e.g. \"en|fr|de\") to ensure the param only accepts known locales\n const filteredLocales = locales.filter((locale) => {\n const { localePrefix } = getPrefix(locale, {\n mode,\n defaultLocale,\n });\n return localePrefix !== undefined;\n });\n const localeGroupRegex = filteredLocales.map(String).join('|');\n\n // If no locales remain to prefix (e.g., only default locale and prefixDefault is false) skip extension\n if (!localeGroupRegex) return;\n\n // Clone the original page list to avoid infinite loops when pushing\n const originalPages = [...pages];\n\n for (const page of originalPages) {\n // Skip already localised routes (prevent double processing)\n if (page.path.startsWith('/:locale')) continue;\n\n // Determine the paths we need to add depending on prefixDefault flag\n // We always add the dynamic \":locale\" prefixed variant so that `/fr/about` works\n const dynPathPrefix = `/:locale(${localeGroupRegex})`;\n const isIndex = page.path === '/';\n const prefixedPath = isIndex\n ? `${dynPathPrefix}`\n : `${dynPathPrefix}${page.path}`;\n\n // If prefixDefault is false and this is the default locale, we keep the original\n // route (already in pages) and add the dynamic variant which will match non default\n // locales. When prefixDefault is true, we still keep the original route for SSR\n // convenience (middleware will redirect anyway) but also expose locale variants.\n\n // Create a shallow copy of the page with the new path\n pages.push({\n ...page,\n path: prefixedPath,\n name: page.name ? `${page.name}___i18n` : undefined,\n });\n }\n });\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,SAAqB,iBAAiB;CACjD,MAAM,EACJ,MAAM,iBACP;CACD,MAAM,UAAU,MAAM;EACpB,MAAM,gBAAgB,kBAAkB;AAExC,OAAK,QAAQ,aAAa,KAAK,QAAQ,cAAc,EAAE;AACvD,OAAK,QAAQ,WAAW,WAAW,KAAK,QAAQ,WAAW,YAAY,EAAE;AACzE,OAAK,QAAQ,WAAW,SAAS,UAC/B,KAAK,QAAQ,WAAW,SAAS,WAAW,EAAE;AAEhD,MACE,CAAC,KAAK,QAAQ,WAAW,SAAS,QAAQ,SACxC,6BACD,CAED,MAAK,QAAQ,WAAW,SAAS,QAAQ,KACvC,6BACD;;;;;;;;;EAWH,MAAM,WAAW,eAAe,OAAO,KAAK,IAAI;AAEhD,YAAU;GACR,KAAK,SAAS,QAAQ,4BAA4B;GAClD,MAAM;GACP,CAAC;AAEF,YAAU;GACR,KAAK,SAAS,QAAQ,sBAAsB;GAC5C,MAAM;GACP,CAAC;AAGF,OAAK,KAAK,sBAAsB,YAAY,EAAE,eAAe;AAC3D,OAAI,SAGF,EAAC,WAAW,WAAW,EAAE,EAAE,KAAK,eAAe,CAAC;AAGlD,cAAW,SAAS,KAAK,UAAU,CAAC;IACpC;AAGF,OAAK,KAAK,iBAAiB,UAAU;GACnC,MAAM,EACJ,sBAAsB,EAAE,SAAS,iBACjC,SAAS,EAAE,WACT;GAUJ,MAAM,mBAPkB,QAAQ,QAAQ,WAAW;IACjD,MAAM,EAAE,iBAAiB,UAAU,QAAQ;KACzC;KACA;KACD,CAAC;AACF,WAAO,iBAAiB;KAEc,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI;AAG9D,OAAI,CAAC,iBAAkB;GAGvB,MAAM,gBAAgB,CAAC,GAAG,MAAM;AAEhC,QAAK,MAAM,QAAQ,eAAe;AAEhC,QAAI,KAAK,KAAK,WAAW,WAAW,CAAE;IAItC,MAAM,gBAAgB,YAAY,iBAAiB;IAEnD,MAAM,eADU,KAAK,SAAS,MAE1B,GAAG,kBACH,GAAG,gBAAgB,KAAK;AAQ5B,UAAM,KAAK;KACT,GAAG;KACH,MAAM;KACN,MAAM,KAAK,OAAO,GAAG,KAAK,KAAK,WAAW;KAC3C,CAAC;;IAEJ;;CAEL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"html-lang.mjs","names":[],"sources":["../../../src/runtime/html-lang.ts"],"sourcesContent":["// @ts-nocheck -- Nuxt runtime types are provided at application level\n\nimport { getHTMLTextDir } from '@intlayer/core/localization';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { defineNuxtPlugin } from '#app';\nimport { useRoute } from '#imports';\n\nexport default defineNuxtPlugin((nuxtApp) => {\n nuxtApp.hook('page:finish', () => {\n const locale = useRoute().params.locale as Locale;\n document.documentElement.lang = locale;\n document.documentElement.dir = getHTMLTextDir(locale);\n });\n});\n"],"mappings":";;;;;AAOA,wBAAe,kBAAkB,YAAY;CAC3C,QAAQ,KAAK,qBAAqB;EAChC,MAAM,SAAS,SAAS,EAAE,OAAO;EACjC,SAAS,gBAAgB,OAAO;EAChC,SAAS,gBAAgB,MAAM,eAAe,MAAM;CACtD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"html-lang.mjs","names":[],"sources":["../../../src/runtime/html-lang.ts"],"sourcesContent":["// @ts-nocheck -- Nuxt runtime types are provided at application level\n\nimport { getHTMLTextDir } from '@intlayer/core/localization';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { defineNuxtPlugin } from '#app';\nimport { useRoute } from '#imports';\n\nexport default defineNuxtPlugin((nuxtApp) => {\n nuxtApp.hook('page:finish', () => {\n const locale = useRoute().params.locale as Locale;\n document.documentElement.lang = locale;\n document.documentElement.dir = getHTMLTextDir(locale);\n });\n});\n"],"mappings":";;;;;AAOA,wBAAe,kBAAkB,YAAY;AAC3C,SAAQ,KAAK,qBAAqB;EAChC,MAAM,SAAS,UAAU,CAAC,OAAO;AACjC,WAAS,gBAAgB,OAAO;AAChC,WAAS,gBAAgB,MAAM,eAAe,OAAO;GACrD;EACF"}
@@ -0,0 +1,90 @@
1
+ import { createIntlayerProxyHandler } from "vite-intlayer";
2
+
3
+ //#region src/runtime/intlayer-middleware.ts
4
+ const nodeMiddleware = createIntlayerProxyHandler();
5
+ /**
6
+ * Native h3 v2 event handler for Nitro-powered Nuxt servers.
7
+ *
8
+ * Registered automatically by `nuxt-intlayer` via `addServerHandler` so locale
9
+ * detection, redirects, and rewrites run in both dev and production.
10
+ *
11
+ * Bridges the Web Fetch API event model (h3 v2) to the Node.js-style
12
+ * `createIntlayerProxyHandler` middleware via IncomingMessage / ServerResponse shims.
13
+ * Compatible with ALL Nitro presets — Node, Bun, Deno — where `event.node` may be
14
+ * undefined and `fromNodeMiddleware` (h3 v1 API) would crash.
15
+ *
16
+ * If you need custom Intlayer config or an `ignore` predicate, bypass
17
+ * auto-registration and add your own handler in `server/middleware/intlayerProxy.ts`:
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * // server/middleware/intlayerProxy.ts
22
+ * import type { H3Event } from 'h3';
23
+ * import { createIntlayerProxyHandler } from 'vite-intlayer';
24
+ *
25
+ * const nodeMiddleware = createIntlayerProxyHandler(myConfig, {
26
+ * ignore: (req) => req.url?.startsWith('/api'),
27
+ * });
28
+ *
29
+ * export default async (event: H3Event): Promise<Response | void> => {
30
+ * // ... same shim pattern as this file
31
+ * };
32
+ * ```
33
+ */
34
+ var intlayer_middleware_default = async (event) => new Promise((resolve) => {
35
+ const initialPath = event.path;
36
+ const fakeReq = {
37
+ url: initialPath,
38
+ method: "GET",
39
+ headers: {
40
+ cookie: event.headers.get("cookie") ?? "",
41
+ host: event.headers.get("host") ?? "",
42
+ "accept-language": event.headers.get("accept-language") ?? "",
43
+ "x-forwarded-host": event.headers.get("x-forwarded-host") ?? "",
44
+ "x-forwarded-proto": event.headers.get("x-forwarded-proto") ?? ""
45
+ }
46
+ };
47
+ let responseStatusCode = 200;
48
+ const accumulatedHeaders = {};
49
+ const fakeRes = {
50
+ writeHead(statusCode, headersArg) {
51
+ responseStatusCode = statusCode;
52
+ if (headersArg && typeof headersArg === "object") for (const [key, value] of Object.entries(headersArg)) accumulatedHeaders[key.toLowerCase()] = Array.isArray(value) ? value[0] ?? "" : String(value);
53
+ return fakeRes;
54
+ },
55
+ setHeader(name, value) {
56
+ accumulatedHeaders[name.toLowerCase()] = Array.isArray(value) ? value[0] ?? "" : String(value);
57
+ return fakeRes;
58
+ },
59
+ getHeader(name) {
60
+ return accumulatedHeaders[name.toLowerCase()];
61
+ },
62
+ getHeaders() {
63
+ return { ...accumulatedHeaders };
64
+ },
65
+ end(body) {
66
+ const webHeaders = new Headers();
67
+ for (const [key, value] of Object.entries(accumulatedHeaders)) webHeaders.set(key, value);
68
+ resolve(new Response(responseStatusCode >= 300 && responseStatusCode < 400 ? null : typeof body === "string" ? body : null, {
69
+ status: responseStatusCode,
70
+ headers: webHeaders
71
+ }));
72
+ return fakeRes;
73
+ },
74
+ headersSent: false
75
+ };
76
+ nodeMiddleware(fakeReq, fakeRes, () => {
77
+ const rewrittenPath = fakeReq.url;
78
+ if (rewrittenPath !== initialPath) try {
79
+ event.url = new URL(rewrittenPath, event.url.origin);
80
+ } catch {
81
+ console.error("[intlayer-proxy] URL rewrite failed — invalid path:", rewrittenPath);
82
+ }
83
+ if (Object.keys(accumulatedHeaders).length > 0) for (const [key, value] of Object.entries(accumulatedHeaders)) event.res.headers.set(key, value);
84
+ resolve(void 0);
85
+ });
86
+ });
87
+
88
+ //#endregion
89
+ export { intlayer_middleware_default as default };
90
+ //# sourceMappingURL=intlayer-middleware.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intlayer-middleware.mjs","names":[],"sources":["../../../src/runtime/intlayer-middleware.ts"],"sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http';\nimport { createIntlayerProxyHandler } from 'vite-intlayer';\n\n/**\n * Minimal duck-type for h3 v2's H3Event (same pattern as vite-intlayer's\n * intlayerNitroHandler). We avoid importing from 'h3' so this file compiles\n * without h3 in devDependencies and works with all Nitro presets.\n */\ntype H3EventLike = {\n readonly path: string;\n url: URL;\n readonly headers: Headers;\n readonly res: { readonly headers: Headers };\n};\n\nconst nodeMiddleware = createIntlayerProxyHandler();\n\n/**\n * Native h3 v2 event handler for Nitro-powered Nuxt servers.\n *\n * Registered automatically by `nuxt-intlayer` via `addServerHandler` so locale\n * detection, redirects, and rewrites run in both dev and production.\n *\n * Bridges the Web Fetch API event model (h3 v2) to the Node.js-style\n * `createIntlayerProxyHandler` middleware via IncomingMessage / ServerResponse shims.\n * Compatible with ALL Nitro presets — Node, Bun, Deno — where `event.node` may be\n * undefined and `fromNodeMiddleware` (h3 v1 API) would crash.\n *\n * If you need custom Intlayer config or an `ignore` predicate, bypass\n * auto-registration and add your own handler in `server/middleware/intlayerProxy.ts`:\n *\n * @example\n * ```ts\n * // server/middleware/intlayerProxy.ts\n * import type { H3Event } from 'h3';\n * import { createIntlayerProxyHandler } from 'vite-intlayer';\n *\n * const nodeMiddleware = createIntlayerProxyHandler(myConfig, {\n * ignore: (req) => req.url?.startsWith('/api'),\n * });\n *\n * export default async (event: H3Event): Promise<Response | void> => {\n * // ... same shim pattern as this file\n * };\n * ```\n */\nexport default async (event: H3EventLike): Promise<Response | void> =>\n new Promise<Response | void>((resolve) => {\n const initialPath = event.path;\n\n const fakeReq = {\n url: initialPath,\n method: 'GET',\n headers: {\n cookie: event.headers.get('cookie') ?? '',\n host: event.headers.get('host') ?? '',\n 'accept-language': event.headers.get('accept-language') ?? '',\n 'x-forwarded-host': event.headers.get('x-forwarded-host') ?? '',\n 'x-forwarded-proto': event.headers.get('x-forwarded-proto') ?? '',\n } as Record<string, string>,\n } as unknown as IncomingMessage;\n\n let responseStatusCode = 200;\n const accumulatedHeaders: Record<string, string> = {};\n\n const fakeRes = {\n writeHead(\n statusCode: number,\n headersArg?: Record<string, string | string[] | number> | string\n ) {\n responseStatusCode = statusCode;\n if (headersArg && typeof headersArg === 'object') {\n for (const [key, value] of Object.entries(headersArg)) {\n accumulatedHeaders[key.toLowerCase()] = Array.isArray(value)\n ? (value[0] ?? '')\n : String(value);\n }\n }\n return fakeRes;\n },\n setHeader(name: string, value: string | number | string[]) {\n accumulatedHeaders[name.toLowerCase()] = Array.isArray(value)\n ? (value[0] ?? '')\n : String(value);\n return fakeRes;\n },\n getHeader(name: string) {\n return accumulatedHeaders[name.toLowerCase()];\n },\n getHeaders() {\n return { ...accumulatedHeaders };\n },\n end(body?: string | Buffer | null) {\n const webHeaders = new Headers();\n for (const [key, value] of Object.entries(accumulatedHeaders)) {\n webHeaders.set(key, value);\n }\n const isRedirect =\n responseStatusCode >= 300 && responseStatusCode < 400;\n resolve(\n new Response(\n isRedirect ? null : typeof body === 'string' ? body : null,\n { status: responseStatusCode, headers: webHeaders }\n )\n );\n return fakeRes;\n },\n headersSent: false,\n } as unknown as ServerResponse<IncomingMessage>;\n\n nodeMiddleware(fakeReq, fakeRes, () => {\n const rewrittenPath = fakeReq.url as string;\n\n if (rewrittenPath !== initialPath) {\n // Rewrite: update event.url so event.path reflects the new path for the router.\n try {\n event.url = new URL(rewrittenPath, event.url.origin);\n } catch {\n console.error(\n '[intlayer-proxy] URL rewrite failed — invalid path:',\n rewrittenPath\n );\n }\n }\n\n // Forward Set-Cookie and any other headers to the h3 v2 response.\n if (Object.keys(accumulatedHeaders).length > 0) {\n for (const [key, value] of Object.entries(accumulatedHeaders)) {\n event.res.headers.set(key, value);\n }\n }\n\n resolve(undefined);\n });\n });\n"],"mappings":";;;AAeA,MAAM,iBAAiB,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BnD,kCAAe,OAAO,UACpB,IAAI,SAA0B,YAAY;CACxC,MAAM,cAAc,MAAM;CAE1B,MAAM,UAAU;EACd,KAAK;EACL,QAAQ;EACR,SAAS;GACP,QAAQ,MAAM,QAAQ,IAAI,SAAS,IAAI;GACvC,MAAM,MAAM,QAAQ,IAAI,OAAO,IAAI;GACnC,mBAAmB,MAAM,QAAQ,IAAI,kBAAkB,IAAI;GAC3D,oBAAoB,MAAM,QAAQ,IAAI,mBAAmB,IAAI;GAC7D,qBAAqB,MAAM,QAAQ,IAAI,oBAAoB,IAAI;GAChE;EACF;CAED,IAAI,qBAAqB;CACzB,MAAM,qBAA6C,EAAE;CAErD,MAAM,UAAU;EACd,UACE,YACA,YACA;AACA,wBAAqB;AACrB,OAAI,cAAc,OAAO,eAAe,SACtC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,CACnD,oBAAmB,IAAI,aAAa,IAAI,MAAM,QAAQ,MAAM,GACvD,MAAM,MAAM,KACb,OAAO,MAAM;AAGrB,UAAO;;EAET,UAAU,MAAc,OAAmC;AACzD,sBAAmB,KAAK,aAAa,IAAI,MAAM,QAAQ,MAAM,GACxD,MAAM,MAAM,KACb,OAAO,MAAM;AACjB,UAAO;;EAET,UAAU,MAAc;AACtB,UAAO,mBAAmB,KAAK,aAAa;;EAE9C,aAAa;AACX,UAAO,EAAE,GAAG,oBAAoB;;EAElC,IAAI,MAA+B;GACjC,MAAM,aAAa,IAAI,SAAS;AAChC,QAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,mBAAmB,CAC3D,YAAW,IAAI,KAAK,MAAM;AAI5B,WACE,IAAI,SAFJ,sBAAsB,OAAO,qBAAqB,MAGnC,OAAO,OAAO,SAAS,WAAW,OAAO,MACtD;IAAE,QAAQ;IAAoB,SAAS;IAAY,CACpD,CACF;AACD,UAAO;;EAET,aAAa;EACd;AAED,gBAAe,SAAS,eAAe;EACrC,MAAM,gBAAgB,QAAQ;AAE9B,MAAI,kBAAkB,YAEpB,KAAI;AACF,SAAM,MAAM,IAAI,IAAI,eAAe,MAAM,IAAI,OAAO;UAC9C;AACN,WAAQ,MACN,uDACA,cACD;;AAKL,MAAI,OAAO,KAAK,mBAAmB,CAAC,SAAS,EAC3C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,mBAAmB,CAC3D,OAAM,IAAI,QAAQ,IAAI,KAAK,MAAM;AAIrC,UAAQ,OAAU;GAClB;EACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"intlayer-plugin.mjs","names":[],"sources":["../../../src/runtime/intlayer-plugin.ts"],"sourcesContent":["// @ts-nocheck -- Nuxt runtime types are provided at application level\n\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { createIntlayerClient, installIntlayer } from 'vue-intlayer';\nimport { defineNuxtPlugin } from '#app';\nimport { useRoute } from '#imports';\n\n/**\n * Nuxt client plugin injected by `nuxt-intlayer` module.\n * It installs the Intlayer Vue composables in the current Nuxt application and keeps\n * the active locale in sync with the current route (e.g. `/fr/about` → `fr`).\n */\nexport default defineNuxtPlugin((nuxtApp) => {\n /**\n * Register the Intlayer provider. We don't pass an explicit locale here so it\n * will fallback to the `defaultLocale` defined in the user configuration.\n * We will synchronise the active locale afterwards, once the current route\n * information is reliably available.\n */\n installIntlayer(nuxtApp.vueApp);\n\n // Obtain a reference to the singleton Intlayer client so we can update the\n // locale reactively whenever the route changes.\n const { setLocale } = createIntlayerClient();\n\n const route = useRoute();\n\n // Helper that applies the `:locale` route param (if any) to Intlayer.\n const syncLocale = () => {\n const localeParam = route.params.locale as Locale | undefined;\n if (localeParam) setLocale(localeParam);\n };\n\n // Initial sync (client & server) once the plugin is executed.\n syncLocale();\n\n // Keep Intlayer locale in sync on every navigation.\n nuxtApp.hook('page:start', () => {\n syncLocale();\n });\n});\n"],"mappings":";;;;;;;;;;AAYA,8BAAe,kBAAkB,YAAY;;;;;;;CAO3C,gBAAgB,QAAQ,MAAM;CAI9B,MAAM,EAAE,cAAc,qBAAqB;CAE3C,MAAM,QAAQ,SAAS;CAGvB,MAAM,mBAAmB;EACvB,MAAM,cAAc,MAAM,OAAO;EACjC,IAAI,aAAa,UAAU,WAAW;CACxC;CAGA,WAAW;CAGX,QAAQ,KAAK,oBAAoB;EAC/B,WAAW;CACb,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"intlayer-plugin.mjs","names":[],"sources":["../../../src/runtime/intlayer-plugin.ts"],"sourcesContent":["// @ts-nocheck -- Nuxt runtime types are provided at application level\n\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { createIntlayerClient, installIntlayer } from 'vue-intlayer';\nimport { defineNuxtPlugin } from '#app';\nimport { useRoute } from '#imports';\n\n/**\n * Nuxt client plugin injected by `nuxt-intlayer` module.\n * It installs the Intlayer Vue composables in the current Nuxt application and keeps\n * the active locale in sync with the current route (e.g. `/fr/about` → `fr`).\n */\nexport default defineNuxtPlugin((nuxtApp) => {\n /**\n * Register the Intlayer provider. We don't pass an explicit locale here so it\n * will fallback to the `defaultLocale` defined in the user configuration.\n * We will synchronise the active locale afterwards, once the current route\n * information is reliably available.\n */\n installIntlayer(nuxtApp.vueApp);\n\n // Obtain a reference to the singleton Intlayer client so we can update the\n // locale reactively whenever the route changes.\n const { setLocale } = createIntlayerClient();\n\n const route = useRoute();\n\n // Helper that applies the `:locale` route param (if any) to Intlayer.\n const syncLocale = () => {\n const localeParam = route.params.locale as Locale | undefined;\n if (localeParam) setLocale(localeParam);\n };\n\n // Initial sync (client & server) once the plugin is executed.\n syncLocale();\n\n // Keep Intlayer locale in sync on every navigation.\n nuxtApp.hook('page:start', () => {\n syncLocale();\n });\n});\n"],"mappings":";;;;;;;;;;AAYA,8BAAe,kBAAkB,YAAY;;;;;;;AAO3C,iBAAgB,QAAQ,OAAO;CAI/B,MAAM,EAAE,cAAc,sBAAsB;CAE5C,MAAM,QAAQ,UAAU;CAGxB,MAAM,mBAAmB;EACvB,MAAM,cAAc,MAAM,OAAO;AACjC,MAAI,YAAa,WAAU,YAAY;;AAIzC,aAAY;AAGZ,SAAQ,KAAK,oBAAoB;AAC/B,cAAY;GACZ;EACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","names":[],"sources":["../../src/module.ts"],"mappings":";;;;;AAuBA;;;;AAsGE;;;;;;;;;;;cAtGW,MAAA,EAAQ,UAsGnB"}
1
+ {"version":3,"file":"module.d.ts","names":[],"sources":["../../src/module.ts"],"mappings":";;;;;AAuBA;;;;;;;;;;;;;;;cAAa,MAAA,EAAQ,UAAA"}
@@ -0,0 +1,47 @@
1
+ //#region src/runtime/intlayer-middleware.d.ts
2
+ /**
3
+ * Minimal duck-type for h3 v2's H3Event (same pattern as vite-intlayer's
4
+ * intlayerNitroHandler). We avoid importing from 'h3' so this file compiles
5
+ * without h3 in devDependencies and works with all Nitro presets.
6
+ */
7
+ type H3EventLike = {
8
+ readonly path: string;
9
+ url: URL;
10
+ readonly headers: Headers;
11
+ readonly res: {
12
+ readonly headers: Headers;
13
+ };
14
+ };
15
+ /**
16
+ * Native h3 v2 event handler for Nitro-powered Nuxt servers.
17
+ *
18
+ * Registered automatically by `nuxt-intlayer` via `addServerHandler` so locale
19
+ * detection, redirects, and rewrites run in both dev and production.
20
+ *
21
+ * Bridges the Web Fetch API event model (h3 v2) to the Node.js-style
22
+ * `createIntlayerProxyHandler` middleware via IncomingMessage / ServerResponse shims.
23
+ * Compatible with ALL Nitro presets — Node, Bun, Deno — where `event.node` may be
24
+ * undefined and `fromNodeMiddleware` (h3 v1 API) would crash.
25
+ *
26
+ * If you need custom Intlayer config or an `ignore` predicate, bypass
27
+ * auto-registration and add your own handler in `server/middleware/intlayerProxy.ts`:
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * // server/middleware/intlayerProxy.ts
32
+ * import type { H3Event } from 'h3';
33
+ * import { createIntlayerProxyHandler } from 'vite-intlayer';
34
+ *
35
+ * const nodeMiddleware = createIntlayerProxyHandler(myConfig, {
36
+ * ignore: (req) => req.url?.startsWith('/api'),
37
+ * });
38
+ *
39
+ * export default async (event: H3Event): Promise<Response | void> => {
40
+ * // ... same shim pattern as this file
41
+ * };
42
+ * ```
43
+ */
44
+ declare const _default: (event: H3EventLike) => Promise<Response | void>;
45
+ //#endregion
46
+ export { _default as default };
47
+ //# sourceMappingURL=intlayer-middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intlayer-middleware.d.ts","names":[],"sources":["../../../src/runtime/intlayer-middleware.ts"],"mappings":";;;;;;KAQK,WAAA;EAAA,SACM,IAAA;EACT,GAAA,EAAK,GAAA;EAAA,SACI,OAAA,EAAS,OAAA;EAAA,SACT,GAAA;IAAA,SAAgB,OAAA,EAAS,OAAA;EAAA;AAAA;;;;;;;AAAO;;;;;;;;;;;;;;;;;;;;;;;cAAA,QAAA,GAkCrB,KAAA,EAAO,WAAA,KAAc,OAAA,CAAQ,QAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-intlayer",
3
- "version": "8.12.1",
3
+ "version": "8.12.3",
4
4
  "private": false,
5
5
  "description": "Easily internationalize i18n your Nuxt applications with type-safe multilingual content management.",
6
6
  "keywords": [
@@ -77,20 +77,20 @@
77
77
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
78
78
  },
79
79
  "dependencies": {
80
- "@intlayer/config": "8.12.1",
81
- "@intlayer/core": "8.12.1",
82
- "@intlayer/types": "8.12.1",
83
- "vite-intlayer": "8.12.1",
84
- "vue-intlayer": "8.12.1"
80
+ "@intlayer/config": "8.12.3",
81
+ "@intlayer/core": "8.12.3",
82
+ "@intlayer/types": "8.12.3",
83
+ "vite-intlayer": "8.12.3",
84
+ "vue-intlayer": "8.12.3"
85
85
  },
86
86
  "devDependencies": {
87
- "@types/node": "25.9.1",
87
+ "@types/node": "25.9.2",
88
88
  "@utils/ts-config": "1.0.4",
89
89
  "@utils/ts-config-types": "1.0.4",
90
90
  "@utils/tsdown-config": "1.0.4",
91
91
  "fast-glob": "3.3.3",
92
92
  "rimraf": "6.1.3",
93
- "tsdown": "0.22.1",
93
+ "tsdown": "0.21.10",
94
94
  "typescript": "6.0.3",
95
95
  "vitest": "4.1.8"
96
96
  },