@fluenti/nuxt 0.4.0-rc.4 → 0.6.0

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.
Files changed (81) hide show
  1. package/README.md +8 -2
  2. package/dist/module.cjs +1 -1
  3. package/dist/module.cjs.map +1 -1
  4. package/dist/module.js +36 -41
  5. package/dist/module.js.map +1 -1
  6. package/dist/packages/nuxt/src/devtools.d.ts.map +1 -0
  7. package/dist/packages/nuxt/src/isr-validation.d.ts.map +1 -0
  8. package/dist/{module.d.ts → packages/nuxt/src/module.d.ts} +11 -3
  9. package/dist/packages/nuxt/src/module.d.ts.map +1 -0
  10. package/dist/packages/nuxt/src/page-meta-transform.d.ts.map +1 -0
  11. package/dist/packages/nuxt/src/runtime/client.d.ts.map +1 -0
  12. package/dist/packages/nuxt/src/runtime/components/NuxtLinkLocale.d.ts.map +1 -0
  13. package/dist/{runtime → packages/nuxt/src/runtime}/composables.d.ts +8 -8
  14. package/dist/packages/nuxt/src/runtime/composables.d.ts.map +1 -0
  15. package/dist/packages/nuxt/src/runtime/define-i18n-route.d.ts.map +1 -0
  16. package/dist/packages/nuxt/src/runtime/detectors/cookie.d.ts.map +1 -0
  17. package/dist/packages/nuxt/src/runtime/detectors/domain.d.ts.map +1 -0
  18. package/dist/packages/nuxt/src/runtime/detectors/header.d.ts.map +1 -0
  19. package/dist/packages/nuxt/src/runtime/detectors/index.d.ts.map +1 -0
  20. package/dist/packages/nuxt/src/runtime/detectors/path.d.ts.map +1 -0
  21. package/dist/packages/nuxt/src/runtime/detectors/query.d.ts.map +1 -0
  22. package/dist/packages/nuxt/src/runtime/index.d.ts.map +1 -0
  23. package/dist/packages/nuxt/src/runtime/locale-head.d.ts.map +1 -0
  24. package/dist/packages/nuxt/src/runtime/middleware/locale-redirect.d.ts.map +1 -0
  25. package/dist/packages/nuxt/src/runtime/page-extend.d.ts.map +1 -0
  26. package/dist/packages/nuxt/src/runtime/path-utils.d.ts.map +1 -0
  27. package/dist/packages/nuxt/src/runtime/plugin.d.ts.map +1 -0
  28. package/dist/packages/nuxt/src/runtime/server/locale-redirect.d.ts.map +1 -0
  29. package/dist/packages/nuxt/src/runtime/standalone-composables.d.ts.map +1 -0
  30. package/dist/packages/nuxt/src/runtime/utils/parse-accept-language.d.ts.map +1 -0
  31. package/dist/packages/nuxt/src/sitemap.d.ts.map +1 -0
  32. package/dist/{types.d.ts → packages/nuxt/src/types.d.ts} +3 -3
  33. package/dist/packages/nuxt/src/types.d.ts.map +1 -0
  34. package/package.json +10 -10
  35. package/dist/devtools.d.ts.map +0 -1
  36. package/dist/isr-validation.d.ts.map +0 -1
  37. package/dist/module.d.ts.map +0 -1
  38. package/dist/page-meta-transform.d.ts.map +0 -1
  39. package/dist/runtime/client.d.ts.map +0 -1
  40. package/dist/runtime/components/NuxtLinkLocale.d.ts.map +0 -1
  41. package/dist/runtime/composables.d.ts.map +0 -1
  42. package/dist/runtime/define-i18n-route.d.ts.map +0 -1
  43. package/dist/runtime/detectors/cookie.d.ts.map +0 -1
  44. package/dist/runtime/detectors/domain.d.ts.map +0 -1
  45. package/dist/runtime/detectors/header.d.ts.map +0 -1
  46. package/dist/runtime/detectors/index.d.ts.map +0 -1
  47. package/dist/runtime/detectors/path.d.ts.map +0 -1
  48. package/dist/runtime/detectors/query.d.ts.map +0 -1
  49. package/dist/runtime/index.d.ts.map +0 -1
  50. package/dist/runtime/locale-head.d.ts.map +0 -1
  51. package/dist/runtime/middleware/locale-redirect.d.ts.map +0 -1
  52. package/dist/runtime/page-extend.d.ts.map +0 -1
  53. package/dist/runtime/path-utils.d.ts.map +0 -1
  54. package/dist/runtime/plugin.d.ts.map +0 -1
  55. package/dist/runtime/server/locale-redirect.d.ts.map +0 -1
  56. package/dist/runtime/standalone-composables.d.ts.map +0 -1
  57. package/dist/runtime/utils/parse-accept-language.d.ts.map +0 -1
  58. package/dist/sitemap.d.ts.map +0 -1
  59. package/dist/types.d.ts.map +0 -1
  60. /package/dist/{devtools.d.ts → packages/nuxt/src/devtools.d.ts} +0 -0
  61. /package/dist/{isr-validation.d.ts → packages/nuxt/src/isr-validation.d.ts} +0 -0
  62. /package/dist/{page-meta-transform.d.ts → packages/nuxt/src/page-meta-transform.d.ts} +0 -0
  63. /package/dist/{runtime → packages/nuxt/src/runtime}/client.d.ts +0 -0
  64. /package/dist/{runtime → packages/nuxt/src/runtime}/components/NuxtLinkLocale.d.ts +0 -0
  65. /package/dist/{runtime → packages/nuxt/src/runtime}/define-i18n-route.d.ts +0 -0
  66. /package/dist/{runtime → packages/nuxt/src/runtime}/detectors/cookie.d.ts +0 -0
  67. /package/dist/{runtime → packages/nuxt/src/runtime}/detectors/domain.d.ts +0 -0
  68. /package/dist/{runtime → packages/nuxt/src/runtime}/detectors/header.d.ts +0 -0
  69. /package/dist/{runtime → packages/nuxt/src/runtime}/detectors/index.d.ts +0 -0
  70. /package/dist/{runtime → packages/nuxt/src/runtime}/detectors/path.d.ts +0 -0
  71. /package/dist/{runtime → packages/nuxt/src/runtime}/detectors/query.d.ts +0 -0
  72. /package/dist/{runtime → packages/nuxt/src/runtime}/index.d.ts +0 -0
  73. /package/dist/{runtime → packages/nuxt/src/runtime}/locale-head.d.ts +0 -0
  74. /package/dist/{runtime → packages/nuxt/src/runtime}/middleware/locale-redirect.d.ts +0 -0
  75. /package/dist/{runtime → packages/nuxt/src/runtime}/page-extend.d.ts +0 -0
  76. /package/dist/{runtime → packages/nuxt/src/runtime}/path-utils.d.ts +0 -0
  77. /package/dist/{runtime → packages/nuxt/src/runtime}/plugin.d.ts +0 -0
  78. /package/dist/{runtime → packages/nuxt/src/runtime}/server/locale-redirect.d.ts +0 -0
  79. /package/dist/{runtime → packages/nuxt/src/runtime}/standalone-composables.d.ts +0 -0
  80. /package/dist/{runtime → packages/nuxt/src/runtime}/utils/parse-accept-language.d.ts +0 -0
  81. /package/dist/{sitemap.d.ts → packages/nuxt/src/sitemap.d.ts} +0 -0
package/README.md CHANGED
@@ -91,14 +91,20 @@ For rich text with embedded HTML and components:
91
91
 
92
92
  ### Template Literal Tag
93
93
 
94
- Use `` t`...` `` in script and template expressions:
94
+ Use direct-import `` t`...` `` in script expressions:
95
95
 
96
96
  ```vue
97
97
  <script setup>
98
- const { t } = useI18n()
98
+ import { computed } from 'vue'
99
+ import { t } from '@fluenti/vue'
100
+
99
101
  const greeting = computed(() => t`Hello, {name}!`)
100
102
  </script>
103
+ ```
101
104
 
