@i18n-micro/route-strategy 1.1.9 → 1.1.12

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.
@@ -0,0 +1,3 @@
1
+ import { LocaleRoutesConfig } from '../strategies/types';
2
+ /** True when localization is disabled via `globalLocaleRoutes[key] === false`. */
3
+ export declare function isLocalizationDisabledForPage(globalLocaleRoutes: LocaleRoutesConfig, originalPath: string, pageName: string): boolean;
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const w=require("node:path"),S=require("node:fs"),k=require("@i18n-micro/core"),b=l=>l.map(e=>({...e})),K=l=>!!(l.redirect&&!l.file),F=(l,e,t,s="localized-")=>t?`${s}${l}-${e}`:`${s}${l}`,C=(l,e)=>l??(e??"").replace(/[^a-z0-9]/gi,"-").replace(/^-+|-+$/g,""),M=(l,e,t)=>t&&l!==e.code,T=(l,e)=>(typeof l=="string"?l:l.code)===e.code,H=[/^\/sitemap.*\.xml$/,/^\/sitemap\.xml$/,/^\/robots\.txt$/,/^\/favicon\.ico$/,/^\/apple-touch-icon.*\.png$/,/^\/manifest\.json$/,/^\/sw\.js$/,/^\/workbox-.*\.js$/,/\.(xml|txt|ico|json|js|css|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$/];function E(l,e){if(/(?:^|\/)__[^/]+/.test(l))return!0;for(const t of H)if(t.test(l))return!0;if(e){for(const t of e)if(typeof t=="string"){if(t.includes("*")||t.includes("?")){if(new RegExp(t.replace(/\*/g,".*").replace(/\?/g,".")).test(l))return!0}else if(l===t||l.startsWith(t))return!0}else if(t instanceof RegExp&&t.test(l))return!0}return!1}function J(l,e){const t=l.reduce((o,a)=>{const r=o.find(i=>i.code===a.code);return r?Object.assign(r,a):o.push(a),o},[]).filter(o=>!o.disabled),s=t.find(o=>o.code===e)??{code:e};return{locales:t,defaultLocale:s}}function x(l){return l.split("/").map(e=>e.startsWith("[...")&&e.endsWith("]")?`:${e.substring(4,e.length-1)}(.*)*`:e.startsWith("[")&&e.endsWith("]")?`:${e.substring(1,e.length-1)}`:e).join("/")}const R=l=>{if(!l)return"";const e=w.posix.normalize(l).replace(/\/+$/,"");return e==="."?"":e},z=l=>l.startsWith("/")?l.slice(1):l;function G(...l){return w.posix.join(...l)}function Q(l){if(!(typeof l>"u"))return l.startsWith("/")&&l.endsWith("/")?l?.slice(1,-1):l}function V(l){return!l||!/[\u0080-\uFFFF]/.test(l)?l:l.split("/").map(e=>!e||e.startsWith(":")||!/[\u0080-\uFFFF]/.test(e)?e:encodeURI(e)).join("/")}function A(l,e,t){const s=Q(t?.toString()),o=s||(Array.isArray(l)?l.join("|"):l),a=V(e);return R(w.posix.join("/",`:locale(${o})`,a))}function I(l){const e=V(l);return R(e)}const X=(l,e)=>l??(e??"").replace(/[^a-z0-9]/gi,"-").replace(/^-+|-+$/g,"");function j(l){return z(l)||"/"}function _(l,e,t,s=""){const o={};return l.forEach(a=>{const r=X(a.name,a.path),i=R(G(s,a.path??"")),n=j(i),f=x(i),c=e[n]||e[f]||e[r];if(c)typeof c=="object"&&(o[n]=c);else{const h=t[r];h&&typeof h=="object"&&!Array.isArray(h)&&(o[n]=h)}if(a.children?.length){const h=R(G(s,a.path??""));Object.assign(o,_(a.children,e,t,h))}}),o}function Y(l,e,t,s){if(!l||Object.keys(l).length===0)return!0;const o=x(t),a=z(o)||"/",r=a==="/"?"/":a,i=l[o]??l[t]??l[a]??l[r]??(a!=="/"?l[`/${a}`]:void 0);if(!Array.isArray(i)||i.length===0)return!0;const n=e.map(c=>c.code),f=i.filter(c=>n.includes(c));return f.length===0?!0:f.includes(s)}function Z(l){const e={};if(!l)return e;for(const t in l){const s=x(t),o=l[t];if(typeof o=="object"){const a={};for(const r in o){const i=o[r];i&&(a[r]=x(i))}e[s]=a}else e[s]=o}return e}class ee{constructor(e){this.locales=e.locales,this.defaultLocale=this.findLocaleByCode(e.locales,e.defaultLocaleCode)??{code:e.defaultLocaleCode},this.strategy=e.strategy,this.globalLocaleRoutes=Z(e.globalLocaleRoutes??{}),this.filesLocaleRoutes=e.filesLocaleRoutes??{},this.routeLocales=e.routeLocales??{},this.localizedPaths=_(e.pages,this.globalLocaleRoutes,this.filesLocaleRoutes),this.activeLocaleCodes=this.locales.filter(t=>t.code!==this.defaultLocale.code||k.isPrefixAndDefaultStrategy(this.strategy)||k.isPrefixStrategy(this.strategy)).map(t=>t.code),this.excludePatterns=e.excludePatterns,this.customRegex=e.customRegex,this.noPrefixRedirect=e.noPrefixRedirect??!1,this.localizedRouteNamePrefix=e.localizedRouteNamePrefix??"localized-",this.fallbackRedirectComponentPath=e.fallbackRedirectComponentPath,this.rawGlobalLocaleRoutes=e.rawGlobalLocaleRoutes}findLocaleByCode(e,t){return e.find(s=>s.code===t)}getAllowedLocales(e,t){const s=this.routeLocales[e]??this.routeLocales[t];return s?.length?s.filter(o=>this.locales.some(a=>a.code===o)):this.locales.map(o=>o.code)}getCustomPath(e,t){const s=j(e);return this.localizedPaths[s]?.[t]}getCustomPathsForPage(e,t){const s=j(e);return this.localizedPaths[s]??this.localizedPaths[t]}hasLocaleRestrictions(e,t){return!!(this.routeLocales[e]??this.routeLocales[t])}filterLocaleCodesWithoutCustomPaths(e){const t=j(e);return this.activeLocaleCodes.filter(s=>!this.localizedPaths[t]?.[s])}}function g(l,e){const t=(e??"").trim();return t.startsWith("/")?R(t):R(w.posix.join(l||"",t))}function p(l,e){const{path:t,name:s,children:o,meta:a,alias:r}=e,i={...l,path:t};return s!==void 0&&(i.name=s),o!==void 0&&(i.children=o),a!==void 0&&(i.meta={...l.meta,...a}),r!==void 0?(i.alias=r,i.meta={...i.meta,alias:r}):"alias"in e&&(i.alias=void 0,i.meta={...i.meta,alias:void 0}),i}function te(l){const e=l.alias,t=l.meta?.alias,s=e??t;return Array.isArray(s)?s:[]}function O(l,e,t,s="localized-"){const o=te(l);if(!o.length)return[];const a=[];for(const r of o){const i=A(e,r,t);a.push(p(l,{path:i,name:`${s}${l.name??""}`,alias:void 0,meta:{alias:void 0},children:l.children}))}return a}class W{processPage(e,t){if(e.path===void 0)throw new Error("page.path is required");if(K(e))return[e];if(e.path&&E(e.path,t.excludePatterns))return[e];const s=e.path??"",o=C(e.name,e.path),a=x(s);return t.globalLocaleRoutes[o]===!1||t.globalLocaleRoutes[a]===!1?[e]:this.generateVariants(e,t)}postProcess(e,t){return e}localizeChildren(e,t,s,o,a,r){return e.flatMap(i=>this.localizeChild(i,t,s,o,a,r))}localizeChildrenAllLocales(e,t,s,o,a){return e.flatMap(r=>this.localizeChildAllLocales(r,t,s,o,a))}localizeChildAllLocales(e,t,s,o,a){const r=g(s,e.path??""),i=g(t,e.path??""),n=j(i),f=a.localizedPaths[n];if(f)return o.flatMap(d=>{const P=f[d]??g(t,e.path??"");return this.localizeChild(e,P,s,d,a,!0)});const c=R(e.path??""),h=z(c),u=this.localizeChildrenAllLocales(b(e.children??[]),i,r,o,a),m=`${a.localizedRouteNamePrefix}${e.name??""}`;return[p(e,{path:h,name:m,children:u})]}localizeChild(e,t,s,o,a,r){const i=g(s,e.path??""),n=a.getCustomPath(i,o),f=z(R(n||(e.path??""))),c=n??g(t,e.path??""),h=this.localizeChildren(b(e.children??[]),c,i,o,a,r),u=C(e.name,e.path),m=`${a.localizedRouteNamePrefix}${u}-${o}`;return[p(e,{path:f,name:m,children:h})]}buildRoutePathForLocales(e,t,s,o,a,r,i){if(o){const n=e.includes(i);return r||!n?A(e,s,a):R(s)}return A(e,t,a)}}class ae extends W{generateVariants(e,t){const s=e.path??"",o=C(e.name,e.path),a=t.getAllowedLocales(s,o),r=t.getCustomPathsForPage(s,o),i=b(e.children??[]),n=[];if(n.push(e),r)for(const f of a){const c=r[f];if(!c)continue;const h=R(c),u=R(s);if(h===u)continue;const m=I(c),d=F(o,f,!0),P=this.localizeChildrenForNoPrefix(i,h,s,s,f,t,1);n.push(p(e,{path:m,name:d,children:P,alias:[],meta:{alias:[]}})),t.noPrefixRedirect&&f===t.defaultLocale.code&&h!==u&&(e.redirect=h)}return n.push(...O(e,a,t.customRegex,t.localizedRouteNamePrefix)),n}localizeChildrenForNoPrefix(e,t,s,o,a,r,i){return e.map(n=>{const f=g(s,n.path??"");let c,h;if(i===1){const P=r.getCustomPath(f,a);if(P){const L=R(P);c=z(L),h=L}else{const L=R(n.path??"");c=z(L),h=g(t,n.path??"")}}else{const P=R(n.path??"");c=z(P),h=g(t,n.path??"")}const u=this.localizeChildrenForNoPrefix(b(n.children??[]),h,f,o,a,r,i+1),m=C(n.name,n.path),d=F(m,a,!0);return p(n,{path:c,name:d,children:u})})}}function se(l){const e=l.alias??l.meta?.alias;return Array.isArray(e)?e:[]}class oe extends W{generateVariants(e,t){const s=e.path??"",o=C(e.name,e.path),a=t.getAllowedLocales(s,o),r=t.getCustomPathsForPage(s,o),i=b(e.children??[]),n=[];if(r)for(const c of a){const h=r[c],u=h?R(h):s,m=A(c,u,t.customRegex),d=F(o,c,!!h,t.localizedRouteNamePrefix),P=h??s,L=this.localizeChildren(i,P,s,c,t,!0);n.push(p(e,{path:m,name:d,children:L,alias:[],meta:{alias:[]}}))}else{const c=A(a,s,t.customRegex),h=F(o,a[0],!1,t.localizedRouteNamePrefix),u=this.localizeChildrenAllLocales(i,s,s,a,t);n.push(p(e,{path:c,name:h,children:u,alias:[],meta:{alias:[]}}))}const f=se(e);if(f.length)for(const c of f){const h=A(a,c,t.customRegex);n.push(p(e,{path:h,name:`${t.localizedRouteNamePrefix}${e.name??""}`,alias:void 0,meta:{alias:void 0}}))}return n}postProcess(e,t){const s=e.filter(a=>{if(a.name==="index"&&a.path==="/")return!1;const r=a.path??"";return!!(r&&E(r,t.excludePatterns)||t.globalLocaleRoutes[a.name??""]===!1||/^\/:locale/.test(r)||r==="/")}),o=t.defaultLocale.code;for(const[a,r]of Object.entries(t.globalLocaleRoutes)){if(r===!1||typeof r!="object")continue;const i=r[o];if(!i)continue;const n=a.startsWith("/")?a:`/${a}`,f=`/${o}${i.startsWith("/")?i:`/${i}`}`;n!==f&&s.push({path:n,name:`redirect-${a.replace(/\//g,"-")}`,redirect:f})}return t.fallbackRedirectComponentPath&&s.push({path:"/:pathMatch(.*)*",name:"custom-fallback-route",file:t.fallbackRedirectComponentPath,meta:{globalLocaleRoutes:t.rawGlobalLocaleRoutes??t.globalLocaleRoutes}}),s}}class le extends W{generateVariants(e,t){const s=e.path??"",o=C(e.name,e.path),a=t.getAllowedLocales(s,o),r=t.getCustomPathsForPage(s,o),i=b(e.children??[]),n=[],f=t.defaultLocale.code;n.push(e);const c=t.locales.filter(u=>a.includes(u.code));if(c.length>0)if(r)for(const u of c){const m=r[u.code];if(m)if(u.code===f){const d=this.createLocalizedRoute(e,[u.code],i,!0,m,t.customRegex,!1,u.code,s,t);d&&n.push(d);const P=this.createLocalizedRoute(e,[u.code],i,!0,m,t.customRegex,!0,u.code,s,t);P&&n.push(P)}else{const d=this.createLocalizedRoute(e,[u.code],i,!0,m,t.customRegex,!1,u.code,s,t);d&&n.push(d)}else{const d=this.createLocalizedRoute(e,[u.code],i,!1,"",t.customRegex,!1,u.code,s,t);d&&n.push(d)}}else{const u=c.map(d=>d.code),m=this.createLocalizedRoute(e,u,i,!1,"",t.customRegex,!1,!0,s,t);m&&n.push(m)}const h=O(e,a,t.customRegex,t.localizedRouteNamePrefix);return h.length&&n.push(...h),n}postProcess(e,t){const s=[],o=[];for(const a of e){const r=a.name??"";typeof r=="string"&&r.startsWith(t.localizedRouteNamePrefix)?o.push(a):s.push(a)}return[...s,...o]}createLocalizedRoute(e,t,s,o,a="",r,i=!1,n=!1,f,c){const h=this.buildRoutePathForLocales(t,e.path??"",encodeURI(a),o,r,i,c.defaultLocale.code);if(!h||!(o&&a)&&h===e.path||t.length===0)return null;const m=t[0];if(!m)return null;const d=f??e.path??"",P=F(C(e.name??"",d),m,o,c.localizedRouteNamePrefix),L=i||m!==c.defaultLocale.code,y=t.length===1?this.localizeChildren(s,h,d,m,c,L):this.localizeChildrenAllLocales(s,h,d,t,c);return p(e,{path:h,name:P,children:y,alias:[],meta:{alias:[]}})}}class ie extends W{generateVariants(e,t){const s=e.path??"",o=C(e.name,e.path),a=t.getAllowedLocales(s,o),r=t.getCustomPathsForPage(s,o),i=b(e.children??[]),n=[],f=t.defaultLocale.code;if(a.includes(f)){const u=r?.[f],m=u?R(u):s,d=u?{[f]:u}:{},P=this.createLocalizedChildren(i,s,[f],!1,!1,!1,d,t);n.push(p(e,{path:m,name:e.name,children:P}))}const c=t.locales.filter(u=>a.includes(u.code)&&u.code!==f);if(c.length)if(r)for(const u of c){const m=r[u.code];if(m){const d=this.createLocalizedRoute(e,[u.code],i,!0,m,t.customRegex,!1,u.code,s,t);d&&n.push(d)}else{const d=this.createLocalizedRoute(e,[u.code],i,!1,"",t.customRegex,!1,u.code,s,t);d&&n.push(d)}}else{const u=c.map(d=>d.code),m=this.createLocalizedRoute(e,u,i,!1,"",t.customRegex,!1,!0,s,t);m&&n.push(m)}const h=O(e,a,t.customRegex,t.localizedRouteNamePrefix);return h.length&&n.push(...h),n}postProcess(e,t){const s=[],o=[];for(const r of e){const i=r.name??"";typeof i=="string"&&i.startsWith(t.localizedRouteNamePrefix)?o.push(r):s.push(r)}const a=[...s,...o];return t.fallbackRedirectComponentPath&&a.push({path:"/:pathMatch(.*)*",name:"custom-fallback-route",file:t.fallbackRedirectComponentPath,meta:{globalLocaleRoutes:t.rawGlobalLocaleRoutes??t.globalLocaleRoutes}}),a}createLocalizedChildren(e,t,s,o=!0,a=!1,r=!1,i={},n){return e.flatMap(f=>this.createLocalizedVariants(f,t,s,o,a,r,i,n))}createLocalizedVariants(e,t,s,o,a,r=!1,i,n){const f=R(e.path??""),c=g(t,e.path??""),h=j(c),u=n.localizedPaths[h],m=!!u,d=[];if(!m){const P=z(f),L=this.createLocalizedChildren(b(e.children??[]),g(t,e.path??""),s,o,a,r,i,n),y=this.buildChildRouteName(e.name,r,n);return d.push(p(e,{path:P,name:y,children:L})),d}for(const P of s){const L=i?.[P],y=!!L,$=u?.[P];let N=R($||(e.path??""));y&&L&&($?N=R($):N=g(L,e.path??""));const v=M(P,n.defaultLocale,a)?A(P,N,n.customRegex):N,U=z(v),D=$?R($):y?L:g(t,e.path??""),q=this.createLocalizedChildren(b(e.children??[]),D,[P],o,a,P,{...i,[P]:D},n),B=this.buildLocalizedRouteName(C(e.name,e.path),P,o,!!u,n);d.push(p(e,{path:U,name:B,children:q}))}return d}buildChildRouteName(e,t,s){return t===!0?`${s.localizedRouteNamePrefix}${e}`:typeof t=="string"?`${s.localizedRouteNamePrefix}${e}-${t}`:e}createLocalizedRoute(e,t,s,o,a="",r,i=!1,n=!1,f,c){const h=this.buildRoutePathForLocales(t,e.path??"",encodeURI(a),o,r,i,c.defaultLocale.code);if(!h||h===e.path||t.length===0)return null;const u=t[0];if(!u)return null;const m=f??e.path??"",d=F(C(e.name??"",m),u,o,c.localizedRouteNamePrefix);return p(e,{path:h,name:d,children:this.createLocalizedChildren(s,m,t,!0,!1,n,{[u]:a},c),alias:[],meta:{alias:[]}})}buildLocalizedRouteName(e,t,s,o=!1,a){return s?o?`${a.localizedRouteNamePrefix}${e}-${t}`:t&&!T(t,a.defaultLocale)?`${a.localizedRouteNamePrefix}${e}-${t}`:`${a.localizedRouteNamePrefix}${e}`:e}}function re(l){switch(l){case"no_prefix":return new ae;case"prefix":return new oe;case"prefix_and_default":return new le;case"prefix_except_default":return new ie;default:throw new Error(`Unknown route strategy: ${l}`)}}class ne{constructor(e){this.localizedPaths={};const{locales:t,defaultLocaleCode:s,strategy:o,globalLocaleRoutes:a,filesLocaleRoutes:r={},routeLocales:i={},noPrefixRedirect:n,excludePatterns:f,localizedRouteNamePrefix:c="localized-",customRegexMatcher:h,fallbackRedirectComponentPath:u}=e,m=J(t,s);this.locales=m.locales,this.defaultLocale=m.defaultLocale,this.strategy=o,this.noPrefixRedirect=n,this.excludePatterns=f,this.localizedRouteNamePrefix=c,this.customRegex=h,this.fallbackRedirectComponentPath=u,this.activeLocaleCodes=this.computeActiveLocaleCodes();const d={};for(const P in a){const L=x(P),y=a[P];if(typeof y=="object"){const $={};for(const N in y){const v=y[N];v&&($[N]=x(v))}d[L]=$}else d[L]=y}this.globalLocaleRoutes=d,this.rawGlobalLocaleRoutes=a??{},this.filesLocaleRoutes=r??{},this.routeLocales=i??{}}computeActiveLocaleCodes(){return this.locales.filter(e=>e.code!==this.defaultLocale.code||k.isPrefixAndDefaultStrategy(this.strategy)||k.isPrefixStrategy(this.strategy)).map(e=>e.code)}extendPages(e){const t=new ee({locales:this.locales,defaultLocaleCode:this.defaultLocale.code,strategy:this.strategy,globalLocaleRoutes:this.globalLocaleRoutes,filesLocaleRoutes:this.filesLocaleRoutes,routeLocales:this.routeLocales,pages:e,excludePatterns:this.excludePatterns,customRegex:this.customRegex,noPrefixRedirect:this.noPrefixRedirect,localizedRouteNamePrefix:this.localizedRouteNamePrefix,fallbackRedirectComponentPath:this.fallbackRedirectComponentPath,rawGlobalLocaleRoutes:this.rawGlobalLocaleRoutes});this.localizedPaths=t.localizedPaths;const s=re(this.strategy),o=[...e],a=[];for(const i of o)a.push(...s.processPage(i,t));const r=s.postProcess(a,t);e.length=0,e.push(...r)}extractLocalizedPaths(e,t=""){return _(e,this.globalLocaleRoutes,this.filesLocaleRoutes,t)}ensureTranslationFilesExist(e,t,s,o){this.locales.forEach(a=>{const r=w.join(s,t,`${a.code}.json`);this.ensureFileExists(r),o||e.forEach(i=>{const n=w.join(s,t,"pages",`${i}/${a.code}.json`);this.ensureFileExists(n)})})}ensureFileExists(e){try{const t=w.dirname(e);S.existsSync(t)||S.mkdirSync(t,{recursive:!0}),S.existsSync(e)||S.writeFileSync(e,JSON.stringify({}),"utf-8")}catch{}}resolveLocalizedPath(e,t){const s=x(e),o=z(s)||"/";let a;const r=this.globalLocaleRoutes[o],i=this.globalLocaleRoutes[s];r&&typeof r=="object"&&!Array.isArray(r)?a=r[t]:i&&typeof i=="object"&&!Array.isArray(i)&&(a=i[t]);const n=!!a,f=a?R(a):R(s)||"";let c=!1;if(this.strategy==="no_prefix"?c=!1:this.strategy==="prefix"||this.strategy==="prefix_and_default"?c=!0:this.strategy==="prefix_except_default"&&(c=t!==this.defaultLocale.code),t===this.defaultLocale.code&&!n&&(this.strategy==="prefix_except_default"||this.strategy==="no_prefix")&&(c=!1),!c)return R(f)||"/";const h=z(f);return h?R(`/${t}/${h}`):`/${t}`}generateDataRoutes(e,t,s){const o=[],a=this.collectPageNames(e);for(const r of this.locales)if(o.push(`/${t}/index/${r.code}/data.json`),!s)for(const i of a)o.push(`/${t}/${i}/${r.code}/data.json`);return o}collectPageNames(e){const t=new Set,s=o=>{for(const a of o)typeof a.name=="string"&&a.name.length>0&&t.add(a.name),a.children&&a.children.length>0&&s(a.children)};return s(e),[...t]}}exports.RouteGenerator=ne;exports.buildFullPath=A;exports.buildFullPathNoPrefix=I;exports.buildRouteName=F;exports.cloneArray=b;exports.extractLocalizedPaths=_;exports.isInternalPath=E;exports.isLocaleAllowedForUnlocalizedRoute=Y;exports.isLocaleDefault=T;exports.isPageRedirectOnly=K;exports.normalizePath=R;exports.normalizeRouteKey=x;exports.removeLeadingSlash=z;exports.shouldAddLocalePrefix=M;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const w=require("node:path"),k=require("node:fs"),_=require("@i18n-micro/core"),C=l=>l.map(e=>({...e})),M=l=>!!(l.redirect&&!l.file),j=(l,e,t,a="localized-")=>t?`${a}${l}-${e}`:`${a}${l}`,b=(l,e)=>l??(e??"").replace(/[^a-z0-9]/gi,"-").replace(/^-+|-+$/g,""),T=(l,e,t)=>t&&l!==e.code,V=(l,e)=>(typeof l=="string"?l:l.code)===e.code,J=[/^\/sitemap.*\.xml$/,/^\/sitemap\.xml$/,/^\/robots\.txt$/,/^\/favicon\.ico$/,/^\/apple-touch-icon.*\.png$/,/^\/manifest\.json$/,/^\/sw\.js$/,/^\/workbox-.*\.js$/,/\.(xml|txt|ico|json|js|css|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$/];function K(l,e){if(/(?:^|\/)__[^/]+/.test(l))return!0;for(const t of J)if(t.test(l))return!0;if(e){for(const t of e)if(typeof t=="string"){if(t.includes("*")||t.includes("?")){if(new RegExp(t.replace(/\*/g,".*").replace(/\?/g,".")).test(l))return!0}else if(l===t||l.startsWith(t))return!0}else if(t instanceof RegExp&&t.test(l))return!0}return!1}function Q(l,e){const t=l.reduce((o,s)=>{const r=o.find(i=>i.code===s.code);return r?Object.assign(r,s):o.push(s),o},[]).filter(o=>!o.disabled),a=t.find(o=>o.code===e)??{code:e};return{locales:t,defaultLocale:a}}function A(l){return l.split("/").map(e=>e.startsWith("[...")&&e.endsWith("]")?`:${e.substring(4,e.length-1)}(.*)*`:e.startsWith("[")&&e.endsWith("]")?`:${e.substring(1,e.length-1)}`:e).join("/")}const R=l=>{if(!l)return"";const e=w.posix.normalize(l).replace(/\/+$/,"");return e==="."?"":e},z=l=>l.startsWith("/")?l.slice(1):l;function G(...l){return w.posix.join(...l)}function X(l){if(!(typeof l>"u"))return l.startsWith("/")&&l.endsWith("/")?l?.slice(1,-1):l}function Y(l){return!l||!/[\u0080-\uFFFF]/.test(l)?l:l.split("/").map(e=>!e||e.startsWith(":")||!/[\u0080-\uFFFF]/.test(e)?e:encodeURI(e)).join("/")}function q(l){const e=Y(l);return e!==l?[e]:[]}function N(l,e,t){const a=X(t?.toString()),o=a||(Array.isArray(l)?l.join("|"):l),s=e;return R(w.posix.join("/",`:locale(${o})`,s))}function B(l){const e=l;return R(e)}const Z=(l,e)=>l??(e??"").replace(/[^a-z0-9]/gi,"-").replace(/^-+|-+$/g,"");function F(l){return z(l)||"/"}function W(l,e,t,a=""){const o={};return l.forEach(s=>{const r=Z(s.name,s.path),i=R(G(a,s.path??"")),n=F(i),f=A(i),c=e[n]||e[f]||e[r];if(c)typeof c=="object"&&(o[n]=c);else{const h=t[r];h&&typeof h=="object"&&!Array.isArray(h)&&(o[n]=h)}if(s.children?.length){const h=R(G(a,s.path??""));Object.assign(o,W(s.children,e,t,h))}}),o}function v(l,e,t){const a=A(e),o=F(e);return l[t]===!1||l[a]===!1||l[o]===!1||l[z(a)]===!1}function ee(l,e,t,a){if(!l||Object.keys(l).length===0)return!0;const o=A(t),s=z(o)||"/",r=s==="/"?"/":s,i=l[o]??l[t]??l[s]??l[r]??(s!=="/"?l[`/${s}`]:void 0);if(!Array.isArray(i)||i.length===0)return!0;const n=e.map(c=>c.code),f=i.filter(c=>n.includes(c));return f.length===0?!0:f.includes(a)}function te(l){const e={};if(!l)return e;for(const t in l){const a=A(t),o=l[t];if(typeof o=="object"){const s={};for(const r in o){const i=o[r];i&&(s[r]=A(i))}e[a]=s}else e[a]=o}return e}class ae{constructor(e){this.locales=e.locales,this.defaultLocale=this.findLocaleByCode(e.locales,e.defaultLocaleCode)??{code:e.defaultLocaleCode},this.strategy=e.strategy,this.globalLocaleRoutes=te(e.globalLocaleRoutes??{}),this.filesLocaleRoutes=e.filesLocaleRoutes??{},this.routeLocales=e.routeLocales??{},this.localizedPaths=W(e.pages,this.globalLocaleRoutes,this.filesLocaleRoutes),this.activeLocaleCodes=this.locales.filter(t=>t.code!==this.defaultLocale.code||_.isPrefixAndDefaultStrategy(this.strategy)||_.isPrefixStrategy(this.strategy)).map(t=>t.code),this.excludePatterns=e.excludePatterns,this.customRegex=e.customRegex,this.noPrefixRedirect=e.noPrefixRedirect??!1,this.localizedRouteNamePrefix=e.localizedRouteNamePrefix??"localized-",this.fallbackRedirectComponentPath=e.fallbackRedirectComponentPath,this.rawGlobalLocaleRoutes=e.rawGlobalLocaleRoutes}findLocaleByCode(e,t){return e.find(a=>a.code===t)}getAllowedLocales(e,t){const a=this.routeLocales[e]??this.routeLocales[t];return a?.length?a.filter(o=>this.locales.some(s=>s.code===o)):this.locales.map(o=>o.code)}getCustomPath(e,t){const a=F(e);return this.localizedPaths[a]?.[t]}getCustomPathsForPage(e,t){const a=F(e);return this.localizedPaths[a]??this.localizedPaths[t]}hasLocaleRestrictions(e,t){return!!(this.routeLocales[e]??this.routeLocales[t])}filterLocaleCodesWithoutCustomPaths(e){const t=F(e);return this.activeLocaleCodes.filter(a=>!this.localizedPaths[t]?.[a])}}function y(l,e){const t=(e??"").trim();return t.startsWith("/")?R(t):R(w.posix.join(l||"",t))}function g(l,e){const{path:t,name:a,children:o,meta:s,alias:r}=e,i={...l,path:t};return a!==void 0&&(i.name=a),o!==void 0&&(i.children=o),s!==void 0&&(i.meta={...l.meta,...s}),r!==void 0?(i.alias=r,i.meta={...i.meta,alias:r}):"alias"in e&&(i.alias=void 0,i.meta={...i.meta,alias:void 0}),i}function se(l){const e=l.alias,t=l.meta?.alias,a=e??t;return Array.isArray(a)?a:[]}function O(l,e,t,a="localized-"){const o=se(l);if(!o.length)return[];const s=[];for(const r of o){const i=N(e,r,t);s.push(g(l,{path:i,name:`${a}${l.name??""}`,alias:void 0,meta:{alias:void 0},children:l.children}))}return s}class E{processPage(e,t){if(e.path===void 0)throw new Error("page.path is required");if(M(e))return[e];if(e.path&&K(e.path,t.excludePatterns))return[e];const a=e.path??"",o=b(e.name,e.path);return v(t.globalLocaleRoutes,a,o)?[e]:this.generateVariants(e,t)}postProcess(e,t){return e}localizeChildren(e,t,a,o,s,r){return e.flatMap(i=>this.localizeChild(i,t,a,o,s,r))}localizeChildrenAllLocales(e,t,a,o,s){return e.flatMap(r=>this.localizeChildAllLocales(r,t,a,o,s))}localizeChildAllLocales(e,t,a,o,s){const r=y(a,e.path??""),i=b(e.name,e.path);if(v(s.globalLocaleRoutes,r,i))return[e];const n=y(t,e.path??""),f=F(n),c=s.localizedPaths[f];if(c)return o.flatMap(P=>{const L=c[P]??y(t,e.path??"");return this.localizeChild(e,L,a,P,s,!0)});const h=R(e.path??""),u=z(h),m=this.localizeChildrenAllLocales(C(e.children??[]),n,r,o,s),d=`${s.localizedRouteNamePrefix}${e.name??""}`;return[g(e,{path:u,name:d,children:m})]}localizeChild(e,t,a,o,s,r){const i=y(a,e.path??""),n=b(e.name,e.path);if(v(s.globalLocaleRoutes,i,n))return[e];const f=s.getCustomPath(i,o),c=z(R(f||(e.path??""))),h=f??y(t,e.path??""),u=this.localizeChildren(C(e.children??[]),h,i,o,s,r),m=b(e.name,e.path),d=`${s.localizedRouteNamePrefix}${m}-${o}`;return[g(e,{path:c,name:d,children:u})]}buildRoutePathForLocales(e,t,a,o,s,r,i){if(o){const n=e.includes(i);return r||!n?N(e,a,s):R(a)}return N(e,t,s)}}class oe extends E{generateVariants(e,t){const a=e.path??"",o=b(e.name,e.path),s=t.getAllowedLocales(a,o),r=t.getCustomPathsForPage(a,o),i=C(e.children??[]),n=[];if(n.push(e),r)for(const f of s){const c=r[f];if(!c)continue;const h=R(c),u=R(a);if(h===u)continue;const m=B(c),d=j(o,f,!0),P=this.localizeChildrenForNoPrefix(i,h,a,a,f,t,1);n.push(g(e,{path:m,name:d,children:P,alias:[],meta:{alias:[]}})),t.noPrefixRedirect&&f===t.defaultLocale.code&&h!==u&&(e.redirect=h)}return n.push(...O(e,s,t.customRegex,t.localizedRouteNamePrefix)),n}localizeChildrenForNoPrefix(e,t,a,o,s,r,i){return e.map(n=>{const f=y(a,n.path??"");let c,h;if(i===1){const P=r.getCustomPath(f,s);if(P){const L=R(P);c=z(L),h=L}else{const L=R(n.path??"");c=z(L),h=y(t,n.path??"")}}else{const P=R(n.path??"");c=z(P),h=y(t,n.path??"")}const u=this.localizeChildrenForNoPrefix(C(n.children??[]),h,f,o,s,r,i+1),m=b(n.name,n.path),d=j(m,s,!0);return g(n,{path:c,name:d,children:u})})}}function le(l){const e=l.alias??l.meta?.alias;return Array.isArray(e)?e:[]}class ie extends E{generateVariants(e,t){const a=e.path??"",o=b(e.name,e.path),s=t.getAllowedLocales(a,o),r=t.getCustomPathsForPage(a,o),i=C(e.children??[]),n=[];if(r)for(const c of s){const h=r[c],u=h?R(h):a,m=N(c,u,t.customRegex),d=j(o,c,!!h,t.localizedRouteNamePrefix),P=h??a,L=this.localizeChildren(i,P,a,c,t,!0),p=q(m);n.push(g(e,{path:m,name:d,children:L,alias:p.length?p:void 0,meta:{alias:p.length?p:[]}}))}else{const c=N(s,a,t.customRegex),h=j(o,s[0],!1,t.localizedRouteNamePrefix),u=this.localizeChildrenAllLocales(i,a,a,s,t);n.push(g(e,{path:c,name:h,children:u,alias:[],meta:{alias:[]}}))}const f=le(e);if(f.length)for(const c of f){const h=N(s,c,t.customRegex);n.push(g(e,{path:h,name:`${t.localizedRouteNamePrefix}${e.name??""}`,alias:void 0,meta:{alias:void 0}}))}return n}postProcess(e,t){const a=e.filter(s=>{if(s.name==="index"&&s.path==="/")return!1;const r=s.path??"";return!!(r&&K(r,t.excludePatterns)||v(t.globalLocaleRoutes,r,s.name??"")||/^\/:locale/.test(r)||r==="/")}),o=t.defaultLocale.code;for(const[s,r]of Object.entries(t.globalLocaleRoutes)){if(r===!1||typeof r!="object")continue;const i=r[o];if(!i)continue;const n=s.startsWith("/")?s:`/${s}`,f=`/${o}${i.startsWith("/")?i:`/${i}`}`;n!==f&&a.push({path:n,name:`redirect-${s.replace(/\//g,"-")}`,redirect:f})}return t.fallbackRedirectComponentPath&&a.push({path:"/:pathMatch(.*)*",name:"custom-fallback-route",file:t.fallbackRedirectComponentPath,meta:{globalLocaleRoutes:t.rawGlobalLocaleRoutes??t.globalLocaleRoutes}}),a}}class re extends E{generateVariants(e,t){const a=e.path??"",o=b(e.name,e.path),s=t.getAllowedLocales(a,o),r=t.getCustomPathsForPage(a,o),i=C(e.children??[]),n=[],f=t.defaultLocale.code;n.push(e);const c=t.locales.filter(u=>s.includes(u.code));if(c.length>0)if(r)for(const u of c){const m=r[u.code];if(m)if(u.code===f){const d=this.createLocalizedRoute(e,[u.code],i,!0,m,t.customRegex,!1,u.code,a,t);d&&n.push(d);const P=this.createLocalizedRoute(e,[u.code],i,!0,m,t.customRegex,!0,u.code,a,t);P&&n.push(P)}else{const d=this.createLocalizedRoute(e,[u.code],i,!0,m,t.customRegex,!1,u.code,a,t);d&&n.push(d)}else{const d=this.createLocalizedRoute(e,[u.code],i,!1,"",t.customRegex,!1,u.code,a,t);d&&n.push(d)}}else{const u=c.map(d=>d.code),m=this.createLocalizedRoute(e,u,i,!1,"",t.customRegex,!1,!0,a,t);m&&n.push(m)}const h=O(e,s,t.customRegex,t.localizedRouteNamePrefix);return h.length&&n.push(...h),n}postProcess(e,t){const a=[],o=[];for(const s of e){const r=s.name??"";typeof r=="string"&&r.startsWith(t.localizedRouteNamePrefix)?o.push(s):a.push(s)}return[...a,...o]}createLocalizedRoute(e,t,a,o,s="",r,i=!1,n=!1,f,c){const h=this.buildRoutePathForLocales(t,e.path??"",s,o,r,i,c.defaultLocale.code);if(!h||!(o&&s)&&h===e.path||t.length===0)return null;const m=t[0];if(!m)return null;const d=f??e.path??"",P=j(b(e.name??"",d),m,o,c.localizedRouteNamePrefix),L=i||m!==c.defaultLocale.code,p=t.length===1?this.localizeChildren(a,h,d,m,c,L):this.localizeChildrenAllLocales(a,h,d,t,c);return g(e,{path:h,name:P,children:p,alias:[],meta:{alias:[]}})}}class ne extends E{generateVariants(e,t){const a=e.path??"",o=b(e.name,e.path),s=t.getAllowedLocales(a,o),r=t.getCustomPathsForPage(a,o),i=C(e.children??[]),n=[],f=t.defaultLocale.code;if(s.includes(f)){const u=r?.[f],m=u?R(u):a,d=u?{[f]:u}:{},P=this.createLocalizedChildren(i,a,[f],!1,!1,!1,d,t);n.push(g(e,{path:m,name:e.name,children:P}))}const c=t.locales.filter(u=>s.includes(u.code)&&u.code!==f);if(c.length)if(r)for(const u of c){const m=r[u.code];if(m){const d=this.createLocalizedRoute(e,[u.code],i,!0,m,t.customRegex,!1,u.code,a,t);d&&n.push(d)}else{const d=this.createLocalizedRoute(e,[u.code],i,!1,"",t.customRegex,!1,u.code,a,t);d&&n.push(d)}}else{const u=c.map(d=>d.code),m=this.createLocalizedRoute(e,u,i,!1,"",t.customRegex,!1,!0,a,t);m&&n.push(m)}const h=O(e,s,t.customRegex,t.localizedRouteNamePrefix);return h.length&&n.push(...h),n}postProcess(e,t){const a=[],o=[];for(const r of e){const i=r.name??"";typeof i=="string"&&i.startsWith(t.localizedRouteNamePrefix)?o.push(r):a.push(r)}const s=[...a,...o];return t.fallbackRedirectComponentPath&&s.push({path:"/:pathMatch(.*)*",name:"custom-fallback-route",file:t.fallbackRedirectComponentPath,meta:{globalLocaleRoutes:t.rawGlobalLocaleRoutes??t.globalLocaleRoutes}}),s}createLocalizedChildren(e,t,a,o=!0,s=!1,r=!1,i={},n){return e.flatMap(f=>this.createLocalizedVariants(f,t,a,o,s,r,i,n))}createLocalizedVariants(e,t,a,o,s,r=!1,i,n){const f=R(e.path??""),c=y(t,e.path??""),h=F(c),u=n.localizedPaths[h],m=!!u,d=[];if(!m){const P=z(f),L=this.createLocalizedChildren(C(e.children??[]),y(t,e.path??""),a,o,s,r,i,n),p=this.buildChildRouteName(e.name,r,n);return d.push(g(e,{path:P,name:p,children:L})),d}for(const P of a){const L=i?.[P],p=!!L,$=u?.[P];let x=R($||(e.path??""));p&&L&&($?x=R($):x=y(L,e.path??""));const S=T(P,n.defaultLocale,s)?N(P,x,n.customRegex):x,I=z(S),D=$?R($):p?L:y(t,e.path??""),U=this.createLocalizedChildren(C(e.children??[]),D,[P],o,s,P,{...i,[P]:D},n),H=this.buildLocalizedRouteName(b(e.name,e.path),P,o,!!u,n);d.push(g(e,{path:I,name:H,children:U}))}return d}buildChildRouteName(e,t,a){return t===!0?`${a.localizedRouteNamePrefix}${e}`:typeof t=="string"?`${a.localizedRouteNamePrefix}${e}-${t}`:e}createLocalizedRoute(e,t,a,o,s="",r,i=!1,n=!1,f,c){const h=this.buildRoutePathForLocales(t,e.path??"",s,o,r,i,c.defaultLocale.code);if(!h||h===e.path||t.length===0)return null;const u=t[0];if(!u)return null;const m=f??e.path??"",d=j(b(e.name??"",m),u,o,c.localizedRouteNamePrefix);return g(e,{path:h,name:d,children:this.createLocalizedChildren(a,m,t,!0,!1,n,{[u]:s},c),alias:[],meta:{alias:[]}})}buildLocalizedRouteName(e,t,a,o=!1,s){return a?o?`${s.localizedRouteNamePrefix}${e}-${t}`:t&&!V(t,s.defaultLocale)?`${s.localizedRouteNamePrefix}${e}-${t}`:`${s.localizedRouteNamePrefix}${e}`:e}}function ce(l){switch(l){case"no_prefix":return new oe;case"prefix":return new ie;case"prefix_and_default":return new re;case"prefix_except_default":return new ne;default:throw new Error(`Unknown route strategy: ${l}`)}}class ue{constructor(e){this.localizedPaths={};const{locales:t,defaultLocaleCode:a,strategy:o,globalLocaleRoutes:s,filesLocaleRoutes:r={},routeLocales:i={},noPrefixRedirect:n,excludePatterns:f,localizedRouteNamePrefix:c="localized-",customRegexMatcher:h,fallbackRedirectComponentPath:u}=e,m=Q(t,a);this.locales=m.locales,this.defaultLocale=m.defaultLocale,this.strategy=o,this.noPrefixRedirect=n,this.excludePatterns=f,this.localizedRouteNamePrefix=c,this.customRegex=h,this.fallbackRedirectComponentPath=u,this.activeLocaleCodes=this.computeActiveLocaleCodes();const d={};for(const P in s){const L=A(P),p=s[P];if(typeof p=="object"){const $={};for(const x in p){const S=p[x];S&&($[x]=A(S))}d[L]=$}else d[L]=p}this.globalLocaleRoutes=d,this.rawGlobalLocaleRoutes=s??{},this.filesLocaleRoutes=r??{},this.routeLocales=i??{}}computeActiveLocaleCodes(){return this.locales.filter(e=>e.code!==this.defaultLocale.code||_.isPrefixAndDefaultStrategy(this.strategy)||_.isPrefixStrategy(this.strategy)).map(e=>e.code)}extendPages(e){const t=new ae({locales:this.locales,defaultLocaleCode:this.defaultLocale.code,strategy:this.strategy,globalLocaleRoutes:this.globalLocaleRoutes,filesLocaleRoutes:this.filesLocaleRoutes,routeLocales:this.routeLocales,pages:e,excludePatterns:this.excludePatterns,customRegex:this.customRegex,noPrefixRedirect:this.noPrefixRedirect,localizedRouteNamePrefix:this.localizedRouteNamePrefix,fallbackRedirectComponentPath:this.fallbackRedirectComponentPath,rawGlobalLocaleRoutes:this.rawGlobalLocaleRoutes});this.localizedPaths=t.localizedPaths;const a=ce(this.strategy),o=[...e],s=[];for(const i of o)s.push(...a.processPage(i,t));const r=a.postProcess(s,t);e.length=0,e.push(...r)}extractLocalizedPaths(e,t=""){return W(e,this.globalLocaleRoutes,this.filesLocaleRoutes,t)}ensureTranslationFilesExist(e,t,a,o){this.locales.forEach(s=>{const r=w.join(a,t,`${s.code}.json`);this.ensureFileExists(r),o||e.forEach(i=>{const n=w.join(a,t,"pages",`${i}/${s.code}.json`);this.ensureFileExists(n)})})}ensureFileExists(e){try{const t=w.dirname(e);k.existsSync(t)||k.mkdirSync(t,{recursive:!0}),k.existsSync(e)||k.writeFileSync(e,JSON.stringify({}),"utf-8")}catch{}}resolveLocalizedPath(e,t){const a=A(e),o=z(a)||"/";let s;const r=this.globalLocaleRoutes[o],i=this.globalLocaleRoutes[a];r&&typeof r=="object"&&!Array.isArray(r)?s=r[t]:i&&typeof i=="object"&&!Array.isArray(i)&&(s=i[t]);const n=!!s,f=s?R(s):R(a)||"";let c=!1;if(this.strategy==="no_prefix"?c=!1:this.strategy==="prefix"||this.strategy==="prefix_and_default"?c=!0:this.strategy==="prefix_except_default"&&(c=t!==this.defaultLocale.code),t===this.defaultLocale.code&&!n&&(this.strategy==="prefix_except_default"||this.strategy==="no_prefix")&&(c=!1),!c)return R(f)||"/";const h=z(f);return h?R(`/${t}/${h}`):`/${t}`}generateDataRoutes(e,t,a){const o=[],s=this.collectPageNames(e);for(const r of this.locales)if(o.push(`/${t}/index/${r.code}/data.json`),!a)for(const i of s)o.push(`/${t}/${i}/${r.code}/data.json`);return o}collectPageNames(e){const t=new Set,a=o=>{for(const s of o)typeof s.name=="string"&&s.name.length>0&&t.add(s.name),s.children&&s.children.length>0&&a(s.children)};return a(e),[...t]}}exports.RouteGenerator=ue;exports.buildEncodedPathAliases=q;exports.buildFullPath=N;exports.buildFullPathNoPrefix=B;exports.buildRouteName=j;exports.cloneArray=C;exports.extractLocalizedPaths=W;exports.isInternalPath=K;exports.isLocaleAllowedForUnlocalizedRoute=ee;exports.isLocaleDefault=V;exports.isLocalizationDisabledForPage=v;exports.isPageRedirectOnly=M;exports.normalizePath=R;exports.normalizeRouteKey=A;exports.removeLeadingSlash=z;exports.shouldAddLocalePrefix=T;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { extractLocalizedPaths, LocalizedPathsMap } from './core/localized-paths';
2
+ import { isLocalizationDisabledForPage } from './core/localization-disabled';
2
3
  import { isLocaleAllowedForUnlocalizedRoute } from './locale-route-access';
3
4
  import { RouteGenerator, RouteGeneratorOptions } from './route-generator';
4
- import { buildFullPath, buildFullPathNoPrefix, buildRouteName, cloneArray, isInternalPath, isLocaleDefault, isPageRedirectOnly, normalizePath, normalizeRouteKey, removeLeadingSlash, shouldAddLocalePrefix } from './utils';
5
- export { RouteGenerator, type RouteGeneratorOptions, isLocaleAllowedForUnlocalizedRoute, extractLocalizedPaths, type LocalizedPathsMap, isInternalPath, normalizeRouteKey, normalizePath, cloneArray, isPageRedirectOnly, removeLeadingSlash, buildRouteName, shouldAddLocalePrefix, isLocaleDefault, buildFullPath, buildFullPathNoPrefix, };
5
+ import { buildEncodedPathAliases, buildFullPath, buildFullPathNoPrefix, buildRouteName, cloneArray, isInternalPath, isLocaleDefault, isPageRedirectOnly, normalizePath, normalizeRouteKey, removeLeadingSlash, shouldAddLocalePrefix } from './utils';
6
+ export { RouteGenerator, type RouteGeneratorOptions, isLocaleAllowedForUnlocalizedRoute, extractLocalizedPaths, type LocalizedPathsMap, isLocalizationDisabledForPage, isInternalPath, normalizeRouteKey, normalizePath, cloneArray, isPageRedirectOnly, removeLeadingSlash, buildRouteName, shouldAddLocalePrefix, isLocaleDefault, buildEncodedPathAliases, buildFullPath, buildFullPathNoPrefix, };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { extractLocalizedPaths, LocalizedPathsMap } from './core/localized-paths';
2
+ import { isLocalizationDisabledForPage } from './core/localization-disabled';
2
3
  import { isLocaleAllowedForUnlocalizedRoute } from './locale-route-access';
3
4
  import { RouteGenerator, RouteGeneratorOptions } from './route-generator';
4
- import { buildFullPath, buildFullPathNoPrefix, buildRouteName, cloneArray, isInternalPath, isLocaleDefault, isPageRedirectOnly, normalizePath, normalizeRouteKey, removeLeadingSlash, shouldAddLocalePrefix } from './utils';
5
- export { RouteGenerator, type RouteGeneratorOptions, isLocaleAllowedForUnlocalizedRoute, extractLocalizedPaths, type LocalizedPathsMap, isInternalPath, normalizeRouteKey, normalizePath, cloneArray, isPageRedirectOnly, removeLeadingSlash, buildRouteName, shouldAddLocalePrefix, isLocaleDefault, buildFullPath, buildFullPathNoPrefix, };
5
+ import { buildEncodedPathAliases, buildFullPath, buildFullPathNoPrefix, buildRouteName, cloneArray, isInternalPath, isLocaleDefault, isPageRedirectOnly, normalizePath, normalizeRouteKey, removeLeadingSlash, shouldAddLocalePrefix } from './utils';
6
+ export { RouteGenerator, type RouteGeneratorOptions, isLocaleAllowedForUnlocalizedRoute, extractLocalizedPaths, type LocalizedPathsMap, isLocalizationDisabledForPage, isInternalPath, normalizeRouteKey, normalizePath, cloneArray, isPageRedirectOnly, removeLeadingSlash, buildRouteName, shouldAddLocalePrefix, isLocaleDefault, buildEncodedPathAliases, buildFullPath, buildFullPathNoPrefix, };
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import w from "node:path";
2
- import { existsSync as E, mkdirSync as U, writeFileSync as B } from "node:fs";
3
- import { isPrefixAndDefaultStrategy as K, isPrefixStrategy as O } from "@i18n-micro/core";
4
- const $ = (l) => l.map((e) => ({ ...e })), q = (l) => !!(l.redirect && !l.file), j = (l, e, t, s = "localized-") => t ? `${s}${l}-${e}` : `${s}${l}`, b = (l, e) => l ?? (e ?? "").replace(/[^a-z0-9]/gi, "-").replace(/^-+|-+$/g, ""), H = (l, e, t) => t && l !== e.code, J = (l, e) => (typeof l == "string" ? l : l.code) === e.code, Q = [
2
+ import { existsSync as K, mkdirSync as I, writeFileSync as U } from "node:fs";
3
+ import { isPrefixAndDefaultStrategy as O, isPrefixStrategy as D } from "@i18n-micro/core";
4
+ const $ = (l) => l.map((e) => ({ ...e })), q = (l) => !!(l.redirect && !l.file), j = (l, e, t, a = "localized-") => t ? `${a}${l}-${e}` : `${a}${l}`, b = (l, e) => l ?? (e ?? "").replace(/[^a-z0-9]/gi, "-").replace(/^-+|-+$/g, ""), H = (l, e, t) => t && l !== e.code, J = (l, e) => (typeof l == "string" ? l : l.code) === e.code, Q = [
5
5
  /^\/sitemap.*\.xml$/,
6
6
  /^\/sitemap\.xml$/,
7
7
  /^\/robots\.txt$/,
@@ -12,7 +12,7 @@ const $ = (l) => l.map((e) => ({ ...e })), q = (l) => !!(l.redirect && !l.file),
12
12
  /^\/workbox-.*\.js$/,
13
13
  /\.(xml|txt|ico|json|js|css|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$/
14
14
  ];
15
- function D(l, e) {
15
+ function M(l, e) {
16
16
  if (/(?:^|\/)__[^/]+/.test(l))
17
17
  return !0;
18
18
  for (const t of Q)
@@ -31,13 +31,13 @@ function D(l, e) {
31
31
  return !1;
32
32
  }
33
33
  function X(l, e) {
34
- const t = l.reduce((o, a) => {
35
- const r = o.find((i) => i.code === a.code);
36
- return r ? Object.assign(r, a) : o.push(a), o;
37
- }, []).filter((o) => !o.disabled), s = t.find((o) => o.code === e) ?? { code: e };
38
- return { locales: t, defaultLocale: s };
34
+ const t = l.reduce((o, s) => {
35
+ const r = o.find((i) => i.code === s.code);
36
+ return r ? Object.assign(r, s) : o.push(s), o;
37
+ }, []).filter((o) => !o.disabled), a = t.find((o) => o.code === e) ?? { code: e };
38
+ return { locales: t, defaultLocale: a };
39
39
  }
40
- function x(l) {
40
+ function N(l) {
41
41
  return l.split("/").map((e) => e.startsWith("[...") && e.endsWith("]") ? `:${e.substring(4, e.length - 1)}(.*)*` : e.startsWith("[") && e.endsWith("]") ? `:${e.substring(1, e.length - 1)}` : e).join("/");
42
42
  }
43
43
  const R = (l) => {
@@ -53,124 +53,132 @@ function Y(l) {
53
53
  if (!(typeof l > "u"))
54
54
  return l.startsWith("/") && l.endsWith("/") ? l?.slice(1, -1) : l;
55
55
  }
56
- function M(l) {
56
+ function Z(l) {
57
57
  return !l || !/[\u0080-\uFFFF]/.test(l) ? l : l.split("/").map((e) => !e || e.startsWith(":") || !/[\u0080-\uFFFF]/.test(e) ? e : encodeURI(e)).join("/");
58
58
  }
59
- function A(l, e, t) {
60
- const s = Y(t?.toString()), o = s || (Array.isArray(l) ? l.join("|") : l), a = M(e);
61
- return R(w.posix.join("/", `:locale(${o})`, a));
59
+ function ee(l) {
60
+ const e = Z(l);
61
+ return e !== l ? [e] : [];
62
62
  }
63
- function Z(l) {
64
- const e = M(l);
63
+ function x(l, e, t) {
64
+ const a = Y(t?.toString()), o = a || (Array.isArray(l) ? l.join("|") : l), s = e;
65
+ return R(w.posix.join("/", `:locale(${o})`, s));
66
+ }
67
+ function te(l) {
68
+ const e = l;
65
69
  return R(e);
66
70
  }
67
- const ee = (l, e) => l ?? (e ?? "").replace(/[^a-z0-9]/gi, "-").replace(/^-+|-+$/g, "");
71
+ const ae = (l, e) => l ?? (e ?? "").replace(/[^a-z0-9]/gi, "-").replace(/^-+|-+$/g, "");
68
72
  function F(l) {
69
73
  return g(l) || "/";
70
74
  }
71
- function S(l, e, t, s = "") {
75
+ function _(l, e, t, a = "") {
72
76
  const o = {};
73
- return l.forEach((a) => {
74
- const r = ee(a.name, a.path), i = R(G(s, a.path ?? "")), n = F(i), f = x(i), c = e[n] || e[f] || e[r];
77
+ return l.forEach((s) => {
78
+ const r = ae(s.name, s.path), i = R(G(a, s.path ?? "")), n = F(i), f = N(i), c = e[n] || e[f] || e[r];
75
79
  if (c)
76
80
  typeof c == "object" && (o[n] = c);
77
81
  else {
78
82
  const h = t[r];
79
83
  h && typeof h == "object" && !Array.isArray(h) && (o[n] = h);
80
84
  }
81
- if (a.children?.length) {
82
- const h = R(G(s, a.path ?? ""));
83
- Object.assign(o, S(a.children, e, t, h));
85
+ if (s.children?.length) {
86
+ const h = R(G(a, s.path ?? ""));
87
+ Object.assign(o, _(s.children, e, t, h));
84
88
  }
85
89
  }), o;
86
90
  }
87
- function de(l, e, t, s) {
91
+ function S(l, e, t) {
92
+ const a = N(e), o = F(e);
93
+ return l[t] === !1 || l[a] === !1 || l[o] === !1 || l[g(a)] === !1;
94
+ }
95
+ function Pe(l, e, t, a) {
88
96
  if (!l || Object.keys(l).length === 0)
89
97
  return !0;
90
- const o = x(t), a = g(o) || "/", r = a === "/" ? "/" : a, i = l[o] ?? l[t] ?? l[a] ?? l[r] ?? (a !== "/" ? l[`/${a}`] : void 0);
98
+ const o = N(t), s = g(o) || "/", r = s === "/" ? "/" : s, i = l[o] ?? l[t] ?? l[s] ?? l[r] ?? (s !== "/" ? l[`/${s}`] : void 0);
91
99
  if (!Array.isArray(i) || i.length === 0)
92
100
  return !0;
93
101
  const n = e.map((c) => c.code), f = i.filter((c) => n.includes(c));
94
- return f.length === 0 ? !0 : f.includes(s);
102
+ return f.length === 0 ? !0 : f.includes(a);
95
103
  }
96
- function te(l) {
104
+ function se(l) {
97
105
  const e = {};
98
106
  if (!l) return e;
99
107
  for (const t in l) {
100
- const s = x(t), o = l[t];
108
+ const a = N(t), o = l[t];
101
109
  if (typeof o == "object") {
102
- const a = {};
110
+ const s = {};
103
111
  for (const r in o) {
104
112
  const i = o[r];
105
- i && (a[r] = x(i));
113
+ i && (s[r] = N(i));
106
114
  }
107
- e[s] = a;
115
+ e[a] = s;
108
116
  } else
109
- e[s] = o;
117
+ e[a] = o;
110
118
  }
111
119
  return e;
112
120
  }
113
- class ae {
121
+ class oe {
114
122
  constructor(e) {
115
- this.locales = e.locales, this.defaultLocale = this.findLocaleByCode(e.locales, e.defaultLocaleCode) ?? { code: e.defaultLocaleCode }, this.strategy = e.strategy, this.globalLocaleRoutes = te(e.globalLocaleRoutes ?? {}), this.filesLocaleRoutes = e.filesLocaleRoutes ?? {}, this.routeLocales = e.routeLocales ?? {}, this.localizedPaths = S(e.pages, this.globalLocaleRoutes, this.filesLocaleRoutes), this.activeLocaleCodes = this.locales.filter((t) => t.code !== this.defaultLocale.code || K(this.strategy) || O(this.strategy)).map((t) => t.code), this.excludePatterns = e.excludePatterns, this.customRegex = e.customRegex, this.noPrefixRedirect = e.noPrefixRedirect ?? !1, this.localizedRouteNamePrefix = e.localizedRouteNamePrefix ?? "localized-", this.fallbackRedirectComponentPath = e.fallbackRedirectComponentPath, this.rawGlobalLocaleRoutes = e.rawGlobalLocaleRoutes;
123
+ this.locales = e.locales, this.defaultLocale = this.findLocaleByCode(e.locales, e.defaultLocaleCode) ?? { code: e.defaultLocaleCode }, this.strategy = e.strategy, this.globalLocaleRoutes = se(e.globalLocaleRoutes ?? {}), this.filesLocaleRoutes = e.filesLocaleRoutes ?? {}, this.routeLocales = e.routeLocales ?? {}, this.localizedPaths = _(e.pages, this.globalLocaleRoutes, this.filesLocaleRoutes), this.activeLocaleCodes = this.locales.filter((t) => t.code !== this.defaultLocale.code || O(this.strategy) || D(this.strategy)).map((t) => t.code), this.excludePatterns = e.excludePatterns, this.customRegex = e.customRegex, this.noPrefixRedirect = e.noPrefixRedirect ?? !1, this.localizedRouteNamePrefix = e.localizedRouteNamePrefix ?? "localized-", this.fallbackRedirectComponentPath = e.fallbackRedirectComponentPath, this.rawGlobalLocaleRoutes = e.rawGlobalLocaleRoutes;
116
124
  }
117
125
  findLocaleByCode(e, t) {
118
- return e.find((s) => s.code === t);
126
+ return e.find((a) => a.code === t);
119
127
  }
120
128
  /**
121
129
  * Returns the list of locale codes allowed for a page (respecting routeLocales).
122
130
  */
123
131
  getAllowedLocales(e, t) {
124
- const s = this.routeLocales[e] ?? this.routeLocales[t];
125
- return s?.length ? s.filter((o) => this.locales.some((a) => a.code === o)) : this.locales.map((o) => o.code);
132
+ const a = this.routeLocales[e] ?? this.routeLocales[t];
133
+ return a?.length ? a.filter((o) => this.locales.some((s) => s.code === o)) : this.locales.map((o) => o.code);
126
134
  }
127
135
  /**
128
136
  * Returns a custom path for a given locale by original page path, if any.
129
137
  */
130
138
  getCustomPath(e, t) {
131
- const s = F(e);
132
- return this.localizedPaths[s]?.[t];
139
+ const a = F(e);
140
+ return this.localizedPaths[a]?.[t];
133
141
  }
134
142
  /**
135
143
  * Returns a map of custom paths (locale → path) for a page by path key or name.
136
144
  */
137
145
  getCustomPathsForPage(e, t) {
138
- const s = F(e);
139
- return this.localizedPaths[s] ?? this.localizedPaths[t];
146
+ const a = F(e);
147
+ return this.localizedPaths[a] ?? this.localizedPaths[t];
140
148
  }
141
149
  hasLocaleRestrictions(e, t) {
142
150
  return !!(this.routeLocales[e] ?? this.routeLocales[t]);
143
151
  }
144
152
  filterLocaleCodesWithoutCustomPaths(e) {
145
153
  const t = F(e);
146
- return this.activeLocaleCodes.filter((s) => !this.localizedPaths[t]?.[s]);
154
+ return this.activeLocaleCodes.filter((a) => !this.localizedPaths[t]?.[a]);
147
155
  }
148
156
  }
149
- function z(l, e) {
157
+ function y(l, e) {
150
158
  const t = (e ?? "").trim();
151
159
  return t.startsWith("/") ? R(t) : R(w.posix.join(l || "", t));
152
160
  }
153
- function p(l, e) {
154
- const { path: t, name: s, children: o, meta: a, alias: r } = e, i = {
161
+ function z(l, e) {
162
+ const { path: t, name: a, children: o, meta: s, alias: r } = e, i = {
155
163
  ...l,
156
164
  path: t
157
165
  };
158
- return s !== void 0 && (i.name = s), o !== void 0 && (i.children = o), a !== void 0 && (i.meta = { ...l.meta, ...a }), r !== void 0 ? (i.alias = r, i.meta = { ...i.meta, alias: r }) : "alias" in e && (i.alias = void 0, i.meta = { ...i.meta, alias: void 0 }), i;
166
+ return a !== void 0 && (i.name = a), o !== void 0 && (i.children = o), s !== void 0 && (i.meta = { ...l.meta, ...s }), r !== void 0 ? (i.alias = r, i.meta = { ...i.meta, alias: r }) : "alias" in e && (i.alias = void 0, i.meta = { ...i.meta, alias: void 0 }), i;
159
167
  }
160
- function se(l) {
161
- const e = l.alias, t = l.meta?.alias, s = e ?? t;
162
- return Array.isArray(s) ? s : [];
168
+ function le(l) {
169
+ const e = l.alias, t = l.meta?.alias, a = e ?? t;
170
+ return Array.isArray(a) ? a : [];
163
171
  }
164
- function _(l, e, t, s = "localized-") {
165
- const o = se(l);
172
+ function W(l, e, t, a = "localized-") {
173
+ const o = le(l);
166
174
  if (!o.length) return [];
167
- const a = [];
175
+ const s = [];
168
176
  for (const r of o) {
169
- const i = A(e, r, t);
170
- a.push(
171
- p(l, {
177
+ const i = x(e, r, t);
178
+ s.push(
179
+ z(l, {
172
180
  path: i,
173
- name: `${s}${l.name ?? ""}`,
181
+ name: `${a}${l.name ?? ""}`,
174
182
  alias: void 0,
175
183
  meta: { alias: void 0 },
176
184
  // Important: if the source page has children, the alias route
@@ -180,7 +188,7 @@ function _(l, e, t, s = "localized-") {
180
188
  })
181
189
  );
182
190
  }
183
- return a;
191
+ return s;
184
192
  }
185
193
  class k {
186
194
  processPage(e, t) {
@@ -188,10 +196,10 @@ class k {
188
196
  throw new Error("page.path is required");
189
197
  if (q(e))
190
198
  return [e];
191
- if (e.path && D(e.path, t.excludePatterns))
199
+ if (e.path && M(e.path, t.excludePatterns))
192
200
  return [e];
193
- const s = e.path ?? "", o = b(e.name, e.path), a = x(s);
194
- return t.globalLocaleRoutes[o] === !1 || t.globalLocaleRoutes[a] === !1 ? [e] : this.generateVariants(e, t);
201
+ const a = e.path ?? "", o = b(e.name, e.path);
202
+ return S(t.globalLocaleRoutes, a, o) ? [e] : this.generateVariants(e, t);
195
203
  }
196
204
  postProcess(e, t) {
197
205
  return e;
@@ -202,39 +210,45 @@ class k {
202
210
  * - parentLocalizedPath used for the final path,
203
211
  * and returns an array of localized child routes.
204
212
  */
205
- localizeChildren(e, t, s, o, a, r) {
206
- return e.flatMap((i) => this.localizeChild(i, t, s, o, a, r));
213
+ localizeChildren(e, t, a, o, s, r) {
214
+ return e.flatMap((i) => this.localizeChild(i, t, a, o, s, r));
207
215
  }
208
216
  /**
209
217
  * Variant for a single route with :locale(locale1|locale2) — without custom paths.
210
218
  * Returns a single child route with a relative path and recursively localized children.
211
219
  */
212
- localizeChildrenAllLocales(e, t, s, o, a) {
213
- return e.flatMap((r) => this.localizeChildAllLocales(r, t, s, o, a));
214
- }
215
- localizeChildAllLocales(e, t, s, o, a) {
216
- const r = z(s, e.path ?? ""), i = z(t, e.path ?? ""), n = F(i), f = a.localizedPaths[n];
217
- if (f)
218
- return o.flatMap((d) => {
219
- const P = f[d] ?? z(t, e.path ?? "");
220
- return this.localizeChild(e, P, s, d, a, !0);
220
+ localizeChildrenAllLocales(e, t, a, o, s) {
221
+ return e.flatMap((r) => this.localizeChildAllLocales(r, t, a, o, s));
222
+ }
223
+ localizeChildAllLocales(e, t, a, o, s) {
224
+ const r = y(a, e.path ?? ""), i = b(e.name, e.path);
225
+ if (S(s.globalLocaleRoutes, r, i))
226
+ return [e];
227
+ const n = y(t, e.path ?? ""), f = F(n), c = s.localizedPaths[f];
228
+ if (c)
229
+ return o.flatMap((P) => {
230
+ const p = c[P] ?? y(t, e.path ?? "");
231
+ return this.localizeChild(e, p, a, P, s, !0);
221
232
  });
222
- const c = R(e.path ?? ""), h = g(c), u = this.localizeChildrenAllLocales($(e.children ?? []), i, r, o, a), m = `${a.localizedRouteNamePrefix}${e.name ?? ""}`;
233
+ const h = R(e.path ?? ""), u = g(h), m = this.localizeChildrenAllLocales($(e.children ?? []), n, r, o, s), d = `${s.localizedRouteNamePrefix}${e.name ?? ""}`;
223
234
  return [
224
- p(e, {
225
- path: h,
226
- name: m,
227
- children: u
235
+ z(e, {
236
+ path: u,
237
+ name: d,
238
+ children: m
228
239
  })
229
240
  ];
230
241
  }
231
- localizeChild(e, t, s, o, a, r) {
232
- const i = z(s, e.path ?? ""), n = a.getCustomPath(i, o), f = g(R(n || (e.path ?? ""))), c = n ?? z(t, e.path ?? ""), h = this.localizeChildren($(e.children ?? []), c, i, o, a, r), u = b(e.name, e.path), m = `${a.localizedRouteNamePrefix}${u}-${o}`;
242
+ localizeChild(e, t, a, o, s, r) {
243
+ const i = y(a, e.path ?? ""), n = b(e.name, e.path);
244
+ if (S(s.globalLocaleRoutes, i, n))
245
+ return [e];
246
+ const f = s.getCustomPath(i, o), c = g(R(f || (e.path ?? ""))), h = f ?? y(t, e.path ?? ""), u = this.localizeChildren($(e.children ?? []), h, i, o, s, r), m = b(e.name, e.path), d = `${s.localizedRouteNamePrefix}${m}-${o}`;
233
247
  return [
234
- p(e, {
235
- path: f,
236
- name: m,
237
- children: h
248
+ z(e, {
249
+ path: c,
250
+ name: d,
251
+ children: u
238
252
  })
239
253
  ];
240
254
  }
@@ -245,27 +259,27 @@ class k {
245
259
  *
246
260
  * The logic matches what used to be duplicated in each strategy's buildRoutePath.
247
261
  */
248
- buildRoutePathForLocales(e, t, s, o, a, r, i) {
262
+ buildRoutePathForLocales(e, t, a, o, s, r, i) {
249
263
  if (o) {
250
264
  const n = e.includes(i);
251
- return r || !n ? A(e, s, a) : R(s);
265
+ return r || !n ? x(e, a, s) : R(a);
252
266
  }
253
- return A(e, t, a);
267
+ return x(e, t, s);
254
268
  }
255
269
  }
256
- class oe extends k {
270
+ class ie extends k {
257
271
  generateVariants(e, t) {
258
- const s = e.path ?? "", o = b(e.name, e.path), a = t.getAllowedLocales(s, o), r = t.getCustomPathsForPage(s, o), i = $(e.children ?? []), n = [];
272
+ const a = e.path ?? "", o = b(e.name, e.path), s = t.getAllowedLocales(a, o), r = t.getCustomPathsForPage(a, o), i = $(e.children ?? []), n = [];
259
273
  if (n.push(e), r)
260
- for (const f of a) {
274
+ for (const f of s) {
261
275
  const c = r[f];
262
276
  if (!c) continue;
263
- const h = R(c), u = R(s);
277
+ const h = R(c), u = R(a);
264
278
  if (h === u)
265
279
  continue;
266
- const m = Z(c), d = j(o, f, !0), P = this.localizeChildrenForNoPrefix(i, h, s, s, f, t, 1);
280
+ const m = te(c), d = j(o, f, !0), P = this.localizeChildrenForNoPrefix(i, h, a, a, f, t, 1);
267
281
  n.push(
268
- p(e, {
282
+ z(e, {
269
283
  path: m,
270
284
  name: d,
271
285
  children: P,
@@ -274,7 +288,7 @@ class oe extends k {
274
288
  })
275
289
  ), t.noPrefixRedirect && f === t.defaultLocale.code && h !== u && (e.redirect = h);
276
290
  }
277
- return n.push(..._(e, a, t.customRegex, t.localizedRouteNamePrefix)), n;
291
+ return n.push(...W(e, s, t.customRegex, t.localizedRouteNamePrefix)), n;
278
292
  }
279
293
  /**
280
294
  * Localizes the children tree for the no_prefix strategy.
@@ -282,33 +296,33 @@ class oe extends k {
282
296
  * - on the first level, custom paths (globalLocaleRoutes/filesLocaleRoutes) are applied;
283
297
  * - on deeper levels, path stays as a segment (item, detail, etc.).
284
298
  */
285
- localizeChildrenForNoPrefix(e, t, s, o, a, r, i) {
299
+ localizeChildrenForNoPrefix(e, t, a, o, s, r, i) {
286
300
  return e.map((n) => {
287
- const f = z(s, n.path ?? "");
301
+ const f = y(a, n.path ?? "");
288
302
  let c, h;
289
303
  if (i === 1) {
290
- const P = r.getCustomPath(f, a);
304
+ const P = r.getCustomPath(f, s);
291
305
  if (P) {
292
- const L = R(P);
293
- c = g(L), h = L;
306
+ const p = R(P);
307
+ c = g(p), h = p;
294
308
  } else {
295
- const L = R(n.path ?? "");
296
- c = g(L), h = z(t, n.path ?? "");
309
+ const p = R(n.path ?? "");
310
+ c = g(p), h = y(t, n.path ?? "");
297
311
  }
298
312
  } else {
299
313
  const P = R(n.path ?? "");
300
- c = g(P), h = z(t, n.path ?? "");
314
+ c = g(P), h = y(t, n.path ?? "");
301
315
  }
302
316
  const u = this.localizeChildrenForNoPrefix(
303
317
  $(n.children ?? []),
304
318
  h,
305
319
  f,
306
320
  o,
307
- a,
321
+ s,
308
322
  r,
309
323
  i + 1
310
- ), m = b(n.name, n.path), d = j(m, a, !0);
311
- return p(n, {
324
+ ), m = b(n.name, n.path), d = j(m, s, !0);
325
+ return z(n, {
312
326
  path: c,
313
327
  name: d,
314
328
  children: u
@@ -316,30 +330,30 @@ class oe extends k {
316
330
  });
317
331
  }
318
332
  }
319
- function le(l) {
333
+ function re(l) {
320
334
  const e = l.alias ?? l.meta?.alias;
321
335
  return Array.isArray(e) ? e : [];
322
336
  }
323
- class ie extends k {
337
+ class ne extends k {
324
338
  generateVariants(e, t) {
325
- const s = e.path ?? "", o = b(e.name, e.path), a = t.getAllowedLocales(s, o), r = t.getCustomPathsForPage(s, o), i = $(e.children ?? []), n = [];
339
+ const a = e.path ?? "", o = b(e.name, e.path), s = t.getAllowedLocales(a, o), r = t.getCustomPathsForPage(a, o), i = $(e.children ?? []), n = [];
326
340
  if (r)
327
- for (const c of a) {
328
- const h = r[c], u = h ? R(h) : s, m = A(c, u, t.customRegex), d = j(o, c, !!h, t.localizedRouteNamePrefix), P = h ?? s, L = this.localizeChildren(i, P, s, c, t, !0);
341
+ for (const c of s) {
342
+ const h = r[c], u = h ? R(h) : a, m = x(c, u, t.customRegex), d = j(o, c, !!h, t.localizedRouteNamePrefix), P = h ?? a, p = this.localizeChildren(i, P, a, c, t, !0), L = ee(m);
329
343
  n.push(
330
- p(e, {
344
+ z(e, {
331
345
  path: m,
332
346
  name: d,
333
- children: L,
334
- alias: [],
335
- meta: { alias: [] }
347
+ children: p,
348
+ alias: L.length ? L : void 0,
349
+ meta: { alias: L.length ? L : [] }
336
350
  })
337
351
  );
338
352
  }
339
353
  else {
340
- const c = A(a, s, t.customRegex), h = j(o, a[0], !1, t.localizedRouteNamePrefix), u = this.localizeChildrenAllLocales(i, s, s, a, t);
354
+ const c = x(s, a, t.customRegex), h = j(o, s[0], !1, t.localizedRouteNamePrefix), u = this.localizeChildrenAllLocales(i, a, a, s, t);
341
355
  n.push(
342
- p(e, {
356
+ z(e, {
343
357
  path: c,
344
358
  name: h,
345
359
  children: u,
@@ -348,12 +362,12 @@ class ie extends k {
348
362
  })
349
363
  );
350
364
  }
351
- const f = le(e);
365
+ const f = re(e);
352
366
  if (f.length)
353
367
  for (const c of f) {
354
- const h = A(a, c, t.customRegex);
368
+ const h = x(s, c, t.customRegex);
355
369
  n.push(
356
- p(e, {
370
+ z(e, {
357
371
  path: h,
358
372
  name: `${t.localizedRouteNamePrefix}${e.name ?? ""}`,
359
373
  alias: void 0,
@@ -364,37 +378,37 @@ class ie extends k {
364
378
  return n;
365
379
  }
366
380
  postProcess(e, t) {
367
- const s = e.filter((a) => {
368
- if (a.name === "index" && a.path === "/") return !1;
369
- const r = a.path ?? "";
370
- return !!(r && D(r, t.excludePatterns) || t.globalLocaleRoutes[a.name ?? ""] === !1 || /^\/:locale/.test(r) || r === "/");
381
+ const a = e.filter((s) => {
382
+ if (s.name === "index" && s.path === "/") return !1;
383
+ const r = s.path ?? "";
384
+ return !!(r && M(r, t.excludePatterns) || S(t.globalLocaleRoutes, r, s.name ?? "") || /^\/:locale/.test(r) || r === "/");
371
385
  }), o = t.defaultLocale.code;
372
- for (const [a, r] of Object.entries(t.globalLocaleRoutes)) {
386
+ for (const [s, r] of Object.entries(t.globalLocaleRoutes)) {
373
387
  if (r === !1 || typeof r != "object") continue;
374
388
  const i = r[o];
375
389
  if (!i) continue;
376
- const n = a.startsWith("/") ? a : `/${a}`, f = `/${o}${i.startsWith("/") ? i : `/${i}`}`;
377
- n !== f && s.push({
390
+ const n = s.startsWith("/") ? s : `/${s}`, f = `/${o}${i.startsWith("/") ? i : `/${i}`}`;
391
+ n !== f && a.push({
378
392
  path: n,
379
- name: `redirect-${a.replace(/\//g, "-")}`,
393
+ name: `redirect-${s.replace(/\//g, "-")}`,
380
394
  redirect: f
381
395
  });
382
396
  }
383
- return t.fallbackRedirectComponentPath && s.push({
397
+ return t.fallbackRedirectComponentPath && a.push({
384
398
  path: "/:pathMatch(.*)*",
385
399
  name: "custom-fallback-route",
386
400
  file: t.fallbackRedirectComponentPath,
387
401
  meta: {
388
402
  globalLocaleRoutes: t.rawGlobalLocaleRoutes ?? t.globalLocaleRoutes
389
403
  }
390
- }), s;
404
+ }), a;
391
405
  }
392
406
  }
393
- class re extends k {
407
+ class ce extends k {
394
408
  generateVariants(e, t) {
395
- const s = e.path ?? "", o = b(e.name, e.path), a = t.getAllowedLocales(s, o), r = t.getCustomPathsForPage(s, o), i = $(e.children ?? []), n = [], f = t.defaultLocale.code;
409
+ const a = e.path ?? "", o = b(e.name, e.path), s = t.getAllowedLocales(a, o), r = t.getCustomPathsForPage(a, o), i = $(e.children ?? []), n = [], f = t.defaultLocale.code;
396
410
  n.push(e);
397
- const c = t.locales.filter((u) => a.includes(u.code));
411
+ const c = t.locales.filter((u) => s.includes(u.code));
398
412
  if (c.length > 0)
399
413
  if (r)
400
414
  for (const u of c) {
@@ -410,7 +424,7 @@ class re extends k {
410
424
  t.customRegex,
411
425
  !1,
412
426
  u.code,
413
- s,
427
+ a,
414
428
  t
415
429
  );
416
430
  d && n.push(d);
@@ -423,7 +437,7 @@ class re extends k {
423
437
  t.customRegex,
424
438
  !0,
425
439
  u.code,
426
- s,
440
+ a,
427
441
  t
428
442
  );
429
443
  P && n.push(P);
@@ -437,7 +451,7 @@ class re extends k {
437
451
  t.customRegex,
438
452
  !1,
439
453
  u.code,
440
- s,
454
+ a,
441
455
  t
442
456
  );
443
457
  d && n.push(d);
@@ -452,7 +466,7 @@ class re extends k {
452
466
  t.customRegex,
453
467
  !1,
454
468
  u.code,
455
- s,
469
+ a,
456
470
  t
457
471
  );
458
472
  d && n.push(d);
@@ -468,33 +482,33 @@ class re extends k {
468
482
  t.customRegex,
469
483
  !1,
470
484
  !0,
471
- s,
485
+ a,
472
486
  t
473
487
  );
474
488
  m && n.push(m);
475
489
  }
476
- const h = _(e, a, t.customRegex, t.localizedRouteNamePrefix);
490
+ const h = W(e, s, t.customRegex, t.localizedRouteNamePrefix);
477
491
  return h.length && n.push(...h), n;
478
492
  }
479
493
  postProcess(e, t) {
480
- const s = [], o = [];
481
- for (const a of e) {
482
- const r = a.name ?? "";
483
- typeof r == "string" && r.startsWith(t.localizedRouteNamePrefix) ? o.push(a) : s.push(a);
494
+ const a = [], o = [];
495
+ for (const s of e) {
496
+ const r = s.name ?? "";
497
+ typeof r == "string" && r.startsWith(t.localizedRouteNamePrefix) ? o.push(s) : a.push(s);
484
498
  }
485
- return [...s, ...o];
499
+ return [...a, ...o];
486
500
  }
487
- createLocalizedRoute(e, t, s, o, a = "", r, i = !1, n = !1, f, c) {
501
+ createLocalizedRoute(e, t, a, o, s = "", r, i = !1, n = !1, f, c) {
488
502
  const h = this.buildRoutePathForLocales(
489
503
  t,
490
504
  e.path ?? "",
491
- encodeURI(a),
505
+ s,
492
506
  o,
493
507
  r,
494
508
  i,
495
509
  c.defaultLocale.code
496
510
  );
497
- if (!h || !(o && a) && h === e.path || t.length === 0) return null;
511
+ if (!h || !(o && s) && h === e.path || t.length === 0) return null;
498
512
  const m = t[0];
499
513
  if (!m) return null;
500
514
  const d = f ?? e.path ?? "", P = j(
@@ -502,23 +516,23 @@ class re extends k {
502
516
  m,
503
517
  o,
504
518
  c.localizedRouteNamePrefix
505
- ), L = i || m !== c.defaultLocale.code, y = t.length === 1 ? this.localizeChildren(s, h, d, m, c, L) : this.localizeChildrenAllLocales(s, h, d, t, c);
506
- return p(e, {
519
+ ), p = i || m !== c.defaultLocale.code, L = t.length === 1 ? this.localizeChildren(a, h, d, m, c, p) : this.localizeChildrenAllLocales(a, h, d, t, c);
520
+ return z(e, {
507
521
  path: h,
508
522
  name: P,
509
- children: y,
523
+ children: L,
510
524
  alias: [],
511
525
  meta: { alias: [] }
512
526
  });
513
527
  }
514
528
  }
515
- class ne extends k {
529
+ class ue extends k {
516
530
  generateVariants(e, t) {
517
- const s = e.path ?? "", o = b(e.name, e.path), a = t.getAllowedLocales(s, o), r = t.getCustomPathsForPage(s, o), i = $(e.children ?? []), n = [], f = t.defaultLocale.code;
518
- if (a.includes(f)) {
519
- const u = r?.[f], m = u ? R(u) : s, d = u ? { [f]: u } : {}, P = this.createLocalizedChildren(
531
+ const a = e.path ?? "", o = b(e.name, e.path), s = t.getAllowedLocales(a, o), r = t.getCustomPathsForPage(a, o), i = $(e.children ?? []), n = [], f = t.defaultLocale.code;
532
+ if (s.includes(f)) {
533
+ const u = r?.[f], m = u ? R(u) : a, d = u ? { [f]: u } : {}, P = this.createLocalizedChildren(
520
534
  i,
521
- s,
535
+ a,
522
536
  [f],
523
537
  !1,
524
538
  !1,
@@ -527,14 +541,14 @@ class ne extends k {
527
541
  t
528
542
  );
529
543
  n.push(
530
- p(e, {
544
+ z(e, {
531
545
  path: m,
532
546
  name: e.name,
533
547
  children: P
534
548
  })
535
549
  );
536
550
  }
537
- const c = t.locales.filter((u) => a.includes(u.code) && u.code !== f);
551
+ const c = t.locales.filter((u) => s.includes(u.code) && u.code !== f);
538
552
  if (c.length)
539
553
  if (r)
540
554
  for (const u of c) {
@@ -549,7 +563,7 @@ class ne extends k {
549
563
  t.customRegex,
550
564
  !1,
551
565
  u.code,
552
- s,
566
+ a,
553
567
  t
554
568
  );
555
569
  d && n.push(d);
@@ -563,7 +577,7 @@ class ne extends k {
563
577
  t.customRegex,
564
578
  !1,
565
579
  u.code,
566
- s,
580
+ a,
567
581
  t
568
582
  );
569
583
  d && n.push(d);
@@ -579,73 +593,73 @@ class ne extends k {
579
593
  t.customRegex,
580
594
  !1,
581
595
  !0,
582
- s,
596
+ a,
583
597
  t
584
598
  );
585
599
  m && n.push(m);
586
600
  }
587
- const h = _(e, a, t.customRegex, t.localizedRouteNamePrefix);
601
+ const h = W(e, s, t.customRegex, t.localizedRouteNamePrefix);
588
602
  return h.length && n.push(...h), n;
589
603
  }
590
604
  postProcess(e, t) {
591
- const s = [], o = [];
605
+ const a = [], o = [];
592
606
  for (const r of e) {
593
607
  const i = r.name ?? "";
594
- typeof i == "string" && i.startsWith(t.localizedRouteNamePrefix) ? o.push(r) : s.push(r);
608
+ typeof i == "string" && i.startsWith(t.localizedRouteNamePrefix) ? o.push(r) : a.push(r);
595
609
  }
596
- const a = [...s, ...o];
597
- return t.fallbackRedirectComponentPath && a.push({
610
+ const s = [...a, ...o];
611
+ return t.fallbackRedirectComponentPath && s.push({
598
612
  path: "/:pathMatch(.*)*",
599
613
  name: "custom-fallback-route",
600
614
  file: t.fallbackRedirectComponentPath,
601
615
  meta: {
602
616
  globalLocaleRoutes: t.rawGlobalLocaleRoutes ?? t.globalLocaleRoutes
603
617
  }
604
- }), a;
618
+ }), s;
605
619
  }
606
- createLocalizedChildren(e, t, s, o = !0, a = !1, r = !1, i = {}, n) {
620
+ createLocalizedChildren(e, t, a, o = !0, s = !1, r = !1, i = {}, n) {
607
621
  return e.flatMap(
608
- (f) => this.createLocalizedVariants(f, t, s, o, a, r, i, n)
622
+ (f) => this.createLocalizedVariants(f, t, a, o, s, r, i, n)
609
623
  );
610
624
  }
611
- createLocalizedVariants(e, t, s, o, a, r = !1, i, n) {
612
- const f = R(e.path ?? ""), c = z(t, e.path ?? ""), h = F(c), u = n.localizedPaths[h], m = !!u, d = [];
625
+ createLocalizedVariants(e, t, a, o, s, r = !1, i, n) {
626
+ const f = R(e.path ?? ""), c = y(t, e.path ?? ""), h = F(c), u = n.localizedPaths[h], m = !!u, d = [];
613
627
  if (!m) {
614
- const P = g(f), L = this.createLocalizedChildren(
628
+ const P = g(f), p = this.createLocalizedChildren(
615
629
  $(e.children ?? []),
616
- z(t, e.path ?? ""),
617
- s,
618
- o,
630
+ y(t, e.path ?? ""),
619
631
  a,
632
+ o,
633
+ s,
620
634
  r,
621
635
  i,
622
636
  n
623
- ), y = this.buildChildRouteName(e.name, r, n);
637
+ ), L = this.buildChildRouteName(e.name, r, n);
624
638
  return d.push(
625
- p(e, {
639
+ z(e, {
626
640
  path: P,
627
- name: y,
628
- children: L
641
+ name: L,
642
+ children: p
629
643
  })
630
644
  ), d;
631
645
  }
632
- for (const P of s) {
633
- const L = i?.[P], y = !!L, C = u?.[P];
634
- let N = R(C || (e.path ?? ""));
635
- y && L && (C ? N = R(C) : N = z(L, e.path ?? ""));
636
- const v = H(P, n.defaultLocale, a) ? A(P, N, n.customRegex) : N, T = g(v), W = C ? R(C) : y ? L : z(t, e.path ?? ""), V = this.createLocalizedChildren(
646
+ for (const P of a) {
647
+ const p = i?.[P], L = !!p, C = u?.[P];
648
+ let A = R(C || (e.path ?? ""));
649
+ L && p && (C ? A = R(C) : A = y(p, e.path ?? ""));
650
+ const v = H(P, n.defaultLocale, s) ? x(P, A, n.customRegex) : A, T = g(v), E = C ? R(C) : L ? p : y(t, e.path ?? ""), V = this.createLocalizedChildren(
637
651
  $(e.children ?? []),
638
- W,
652
+ E,
639
653
  [P],
640
654
  o,
641
- a,
655
+ s,
642
656
  P,
643
657
  {
644
658
  ...i,
645
- [P]: W
659
+ [P]: E
646
660
  },
647
661
  n
648
- ), I = this.buildLocalizedRouteName(
662
+ ), B = this.buildLocalizedRouteName(
649
663
  b(e.name, e.path),
650
664
  P,
651
665
  o,
@@ -653,23 +667,23 @@ class ne extends k {
653
667
  n
654
668
  );
655
669
  d.push(
656
- p(e, {
670
+ z(e, {
657
671
  path: T,
658
- name: I,
672
+ name: B,
659
673
  children: V
660
674
  })
661
675
  );
662
676
  }
663
677
  return d;
664
678
  }
665
- buildChildRouteName(e, t, s) {
666
- return t === !0 ? `${s.localizedRouteNamePrefix}${e}` : typeof t == "string" ? `${s.localizedRouteNamePrefix}${e}-${t}` : e;
679
+ buildChildRouteName(e, t, a) {
680
+ return t === !0 ? `${a.localizedRouteNamePrefix}${e}` : typeof t == "string" ? `${a.localizedRouteNamePrefix}${e}-${t}` : e;
667
681
  }
668
- createLocalizedRoute(e, t, s, o, a = "", r, i = !1, n = !1, f, c) {
682
+ createLocalizedRoute(e, t, a, o, s = "", r, i = !1, n = !1, f, c) {
669
683
  const h = this.buildRoutePathForLocales(
670
684
  t,
671
685
  e.path ?? "",
672
- encodeURI(a),
686
+ s,
673
687
  o,
674
688
  r,
675
689
  i,
@@ -684,49 +698,49 @@ class ne extends k {
684
698
  o,
685
699
  c.localizedRouteNamePrefix
686
700
  );
687
- return p(e, {
701
+ return z(e, {
688
702
  path: h,
689
703
  name: d,
690
704
  children: this.createLocalizedChildren(
691
- s,
705
+ a,
692
706
  m,
693
707
  t,
694
708
  !0,
695
709
  !1,
696
710
  n,
697
- { [u]: a },
711
+ { [u]: s },
698
712
  c
699
713
  ),
700
714
  alias: [],
701
715
  meta: { alias: [] }
702
716
  });
703
717
  }
704
- buildLocalizedRouteName(e, t, s, o = !1, a) {
705
- return s ? o ? `${a.localizedRouteNamePrefix}${e}-${t}` : t && !J(t, a.defaultLocale) ? `${a.localizedRouteNamePrefix}${e}-${t}` : `${a.localizedRouteNamePrefix}${e}` : e;
718
+ buildLocalizedRouteName(e, t, a, o = !1, s) {
719
+ return a ? o ? `${s.localizedRouteNamePrefix}${e}-${t}` : t && !J(t, s.defaultLocale) ? `${s.localizedRouteNamePrefix}${e}-${t}` : `${s.localizedRouteNamePrefix}${e}` : e;
706
720
  }
707
721
  }
708
- function ce(l) {
722
+ function he(l) {
709
723
  switch (l) {
710
724
  case "no_prefix":
711
- return new oe();
712
- case "prefix":
713
725
  return new ie();
726
+ case "prefix":
727
+ return new ne();
714
728
  case "prefix_and_default":
715
- return new re();
729
+ return new ce();
716
730
  case "prefix_except_default":
717
- return new ne();
731
+ return new ue();
718
732
  default:
719
733
  throw new Error(`Unknown route strategy: ${l}`);
720
734
  }
721
735
  }
722
- class me {
736
+ class Re {
723
737
  constructor(e) {
724
738
  this.localizedPaths = {};
725
739
  const {
726
740
  locales: t,
727
- defaultLocaleCode: s,
741
+ defaultLocaleCode: a,
728
742
  strategy: o,
729
- globalLocaleRoutes: a,
743
+ globalLocaleRoutes: s,
730
744
  filesLocaleRoutes: r = {},
731
745
  routeLocales: i = {},
732
746
  noPrefixRedirect: n,
@@ -734,28 +748,28 @@ class me {
734
748
  localizedRouteNamePrefix: c = "localized-",
735
749
  customRegexMatcher: h,
736
750
  fallbackRedirectComponentPath: u
737
- } = e, m = X(t, s);
751
+ } = e, m = X(t, a);
738
752
  this.locales = m.locales, this.defaultLocale = m.defaultLocale, this.strategy = o, this.noPrefixRedirect = n, this.excludePatterns = f, this.localizedRouteNamePrefix = c, this.customRegex = h, this.fallbackRedirectComponentPath = u, this.activeLocaleCodes = this.computeActiveLocaleCodes();
739
753
  const d = {};
740
- for (const P in a) {
741
- const L = x(P), y = a[P];
742
- if (typeof y == "object") {
754
+ for (const P in s) {
755
+ const p = N(P), L = s[P];
756
+ if (typeof L == "object") {
743
757
  const C = {};
744
- for (const N in y) {
745
- const v = y[N];
746
- v && (C[N] = x(v));
758
+ for (const A in L) {
759
+ const v = L[A];
760
+ v && (C[A] = N(v));
747
761
  }
748
- d[L] = C;
762
+ d[p] = C;
749
763
  } else
750
- d[L] = y;
764
+ d[p] = L;
751
765
  }
752
- this.globalLocaleRoutes = d, this.rawGlobalLocaleRoutes = a ?? {}, this.filesLocaleRoutes = r ?? {}, this.routeLocales = i ?? {};
766
+ this.globalLocaleRoutes = d, this.rawGlobalLocaleRoutes = s ?? {}, this.filesLocaleRoutes = r ?? {}, this.routeLocales = i ?? {};
753
767
  }
754
768
  computeActiveLocaleCodes() {
755
- return this.locales.filter((e) => e.code !== this.defaultLocale.code || K(this.strategy) || O(this.strategy)).map((e) => e.code);
769
+ return this.locales.filter((e) => e.code !== this.defaultLocale.code || O(this.strategy) || D(this.strategy)).map((e) => e.code);
756
770
  }
757
771
  extendPages(e) {
758
- const t = new ae({
772
+ const t = new oe({
759
773
  locales: this.locales,
760
774
  defaultLocaleCode: this.defaultLocale.code,
761
775
  strategy: this.strategy,
@@ -771,23 +785,23 @@ class me {
771
785
  rawGlobalLocaleRoutes: this.rawGlobalLocaleRoutes
772
786
  });
773
787
  this.localizedPaths = t.localizedPaths;
774
- const s = ce(this.strategy), o = [...e], a = [];
788
+ const a = he(this.strategy), o = [...e], s = [];
775
789
  for (const i of o)
776
- a.push(...s.processPage(i, t));
777
- const r = s.postProcess(a, t);
790
+ s.push(...a.processPage(i, t));
791
+ const r = a.postProcess(s, t);
778
792
  e.length = 0, e.push(...r);
779
793
  }
780
794
  extractLocalizedPaths(e, t = "") {
781
- return S(e, this.globalLocaleRoutes, this.filesLocaleRoutes, t);
795
+ return _(e, this.globalLocaleRoutes, this.filesLocaleRoutes, t);
782
796
  }
783
797
  /**
784
798
  * Creates global and per-page translation JSON files for the current resolved locales.
785
799
  */
786
- ensureTranslationFilesExist(e, t, s, o) {
787
- this.locales.forEach((a) => {
788
- const r = w.join(s, t, `${a.code}.json`);
800
+ ensureTranslationFilesExist(e, t, a, o) {
801
+ this.locales.forEach((s) => {
802
+ const r = w.join(a, t, `${s.code}.json`);
789
803
  this.ensureFileExists(r), o || e.forEach((i) => {
790
- const n = w.join(s, t, "pages", `${i}/${a.code}.json`);
804
+ const n = w.join(a, t, "pages", `${i}/${s.code}.json`);
791
805
  this.ensureFileExists(n);
792
806
  });
793
807
  });
@@ -795,7 +809,7 @@ class me {
795
809
  ensureFileExists(e) {
796
810
  try {
797
811
  const t = w.dirname(e);
798
- E(t) || U(t, { recursive: !0 }), E(e) || B(e, JSON.stringify({}), "utf-8");
812
+ K(t) || I(t, { recursive: !0 }), K(e) || U(e, JSON.stringify({}), "utf-8");
799
813
  } catch {
800
814
  }
801
815
  }
@@ -805,11 +819,11 @@ class me {
805
819
  * Used by nitro:config and prerender so route rules work with custom paths (e.g. /de/ueber-uns).
806
820
  */
807
821
  resolveLocalizedPath(e, t) {
808
- const s = x(e), o = g(s) || "/";
809
- let a;
810
- const r = this.globalLocaleRoutes[o], i = this.globalLocaleRoutes[s];
811
- r && typeof r == "object" && !Array.isArray(r) ? a = r[t] : i && typeof i == "object" && !Array.isArray(i) && (a = i[t]);
812
- const n = !!a, f = a ? R(a) : R(s) || "";
822
+ const a = N(e), o = g(a) || "/";
823
+ let s;
824
+ const r = this.globalLocaleRoutes[o], i = this.globalLocaleRoutes[a];
825
+ r && typeof r == "object" && !Array.isArray(r) ? s = r[t] : i && typeof i == "object" && !Array.isArray(i) && (s = i[t]);
826
+ const n = !!s, f = s ? R(s) : R(a) || "";
813
827
  let c = !1;
814
828
  if (this.strategy === "no_prefix" ? c = !1 : this.strategy === "prefix" || this.strategy === "prefix_and_default" ? c = !0 : this.strategy === "prefix_except_default" && (c = t !== this.defaultLocale.code), t === this.defaultLocale.code && !n && (this.strategy === "prefix_except_default" || this.strategy === "no_prefix") && (c = !1), !c)
815
829
  return R(f) || "/";
@@ -821,35 +835,37 @@ class me {
821
835
  * When disablePageLocales is true, only index routes are generated (all pages share root translations).
822
836
  * Otherwise, generates index + per-page routes for each locale.
823
837
  */
824
- generateDataRoutes(e, t, s) {
825
- const o = [], a = this.collectPageNames(e);
838
+ generateDataRoutes(e, t, a) {
839
+ const o = [], s = this.collectPageNames(e);
826
840
  for (const r of this.locales)
827
- if (o.push(`/${t}/index/${r.code}/data.json`), !s)
828
- for (const i of a)
841
+ if (o.push(`/${t}/index/${r.code}/data.json`), !a)
842
+ for (const i of s)
829
843
  o.push(`/${t}/${i}/${r.code}/data.json`);
830
844
  return o;
831
845
  }
832
846
  collectPageNames(e) {
833
- const t = /* @__PURE__ */ new Set(), s = (o) => {
834
- for (const a of o)
835
- typeof a.name == "string" && a.name.length > 0 && t.add(a.name), a.children && a.children.length > 0 && s(a.children);
847
+ const t = /* @__PURE__ */ new Set(), a = (o) => {
848
+ for (const s of o)
849
+ typeof s.name == "string" && s.name.length > 0 && t.add(s.name), s.children && s.children.length > 0 && a(s.children);
836
850
  };
837
- return s(e), [...t];
851
+ return a(e), [...t];
838
852
  }
839
853
  }
840
854
  export {
841
- me as RouteGenerator,
842
- A as buildFullPath,
843
- Z as buildFullPathNoPrefix,
855
+ Re as RouteGenerator,
856
+ ee as buildEncodedPathAliases,
857
+ x as buildFullPath,
858
+ te as buildFullPathNoPrefix,
844
859
  j as buildRouteName,
845
860
  $ as cloneArray,
846
- S as extractLocalizedPaths,
847
- D as isInternalPath,
848
- de as isLocaleAllowedForUnlocalizedRoute,
861
+ _ as extractLocalizedPaths,
862
+ M as isInternalPath,
863
+ Pe as isLocaleAllowedForUnlocalizedRoute,
849
864
  J as isLocaleDefault,
865
+ S as isLocalizationDisabledForPage,
850
866
  q as isPageRedirectOnly,
851
867
  R as normalizePath,
852
- x as normalizeRouteKey,
868
+ N as normalizeRouteKey,
853
869
  g as removeLeadingSlash,
854
870
  H as shouldAddLocalePrefix
855
871
  };
@@ -1,3 +1,3 @@
1
1
  export { buildRouteName, buildRouteNameFromRoute, cloneArray, isInternalPath, isLocaleDefault, isPageRedirectOnly, shouldAddLocalePrefix, } from './common';
2
2
  export { type ResolvedLocales, resolveLocales } from './locales';
3
- export { buildFullPath, buildFullPathNoPrefix, joinPath, normalizePath, normalizeRouteKey, removeLeadingSlash } from './path';
3
+ export { buildEncodedPathAliases, buildFullPath, buildFullPathNoPrefix, joinPath, normalizePath, normalizeRouteKey, removeLeadingSlash } from './path';
@@ -1,3 +1,3 @@
1
1
  export { buildRouteName, buildRouteNameFromRoute, cloneArray, isInternalPath, isLocaleDefault, isPageRedirectOnly, shouldAddLocalePrefix, } from './common';
2
2
  export { type ResolvedLocales, resolveLocales } from './locales';
3
- export { buildFullPath, buildFullPathNoPrefix, joinPath, normalizePath, normalizeRouteKey, removeLeadingSlash } from './path';
3
+ export { buildEncodedPathAliases, buildFullPath, buildFullPathNoPrefix, joinPath, normalizePath, normalizeRouteKey, removeLeadingSlash } from './path';
@@ -2,5 +2,7 @@ export declare function normalizeRouteKey(key: string): string;
2
2
  export declare const normalizePath: (routePath: string) => string;
3
3
  export declare const removeLeadingSlash: (routePath: string) => string;
4
4
  export declare function joinPath(...segments: string[]): string;
5
+ /** Alias paths for percent-encoded variants of non-ASCII localized routes. */
6
+ export declare function buildEncodedPathAliases(routePath: string): string[];
5
7
  export declare function buildFullPath(locale: string | string[], basePath: string, customRegex?: string | RegExp): string;
6
8
  export declare function buildFullPathNoPrefix(basePath: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@i18n-micro/route-strategy",
3
- "version": "1.1.9",
3
+ "version": "1.1.12",
4
4
  "description": "Locale-aware route generator for Nuxt i18n micro",
5
5
  "keywords": [
6
6
  "i18n",
@@ -63,17 +63,14 @@
63
63
  },
64
64
  "dependencies": {
65
65
  "@nuxt/schema": "^3.18.1 || ^4.0.0",
66
- "@i18n-micro/types": "1.2.6",
67
- "@i18n-micro/core": "1.3.3"
66
+ "@i18n-micro/core": "1.3.8",
67
+ "@i18n-micro/types": "1.2.7"
68
68
  },
69
69
  "devDependencies": {
70
- "@types/jest": "^29.5.14",
71
- "jest": "^29.7.0",
72
70
  "publint": "^0.3.17",
73
- "ts-jest": "^29.4.6",
74
- "vite": "^7.3.1",
71
+ "vite": "^7.3.6",
75
72
  "vite-plugin-dts": "^4.5.4",
76
- "vitest": "^3.2.4"
73
+ "vitest": "^4.1.10"
77
74
  },
78
75
  "engines": {
79
76
  "node": ">=18"
@@ -81,7 +78,7 @@
81
78
  "scripts": {
82
79
  "build": "vite build",
83
80
  "check:package": "publint",
84
- "test": "jest",
81
+ "test": "vitest run",
85
82
  "test:dist": "vitest run --config vitest.dist.config.ts"
86
83
  }
87
84
  }