105
+ Use `` t`...` `` directly in templates:
106
+
107
+ ```vue
102
108
  <template>
103
109
  <p>{{ t`You have {count, plural, one {# item} other {# items}}` }}</p>
104
110
  </template>
package/dist/module.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=require(`./page-extend-DqTELmU6.cjs`),l=require(`./path-utils-BQIsp_or.cjs`),u=require(`./locale-head-jGmp0Xnb.cjs`),d=require(`./runtime/standalone-composables.cjs`),f=require(`./runtime/define-i18n-route.cjs`);let p=require(`@nuxt/kit`),m=require(`node:module`),h=require(`@fluenti/core/internal`),g=require(`@fluenti/vue/vite-plugin`);g=s(g);function _(e){let t={};for(let n of e)typeof n==`string`?t[n]={code:n}:t[n.code]=n;return t}function v(e,t){if(t?.length)return t;let n=[];for(let t of e)typeof t!=`string`&&t.domain&&n.push({domain:t.domain,locale:t.code});return n}function y(e,t,n){let r=[];if(!e?.enabled)return r;let i=n.filter(e=>e===`cookie`||e===`header`);return i.length>0&&r.push({level:`warn`,message:`[@fluenti/nuxt] ISR is enabled but detectOrder includes non-path detectors (${i.join(`, `)}). ISR caches by URL path, so cookie/header-based detection may serve the wrong locale from cache. Consider using detectOrder: ['path'] with ISR.`}),t===`no_prefix`&&r.push({level:`warn`,message:`[@fluenti/nuxt] ISR is enabled with strategy: 'no_prefix'. All locales share the same URL path, so ISR will cache only one locale per URL. Use 'prefix' or 'prefix_except_default' strategy with ISR.`}),r}function b(e,t,n,r){try{e.hook(`devtools:customTabs`,e=>{e.push({name:`fluenti`,title:`Fluenti i18n`,icon:`i-carbon-translate`,view:{type:`client-component`,componentName:`FluentiDevToolsPanel`}})})}catch{}e.hook(`nitro:config`,e=>{let i=e.runtimeConfig;if(i){let e=(i.public??={}).fluenti??{};e.devtools={enabled:!0,locales:t,defaultLocale:n,strategy:r}}})}function x(){return{name:`fluenti:page-meta-transform`,enforce:`pre`,transform(e,t){if(!t.includes(`/pages/`)&&!t.includes(`\\pages\\`)||!e.includes(`defineI18nRoute`)&&!e.includes(`i18n`))return null;let n=e;return n.includes(`defineI18nRoute`)&&(n=n.replace(/defineI18nRoute\s*\(([^)]*?)\)/g,(e,t)=>`definePageMeta({ i18nRoute: ${t.trim()} })`)),n.includes(`definePageMeta`)&&n.includes(`i18n:`)&&(n=n.replace(/(definePageMeta\s*\(\s*\{[^}]*?)\bi18n\s*:/g,`$1i18nRoute:`)),n===e?null:{code:n,map:null}}}}function S(e,t,n,r,i){let a=[],o=i??``;for(let i of e){let e=i.startsWith(`/`)?i:`/${i}`;for(let i of t){let s=C(e,i,n,r),c=t.map(t=>({hreflang:t,href:`${o}${C(e,t,n,r)}`}));c.push({hreflang:`x-default`,href:`${o}${C(e,n,n,r)}`}),a.push({loc:`${o}${s}`,alternatives:c})}}return a}function C(e,t,n,r){return r===`no_prefix`||r===`prefix_except_default`&&t===n?e:`/${t}${e===`/`?``:e}`}function w(e,t,n,r){return i=>{if(n===`no_prefix`)return i;let a=[];for(let o of i){let i=o.loc.replace(/^https?:\/\/[^/]+/,``);for(let o of e){let s=C(i,o,t,n),c=e.map(e=>({hreflang:e,href:`${r??``}${C(i,e,t,n)}`}));c.push({hreflang:`x-default`,href:`${r??``}${C(i,t,t,n)}`}),a.push({loc:`${r??``}${s}`,alternatives:c})}}return a}}var T=`@fluenti/nuxt`,E=`fluenti`,D=(0,m.createRequire)(typeof __filename<`u`?__filename:{}.url);function O(e,t){if(typeof e==`object`){let{DEFAULT_FLUENTI_CONFIG:t}=D(`@fluenti/core/config`);return{...t,...e}}let{loadConfigSync:n}=D(`@fluenti/core/config`);return n(typeof e==`string`?e:void 0,t)}var k=(0,p.defineNuxtModule)({meta:{name:T,configKey:E,compatibility:{nuxt:`>=3.0.0`}},defaults:{strategy:`prefix_except_default`},setup(e,t){let{resolve:n}=(0,p.createResolver)({}.url),r=t.options.rootDir??process.cwd(),i=O(e.config,r);e.locales&&(i.locales=e.locales),e.defaultLocale&&(i.defaultLocale=e.defaultLocale),e.sourceLocale&&(i.sourceLocale=e.sourceLocale),e.catalogDir&&(i.catalogDir=e.catalogDir);let a=(0,h.resolveLocaleCodes)(i.locales),o=_(i.locales),s=i.defaultLocale??i.sourceLocale,l=e.strategy===`domains`?v(i.locales,e.domains):void 0,u=e.detectOrder??(e.strategy===`domains`?[`domain`,`cookie`,`header`]:[`path`,`cookie`,`header`]);t.options.runtimeConfig.public.fluenti={locales:a,defaultLocale:s,strategy:e.strategy??`prefix_except_default`,detectBrowserLanguage:e.detectBrowserLanguage,detectOrder:u,queryParamKey:e.queryParamKey??`locale`,injectGlobalProperties:e.injectGlobalProperties!==!1,...l?{domains:l}:{},localeProperties:o},e.autoVitePlugin!==!1&&(t.options.vite=t.options.vite||{},t.options.vite.plugins=t.options.vite.plugins||[],t.options.vite.plugins.push(...(0,g.default)({config:i}))),e.pageMetaTransform!==!1&&(t.options.vite=t.options.vite||{},t.options.vite.plugins=t.options.vite.plugins||[],t.options.vite.plugins.push(x())),(0,p.addPlugin)({src:n(`./runtime/plugin`),mode:`all`});let d=e.strategy??`prefix_except_default`;d!==`no_prefix`&&d!==`domains`&&e.extendRoutes!==!1&&t.hook(`pages:extend`,t=>{c.t(t,{locales:a,defaultLocale:s,strategy:d,...e.routeNameTemplate?{routeNameTemplate:e.routeNameTemplate}:{},...e.routeOverrides?{routeOverrides:e.routeOverrides}:{},...e.routeMode?{routeMode:e.routeMode}:{}})}),d===`prefix`&&(0,p.addRouteMiddleware)({name:`fluenti-locale-redirect`,path:n(`./runtime/middleware/locale-redirect`),global:e.globalMiddleware!==!1}),e.autoImports!==!1&&(0,p.addImports)([{name:`useLocalePath`,from:n(`./runtime/composables`)},{name:`useSwitchLocalePath`,from:n(`./runtime/composables`)},{name:`useLocaleRoute`,from:n(`./runtime/composables`)},{name:`useLocaleHead`,from:n(`./runtime/composables`)},{name:`useI18nScoped`,from:n(`./runtime/composables`)},{name:`useI18n`,from:`@fluenti/vue`},{name:`defineI18nRoute`,from:n(`./runtime/define-i18n-route`)}]);let f=e.componentPrefix??``;if(e.registerNuxtLinkLocale!==!1&&(0,p.addComponent)({name:`${f}NuxtLinkLocale`,filePath:n(`./runtime/components/NuxtLinkLocale`)}),(0,p.addComponent)({name:`${f}Trans`,filePath:`@fluenti/vue/components`,export:`Trans`}),(0,p.addComponent)({name:`${f}Plural`,filePath:`@fluenti/vue/components`,export:`Plural`}),(0,p.addComponent)({name:`${f}Select`,filePath:`@fluenti/vue/components`,export:`Select`}),(0,p.addComponent)({name:`${f}DateTime`,filePath:`@fluenti/vue/components`,export:`DateTime`}),(0,p.addComponent)({name:`${f}NumberFormat`,filePath:`@fluenti/vue/components`,export:`NumberFormat`}),d!==`no_prefix`&&d!==`domains`){let n=t.options,r=n.nitro??={},i=r.prerender??={};i.crawlLinks=i.crawlLinks??!0,d===`prefix`&&(i.routes=(i.routes??[`/`]).map(e=>e===`/`?`/${s}`:e));for(let t of y(e.isr,d,u))console.warn(t.message);if(e.isr?.enabled){let t=n.routeRules??={},r=e.isr.ttl??3600;for(let e of a)e===s&&d===`prefix_except_default`?t[`/**`]={...t[`/**`],isr:r}:t[`/${e}/**`]={...t[`/${e}/**`],isr:r}}}t.options.dev&&b(t,a,s,d),(d===`prefix`||d===`prefix_and_default`)&&(0,p.addServerHandler)({handler:n(`./runtime/server/locale-redirect`),middleware:!0})}});exports.CONFIG_KEY=E,exports.MODULE_NAME=T,exports.buildLocaleHead=u.t,exports.createSitemapHook=w,exports.default=k,exports.defineI18nRoute=f.defineI18nRoute,exports.extendPages=c.t,exports.extractLocaleFromPath=l.t,exports.generateSitemapUrls=S,exports.localePath=l.n,exports.resolveDomainConfigs=v,Object.defineProperty(exports,`resolveLocaleCodes`,{enumerable:!0,get:function(){return h.resolveLocaleCodes}}),exports.resolveLocaleProperties=_,exports.switchLocalePath=l.r,exports.t=s,exports.useLocaleHead=d.useLocaleHead,exports.useLocalePath=d.useLocalePath,exports.useLocaleRoute=d.useLocaleRoute,exports.useSwitchLocalePath=d.useSwitchLocalePath;
1
+ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=require(`./page-extend-DqTELmU6.cjs`),l=require(`./path-utils-BQIsp_or.cjs`),u=require(`./locale-head-jGmp0Xnb.cjs`),d=require(`./runtime/standalone-composables.cjs`),f=require(`./runtime/define-i18n-route.cjs`);let p=require(`@nuxt/kit`),m=require(`@fluenti/core/compiler`),h=require(`@fluenti/core/config`),g=require(`@fluenti/vue/vite-plugin`);g=s(g);function _(e){let t={};for(let n of e)typeof n==`string`?t[n]={code:n}:t[n.code]=n;return t}function v(e,t){if(t?.length)return t;let n=[];for(let t of e)typeof t!=`string`&&t.domain&&n.push({domain:t.domain,locale:t.code});return n}function y(e,t,n){let r=[];if(!e?.enabled)return r;let i=n.filter(e=>e===`cookie`||e===`header`);return i.length>0&&r.push({level:`warn`,message:`[@fluenti/nuxt] ISR is enabled but detectOrder includes non-path detectors (${i.join(`, `)}). ISR caches by URL path, so cookie/header-based detection may serve the wrong locale from cache. Consider using detectOrder: ['path'] with ISR.`}),t===`no_prefix`&&r.push({level:`warn`,message:`[@fluenti/nuxt] ISR is enabled with strategy: 'no_prefix'. All locales share the same URL path, so ISR will cache only one locale per URL. Use 'prefix' or 'prefix_except_default' strategy with ISR.`}),r}function b(e,t,n,r){try{e.hook(`devtools:customTabs`,e=>{e.push({name:`fluenti`,title:`Fluenti i18n`,icon:`i-carbon-translate`,view:{type:`client-component`,componentName:`FluentiDevToolsPanel`}})})}catch{}e.hook(`nitro:config`,e=>{let i=e.runtimeConfig;if(i){let e=(i.public??={}).fluenti??{};e.devtools={enabled:!0,locales:t,defaultLocale:n,strategy:r}}})}function x(){return{name:`fluenti:page-meta-transform`,enforce:`pre`,transform(e,t){if(!t.includes(`/pages/`)&&!t.includes(`\\pages\\`)||!e.includes(`defineI18nRoute`)&&!e.includes(`i18n`))return null;let n=e;return n.includes(`defineI18nRoute`)&&(n=n.replace(/defineI18nRoute\s*\(([^)]*?)\)/g,(e,t)=>`definePageMeta({ i18nRoute: ${t.trim()} })`)),n.includes(`definePageMeta`)&&n.includes(`i18n:`)&&(n=n.replace(/(definePageMeta\s*\(\s*\{[^}]*?)\bi18n\s*:/g,`$1i18nRoute:`)),n===e?null:{code:n,map:null}}}}function S(e,t,n,r,i){let a=[],o=i??``;for(let i of e){let e=i.startsWith(`/`)?i:`/${i}`;for(let i of t){let s=C(e,i,n,r),c=t.map(t=>({hreflang:t,href:`${o}${C(e,t,n,r)}`}));c.push({hreflang:`x-default`,href:`${o}${C(e,n,n,r)}`}),a.push({loc:`${o}${s}`,alternatives:c})}}return a}function C(e,t,n,r){return r===`no_prefix`||r===`prefix_except_default`&&t===n?e:`/${t}${e===`/`?``:e}`}function w(e,t,n,r){return i=>{if(n===`no_prefix`)return i;let a=[];for(let o of i){let i=o.loc.replace(/^https?:\/\/[^/]+/,``);for(let o of e){let s=C(i,o,t,n),c=e.map(e=>({hreflang:e,href:`${r??``}${C(i,e,t,n)}`}));c.push({hreflang:`x-default`,href:`${r??``}${C(i,t,t,n)}`}),a.push({loc:`${r??``}${s}`,alternatives:c})}}return a}}var T=`@fluenti/nuxt`,E=`fluenti`;function D(e,t){return typeof e==`object`?{...h.DEFAULT_FLUENTI_CONFIG,...e}:(0,h.loadConfigSync)(typeof e==`string`?e:void 0,t)}var O=(0,p.defineNuxtModule)({meta:{name:T,configKey:E,compatibility:{nuxt:`>=3.0.0`}},defaults:{strategy:`prefix_except_default`},setup(e,t){let{resolve:n}=(0,p.createResolver)({}.url),r=t.options.rootDir??process.cwd(),i=D(e.config,r);e.locales&&(i.locales=e.locales),e.defaultLocale&&(i.defaultLocale=e.defaultLocale),e.sourceLocale&&(i.sourceLocale=e.sourceLocale),e.catalogDir&&(i.catalogDir=e.catalogDir);let a=(0,m.resolveLocaleCodes)(i.locales),o=_(i.locales),s=i.defaultLocale??i.sourceLocale,l=e.strategy===`domains`?v(i.locales,e.domains):void 0,u=e.detectOrder??(e.strategy===`domains`?[`domain`,`cookie`,`header`]:[`path`,`cookie`,`header`]);t.options.runtimeConfig.public.fluenti={locales:a,defaultLocale:s,strategy:e.strategy??`prefix_except_default`,detectBrowserLanguage:e.detectBrowserLanguage,detectOrder:u,queryParamKey:e.queryParamKey??`locale`,injectGlobalProperties:e.injectGlobalProperties!==!1,...l?{domains:l}:{},localeProperties:o},e.autoVitePlugin!==!1&&(t.options.vite=t.options.vite||{},t.options.vite.plugins=t.options.vite.plugins||[],t.options.vite.plugins.push(...(0,g.default)({config:i}))),e.pageMetaTransform!==!1&&(t.options.vite=t.options.vite||{},t.options.vite.plugins=t.options.vite.plugins||[],t.options.vite.plugins.push(x())),(0,p.addPlugin)({src:n(`./runtime/plugin`),mode:`all`});let d=e.strategy??`prefix_except_default`;d!==`no_prefix`&&d!==`domains`&&e.extendRoutes!==!1&&t.hook(`pages:extend`,t=>{c.t(t,{locales:a,defaultLocale:s,strategy:d,...e.routeNameTemplate?{routeNameTemplate:e.routeNameTemplate}:{},...e.routeOverrides?{routeOverrides:e.routeOverrides}:{},...e.routeMode?{routeMode:e.routeMode}:{}})}),d===`prefix`&&(0,p.addRouteMiddleware)({name:`fluenti-locale-redirect`,path:n(`./runtime/middleware/locale-redirect`),global:e.globalMiddleware!==!1}),e.autoImports!==!1&&(0,p.addImports)([{name:`useLocalePath`,from:n(`./runtime/composables`)},{name:`useSwitchLocalePath`,from:n(`./runtime/composables`)},{name:`useLocaleRoute`,from:n(`./runtime/composables`)},{name:`useLocaleHead`,from:n(`./runtime/composables`)},{name:`useI18nScoped`,from:n(`./runtime/composables`)},{name:`useI18n`,from:`@fluenti/vue`},{name:`defineI18nRoute`,from:n(`./runtime/define-i18n-route`)}]);let f=e.componentPrefix??``;if(e.registerNuxtLinkLocale!==!1&&(0,p.addComponent)({name:`${f}NuxtLinkLocale`,filePath:n(`./runtime/components/NuxtLinkLocale`)}),(0,p.addComponent)({name:`${f}Trans`,filePath:`@fluenti/vue/components`,export:`Trans`}),(0,p.addComponent)({name:`${f}Plural`,filePath:`@fluenti/vue/components`,export:`Plural`}),(0,p.addComponent)({name:`${f}Select`,filePath:`@fluenti/vue/components`,export:`Select`}),(0,p.addComponent)({name:`${f}DateTime`,filePath:`@fluenti/vue/components`,export:`DateTime`}),(0,p.addComponent)({name:`${f}NumberFormat`,filePath:`@fluenti/vue/components`,export:`NumberFormat`}),d!==`no_prefix`&&d!==`domains`){let n=t.options,r=n.nitro??={},i=r.prerender??={};i.crawlLinks=i.crawlLinks??!0,d===`prefix`&&(i.routes=(i.routes??[`/`]).map(e=>e===`/`?`/${s}`:e));for(let t of y(e.isr,d,u))console.warn(t.message);if(e.isr?.enabled){let t=n.routeRules??={},r=e.isr.ttl??3600;for(let e of a)e===s&&d===`prefix_except_default`?t[`/**`]={...t[`/**`],isr:r}:t[`/${e}/**`]={...t[`/${e}/**`],isr:r}}}t.options.dev&&b(t,a,s,d),(d===`prefix`||d===`prefix_and_default`)&&(0,p.addServerHandler)({handler:n(`./runtime/server/locale-redirect`),middleware:!0})}});exports.CONFIG_KEY=E,exports.MODULE_NAME=T,exports.buildLocaleHead=u.t,exports.createSitemapHook=w,exports.default=O,exports.defineI18nRoute=f.defineI18nRoute,exports.extendPages=c.t,exports.extractLocaleFromPath=l.t,exports.generateSitemapUrls=S,exports.localePath=l.n,exports.resolveDomainConfigs=v,Object.defineProperty(exports,`resolveLocaleCodes`,{enumerable:!0,get:function(){return m.resolveLocaleCodes}}),exports.resolveLocaleProperties=_,exports.switchLocalePath=l.r,exports.t=s,exports.useLocaleHead=d.useLocaleHead,exports.useLocalePath=d.useLocalePath,exports.useLocaleRoute=d.useLocaleRoute,exports.useSwitchLocalePath=d.useSwitchLocalePath;
2
2
  //# sourceMappingURL=module.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"module.cjs","names":[],"sources":["../src/types.ts","../src/isr-validation.ts","../src/devtools.ts","../src/page-meta-transform.ts","../src/sitemap.ts","../src/module.ts"],"sourcesContent":["import type { FluentiBuildConfig } from '@fluenti/core/internal'\nimport { resolveLocaleCodes } from '@fluenti/core/internal'\n// Re-export core types for backwards compatibility\nexport type { LocaleObject, LocaleDefinition } from '@fluenti/core'\nexport { resolveLocaleCodes }\n\n// Import core types needed locally\nimport type { LocaleDefinition, LocaleObject } from '@fluenti/core'\n\n/** Routing strategy for locale-prefixed URLs */\nexport type Strategy = 'prefix' | 'prefix_except_default' | 'prefix_and_default' | 'no_prefix' | 'domains'\n\n/** Browser language detection options */\nexport interface DetectBrowserLanguageOptions {\n /** Use a cookie to persist the detected locale */\n useCookie?: boolean\n /** Cookie key name (default: 'fluenti_locale') */\n cookieKey?: string\n /** Fallback locale when detection fails */\n fallbackLocale?: string\n}\n\n/** Built-in detector names */\nexport type BuiltinDetector = 'path' | 'cookie' | 'header' | 'query' | 'domain'\n\n/**\n * Context passed to locale detectors and the `fluenti:detect-locale` hook.\n *\n * Detectors inspect the context and call `setLocale()` to claim a locale.\n * Once a locale is set, subsequent detectors are skipped.\n */\nexport interface LocaleDetectContext {\n /** The request path (e.g. '/ja/about') */\n path: string\n /** Available locale codes */\n locales: string[]\n /** Default locale */\n defaultLocale: string\n /** Routing strategy */\n strategy: Strategy\n /** detectBrowserLanguage config */\n detectBrowserLanguage?: DetectBrowserLanguageOptions\n /** The detected locale so far (null if not yet detected) */\n detectedLocale: string | null\n /** Set the locale and stop the detection chain */\n setLocale: (locale: string) => void\n /** Whether we are running on the server */\n isServer: boolean\n /** The request hostname (available when `strategy: 'domains'`) */\n host?: string\n /** Pre-read cookie value (hoisted before await in plugin) */\n cookieValue?: string | null\n /** Pre-read Accept-Language header (hoisted before await in plugin) */\n acceptLanguage?: string\n}\n\n/**\n * A locale detector function.\n *\n * Can be sync or async. Call `ctx.setLocale(locale)` to claim a locale.\n */\nexport type LocaleDetectorFn = (ctx: LocaleDetectContext) => void | Promise<void>\n\n/**\n * Per-page locale configuration.\n *\n * Restricts which locales a page supports. Routes will only be generated\n * for the specified locales.\n *\n * @example\n * ```ts\n * // In a page component's <script setup>\n * defineI18nRoute({ locales: ['en', 'ja'] }) // only en and ja for this page\n * defineI18nRoute(false) // disable i18n for this page\n * ```\n */\nexport type I18nRouteConfig = { locales: string[] } | false\n\n/** Domain-to-locale mapping for the `'domains'` strategy */\nexport interface DomainConfig {\n /** Domain hostname (e.g. 'example.jp', 'ja.example.com') */\n domain: string\n /** Locale code for this domain */\n locale: string\n /** Whether this is the default domain (used for x-default hreflang) */\n defaultForLocale?: boolean\n}\n\n/** @fluenti/nuxt module options (set in nuxt.config.ts under `fluenti` key) */\nexport interface FluentNuxtOptions {\n /** fluenti.config.ts path or inline config */\n config?: string | FluentiBuildConfig\n\n // ---- Core overrides (take precedence over fluenti.config.ts) ----\n\n /** Override locales from fluenti.config.ts */\n locales?: FluentiBuildConfig['locales']\n /** Override defaultLocale from fluenti.config.ts */\n defaultLocale?: string\n /** Override sourceLocale from fluenti.config.ts */\n sourceLocale?: string\n /** Override catalogDir from fluenti.config.ts */\n catalogDir?: string\n\n // ---- Nuxt-specific: routing, detection, components ----\n\n /** URL routing strategy */\n strategy?: Strategy\n /** Browser language detection settings */\n detectBrowserLanguage?: DetectBrowserLanguageOptions\n /**\n * Ordered list of locale detectors.\n *\n * Each entry is either a built-in detector name ('path', 'cookie', 'header', 'query', 'domain')\n * or a file path to a custom detector module (e.g. '~/detectors/jwt-detector').\n *\n * Detectors run in order; the first one to call `ctx.setLocale()` wins.\n *\n * @default ['path', 'cookie', 'header']\n */\n detectOrder?: Array<BuiltinDetector | string>\n /**\n * Query parameter name for locale detection (e.g. `?lang=ja`).\n *\n * @default 'locale'\n */\n queryParamKey?: string\n /**\n * Prefix for globally registered i18n components (Trans, Plural, Select, DateTime, NumberFormat).\n *\n * Use this to avoid naming conflicts with other libraries.\n *\n * @example 'I18n' // → I18nTrans, I18nPlural, I18nSelect, I18nDateTime, I18nNumberFormat\n * @default '' (no prefix)\n */\n componentPrefix?: string\n /**\n * Automatically register `@fluenti/vite-plugin` in the Vite config.\n *\n * Set to `false` to disable if you configure the Vite plugin manually.\n *\n * @default true\n */\n autoVitePlugin?: boolean\n /**\n * Whether to auto-import composables (useLocalePath, useSwitchLocalePath, useLocaleHead, useI18n).\n *\n * Set to `false` to disable all auto-imports. Useful when migrating from `@nuxtjs/i18n`\n * or when you want explicit imports to avoid naming collisions.\n *\n * @default true\n */\n autoImports?: boolean\n /**\n * Whether to extend routes with locale-prefixed variants.\n *\n * Set to `false` to handle locale routing yourself (e.g., via a custom\n * `pages:extend` hook or Nuxt Layers). When `false`, the module will NOT\n * create locale-suffixed route clones and will NOT remove unprefixed routes.\n *\n * @default true\n */\n extendRoutes?: boolean\n /**\n * Route generation mode for locale variants.\n *\n * - `'all'` (default): All pages get locale route variants unless explicitly\n * opted out via `definePageMeta({ i18n: false })`.\n * - `'opt-in'`: Only pages that explicitly declare `definePageMeta({ i18n: { locales: [...] } })`\n * get locale route variants. Pages without an `i18n` meta field are left untouched.\n *\n * Use `'opt-in'` for large projects where only a subset of pages need i18n routing.\n *\n * @default 'all'\n */\n routeMode?: 'all' | 'opt-in'\n /**\n * Template for generating locale-specific route names.\n *\n * Receives the original route name and locale code, returns the desired name.\n * Only used when `extendRoutes` is not `false`.\n *\n * @default (name, locale) => `${name}___${locale}`\n * @example (name, locale) => `${locale}:${name}`\n */\n routeNameTemplate?: (name: string, locale: string) => string\n /**\n * Custom route paths per locale.\n *\n * Allows different URL slugs for different locales (e.g. `/about` in English\n * becomes `/について` in Japanese).\n *\n * Keys are the original route paths; values are locale-to-path mappings.\n *\n * @example\n * ```ts\n * routeOverrides: {\n * '/about': { ja: '/について', 'zh-CN': '/关于' },\n * '/contact': { ja: '/お問い合わせ' },\n * }\n * ```\n */\n routeOverrides?: Record<string, Record<string, string>>\n /**\n * Whether the locale redirect middleware should be registered globally.\n *\n * Set to `false` to register it as a named middleware instead, so you can\n * apply it only to specific pages via `definePageMeta({ middleware: ['fluenti-locale-redirect'] })`.\n *\n * Only relevant when `strategy` is `'prefix'`.\n *\n * @default true\n */\n globalMiddleware?: boolean\n /**\n * Whether to register the page meta transform plugin.\n *\n * When enabled (default), `defineI18nRoute()` and `definePageMeta({ i18n: ... })`\n * are automatically transformed. Set to `false` to disable the Vite transform.\n *\n * @default true\n */\n pageMetaTransform?: boolean\n /**\n * Whether to register the `NuxtLinkLocale` component globally.\n *\n * Set to `false` to disable registration. You can still import it manually\n * from `@fluenti/nuxt/runtime/components/NuxtLinkLocale`.\n *\n * @default true\n */\n registerNuxtLinkLocale?: boolean\n /**\n * Domain-to-locale mappings for the `'domains'` strategy.\n *\n * Each entry maps a domain hostname to a locale. Required when `strategy` is `'domains'`.\n *\n * Can also be specified inline in locale objects via `{ code: 'ja', domain: 'example.jp' }`.\n *\n * @example\n * ```ts\n * domains: [\n * { domain: 'example.com', locale: 'en', defaultForLocale: true },\n * { domain: 'example.jp', locale: 'ja' },\n * ]\n * ```\n */\n domains?: DomainConfig[]\n /**\n * Incremental Static Regeneration (ISR) settings.\n *\n * When enabled, the module automatically generates `routeRules` with\n * ISR caching for all locale route patterns.\n */\n isr?: ISROptions\n /** Enable @fluenti/vue-i18n-compat bridge mode */\n compat?: boolean\n /**\n * Whether to inject `$localePath` onto `app.config.globalProperties`.\n *\n * Set to `false` if another plugin (e.g. `@nuxtjs/i18n`) already provides `$localePath`,\n * or when using composition API exclusively.\n *\n * @default true\n */\n injectGlobalProperties?: boolean\n /**\n * Callback fired when a translation key is missing from the catalog.\n *\n * Useful for logging, error tracking, or providing dynamic fallbacks.\n */\n onMissingTranslation?: (locale: string, id: string) => string | undefined\n /**\n * Structured error handler for i18n errors.\n */\n onError?: I18nErrorHandler\n /**\n * Generate fallback text when a translation is missing or errors.\n */\n getMessageFallback?: MessageFallbackHandler\n}\n\n/** Structured i18n error types */\nexport type I18nErrorCode = 'MISSING_MESSAGE' | 'MISSING_LOCALE' | 'FORMAT_ERROR' | 'LOAD_ERROR'\n\n/** Structured error passed to the onError callback */\nexport interface I18nError {\n /** Error classification */\n code: I18nErrorCode\n /** Human-readable error message */\n message: string\n /** The message key that caused the error */\n key?: string\n /** The locale that caused the error */\n locale?: string\n /** The original error (if wrapping a lower-level error) */\n cause?: unknown\n}\n\n/** Callback for structured i18n error handling */\nexport type I18nErrorHandler = (error: I18nError) => void\n\n/**\n * Callback to generate fallback text when a translation is missing or errors.\n *\n * Return a string to use as the fallback, or `undefined` for default behavior\n * (which shows the message key).\n */\nexport type MessageFallbackHandler = (error: I18nError) => string | undefined\n\n/** ISR configuration */\nexport interface ISROptions {\n /** Enable ISR route rules generation */\n enabled: boolean\n /** Cache TTL in seconds (default: 3600 — 1 hour) */\n ttl?: number\n}\n\n/** Runtime config injected into Nuxt's public runtimeConfig */\nexport interface FluentNuxtRuntimeConfig {\n locales: string[]\n defaultLocale: string\n strategy: Strategy\n detectBrowserLanguage?: DetectBrowserLanguageOptions\n /** Ordered list of detector names/paths */\n detectOrder: Array<string>\n /** Query parameter name for locale detection */\n queryParamKey: string\n /** Whether to inject $localePath onto globalProperties */\n injectGlobalProperties: boolean\n /** Domain-to-locale mappings (when strategy is 'domains') */\n domains?: DomainConfig[]\n /** Locale metadata (iso tags, dir, names) — keyed by locale code */\n localeProperties?: Record<string, LocaleObject>\n}\n\n// ---- Utility helpers ----\n\n/** Build a locale properties map from LocaleDefinition[] */\nexport function resolveLocaleProperties(locales: LocaleDefinition[]): Record<string, LocaleObject> {\n const map: Record<string, LocaleObject> = {}\n for (const l of locales) {\n if (typeof l === 'string') {\n map[l] = { code: l }\n } else {\n map[l.code] = l\n }\n }\n return map\n}\n\n/** Build domain configs from locale objects that have a `domain` field */\nexport function resolveDomainConfigs(\n locales: LocaleDefinition[],\n explicit?: DomainConfig[],\n): DomainConfig[] {\n if (explicit?.length) return explicit\n const configs: DomainConfig[] = []\n for (const l of locales) {\n if (typeof l !== 'string' && l.domain) {\n configs.push({ domain: l.domain, locale: l.code })\n }\n }\n return configs\n}\n","import type { FluentNuxtOptions, Strategy } from './types'\n\nexport interface ISRWarning {\n level: 'warn' | 'error'\n message: string\n}\n\n/**\n * Validate ISR configuration against locale detection settings.\n *\n * ISR caches responses by URL path. If locale detection relies on\n * non-path signals (cookies, headers), the cached response may serve\n * the wrong locale to subsequent visitors.\n */\nexport function validateISRConfig(\n isr: FluentNuxtOptions['isr'],\n strategy: Strategy,\n detectOrder: string[],\n): ISRWarning[] {\n const warnings: ISRWarning[] = []\n if (!isr?.enabled) return warnings\n\n const nonPathDetectors = detectOrder.filter(\n (d) => d === 'cookie' || d === 'header',\n )\n if (nonPathDetectors.length > 0) {\n warnings.push({\n level: 'warn',\n message:\n `[@fluenti/nuxt] ISR is enabled but detectOrder includes non-path ` +\n `detectors (${nonPathDetectors.join(', ')}). ISR caches by URL path, ` +\n `so cookie/header-based detection may serve the wrong locale from ` +\n `cache. Consider using detectOrder: ['path'] with ISR.`,\n })\n }\n\n if (strategy === 'no_prefix') {\n warnings.push({\n level: 'warn',\n message:\n `[@fluenti/nuxt] ISR is enabled with strategy: 'no_prefix'. All ` +\n `locales share the same URL path, so ISR will cache only one locale ` +\n `per URL. Use 'prefix' or 'prefix_except_default' strategy with ISR.`,\n })\n }\n\n return warnings\n}\n","import type { Nuxt } from '@nuxt/schema'\n\n/**\n * DevTools state exposed to the custom tab.\n * Serialized to JSON and sent to the DevTools panel.\n */\nexport interface DevToolsI18nState {\n currentLocale: string\n availableLocales: string[]\n defaultLocale: string\n strategy: string\n detectedBy: string\n messageCount: number\n loadedLocales: string[]\n missingKeys: string[]\n}\n\n/**\n * Register a Nuxt DevTools custom tab for Fluenti.\n *\n * Shows: current locale, available locales, detection chain result,\n * loaded message count, and missing translation keys.\n */\nexport function setupDevTools(nuxt: Nuxt, localeCodes: string[], defaultLocale: string, strategy: string): void {\n try {\n // Attempt to use @nuxt/devtools-kit if available\n // @ts-expect-error — devtools:customTabs hook is provided by @nuxt/devtools\n nuxt.hook('devtools:customTabs', (tabs: unknown[]) => {\n tabs.push({\n name: 'fluenti',\n title: 'Fluenti i18n',\n icon: 'i-carbon-translate',\n view: {\n type: 'client-component',\n componentName: 'FluentiDevToolsPanel',\n },\n })\n })\n } catch {\n // DevTools not available — silently skip\n }\n\n // Inject DevTools client component via virtual module\n // @ts-expect-error — nitro:config hook is provided by Nitro\n nuxt.hook('nitro:config', (nitroConfig: Record<string, unknown>) => {\n const publicConfig = nitroConfig['runtimeConfig'] as Record<string, unknown> | undefined\n if (publicConfig) {\n const pub = (publicConfig['public'] ?? (publicConfig['public'] = {})) as Record<string, unknown>\n const fluentiConfig = (pub['fluenti'] ?? {}) as Record<string, unknown>\n fluentiConfig['devtools'] = {\n enabled: true,\n locales: localeCodes,\n defaultLocale,\n strategy,\n }\n }\n })\n}\n\n/**\n * Client-side DevTools panel component source.\n *\n * This is injected as a virtual module and rendered inside the\n * Nuxt DevTools panel. It reads the Fluenti runtime state and\n * displays it in a simple, readable format.\n */\nexport const DEVTOOLS_PANEL_COMPONENT = `\n<template>\n <div style=\"padding: 16px; font-family: system-ui, sans-serif;\">\n <h2 style=\"margin: 0 0 16px; font-size: 18px;\">🌐 Fluenti i18n</h2>\n\n <div style=\"display: grid; grid-template-columns: 140px 1fr; gap: 8px 16px; font-size: 14px;\">\n <span style=\"color: #888;\">Current locale:</span>\n <strong>{{ state.currentLocale }}</strong>\n\n <span style=\"color: #888;\">Default locale:</span>\n <span>{{ state.defaultLocale }}</span>\n\n <span style=\"color: #888;\">Strategy:</span>\n <span>{{ state.strategy }}</span>\n\n <span style=\"color: #888;\">Available:</span>\n <span>{{ state.availableLocales.join(', ') }}</span>\n\n <span style=\"color: #888;\">Loaded:</span>\n <span>{{ state.loadedLocales.join(', ') || 'none' }}</span>\n\n <span style=\"color: #888;\">Messages:</span>\n <span>{{ state.messageCount }}</span>\n\n <span style=\"color: #888;\">Missing keys:</span>\n <span :style=\"{ color: state.missingKeys.length > 0 ? '#e53e3e' : '#38a169' }\">\n {{ state.missingKeys.length > 0 ? state.missingKeys.length + ' missing' : 'All translated ✓' }}\n </span>\n </div>\n\n <div v-if=\"state.missingKeys.length > 0\" style=\"margin-top: 16px;\">\n <h3 style=\"margin: 0 0 8px; font-size: 14px; color: #e53e3e;\">Missing translations:</h3>\n <ul style=\"margin: 0; padding: 0 0 0 20px; font-size: 13px; font-family: monospace;\">\n <li v-for=\"key in state.missingKeys\" :key=\"key\" style=\"margin: 2px 0;\">{{ key }}</li>\n </ul>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, onMounted } from 'vue'\n\nconst state = ref({\n currentLocale: '',\n defaultLocale: '',\n strategy: '',\n availableLocales: [],\n loadedLocales: [],\n messageCount: 0,\n missingKeys: [],\n})\n\nonMounted(() => {\n try {\n const nuxtApp = window.__NUXT_DEVTOOLS_VIEW__?.nuxtApp ?? useNuxtApp()\n const config = nuxtApp.$config?.public?.fluenti ?? {}\n const fluentiLocale = nuxtApp.$fluentiLocale ?? ref('')\n\n state.value = {\n currentLocale: fluentiLocale.value || config.defaultLocale || '',\n defaultLocale: config.defaultLocale || '',\n strategy: config.strategy || '',\n availableLocales: config.locales || [],\n loadedLocales: [],\n messageCount: 0,\n missingKeys: [],\n }\n } catch (e) {\n // DevTools context not available\n }\n})\n</script>\n`\n","import type { Plugin } from 'vite'\n\n/**\n * Vite plugin that transforms `definePageMeta({ i18n: ... })` into\n * the internal `i18nRoute` format used by the page extension system.\n *\n * This allows users to use native Nuxt `definePageMeta` with an `i18n` key\n * instead of the separate `defineI18nRoute()` macro.\n *\n * Supports:\n * - `definePageMeta({ i18n: { locales: ['en', 'ja'] } })`\n * - `definePageMeta({ i18n: false })`\n *\n * The transform also rewrites `defineI18nRoute(...)` to\n * `definePageMeta({ i18nRoute: ... })` for backwards compatibility.\n */\nexport function createPageMetaTransform(): Plugin {\n return {\n name: 'fluenti:page-meta-transform',\n enforce: 'pre',\n\n transform(code, id) {\n // Only transform Vue SFC script blocks and TS/JS files in pages/\n if (!id.includes('/pages/') && !id.includes('\\\\pages\\\\')) return null\n if (!code.includes('defineI18nRoute') && !code.includes('i18n')) return null\n\n let transformed = code\n\n // Transform: defineI18nRoute({ locales: [...] })\n // → definePageMeta({ i18nRoute: { locales: [...] } })\n // Transform: defineI18nRoute(false)\n // → definePageMeta({ i18nRoute: false })\n if (transformed.includes('defineI18nRoute')) {\n transformed = transformed.replace(\n /defineI18nRoute\\s*\\(([^)]*?)\\)/g,\n (_match, arg: string) => `definePageMeta({ i18nRoute: ${arg.trim()} })`,\n )\n }\n\n // Support native: definePageMeta({ i18n: { locales: [...] } })\n // Rewrite `i18n:` key to `i18nRoute:` so page-extend can read it\n if (transformed.includes('definePageMeta') && transformed.includes('i18n:')) {\n // Simple regex for { i18n: ... } within definePageMeta\n // This handles the common case; complex nested objects may need\n // AST-based transformation in the future.\n transformed = transformed.replace(\n /(definePageMeta\\s*\\(\\s*\\{[^}]*?)\\bi18n\\s*:/g,\n '$1i18nRoute:',\n )\n }\n\n if (transformed === code) return null\n\n return {\n code: transformed,\n map: null,\n }\n },\n }\n}\n","import type { Strategy } from './types'\n\nexport interface SitemapUrl {\n loc: string\n alternatives?: Array<{ hreflang: string; href: string }>\n}\n\n/**\n * Generate multi-locale sitemap URLs from a list of base paths.\n *\n * For each base path, produces a URL entry with hreflang alternatives\n * pointing to every locale variant. Compatible with `@nuxtjs/sitemap`'s\n * `sources` hook format.\n */\nexport function generateSitemapUrls(\n paths: string[],\n locales: string[],\n defaultLocale: string,\n strategy: Strategy,\n baseUrl?: string,\n): SitemapUrl[] {\n const urls: SitemapUrl[] = []\n const base = baseUrl ?? ''\n\n for (const rawPath of paths) {\n const path = rawPath.startsWith('/') ? rawPath : `/${rawPath}`\n\n for (const locale of locales) {\n const localizedPath = buildLocalePath(path, locale, defaultLocale, strategy)\n\n const alternatives = locales.map((altLocale) => ({\n hreflang: altLocale,\n href: `${base}${buildLocalePath(path, altLocale, defaultLocale, strategy)}`,\n }))\n\n // Add x-default pointing to default locale\n alternatives.push({\n hreflang: 'x-default',\n href: `${base}${buildLocalePath(path, defaultLocale, defaultLocale, strategy)}`,\n })\n\n urls.push({\n loc: `${base}${localizedPath}`,\n alternatives,\n })\n }\n }\n\n return urls\n}\n\nfunction buildLocalePath(\n path: string,\n locale: string,\n defaultLocale: string,\n strategy: Strategy,\n): string {\n if (strategy === 'no_prefix') return path\n\n if (strategy === 'prefix_except_default' && locale === defaultLocale) {\n return path\n }\n\n const cleanPath = path === '/' ? '' : path\n return `/${locale}${cleanPath}`\n}\n\n/**\n * Hook handler for `@nuxtjs/sitemap`'s `sitemap:generate` hook.\n *\n * Transforms single-locale URLs into multi-locale entries with hreflang.\n * Register this in your nuxt.config.ts or let the module auto-register it.\n */\nexport function createSitemapHook(\n locales: string[],\n defaultLocale: string,\n strategy: Strategy,\n baseUrl?: string,\n) {\n return (urls: SitemapUrl[]) => {\n if (strategy === 'no_prefix') return urls\n\n const expanded: SitemapUrl[] = []\n\n for (const url of urls) {\n const loc = url.loc.replace(/^https?:\\/\\/[^/]+/, '')\n\n for (const locale of locales) {\n const localizedPath = buildLocalePath(loc, locale, defaultLocale, strategy)\n const alternatives = locales.map((altLocale) => ({\n hreflang: altLocale,\n href: `${baseUrl ?? ''}${buildLocalePath(loc, altLocale, defaultLocale, strategy)}`,\n }))\n alternatives.push({\n hreflang: 'x-default',\n href: `${baseUrl ?? ''}${buildLocalePath(loc, defaultLocale, defaultLocale, strategy)}`,\n })\n\n expanded.push({\n loc: `${baseUrl ?? ''}${localizedPath}`,\n alternatives,\n })\n }\n }\n\n return expanded\n }\n}\n","import { defineNuxtModule, addPlugin, addImports, addComponent, addRouteMiddleware, addServerHandler, createResolver } from '@nuxt/kit'\nimport { createRequire } from 'node:module'\nimport type { FluentNuxtOptions } from './types'\nimport { resolveLocaleProperties, resolveDomainConfigs } from './types'\nimport { resolveLocaleCodes } from '@fluenti/core/internal'\nimport type { FluentiBuildConfig } from '@fluenti/core/internal'\nimport fluentiVue from '@fluenti/vue/vite-plugin'\nimport { extendPages } from './runtime/page-extend'\nimport { validateISRConfig } from './isr-validation'\nimport { setupDevTools } from './devtools'\nimport { createPageMetaTransform } from './page-meta-transform'\n\nexport type { FluentNuxtOptions, Strategy, FluentNuxtRuntimeConfig, DetectBrowserLanguageOptions, LocaleDetectContext, LocaleDetectorFn, BuiltinDetector, ISROptions, LocaleObject, LocaleDefinition, DomainConfig, I18nRouteConfig, I18nError, I18nErrorCode, I18nErrorHandler, MessageFallbackHandler } from './types'\nexport { generateSitemapUrls, createSitemapHook } from './sitemap'\nexport type { SitemapUrl } from './sitemap'\nexport { resolveLocaleProperties, resolveDomainConfigs } from './types'\nexport { resolveLocaleCodes } from '@fluenti/core/internal'\nexport { localePath, extractLocaleFromPath, switchLocalePath } from './runtime/path-utils'\nexport { extendPages } from './runtime/page-extend'\nexport type { PageRoute, RouteNameTemplate, ExtendPagesOptions } from './runtime/page-extend'\nexport { buildLocaleHead } from './runtime/locale-head'\nexport type { LocaleHeadMeta, LocaleHeadOptions } from './runtime/locale-head'\nexport { useLocalePath, useSwitchLocalePath, useLocaleRoute, useLocaleHead } from './runtime/standalone-composables'\nexport { defineI18nRoute } from './runtime/define-i18n-route'\n\nexport const MODULE_NAME = '@fluenti/nuxt'\nexport const CONFIG_KEY = 'fluenti'\n\n// Module-level require that works in both CJS and ESM after bundling.\n// See packages/core/src/config-loader.ts for explanation of the pattern.\nconst _require = createRequire(\n typeof __filename !== 'undefined' ? __filename : import.meta.url,\n)\n\n/**\n * Resolve the FluentiBuildConfig from the module options.\n */\nfunction resolveFluentiBuildConfig(configOption: string | FluentiBuildConfig | undefined, rootDir: string): FluentiBuildConfig {\n\n if (typeof configOption === 'object') {\n const { DEFAULT_FLUENTI_CONFIG } = _require('@fluenti/core/config') as {\n DEFAULT_FLUENTI_CONFIG: FluentiBuildConfig\n }\n return { ...DEFAULT_FLUENTI_CONFIG, ...configOption }\n }\n\n const { loadConfigSync } = _require('@fluenti/core/config') as {\n loadConfigSync: (configPath?: string, cwd?: string) => FluentiBuildConfig\n }\n return loadConfigSync(\n typeof configOption === 'string' ? configOption : undefined,\n rootDir,\n )\n}\n\nexport default defineNuxtModule<FluentNuxtOptions>({\n meta: {\n name: MODULE_NAME,\n configKey: CONFIG_KEY,\n compatibility: { nuxt: '>=3.0.0' },\n },\n defaults: {\n strategy: 'prefix_except_default',\n },\n setup(options, nuxt) {\n const { resolve } = createResolver(import.meta.url)\n\n // --- Resolve FluentiBuildConfig from options.config, then overlay module-level options ---\n const rootDir = nuxt.options.rootDir ?? process.cwd()\n const fluentiConfig = resolveFluentiBuildConfig(options.config, rootDir)\n\n // Module-level options (e.g. nuxt.config.ts `fluenti.locales`) override the\n // resolved fluenti.config.ts values — this ensures Nuxt-specific config takes\n // precedence even when config file loading fails (e.g. CJS/jiti issues).\n if (options.locales) fluentiConfig.locales = options.locales\n if (options.defaultLocale) fluentiConfig.defaultLocale = options.defaultLocale\n if (options.sourceLocale) fluentiConfig.sourceLocale = options.sourceLocale\n if (options.catalogDir) fluentiConfig.catalogDir = options.catalogDir\n\n // --- Resolve locale codes and metadata ---\n const localeCodes = resolveLocaleCodes(fluentiConfig.locales)\n const localeProperties = resolveLocaleProperties(fluentiConfig.locales)\n const defaultLocale = fluentiConfig.defaultLocale ?? fluentiConfig.sourceLocale\n const domainConfigs = options.strategy === 'domains'\n ? resolveDomainConfigs(fluentiConfig.locales, options.domains)\n : undefined\n\n // --- Inject runtime config ---\n const detectOrder = options.detectOrder ?? (\n options.strategy === 'domains'\n ? ['domain', 'cookie', 'header']\n : ['path', 'cookie', 'header']\n )\n nuxt.options.runtimeConfig.public['fluenti'] = {\n locales: localeCodes,\n defaultLocale,\n strategy: options.strategy ?? 'prefix_except_default',\n detectBrowserLanguage: options.detectBrowserLanguage,\n detectOrder,\n queryParamKey: options.queryParamKey ?? 'locale',\n injectGlobalProperties: options.injectGlobalProperties !== false,\n ...(domainConfigs ? { domains: domainConfigs } : {}),\n localeProperties,\n }\n\n // --- Auto-register @fluenti/vue vite plugin (includes v-t transform + scope transform) ---\n if (options.autoVitePlugin !== false) {\n nuxt.options.vite = nuxt.options.vite || {}\n nuxt.options.vite.plugins = nuxt.options.vite.plugins || []\n ;(nuxt.options.vite.plugins as unknown[]).push(\n ...fluentiVue({ config: fluentiConfig }),\n )\n }\n\n // --- Register definePageMeta({ i18n }) transform ---\n if (options.pageMetaTransform !== false) {\n nuxt.options.vite = nuxt.options.vite || {}\n nuxt.options.vite.plugins = nuxt.options.vite.plugins || []\n ;(nuxt.options.vite.plugins as unknown[]).push(createPageMetaTransform())\n }\n\n // --- Register runtime plugin ---\n addPlugin({\n src: resolve('./runtime/plugin'),\n mode: 'all',\n })\n\n // --- Extend routes with locale prefixes ---\n const strategy = options.strategy ?? 'prefix_except_default'\n if (strategy !== 'no_prefix' && strategy !== 'domains' && options.extendRoutes !== false) {\n nuxt.hook('pages:extend', (pages) => {\n extendPages(pages, {\n locales: localeCodes,\n defaultLocale,\n strategy,\n ...(options.routeNameTemplate ? { routeNameTemplate: options.routeNameTemplate } : {}),\n ...(options.routeOverrides ? { routeOverrides: options.routeOverrides } : {}),\n ...(options.routeMode ? { routeMode: options.routeMode } : {}),\n })\n })\n }\n\n // --- Register locale redirect middleware ---\n if (strategy === 'prefix') {\n addRouteMiddleware({\n name: 'fluenti-locale-redirect',\n path: resolve('./runtime/middleware/locale-redirect'),\n global: options.globalMiddleware !== false,\n })\n }\n\n // --- Auto-import composables ---\n if (options.autoImports !== false) {\n addImports([\n { name: 'useLocalePath', from: resolve('./runtime/composables') },\n { name: 'useSwitchLocalePath', from: resolve('./runtime/composables') },\n { name: 'useLocaleRoute', from: resolve('./runtime/composables') },\n { name: 'useLocaleHead', from: resolve('./runtime/composables') },\n { name: 'useI18nScoped', from: resolve('./runtime/composables') },\n { name: 'useI18n', from: '@fluenti/vue' },\n { name: 'defineI18nRoute', from: resolve('./runtime/define-i18n-route') },\n ])\n }\n\n // --- Register components (including DateTime + NumberFormat) ---\n const prefix = options.componentPrefix ?? ''\n if (options.registerNuxtLinkLocale !== false) {\n addComponent({\n name: `${prefix}NuxtLinkLocale`,\n filePath: resolve('./runtime/components/NuxtLinkLocale'),\n })\n }\n\n // Auto-import DateTime and NumberFormat from @fluenti/vue\n addComponent({ name: `${prefix}Trans`, filePath: '@fluenti/vue/components', export: 'Trans' })\n addComponent({ name: `${prefix}Plural`, filePath: '@fluenti/vue/components', export: 'Plural' })\n addComponent({ name: `${prefix}Select`, filePath: '@fluenti/vue/components', export: 'Select' })\n addComponent({ name: `${prefix}DateTime`, filePath: '@fluenti/vue/components', export: 'DateTime' })\n addComponent({ name: `${prefix}NumberFormat`, filePath: '@fluenti/vue/components', export: 'NumberFormat' })\n\n // --- SSG / ISR: configure nitro prerender and route rules ---\n if (strategy !== 'no_prefix' && strategy !== 'domains') {\n const nuxtOpts = nuxt.options as unknown as Record<string, unknown>\n\n // Enable link crawling so locale-prefixed routes are discovered during prerender\n const nitroOpts = (nuxtOpts['nitro'] ?? (nuxtOpts['nitro'] = {})) as Record<string, unknown>\n const prerender = (nitroOpts['prerender'] ?? (nitroOpts['prerender'] = {})) as Record<string, unknown>\n prerender['crawlLinks'] = prerender['crawlLinks'] ?? true\n\n // For 'prefix' strategy, / has no matching route (all routes are\n // locale-prefixed). Replace the default / initial route with\n // /<defaultLocale> so the prerenderer starts from a valid route.\n if (strategy === 'prefix') {\n const routes = (prerender['routes'] ?? ['/']) as string[]\n prerender['routes'] = routes.map((r) =>\n r === '/' ? `/${defaultLocale}` : r,\n )\n }\n\n // ISR: validate configuration and generate routeRules\n for (const w of validateISRConfig(options.isr, strategy, detectOrder)) {\n console.warn(w.message)\n }\n if (options.isr?.enabled) {\n const routeRules = (nuxtOpts['routeRules'] ?? (nuxtOpts['routeRules'] = {})) as Record<string, Record<string, unknown>>\n const ttl = options.isr.ttl ?? 3600\n for (const locale of localeCodes) {\n if (locale === defaultLocale && strategy === 'prefix_except_default') {\n routeRules['/**'] = { ...routeRules['/**'], isr: ttl }\n } else {\n routeRules[`/${locale}/**`] = { ...routeRules[`/${locale}/**`], isr: ttl }\n }\n }\n }\n }\n\n // --- Nuxt DevTools integration ---\n if (nuxt.options.dev) {\n setupDevTools(nuxt as any, localeCodes, defaultLocale, strategy)\n }\n\n // --- Nitro server handler for locale redirect (T2-10) ---\n if (strategy === 'prefix' || strategy === 'prefix_and_default') {\n addServerHandler({\n handler: resolve('./runtime/server/locale-redirect'),\n middleware: true,\n })\n }\n },\n})\n"],"mappings":"85BAmVA,SAAgB,EAAwB,EAA2D,CACjG,IAAM,EAAoC,EAAE,CAC5C,IAAK,IAAM,KAAK,EACV,OAAO,GAAM,SACf,EAAI,GAAK,CAAE,KAAM,EAAG,CAEpB,EAAI,EAAE,MAAQ,EAGlB,OAAO,EAIT,SAAgB,EACd,EACA,EACgB,CAChB,GAAI,GAAU,OAAQ,OAAO,EAC7B,IAAM,EAA0B,EAAE,CAClC,IAAK,IAAM,KAAK,EACV,OAAO,GAAM,UAAY,EAAE,QAC7B,EAAQ,KAAK,CAAE,OAAQ,EAAE,OAAQ,OAAQ,EAAE,KAAM,CAAC,CAGtD,OAAO,EC7VT,SAAgB,EACd,EACA,EACA,EACc,CACd,IAAM,EAAyB,EAAE,CACjC,GAAI,CAAC,GAAK,QAAS,OAAO,EAE1B,IAAM,EAAmB,EAAY,OAClC,GAAM,IAAM,UAAY,IAAM,SAChC,CAsBD,OArBI,EAAiB,OAAS,GAC5B,EAAS,KAAK,CACZ,MAAO,OACP,QACE,+EACc,EAAiB,KAAK,KAAK,CAAC,mJAG7C,CAAC,CAGA,IAAa,aACf,EAAS,KAAK,CACZ,MAAO,OACP,QACE,wMAGH,CAAC,CAGG,ECvBT,SAAgB,EAAc,EAAY,EAAuB,EAAuB,EAAwB,CAC9G,GAAI,CAGF,EAAK,KAAK,sBAAwB,GAAoB,CACpD,EAAK,KAAK,CACR,KAAM,UACN,MAAO,eACP,KAAM,qBACN,KAAM,CACJ,KAAM,mBACN,cAAe,uBAChB,CACF,CAAC,EACF,MACI,EAMR,EAAK,KAAK,eAAiB,GAAyC,CAClE,IAAM,EAAe,EAAY,cACjC,GAAI,EAAc,CAEhB,IAAM,GADO,AAA2B,EAAa,SAAY,EAAE,EACxC,SAAc,EAAE,CAC3C,EAAc,SAAc,CAC1B,QAAS,GACT,QAAS,EACT,gBACA,WACD,GAEH,CCxCJ,SAAgB,GAAkC,CAChD,MAAO,CACL,KAAM,8BACN,QAAS,MAET,UAAU,EAAM,EAAI,CAGlB,GADI,CAAC,EAAG,SAAS,UAAU,EAAI,CAAC,EAAG,SAAS,YAAY,EACpD,CAAC,EAAK,SAAS,kBAAkB,EAAI,CAAC,EAAK,SAAS,OAAO,CAAE,OAAO,KAExE,IAAI,EAAc,EA2BlB,OArBI,EAAY,SAAS,kBAAkB,GACzC,EAAc,EAAY,QACxB,mCACC,EAAQ,IAAgB,+BAA+B,EAAI,MAAM,CAAC,KACpE,EAKC,EAAY,SAAS,iBAAiB,EAAI,EAAY,SAAS,QAAQ,GAIzE,EAAc,EAAY,QACxB,8CACA,eACD,EAGC,IAAgB,EAAa,KAE1B,CACL,KAAM,EACN,IAAK,KACN,EAEJ,CC5CH,SAAgB,EACd,EACA,EACA,EACA,EACA,EACc,CACd,IAAM,EAAqB,EAAE,CACvB,EAAO,GAAW,GAExB,IAAK,IAAM,KAAW,EAAO,CAC3B,IAAM,EAAO,EAAQ,WAAW,IAAI,CAAG,EAAU,IAAI,IAErD,IAAK,IAAM,KAAU,EAAS,CAC5B,IAAM,EAAgB,EAAgB,EAAM,EAAQ,EAAe,EAAS,CAEtE,EAAe,EAAQ,IAAK,IAAe,CAC/C,SAAU,EACV,KAAM,GAAG,IAAO,EAAgB,EAAM,EAAW,EAAe,EAAS,GAC1E,EAAE,CAGH,EAAa,KAAK,CAChB,SAAU,YACV,KAAM,GAAG,IAAO,EAAgB,EAAM,EAAe,EAAe,EAAS,GAC9E,CAAC,CAEF,EAAK,KAAK,CACR,IAAK,GAAG,IAAO,IACf,eACD,CAAC,EAIN,OAAO,EAGT,SAAS,EACP,EACA,EACA,EACA,EACQ,CAQR,OAPI,IAAa,aAEb,IAAa,yBAA2B,IAAW,EAC9C,EAIF,IAAI,IADO,IAAS,IAAM,GAAK,IAUxC,SAAgB,EACd,EACA,EACA,EACA,EACA,CACA,MAAQ,IAAuB,CAC7B,GAAI,IAAa,YAAa,OAAO,EAErC,IAAM,EAAyB,EAAE,CAEjC,IAAK,IAAM,KAAO,EAAM,CACtB,IAAM,EAAM,EAAI,IAAI,QAAQ,oBAAqB,GAAG,CAEpD,IAAK,IAAM,KAAU,EAAS,CAC5B,IAAM,EAAgB,EAAgB,EAAK,EAAQ,EAAe,EAAS,CACrE,EAAe,EAAQ,IAAK,IAAe,CAC/C,SAAU,EACV,KAAM,GAAG,GAAW,KAAK,EAAgB,EAAK,EAAW,EAAe,EAAS,GAClF,EAAE,CACH,EAAa,KAAK,CAChB,SAAU,YACV,KAAM,GAAG,GAAW,KAAK,EAAgB,EAAK,EAAe,EAAe,EAAS,GACtF,CAAC,CAEF,EAAS,KAAK,CACZ,IAAK,GAAG,GAAW,KAAK,IACxB,eACD,CAAC,EAIN,OAAO,GChFX,IAAa,EAAc,gBACd,EAAa,UAIpB,GAAA,EAAA,EAAA,eACJ,OAAO,WAAe,IAAc,WAAA,EAAA,CAAyB,IAC9D,CAKD,SAAS,EAA0B,EAAuD,EAAqC,CAE7H,GAAI,OAAO,GAAiB,SAAU,CACpC,GAAM,CAAE,0BAA2B,EAAS,uBAAuB,CAGnE,MAAO,CAAE,GAAG,EAAwB,GAAG,EAAc,CAGvD,GAAM,CAAE,kBAAmB,EAAS,uBAAuB,CAG3D,OAAO,EACL,OAAO,GAAiB,SAAW,EAAe,IAAA,GAClD,EACD,CAGH,IAAA,GAAA,EAAA,EAAA,kBAAmD,CACjD,KAAM,CACJ,KAAM,EACN,UAAW,EACX,cAAe,CAAE,KAAM,UAAW,CACnC,CACD,SAAU,CACR,SAAU,wBACX,CACD,MAAM,EAAS,EAAM,CACnB,GAAM,CAAE,YAAA,EAAA,EAAA,gBAAA,EAAA,CAAuC,IAAI,CAG7C,EAAU,EAAK,QAAQ,SAAW,QAAQ,KAAK,CAC/C,EAAgB,EAA0B,EAAQ,OAAQ,EAAQ,CAKpE,EAAQ,UAAS,EAAc,QAAU,EAAQ,SACjD,EAAQ,gBAAe,EAAc,cAAgB,EAAQ,eAC7D,EAAQ,eAAc,EAAc,aAAe,EAAQ,cAC3D,EAAQ,aAAY,EAAc,WAAa,EAAQ,YAG3D,IAAM,GAAA,EAAA,EAAA,oBAAiC,EAAc,QAAQ,CACvD,EAAmB,EAAwB,EAAc,QAAQ,CACjE,EAAgB,EAAc,eAAiB,EAAc,aAC7D,EAAgB,EAAQ,WAAa,UACvC,EAAqB,EAAc,QAAS,EAAQ,QAAQ,CAC5D,IAAA,GAGE,EAAc,EAAQ,cAC1B,EAAQ,WAAa,UACjB,CAAC,SAAU,SAAU,SAAS,CAC9B,CAAC,OAAQ,SAAU,SAAS,EAElC,EAAK,QAAQ,cAAc,OAAO,QAAa,CAC7C,QAAS,EACT,gBACA,SAAU,EAAQ,UAAY,wBAC9B,sBAAuB,EAAQ,sBAC/B,cACA,cAAe,EAAQ,eAAiB,SACxC,uBAAwB,EAAQ,yBAA2B,GAC3D,GAAI,EAAgB,CAAE,QAAS,EAAe,CAAG,EAAE,CACnD,mBACD,CAGG,EAAQ,iBAAmB,KAC7B,EAAK,QAAQ,KAAO,EAAK,QAAQ,MAAQ,EAAE,CAC3C,EAAK,QAAQ,KAAK,QAAU,EAAK,QAAQ,KAAK,SAAW,EAAE,CACzD,EAAK,QAAQ,KAAK,QAAsB,KACxC,IAAA,EAAA,EAAA,SAAc,CAAE,OAAQ,EAAe,CAAC,CACzC,EAIC,EAAQ,oBAAsB,KAChC,EAAK,QAAQ,KAAO,EAAK,QAAQ,MAAQ,EAAE,CAC3C,EAAK,QAAQ,KAAK,QAAU,EAAK,QAAQ,KAAK,SAAW,EAAE,CACzD,EAAK,QAAQ,KAAK,QAAsB,KAAK,GAAyB,CAAC,GAI3E,EAAA,EAAA,WAAU,CACR,IAAK,EAAQ,mBAAmB,CAChC,KAAM,MACP,CAAC,CAGF,IAAM,EAAW,EAAQ,UAAY,wBACjC,IAAa,aAAe,IAAa,WAAa,EAAQ,eAAiB,IACjF,EAAK,KAAK,eAAiB,GAAU,CACnC,EAAA,EAAY,EAAO,CACjB,QAAS,EACT,gBACA,WACA,GAAI,EAAQ,kBAAoB,CAAE,kBAAmB,EAAQ,kBAAmB,CAAG,EAAE,CACrF,GAAI,EAAQ,eAAiB,CAAE,eAAgB,EAAQ,eAAgB,CAAG,EAAE,CAC5E,GAAI,EAAQ,UAAY,CAAE,UAAW,EAAQ,UAAW,CAAG,EAAE,CAC9D,CAAC,EACF,CAIA,IAAa,WACf,EAAA,EAAA,oBAAmB,CACjB,KAAM,0BACN,KAAM,EAAQ,uCAAuC,CACrD,OAAQ,EAAQ,mBAAqB,GACtC,CAAC,CAIA,EAAQ,cAAgB,KAC1B,EAAA,EAAA,YAAW,CACT,CAAE,KAAM,gBAAiB,KAAM,EAAQ,wBAAwB,CAAE,CACjE,CAAE,KAAM,sBAAuB,KAAM,EAAQ,wBAAwB,CAAE,CACvE,CAAE,KAAM,iBAAkB,KAAM,EAAQ,wBAAwB,CAAE,CAClE,CAAE,KAAM,gBAAiB,KAAM,EAAQ,wBAAwB,CAAE,CACjE,CAAE,KAAM,gBAAiB,KAAM,EAAQ,wBAAwB,CAAE,CACjE,CAAE,KAAM,UAAW,KAAM,eAAgB,CACzC,CAAE,KAAM,kBAAmB,KAAM,EAAQ,8BAA8B,CAAE,CAC1E,CAAC,CAIJ,IAAM,EAAS,EAAQ,iBAAmB,GAgB1C,GAfI,EAAQ,yBAA2B,KACrC,EAAA,EAAA,cAAa,CACX,KAAM,GAAG,EAAO,gBAChB,SAAU,EAAQ,sCAAsC,CACzD,CAAC,EAIJ,EAAA,EAAA,cAAa,CAAE,KAAM,GAAG,EAAO,OAAQ,SAAU,0BAA2B,OAAQ,QAAS,CAAC,EAC9F,EAAA,EAAA,cAAa,CAAE,KAAM,GAAG,EAAO,QAAS,SAAU,0BAA2B,OAAQ,SAAU,CAAC,EAChG,EAAA,EAAA,cAAa,CAAE,KAAM,GAAG,EAAO,QAAS,SAAU,0BAA2B,OAAQ,SAAU,CAAC,EAChG,EAAA,EAAA,cAAa,CAAE,KAAM,GAAG,EAAO,UAAW,SAAU,0BAA2B,OAAQ,WAAY,CAAC,EACpG,EAAA,EAAA,cAAa,CAAE,KAAM,GAAG,EAAO,cAAe,SAAU,0BAA2B,OAAQ,eAAgB,CAAC,CAGxG,IAAa,aAAe,IAAa,UAAW,CACtD,IAAM,EAAW,EAAK,QAGhB,EAAa,AAAsB,EAAS,QAAW,EAAE,CACzD,EAAa,AAA2B,EAAU,YAAe,EAAE,CACzE,EAAU,WAAgB,EAAU,YAAiB,GAKjD,IAAa,WAEf,EAAU,QADM,EAAU,QAAa,CAAC,IAAI,EACf,IAAK,GAChC,IAAM,IAAM,IAAI,IAAkB,EACnC,EAIH,IAAK,IAAM,KAAK,EAAkB,EAAQ,IAAK,EAAU,EAAY,CACnE,QAAQ,KAAK,EAAE,QAAQ,CAEzB,GAAI,EAAQ,KAAK,QAAS,CACxB,IAAM,EAAc,AAA2B,EAAS,aAAgB,EAAE,CACpE,EAAM,EAAQ,IAAI,KAAO,KAC/B,IAAK,IAAM,KAAU,EACf,IAAW,GAAiB,IAAa,wBAC3C,EAAW,OAAS,CAAE,GAAG,EAAW,OAAQ,IAAK,EAAK,CAEtD,EAAW,IAAI,EAAO,MAAQ,CAAE,GAAG,EAAW,IAAI,EAAO,MAAO,IAAK,EAAK,EAO9E,EAAK,QAAQ,KACf,EAAc,EAAa,EAAa,EAAe,EAAS,EAI9D,IAAa,UAAY,IAAa,wBACxC,EAAA,EAAA,kBAAiB,CACf,QAAS,EAAQ,mCAAmC,CACpD,WAAY,GACb,CAAC,EAGP,CAAC"}
1
+ {"version":3,"file":"module.cjs","names":[],"sources":["../src/types.ts","../src/isr-validation.ts","../src/devtools.ts","../src/page-meta-transform.ts","../src/sitemap.ts","../src/module.ts"],"sourcesContent":["import type { FluentiBuildConfig } from '@fluenti/core/compiler'\nimport { resolveLocaleCodes } from '@fluenti/core/compiler'\n// Re-export core types for backwards compatibility\nexport type { LocaleObject, LocaleDefinition } from '@fluenti/core'\nexport { resolveLocaleCodes }\n\n// Import core types needed locally\nimport type { LocaleDefinition, LocaleObject } from '@fluenti/core'\n\n/** Routing strategy for locale-prefixed URLs */\nexport type Strategy = 'prefix' | 'prefix_except_default' | 'prefix_and_default' | 'no_prefix' | 'domains'\n\n/** Browser language detection options */\nexport interface DetectBrowserLanguageOptions {\n /** Use a cookie to persist the detected locale */\n useCookie?: boolean\n /** Cookie key name (default: 'fluenti_locale') */\n cookieKey?: string\n /** Fallback locale when detection fails */\n fallbackLocale?: string\n}\n\n/** Built-in detector names */\nexport type BuiltinDetector = 'path' | 'cookie' | 'header' | 'query' | 'domain'\n\n/**\n * Context passed to locale detectors and the `fluenti:detect-locale` hook.\n *\n * Detectors inspect the context and call `setLocale()` to claim a locale.\n * Once a locale is set, subsequent detectors are skipped.\n */\nexport interface LocaleDetectContext {\n /** The request path (e.g. '/ja/about') */\n path: string\n /** Available locale codes */\n locales: string[]\n /** Default locale */\n defaultLocale: string\n /** Routing strategy */\n strategy: Strategy\n /** detectBrowserLanguage config */\n detectBrowserLanguage?: DetectBrowserLanguageOptions\n /** The detected locale so far (null if not yet detected) */\n detectedLocale: string | null\n /** Set the locale and stop the detection chain */\n setLocale: (locale: string) => void\n /** Whether we are running on the server */\n isServer: boolean\n /** The request hostname (available when `strategy: 'domains'`) */\n host?: string\n /** Pre-read cookie value (hoisted before await in plugin) */\n cookieValue?: string | null\n /** Pre-read Accept-Language header (hoisted before await in plugin) */\n acceptLanguage?: string\n}\n\n/**\n * A locale detector function.\n *\n * Can be sync or async. Call `ctx.setLocale(locale)` to claim a locale.\n */\nexport type LocaleDetectorFn = (ctx: LocaleDetectContext) => void | Promise<void>\n\n/**\n * Per-page locale configuration.\n *\n * Restricts which locales a page supports. Routes will only be generated\n * for the specified locales.\n *\n * @example\n * ```ts\n * // In a page component's <script setup>\n * defineI18nRoute({ locales: ['en', 'ja'] }) // only en and ja for this page\n * defineI18nRoute(false) // disable i18n for this page\n * ```\n */\nexport type I18nRouteConfig = { locales: string[] } | false\n\n/** Domain-to-locale mapping for the `'domains'` strategy */\nexport interface DomainConfig {\n /** Domain hostname (e.g. 'example.jp', 'ja.example.com') */\n domain: string\n /** Locale code for this domain */\n locale: string\n /** Whether this is the default domain (used for x-default hreflang) */\n defaultForLocale?: boolean\n}\n\n/** @fluenti/nuxt module options (set in nuxt.config.ts under `fluenti` key) */\nexport interface FluentNuxtOptions {\n /** fluenti.config.ts path or inline config */\n config?: string | FluentiBuildConfig\n\n // ---- Core overrides (take precedence over fluenti.config.ts) ----\n\n /** Override locales from fluenti.config.ts */\n locales?: FluentiBuildConfig['locales']\n /** Override defaultLocale from fluenti.config.ts */\n defaultLocale?: string\n /** Override sourceLocale from fluenti.config.ts */\n sourceLocale?: string\n /** Override catalogDir from fluenti.config.ts */\n catalogDir?: string\n\n // ---- Nuxt-specific: routing, detection, components ----\n\n /** URL routing strategy */\n strategy?: Strategy\n /** Browser language detection settings */\n detectBrowserLanguage?: DetectBrowserLanguageOptions\n /**\n * Ordered list of locale detectors.\n *\n * Each entry is either a built-in detector name ('path', 'cookie', 'header', 'query', 'domain')\n * or a file path to a custom detector module (e.g. '~/detectors/jwt-detector').\n *\n * Detectors run in order; the first one to call `ctx.setLocale()` wins.\n *\n * @default ['path', 'cookie', 'header']\n */\n detectOrder?: Array<BuiltinDetector | string>\n /**\n * Query parameter name for locale detection (e.g. `?lang=ja`).\n *\n * @default 'locale'\n */\n queryParamKey?: string\n /**\n * Prefix for globally registered i18n components (Trans, Plural, Select, DateTime, NumberFormat).\n *\n * Use this to avoid naming conflicts with other libraries.\n *\n * @example 'I18n' // → I18nTrans, I18nPlural, I18nSelect, I18nDateTime, I18nNumberFormat\n * @default '' (no prefix)\n */\n componentPrefix?: string\n /**\n * Automatically register `@fluenti/vite-plugin` in the Vite config.\n *\n * Set to `false` to disable if you configure the Vite plugin manually.\n *\n * @default true\n */\n autoVitePlugin?: boolean\n /**\n * Whether to auto-import composables (useLocalePath, useSwitchLocalePath, useLocaleHead, useI18n).\n *\n * Set to `false` to disable all auto-imports. Useful when migrating from `@nuxtjs/i18n`\n * or when you want explicit imports to avoid naming collisions.\n *\n * @default true\n */\n autoImports?: boolean\n /**\n * Whether to extend routes with locale-prefixed variants.\n *\n * Set to `false` to handle locale routing yourself (e.g., via a custom\n * `pages:extend` hook or Nuxt Layers). When `false`, the module will NOT\n * create locale-suffixed route clones and will NOT remove unprefixed routes.\n *\n * @default true\n */\n extendRoutes?: boolean\n /**\n * Route generation mode for locale variants.\n *\n * - `'all'` (default): All pages get locale route variants unless explicitly\n * opted out via `definePageMeta({ i18n: false })`.\n * - `'opt-in'`: Only pages that explicitly declare `definePageMeta({ i18n: { locales: [...] } })`\n * get locale route variants. Pages without an `i18n` meta field are left untouched.\n *\n * Use `'opt-in'` for large projects where only a subset of pages need i18n routing.\n *\n * @default 'all'\n */\n routeMode?: 'all' | 'opt-in'\n /**\n * Template for generating locale-specific route names.\n *\n * Receives the original route name and locale code, returns the desired name.\n * Only used when `extendRoutes` is not `false`.\n *\n * @default (name, locale) => `${name}___${locale}`\n * @example (name, locale) => `${locale}:${name}`\n */\n routeNameTemplate?: (name: string, locale: string) => string\n /**\n * Custom route paths per locale.\n *\n * Allows different URL slugs for different locales (e.g. `/about` in English\n * becomes `/について` in Japanese).\n *\n * Keys are the original route paths; values are locale-to-path mappings.\n *\n * @example\n * ```ts\n * routeOverrides: {\n * '/about': { ja: '/について', 'zh-CN': '/关于' },\n * '/contact': { ja: '/お問い合わせ' },\n * }\n * ```\n */\n routeOverrides?: Record<string, Record<string, string>>\n /**\n * Whether the locale redirect middleware should be registered globally.\n *\n * Set to `false` to register it as a named middleware instead, so you can\n * apply it only to specific pages via `definePageMeta({ middleware: ['fluenti-locale-redirect'] })`.\n *\n * Only relevant when `strategy` is `'prefix'`.\n *\n * @default true\n */\n globalMiddleware?: boolean\n /**\n * Whether to register the page meta transform plugin.\n *\n * When enabled (default), `defineI18nRoute()` and `definePageMeta({ i18n: ... })`\n * are automatically transformed. Set to `false` to disable the Vite transform.\n *\n * @default true\n */\n pageMetaTransform?: boolean\n /**\n * Whether to register the `NuxtLinkLocale` component globally.\n *\n * Set to `false` to disable registration. You can still import it manually\n * from `@fluenti/nuxt/runtime/components/NuxtLinkLocale`.\n *\n * @default true\n */\n registerNuxtLinkLocale?: boolean\n /**\n * Domain-to-locale mappings for the `'domains'` strategy.\n *\n * Each entry maps a domain hostname to a locale. Required when `strategy` is `'domains'`.\n *\n * Can also be specified inline in locale objects via `{ code: 'ja', domain: 'example.jp' }`.\n *\n * @example\n * ```ts\n * domains: [\n * { domain: 'example.com', locale: 'en', defaultForLocale: true },\n * { domain: 'example.jp', locale: 'ja' },\n * ]\n * ```\n */\n domains?: DomainConfig[]\n /**\n * Incremental Static Regeneration (ISR) settings.\n *\n * When enabled, the module automatically generates `routeRules` with\n * ISR caching for all locale route patterns.\n */\n isr?: ISROptions\n /** Enable @fluenti/vue-i18n-compat bridge mode */\n compat?: boolean\n /**\n * Whether to inject `$localePath` onto `app.config.globalProperties`.\n *\n * Set to `false` if another plugin (e.g. `@nuxtjs/i18n`) already provides `$localePath`,\n * or when using composition API exclusively.\n *\n * @default true\n */\n injectGlobalProperties?: boolean\n /**\n * Callback fired when a translation key is missing from the catalog.\n *\n * Useful for logging, error tracking, or providing dynamic fallbacks.\n */\n onMissingTranslation?: (locale: string, id: string) => string | undefined\n /**\n * Structured error handler for i18n errors.\n */\n onError?: I18nErrorHandler\n /**\n * Generate fallback text when a translation is missing or errors.\n */\n getMessageFallback?: MessageFallbackHandler\n}\n\n/** Structured i18n error types */\nexport type I18nErrorCode = 'MISSING_MESSAGE' | 'MISSING_LOCALE' | 'FORMAT_ERROR' | 'LOAD_ERROR'\n\n/** Structured error passed to the onError callback */\nexport interface I18nError {\n /** Error classification */\n code: I18nErrorCode\n /** Human-readable error message */\n message: string\n /** The message key that caused the error */\n key?: string\n /** The locale that caused the error */\n locale?: string\n /** The original error (if wrapping a lower-level error) */\n cause?: unknown\n}\n\n/** Callback for structured i18n error handling */\nexport type I18nErrorHandler = (error: I18nError) => void\n\n/**\n * Callback to generate fallback text when a translation is missing or errors.\n *\n * Return a string to use as the fallback, or `undefined` for default behavior\n * (which shows the message key).\n */\nexport type MessageFallbackHandler = (error: I18nError) => string | undefined\n\n/** ISR configuration */\nexport interface ISROptions {\n /** Enable ISR route rules generation */\n enabled: boolean\n /** Cache TTL in seconds (default: 3600 — 1 hour) */\n ttl?: number\n}\n\n/** Runtime config injected into Nuxt's public runtimeConfig */\nexport interface FluentNuxtRuntimeConfig {\n locales: string[]\n defaultLocale: string\n strategy: Strategy\n detectBrowserLanguage?: DetectBrowserLanguageOptions\n /** Ordered list of detector names/paths */\n detectOrder: Array<string>\n /** Query parameter name for locale detection */\n queryParamKey: string\n /** Whether to inject $localePath onto globalProperties */\n injectGlobalProperties: boolean\n /** Domain-to-locale mappings (when strategy is 'domains') */\n domains?: DomainConfig[]\n /** Locale metadata (iso tags, dir, names) — keyed by locale code */\n localeProperties?: Record<string, LocaleObject>\n}\n\n// ---- Utility helpers ----\n\n/** Build a locale properties map from LocaleDefinition[] */\nexport function resolveLocaleProperties(locales: LocaleDefinition[]): Record<string, LocaleObject> {\n const map: Record<string, LocaleObject> = {}\n for (const l of locales) {\n if (typeof l === 'string') {\n map[l] = { code: l }\n } else {\n map[l.code] = l\n }\n }\n return map\n}\n\n/** Build domain configs from locale objects that have a `domain` field */\nexport function resolveDomainConfigs(\n locales: LocaleDefinition[],\n explicit?: DomainConfig[],\n): DomainConfig[] {\n if (explicit?.length) return explicit\n const configs: DomainConfig[] = []\n for (const l of locales) {\n if (typeof l !== 'string' && l.domain) {\n configs.push({ domain: l.domain, locale: l.code })\n }\n }\n return configs\n}\n","import type { FluentNuxtOptions, Strategy } from './types'\n\nexport interface ISRWarning {\n level: 'warn' | 'error'\n message: string\n}\n\n/**\n * Validate ISR configuration against locale detection settings.\n *\n * ISR caches responses by URL path. If locale detection relies on\n * non-path signals (cookies, headers), the cached response may serve\n * the wrong locale to subsequent visitors.\n */\nexport function validateISRConfig(\n isr: FluentNuxtOptions['isr'],\n strategy: Strategy,\n detectOrder: string[],\n): ISRWarning[] {\n const warnings: ISRWarning[] = []\n if (!isr?.enabled) return warnings\n\n const nonPathDetectors = detectOrder.filter(\n (d) => d === 'cookie' || d === 'header',\n )\n if (nonPathDetectors.length > 0) {\n warnings.push({\n level: 'warn',\n message:\n `[@fluenti/nuxt] ISR is enabled but detectOrder includes non-path ` +\n `detectors (${nonPathDetectors.join(', ')}). ISR caches by URL path, ` +\n `so cookie/header-based detection may serve the wrong locale from ` +\n `cache. Consider using detectOrder: ['path'] with ISR.`,\n })\n }\n\n if (strategy === 'no_prefix') {\n warnings.push({\n level: 'warn',\n message:\n `[@fluenti/nuxt] ISR is enabled with strategy: 'no_prefix'. All ` +\n `locales share the same URL path, so ISR will cache only one locale ` +\n `per URL. Use 'prefix' or 'prefix_except_default' strategy with ISR.`,\n })\n }\n\n return warnings\n}\n","import type { Nuxt } from '@nuxt/schema'\n\n/**\n * DevTools state exposed to the custom tab.\n * Serialized to JSON and sent to the DevTools panel.\n */\nexport interface DevToolsI18nState {\n currentLocale: string\n availableLocales: string[]\n defaultLocale: string\n strategy: string\n detectedBy: string\n messageCount: number\n loadedLocales: string[]\n missingKeys: string[]\n}\n\n/**\n * Register a Nuxt DevTools custom tab for Fluenti.\n *\n * Shows: current locale, available locales, detection chain result,\n * loaded message count, and missing translation keys.\n */\nexport function setupDevTools(nuxt: Nuxt, localeCodes: string[], defaultLocale: string, strategy: string): void {\n try {\n // Attempt to use @nuxt/devtools-kit if available\n // @ts-expect-error — devtools:customTabs hook is provided by @nuxt/devtools\n nuxt.hook('devtools:customTabs', (tabs: unknown[]) => {\n tabs.push({\n name: 'fluenti',\n title: 'Fluenti i18n',\n icon: 'i-carbon-translate',\n view: {\n type: 'client-component',\n componentName: 'FluentiDevToolsPanel',\n },\n })\n })\n } catch {\n // DevTools not available — silently skip\n }\n\n // Inject DevTools client component via virtual module\n // @ts-expect-error — nitro:config hook is provided by Nitro\n nuxt.hook('nitro:config', (nitroConfig: Record<string, unknown>) => {\n const publicConfig = nitroConfig['runtimeConfig'] as Record<string, unknown> | undefined\n if (publicConfig) {\n const pub = (publicConfig['public'] ?? (publicConfig['public'] = {})) as Record<string, unknown>\n const fluentiConfig = (pub['fluenti'] ?? {}) as Record<string, unknown>\n fluentiConfig['devtools'] = {\n enabled: true,\n locales: localeCodes,\n defaultLocale,\n strategy,\n }\n }\n })\n}\n\n/**\n * Client-side DevTools panel component source.\n *\n * This is injected as a virtual module and rendered inside the\n * Nuxt DevTools panel. It reads the Fluenti runtime state and\n * displays it in a simple, readable format.\n */\nexport const DEVTOOLS_PANEL_COMPONENT = `\n<template>\n <div style=\"padding: 16px; font-family: system-ui, sans-serif;\">\n <h2 style=\"margin: 0 0 16px; font-size: 18px;\">🌐 Fluenti i18n</h2>\n\n <div style=\"display: grid; grid-template-columns: 140px 1fr; gap: 8px 16px; font-size: 14px;\">\n <span style=\"color: #888;\">Current locale:</span>\n <strong>{{ state.currentLocale }}</strong>\n\n <span style=\"color: #888;\">Default locale:</span>\n <span>{{ state.defaultLocale }}</span>\n\n <span style=\"color: #888;\">Strategy:</span>\n <span>{{ state.strategy }}</span>\n\n <span style=\"color: #888;\">Available:</span>\n <span>{{ state.availableLocales.join(', ') }}</span>\n\n <span style=\"color: #888;\">Loaded:</span>\n <span>{{ state.loadedLocales.join(', ') || 'none' }}</span>\n\n <span style=\"color: #888;\">Messages:</span>\n <span>{{ state.messageCount }}</span>\n\n <span style=\"color: #888;\">Missing keys:</span>\n <span :style=\"{ color: state.missingKeys.length > 0 ? '#e53e3e' : '#38a169' }\">\n {{ state.missingKeys.length > 0 ? state.missingKeys.length + ' missing' : 'All translated ✓' }}\n </span>\n </div>\n\n <div v-if=\"state.missingKeys.length > 0\" style=\"margin-top: 16px;\">\n <h3 style=\"margin: 0 0 8px; font-size: 14px; color: #e53e3e;\">Missing translations:</h3>\n <ul style=\"margin: 0; padding: 0 0 0 20px; font-size: 13px; font-family: monospace;\">\n <li v-for=\"key in state.missingKeys\" :key=\"key\" style=\"margin: 2px 0;\">{{ key }}</li>\n </ul>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, onMounted } from 'vue'\n\nconst state = ref({\n currentLocale: '',\n defaultLocale: '',\n strategy: '',\n availableLocales: [],\n loadedLocales: [],\n messageCount: 0,\n missingKeys: [],\n})\n\nonMounted(() => {\n try {\n const nuxtApp = window.__NUXT_DEVTOOLS_VIEW__?.nuxtApp ?? useNuxtApp()\n const config = nuxtApp.$config?.public?.fluenti ?? {}\n const fluentiLocale = nuxtApp.$fluentiLocale ?? ref('')\n\n state.value = {\n currentLocale: fluentiLocale.value || config.defaultLocale || '',\n defaultLocale: config.defaultLocale || '',\n strategy: config.strategy || '',\n availableLocales: config.locales || [],\n loadedLocales: [],\n messageCount: 0,\n missingKeys: [],\n }\n } catch (e) {\n // DevTools context not available\n }\n})\n</script>\n`\n","import type { Plugin } from 'vite'\n\n/**\n * Vite plugin that transforms `definePageMeta({ i18n: ... })` into\n * the internal `i18nRoute` format used by the page extension system.\n *\n * This allows users to use native Nuxt `definePageMeta` with an `i18n` key\n * instead of the separate `defineI18nRoute()` macro.\n *\n * Supports:\n * - `definePageMeta({ i18n: { locales: ['en', 'ja'] } })`\n * - `definePageMeta({ i18n: false })`\n *\n * The transform also rewrites `defineI18nRoute(...)` to\n * `definePageMeta({ i18nRoute: ... })` for backwards compatibility.\n */\nexport function createPageMetaTransform(): Plugin {\n return {\n name: 'fluenti:page-meta-transform',\n enforce: 'pre',\n\n transform(code, id) {\n // Only transform Vue SFC script blocks and TS/JS files in pages/\n if (!id.includes('/pages/') && !id.includes('\\\\pages\\\\')) return null\n if (!code.includes('defineI18nRoute') && !code.includes('i18n')) return null\n\n let transformed = code\n\n // Transform: defineI18nRoute({ locales: [...] })\n // → definePageMeta({ i18nRoute: { locales: [...] } })\n // Transform: defineI18nRoute(false)\n // → definePageMeta({ i18nRoute: false })\n if (transformed.includes('defineI18nRoute')) {\n transformed = transformed.replace(\n /defineI18nRoute\\s*\\(([^)]*?)\\)/g,\n (_match, arg: string) => `definePageMeta({ i18nRoute: ${arg.trim()} })`,\n )\n }\n\n // Support native: definePageMeta({ i18n: { locales: [...] } })\n // Rewrite `i18n:` key to `i18nRoute:` so page-extend can read it\n if (transformed.includes('definePageMeta') && transformed.includes('i18n:')) {\n // Simple regex for { i18n: ... } within definePageMeta\n // This handles the common case; complex nested objects may need\n // AST-based transformation in the future.\n transformed = transformed.replace(\n /(definePageMeta\\s*\\(\\s*\\{[^}]*?)\\bi18n\\s*:/g,\n '$1i18nRoute:',\n )\n }\n\n if (transformed === code) return null\n\n return {\n code: transformed,\n map: null,\n }\n },\n }\n}\n","import type { Strategy } from './types'\n\nexport interface SitemapUrl {\n loc: string\n alternatives?: Array<{ hreflang: string; href: string }>\n}\n\n/**\n * Generate multi-locale sitemap URLs from a list of base paths.\n *\n * For each base path, produces a URL entry with hreflang alternatives\n * pointing to every locale variant. Compatible with `@nuxtjs/sitemap`'s\n * `sources` hook format.\n */\nexport function generateSitemapUrls(\n paths: string[],\n locales: string[],\n defaultLocale: string,\n strategy: Strategy,\n baseUrl?: string,\n): SitemapUrl[] {\n const urls: SitemapUrl[] = []\n const base = baseUrl ?? ''\n\n for (const rawPath of paths) {\n const path = rawPath.startsWith('/') ? rawPath : `/${rawPath}`\n\n for (const locale of locales) {\n const localizedPath = buildLocalePath(path, locale, defaultLocale, strategy)\n\n const alternatives = locales.map((altLocale) => ({\n hreflang: altLocale,\n href: `${base}${buildLocalePath(path, altLocale, defaultLocale, strategy)}`,\n }))\n\n // Add x-default pointing to default locale\n alternatives.push({\n hreflang: 'x-default',\n href: `${base}${buildLocalePath(path, defaultLocale, defaultLocale, strategy)}`,\n })\n\n urls.push({\n loc: `${base}${localizedPath}`,\n alternatives,\n })\n }\n }\n\n return urls\n}\n\nfunction buildLocalePath(\n path: string,\n locale: string,\n defaultLocale: string,\n strategy: Strategy,\n): string {\n if (strategy === 'no_prefix') return path\n\n if (strategy === 'prefix_except_default' && locale === defaultLocale) {\n return path\n }\n\n const cleanPath = path === '/' ? '' : path\n return `/${locale}${cleanPath}`\n}\n\n/**\n * Hook handler for `@nuxtjs/sitemap`'s `sitemap:generate` hook.\n *\n * Transforms single-locale URLs into multi-locale entries with hreflang.\n * Register this in your nuxt.config.ts or let the module auto-register it.\n */\nexport function createSitemapHook(\n locales: string[],\n defaultLocale: string,\n strategy: Strategy,\n baseUrl?: string,\n) {\n return (urls: SitemapUrl[]) => {\n if (strategy === 'no_prefix') return urls\n\n const expanded: SitemapUrl[] = []\n\n for (const url of urls) {\n const loc = url.loc.replace(/^https?:\\/\\/[^/]+/, '')\n\n for (const locale of locales) {\n const localizedPath = buildLocalePath(loc, locale, defaultLocale, strategy)\n const alternatives = locales.map((altLocale) => ({\n hreflang: altLocale,\n href: `${baseUrl ?? ''}${buildLocalePath(loc, altLocale, defaultLocale, strategy)}`,\n }))\n alternatives.push({\n hreflang: 'x-default',\n href: `${baseUrl ?? ''}${buildLocalePath(loc, defaultLocale, defaultLocale, strategy)}`,\n })\n\n expanded.push({\n loc: `${baseUrl ?? ''}${localizedPath}`,\n alternatives,\n })\n }\n }\n\n return expanded\n }\n}\n","import { defineNuxtModule, addPlugin, addImports, addComponent, addRouteMiddleware, addServerHandler, createResolver } from '@nuxt/kit'\nimport type { FluentNuxtOptions } from './types'\nimport { resolveLocaleProperties, resolveDomainConfigs } from './types'\nimport { resolveLocaleCodes } from '@fluenti/core/compiler'\nimport type { FluentiBuildConfig } from '@fluenti/core/compiler'\nimport { DEFAULT_FLUENTI_CONFIG, loadConfigSync } from '@fluenti/core/config'\nimport fluentiVue from '@fluenti/vue/vite-plugin'\nimport { extendPages } from './runtime/page-extend'\nimport { validateISRConfig } from './isr-validation'\nimport { setupDevTools } from './devtools'\nimport { createPageMetaTransform } from './page-meta-transform'\n\nexport type { FluentNuxtOptions, Strategy, FluentNuxtRuntimeConfig, DetectBrowserLanguageOptions, LocaleDetectContext, LocaleDetectorFn, BuiltinDetector, ISROptions, LocaleObject, LocaleDefinition, DomainConfig, I18nRouteConfig, I18nError, I18nErrorCode, I18nErrorHandler, MessageFallbackHandler } from './types'\nexport { generateSitemapUrls, createSitemapHook } from './sitemap'\nexport type { SitemapUrl } from './sitemap'\nexport { resolveLocaleProperties, resolveDomainConfigs } from './types'\nexport { resolveLocaleCodes } from '@fluenti/core/compiler'\nexport { localePath, extractLocaleFromPath, switchLocalePath } from './runtime/path-utils'\nexport { extendPages } from './runtime/page-extend'\nexport type { PageRoute, RouteNameTemplate, ExtendPagesOptions } from './runtime/page-extend'\nexport { buildLocaleHead } from './runtime/locale-head'\nexport type { LocaleHeadMeta, LocaleHeadOptions } from './runtime/locale-head'\nexport { useLocalePath, useSwitchLocalePath, useLocaleRoute, useLocaleHead } from './runtime/standalone-composables'\nexport { defineI18nRoute } from './runtime/define-i18n-route'\n\nexport const MODULE_NAME = '@fluenti/nuxt'\nexport const CONFIG_KEY = 'fluenti'\n\ntype PortableNuxtModule<TOptions> = {\n (this: void, resolvedOptions: TOptions, nuxt: any): any\n getOptions?: (inlineOptions?: Partial<TOptions>, nuxt?: any) => Promise<TOptions>\n getModuleDependencies?: (nuxt: any) => any\n getMeta?: () => Promise<any>\n onInstall?: (nuxt: any) => any\n onUpgrade?: (nuxt: any, options: TOptions, previousVersion: string) => any\n}\n\n/**\n * Resolve the FluentiBuildConfig from the module options.\n */\nfunction resolveFluentiBuildConfig(configOption: string | FluentiBuildConfig | undefined, rootDir: string): FluentiBuildConfig {\n\n if (typeof configOption === 'object') {\n return { ...DEFAULT_FLUENTI_CONFIG, ...configOption }\n }\n\n return loadConfigSync(\n typeof configOption === 'string' ? configOption : undefined,\n rootDir,\n )\n}\n\nconst fluentiNuxtModule: PortableNuxtModule<FluentNuxtOptions> = defineNuxtModule<FluentNuxtOptions>({\n meta: {\n name: MODULE_NAME,\n configKey: CONFIG_KEY,\n compatibility: { nuxt: '>=3.0.0' },\n },\n defaults: {\n strategy: 'prefix_except_default',\n },\n setup(options, nuxt) {\n const { resolve } = createResolver(import.meta.url)\n\n // --- Resolve FluentiBuildConfig from options.config, then overlay module-level options ---\n const rootDir = nuxt.options.rootDir ?? process.cwd()\n const fluentiConfig = resolveFluentiBuildConfig(options.config, rootDir)\n\n // Module-level options (e.g. nuxt.config.ts `fluenti.locales`) override the\n // resolved fluenti.config.ts values — this ensures Nuxt-specific config takes\n // precedence even when config file loading fails (e.g. CJS/jiti issues).\n if (options.locales) fluentiConfig.locales = options.locales\n if (options.defaultLocale) fluentiConfig.defaultLocale = options.defaultLocale\n if (options.sourceLocale) fluentiConfig.sourceLocale = options.sourceLocale\n if (options.catalogDir) fluentiConfig.catalogDir = options.catalogDir\n\n // --- Resolve locale codes and metadata ---\n const localeCodes = resolveLocaleCodes(fluentiConfig.locales)\n const localeProperties = resolveLocaleProperties(fluentiConfig.locales)\n const defaultLocale = fluentiConfig.defaultLocale ?? fluentiConfig.sourceLocale\n const domainConfigs = options.strategy === 'domains'\n ? resolveDomainConfigs(fluentiConfig.locales, options.domains)\n : undefined\n\n // --- Inject runtime config ---\n const detectOrder = options.detectOrder ?? (\n options.strategy === 'domains'\n ? ['domain', 'cookie', 'header']\n : ['path', 'cookie', 'header']\n )\n nuxt.options.runtimeConfig.public['fluenti'] = {\n locales: localeCodes,\n defaultLocale,\n strategy: options.strategy ?? 'prefix_except_default',\n detectBrowserLanguage: options.detectBrowserLanguage,\n detectOrder,\n queryParamKey: options.queryParamKey ?? 'locale',\n injectGlobalProperties: options.injectGlobalProperties !== false,\n ...(domainConfigs ? { domains: domainConfigs } : {}),\n localeProperties,\n }\n\n // --- Auto-register @fluenti/vue vite plugin (includes v-t transform + scope transform) ---\n if (options.autoVitePlugin !== false) {\n nuxt.options.vite = nuxt.options.vite || {}\n nuxt.options.vite.plugins = nuxt.options.vite.plugins || []\n ;(nuxt.options.vite.plugins as unknown[]).push(\n ...fluentiVue({ config: fluentiConfig }),\n )\n }\n\n // --- Register definePageMeta({ i18n }) transform ---\n if (options.pageMetaTransform !== false) {\n nuxt.options.vite = nuxt.options.vite || {}\n nuxt.options.vite.plugins = nuxt.options.vite.plugins || []\n ;(nuxt.options.vite.plugins as unknown[]).push(createPageMetaTransform())\n }\n\n // --- Register runtime plugin ---\n addPlugin({\n src: resolve('./runtime/plugin'),\n mode: 'all',\n })\n\n // --- Extend routes with locale prefixes ---\n const strategy = options.strategy ?? 'prefix_except_default'\n if (strategy !== 'no_prefix' && strategy !== 'domains' && options.extendRoutes !== false) {\n nuxt.hook('pages:extend', (pages) => {\n extendPages(pages, {\n locales: localeCodes,\n defaultLocale,\n strategy,\n ...(options.routeNameTemplate ? { routeNameTemplate: options.routeNameTemplate } : {}),\n ...(options.routeOverrides ? { routeOverrides: options.routeOverrides } : {}),\n ...(options.routeMode ? { routeMode: options.routeMode } : {}),\n })\n })\n }\n\n // --- Register locale redirect middleware ---\n if (strategy === 'prefix') {\n addRouteMiddleware({\n name: 'fluenti-locale-redirect',\n path: resolve('./runtime/middleware/locale-redirect'),\n global: options.globalMiddleware !== false,\n })\n }\n\n // --- Auto-import composables ---\n if (options.autoImports !== false) {\n addImports([\n { name: 'useLocalePath', from: resolve('./runtime/composables') },\n { name: 'useSwitchLocalePath', from: resolve('./runtime/composables') },\n { name: 'useLocaleRoute', from: resolve('./runtime/composables') },\n { name: 'useLocaleHead', from: resolve('./runtime/composables') },\n { name: 'useI18nScoped', from: resolve('./runtime/composables') },\n { name: 'useI18n', from: '@fluenti/vue' },\n { name: 'defineI18nRoute', from: resolve('./runtime/define-i18n-route') },\n ])\n }\n\n // --- Register components (including DateTime + NumberFormat) ---\n const prefix = options.componentPrefix ?? ''\n if (options.registerNuxtLinkLocale !== false) {\n addComponent({\n name: `${prefix}NuxtLinkLocale`,\n filePath: resolve('./runtime/components/NuxtLinkLocale'),\n })\n }\n\n // Auto-import DateTime and NumberFormat from @fluenti/vue\n addComponent({ name: `${prefix}Trans`, filePath: '@fluenti/vue/components', export: 'Trans' })\n addComponent({ name: `${prefix}Plural`, filePath: '@fluenti/vue/components', export: 'Plural' })\n addComponent({ name: `${prefix}Select`, filePath: '@fluenti/vue/components', export: 'Select' })\n addComponent({ name: `${prefix}DateTime`, filePath: '@fluenti/vue/components', export: 'DateTime' })\n addComponent({ name: `${prefix}NumberFormat`, filePath: '@fluenti/vue/components', export: 'NumberFormat' })\n\n // --- SSG / ISR: configure nitro prerender and route rules ---\n if (strategy !== 'no_prefix' && strategy !== 'domains') {\n const nuxtOpts = nuxt.options as unknown as Record<string, unknown>\n\n // Enable link crawling so locale-prefixed routes are discovered during prerender\n const nitroOpts = (nuxtOpts['nitro'] ?? (nuxtOpts['nitro'] = {})) as Record<string, unknown>\n const prerender = (nitroOpts['prerender'] ?? (nitroOpts['prerender'] = {})) as Record<string, unknown>\n prerender['crawlLinks'] = prerender['crawlLinks'] ?? true\n\n // For 'prefix' strategy, / has no matching route (all routes are\n // locale-prefixed). Replace the default / initial route with\n // /<defaultLocale> so the prerenderer starts from a valid route.\n if (strategy === 'prefix') {\n const routes = (prerender['routes'] ?? ['/']) as string[]\n prerender['routes'] = routes.map((r) =>\n r === '/' ? `/${defaultLocale}` : r,\n )\n }\n\n // ISR: validate configuration and generate routeRules\n for (const w of validateISRConfig(options.isr, strategy, detectOrder)) {\n console.warn(w.message)\n }\n if (options.isr?.enabled) {\n const routeRules = (nuxtOpts['routeRules'] ?? (nuxtOpts['routeRules'] = {})) as Record<string, Record<string, unknown>>\n const ttl = options.isr.ttl ?? 3600\n for (const locale of localeCodes) {\n if (locale === defaultLocale && strategy === 'prefix_except_default') {\n routeRules['/**'] = { ...routeRules['/**'], isr: ttl }\n } else {\n routeRules[`/${locale}/**`] = { ...routeRules[`/${locale}/**`], isr: ttl }\n }\n }\n }\n }\n\n // --- Nuxt DevTools integration ---\n if (nuxt.options.dev) {\n setupDevTools(nuxt as any, localeCodes, defaultLocale, strategy)\n }\n\n // --- Nitro server handler for locale redirect (T2-10) ---\n if (strategy === 'prefix' || strategy === 'prefix_and_default') {\n addServerHandler({\n handler: resolve('./runtime/server/locale-redirect'),\n middleware: true,\n })\n }\n },\n})\n\nexport default fluentiNuxtModule\n"],"mappings":"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"}
package/dist/module.js CHANGED
@@ -4,16 +4,16 @@ import { t as i } from "./locale-head-Ezrd93Ax.js";
4
4
  import { useLocaleHead as a, useLocalePath as o, useLocaleRoute as s, useSwitchLocalePath as c } from "./runtime/standalone-composables.js";
5
5
  import { defineI18nRoute as l } from "./runtime/define-i18n-route.js";
6
6
  import { addComponent as u, addImports as d, addPlugin as f, addRouteMiddleware as p, addServerHandler as m, createResolver as h, defineNuxtModule as g } from "@nuxt/kit";
7
- import { createRequire as _ } from "node:module";
8
- import { resolveLocaleCodes as v, resolveLocaleCodes as y } from "@fluenti/core/internal";
9
- import b from "@fluenti/vue/vite-plugin";
7
+ import { resolveLocaleCodes as _, resolveLocaleCodes as v } from "@fluenti/core/compiler";
8
+ import { DEFAULT_FLUENTI_CONFIG as y, loadConfigSync as b } from "@fluenti/core/config";
9
+ import x from "@fluenti/vue/vite-plugin";
10
10
  //#region src/types.ts
11
- function x(e) {
11
+ function S(e) {
12
12
  let t = {};
13
13
  for (let n of e) typeof n == "string" ? t[n] = { code: n } : t[n.code] = n;
14
14
  return t;
15
15
  }
16
- function S(e, t) {
16
+ function C(e, t) {
17
17
  if (t?.length) return t;
18
18
  let n = [];
19
19
  for (let t of e) typeof t != "string" && t.domain && n.push({
@@ -24,7 +24,7 @@ function S(e, t) {
24
24
  }
25
25
  //#endregion
26
26
  //#region src/isr-validation.ts
27
- function C(e, t, n) {
27
+ function w(e, t, n) {
28
28
  let r = [];
29
29
  if (!e?.enabled) return r;
30
30
  let i = n.filter((e) => e === "cookie" || e === "header");
@@ -38,7 +38,7 @@ function C(e, t, n) {
38
38
  }
39
39
  //#endregion
40
40
  //#region src/devtools.ts
41
- function w(e, t, n, r) {
41
+ function T(e, t, n, r) {
42
42
  try {
43
43
  e.hook("devtools:customTabs", (e) => {
44
44
  e.push({
@@ -67,7 +67,7 @@ function w(e, t, n, r) {
67
67
  }
68
68
  //#endregion
69
69
  //#region src/page-meta-transform.ts
70
- function T() {
70
+ function E() {
71
71
  return {
72
72
  name: "fluenti:page-meta-transform",
73
73
  enforce: "pre",
@@ -83,18 +83,18 @@ function T() {
83
83
  }
84
84
  //#endregion
85
85
  //#region src/sitemap.ts
86
- function E(e, t, n, r, i) {
86
+ function D(e, t, n, r, i) {
87
87
  let a = [], o = i ?? "";
88
88
  for (let i of e) {
89
89
  let e = i.startsWith("/") ? i : `/${i}`;
90
90
  for (let i of t) {
91
- let s = D(e, i, n, r), c = t.map((t) => ({
91
+ let s = O(e, i, n, r), c = t.map((t) => ({
92
92
  hreflang: t,
93
- href: `${o}${D(e, t, n, r)}`
93
+ href: `${o}${O(e, t, n, r)}`
94
94
  }));
95
95
  c.push({
96
96
  hreflang: "x-default",
97
- href: `${o}${D(e, n, n, r)}`
97
+ href: `${o}${O(e, n, n, r)}`
98
98
  }), a.push({
99
99
  loc: `${o}${s}`,
100
100
  alternatives: c
@@ -103,23 +103,23 @@ function E(e, t, n, r, i) {
103
103
  }
104
104
  return a;
105
105
  }
106
- function D(e, t, n, r) {
106
+ function O(e, t, n, r) {
107
107
  return r === "no_prefix" || r === "prefix_except_default" && t === n ? e : `/${t}${e === "/" ? "" : e}`;
108
108
  }
109
- function O(e, t, n, r) {
109
+ function k(e, t, n, r) {
110
110
  return (i) => {
111
111
  if (n === "no_prefix") return i;
112
112
  let a = [];
113
113
  for (let o of i) {
114
114
  let i = o.loc.replace(/^https?:\/\/[^/]+/, "");
115
115
  for (let o of e) {
116
- let s = D(i, o, t, n), c = e.map((e) => ({
116
+ let s = O(i, o, t, n), c = e.map((e) => ({
117
117
  hreflang: e,
118
- href: `${r ?? ""}${D(i, e, t, n)}`
118
+ href: `${r ?? ""}${O(i, e, t, n)}`
119
119
  }));
120
120
  c.push({
121
121
  hreflang: "x-default",
122
- href: `${r ?? ""}${D(i, t, t, n)}`
122
+ href: `${r ?? ""}${O(i, t, t, n)}`
123
123
  }), a.push({
124
124
  loc: `${r ?? ""}${s}`,
125
125
  alternatives: c
@@ -131,29 +131,24 @@ function O(e, t, n, r) {
131
131
  }
132
132
  //#endregion
133
133
  //#region src/module.ts
134
- var k = "@fluenti/nuxt", A = "fluenti", j = _(typeof __filename < "u" ? __filename : import.meta.url);
134
+ var A = "@fluenti/nuxt", j = "fluenti";
135
135
  function M(e, t) {
136
- if (typeof e == "object") {
137
- let { DEFAULT_FLUENTI_CONFIG: t } = j("@fluenti/core/config");
138
- return {
139
- ...t,
140
- ...e
141
- };
142
- }
143
- let { loadConfigSync: n } = j("@fluenti/core/config");
144
- return n(typeof e == "string" ? e : void 0, t);
136
+ return typeof e == "object" ? {
137
+ ...y,
138
+ ...e
139
+ } : b(typeof e == "string" ? e : void 0, t);
145
140
  }
146
141
  var N = g({
147
142
  meta: {
148
- name: k,
149
- configKey: A,
143
+ name: A,
144
+ configKey: j,
150
145
  compatibility: { nuxt: ">=3.0.0" }
151
146
  },
152
147
  defaults: { strategy: "prefix_except_default" },
153
148
  setup(t, n) {
154
149
  let { resolve: r } = h(import.meta.url), i = n.options.rootDir ?? process.cwd(), a = M(t.config, i);
155
150
  t.locales && (a.locales = t.locales), t.defaultLocale && (a.defaultLocale = t.defaultLocale), t.sourceLocale && (a.sourceLocale = t.sourceLocale), t.catalogDir && (a.catalogDir = t.catalogDir);
156
- let o = y(a.locales), s = x(a.locales), c = a.defaultLocale ?? a.sourceLocale, l = t.strategy === "domains" ? S(a.locales, t.domains) : void 0, g = t.detectOrder ?? (t.strategy === "domains" ? [
151
+ let o = v(a.locales), s = S(a.locales), c = a.defaultLocale ?? a.sourceLocale, l = t.strategy === "domains" ? C(a.locales, t.domains) : void 0, g = t.detectOrder ?? (t.strategy === "domains" ? [
157
152
  "domain",
158
153
  "cookie",
159
154
  "header"
@@ -172,7 +167,7 @@ var N = g({
172
167
  injectGlobalProperties: t.injectGlobalProperties !== !1,
173
168
  ...l ? { domains: l } : {},
174
169
  localeProperties: s
175
- }, t.autoVitePlugin !== !1 && (n.options.vite = n.options.vite || {}, n.options.vite.plugins = n.options.vite.plugins || [], n.options.vite.plugins.push(...b({ config: a }))), t.pageMetaTransform !== !1 && (n.options.vite = n.options.vite || {}, n.options.vite.plugins = n.options.vite.plugins || [], n.options.vite.plugins.push(T())), f({
170
+ }, t.autoVitePlugin !== !1 && (n.options.vite = n.options.vite || {}, n.options.vite.plugins = n.options.vite.plugins || [], n.options.vite.plugins.push(...x({ config: a }))), t.pageMetaTransform !== !1 && (n.options.vite = n.options.vite || {}, n.options.vite.plugins = n.options.vite.plugins || [], n.options.vite.plugins.push(E())), f({
176
171
  src: r("./runtime/plugin"),
177
172
  mode: "all"
178
173
  });
@@ -220,34 +215,34 @@ var N = g({
220
215
  from: r("./runtime/define-i18n-route")
221
216
  }
222
217
  ]);
223
- let v = t.componentPrefix ?? "";
218
+ let y = t.componentPrefix ?? "";
224
219
  if (t.registerNuxtLinkLocale !== !1 && u({
225
- name: `${v}NuxtLinkLocale`,
220
+ name: `${y}NuxtLinkLocale`,
226
221
  filePath: r("./runtime/components/NuxtLinkLocale")
227
222
  }), u({
228
- name: `${v}Trans`,
223
+ name: `${y}Trans`,
229
224
  filePath: "@fluenti/vue/components",
230
225
  export: "Trans"
231
226
  }), u({
232
- name: `${v}Plural`,
227
+ name: `${y}Plural`,
233
228
  filePath: "@fluenti/vue/components",
234
229
  export: "Plural"
235
230
  }), u({
236
- name: `${v}Select`,
231
+ name: `${y}Select`,
237
232
  filePath: "@fluenti/vue/components",
238
233
  export: "Select"
239
234
  }), u({
240
- name: `${v}DateTime`,
235
+ name: `${y}DateTime`,
241
236
  filePath: "@fluenti/vue/components",
242
237
  export: "DateTime"
243
238
  }), u({
244
- name: `${v}NumberFormat`,
239
+ name: `${y}NumberFormat`,
245
240
  filePath: "@fluenti/vue/components",
246
241
  export: "NumberFormat"
247
242
  }), _ !== "no_prefix" && _ !== "domains") {
248
243
  let e = n.options, r = e.nitro ??= {}, i = r.prerender ??= {};
249
244
  i.crawlLinks = i.crawlLinks ?? !0, _ === "prefix" && (i.routes = (i.routes ?? ["/"]).map((e) => e === "/" ? `/${c}` : e));
250
- for (let e of C(t.isr, _, g)) console.warn(e.message);
245
+ for (let e of w(t.isr, _, g)) console.warn(e.message);
251
246
  if (t.isr?.enabled) {
252
247
  let n = e.routeRules ??= {}, r = t.isr.ttl ?? 3600;
253
248
  for (let e of o) e === c && _ === "prefix_except_default" ? n["/**"] = {
@@ -259,13 +254,13 @@ var N = g({
259
254
  };
260
255
  }
261
256
  }
262
- n.options.dev && w(n, o, c, _), (_ === "prefix" || _ === "prefix_and_default") && m({
257
+ n.options.dev && T(n, o, c, _), (_ === "prefix" || _ === "prefix_and_default") && m({
263
258
  handler: r("./runtime/server/locale-redirect"),
264
259
  middleware: !0
265
260
  });
266
261
  }
267
262
  });
268
263
  //#endregion
269
- export { A as CONFIG_KEY, k as MODULE_NAME, i as buildLocaleHead, O as createSitemapHook, N as default, l as defineI18nRoute, e as extendPages, r as extractLocaleFromPath, E as generateSitemapUrls, t as localePath, S as resolveDomainConfigs, v as resolveLocaleCodes, x as resolveLocaleProperties, n as switchLocalePath, a as useLocaleHead, o as useLocalePath, s as useLocaleRoute, c as useSwitchLocalePath };
264
+ export { j as CONFIG_KEY, A as MODULE_NAME, i as buildLocaleHead, k as createSitemapHook, N as default, l as defineI18nRoute, e as extendPages, r as extractLocaleFromPath, D as generateSitemapUrls, t as localePath, C as resolveDomainConfigs, _ as resolveLocaleCodes, S as resolveLocaleProperties, n as switchLocalePath, a as useLocaleHead, o as useLocalePath, s as useLocaleRoute, c as useSwitchLocalePath };
270
265
 
271
266
  //# sourceMappingURL=module.js.map