@i18n-micro/route-strategy 1.1.8 → 1.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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"),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},g=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 X(l){return!l||!/[\u0080-\uFFFF]/.test(l)?l:l.split("/").map(e=>!e||e.startsWith(":")||!/[\u0080-\uFFFF]/.test(e)?e:encodeURI(e)).join("/")}function V(l){const e=X(l);return e!==l?[e]:[]}function A(l,e,t){const s=Q(t?.toString()),o=s||(Array.isArray(l)?l.join("|"):l),a=e;return R(w.posix.join("/",`:locale(${o})`,a))}function q(l){const e=l;return R(e)}const Y=(l,e)=>l??(e??"").replace(/[^a-z0-9]/gi,"-").replace(/^-+|-+$/g,"");function j(l){return g(l)||"/"}function _(l,e,t,s=""){const o={};return l.forEach(a=>{const r=Y(a.name,a.path),i=R(G(s,a.path??"")),n=j(i),d=x(i),c=e[n]||e[d]||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 Z(l,e,t,s){if(!l||Object.keys(l).length===0)return!0;const o=x(t),a=g(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),d=i.filter(c=>n.includes(c));return d.length===0?!0:d.includes(s)}function ee(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 te{constructor(e){this.locales=e.locales,this.defaultLocale=this.findLocaleByCode(e.locales,e.defaultLocaleCode)??{code:e.defaultLocaleCode},this.strategy=e.strategy,this.globalLocaleRoutes=ee(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 y(l,e){const t=(e??"").trim();return t.startsWith("/")?R(t):R(w.posix.join(l||"",t))}function z(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 ae(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=ae(l);if(!o.length)return[];const a=[];for(const r of o){const i=A(e,r,t);a.push(z(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=y(s,e.path??""),i=y(t,e.path??""),n=j(i),d=a.localizedPaths[n];if(d)return o.flatMap(f=>{const P=d[f]??y(t,e.path??"");return this.localizeChild(e,P,s,f,a,!0)});const c=R(e.path??""),h=g(c),u=this.localizeChildrenAllLocales(b(e.children??[]),i,r,o,a),m=`${a.localizedRouteNamePrefix}${e.name??""}`;return[z(e,{path:h,name:m,children:u})]}localizeChild(e,t,s,o,a,r){const i=y(s,e.path??""),n=a.getCustomPath(i,o),d=g(R(n||(e.path??""))),c=n??y(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[z(e,{path:d,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 se 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 d of a){const c=r[d];if(!c)continue;const h=R(c),u=R(s);if(h===u)continue;const m=q(c),f=F(o,d,!0),P=this.localizeChildrenForNoPrefix(i,h,s,s,d,t,1);n.push(z(e,{path:m,name:f,children:P,alias:[],meta:{alias:[]}})),t.noPrefixRedirect&&d===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 d=y(s,n.path??"");let c,h;if(i===1){const P=r.getCustomPath(d,a);if(P){const L=R(P);c=g(L),h=L}else{const L=R(n.path??"");c=g(L),h=y(t,n.path??"")}}else{const P=R(n.path??"");c=g(P),h=y(t,n.path??"")}const u=this.localizeChildrenForNoPrefix(b(n.children??[]),h,d,o,a,r,i+1),m=C(n.name,n.path),f=F(m,a,!0);return z(n,{path:c,name:f,children:u})})}}function oe(l){const e=l.alias??l.meta?.alias;return Array.isArray(e)?e:[]}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=[];if(r)for(const c of a){const h=r[c],u=h?R(h):s,m=A(c,u,t.customRegex),f=F(o,c,!!h,t.localizedRouteNamePrefix),P=h??s,L=this.localizeChildren(i,P,s,c,t,!0),p=V(m);n.push(z(e,{path:m,name:f,children:L,alias:p.length?p:void 0,meta:{alias:p.length?p:[]}}))}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(z(e,{path:c,name:h,children:u,alias:[],meta:{alias:[]}}))}const d=oe(e);if(d.length)for(const c of d){const h=A(a,c,t.customRegex);n.push(z(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}`,d=`/${o}${i.startsWith("/")?i:`/${i}`}`;n!==d&&s.push({path:n,name:`redirect-${a.replace(/\//g,"-")}`,redirect:d})}return t.fallbackRedirectComponentPath&&s.push({path:"/:pathMatch(.*)*",name:"custom-fallback-route",file:t.fallbackRedirectComponentPath,meta:{globalLocaleRoutes:t.rawGlobalLocaleRoutes??t.globalLocaleRoutes}}),s}}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=[],d=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===d){const f=this.createLocalizedRoute(e,[u.code],i,!0,m,t.customRegex,!1,u.code,s,t);f&&n.push(f);const P=this.createLocalizedRoute(e,[u.code],i,!0,m,t.customRegex,!0,u.code,s,t);P&&n.push(P)}else{const f=this.createLocalizedRoute(e,[u.code],i,!0,m,t.customRegex,!1,u.code,s,t);f&&n.push(f)}else{const f=this.createLocalizedRoute(e,[u.code],i,!1,"",t.customRegex,!1,u.code,s,t);f&&n.push(f)}}else{const u=c.map(f=>f.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,d,c){const h=this.buildRoutePathForLocales(t,e.path??"",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 f=d??e.path??"",P=F(C(e.name??"",f),m,o,c.localizedRouteNamePrefix),L=i||m!==c.defaultLocale.code,p=t.length===1?this.localizeChildren(s,h,f,m,c,L):this.localizeChildrenAllLocales(s,h,f,t,c);return z(e,{path:h,name:P,children:p,alias:[],meta:{alias:[]}})}}class re 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=[],d=t.defaultLocale.code;if(a.includes(d)){const u=r?.[d],m=u?R(u):s,f=u?{[d]:u}:{},P=this.createLocalizedChildren(i,s,[d],!1,!1,!1,f,t);n.push(z(e,{path:m,name:e.name,children:P}))}const c=t.locales.filter(u=>a.includes(u.code)&&u.code!==d);if(c.length)if(r)for(const u of c){const m=r[u.code];if(m){const f=this.createLocalizedRoute(e,[u.code],i,!0,m,t.customRegex,!1,u.code,s,t);f&&n.push(f)}else{const f=this.createLocalizedRoute(e,[u.code],i,!1,"",t.customRegex,!1,u.code,s,t);f&&n.push(f)}}else{const u=c.map(f=>f.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(d=>this.createLocalizedVariants(d,t,s,o,a,r,i,n))}createLocalizedVariants(e,t,s,o,a,r=!1,i,n){const d=R(e.path??""),c=y(t,e.path??""),h=j(c),u=n.localizedPaths[h],m=!!u,f=[];if(!m){const P=g(d),L=this.createLocalizedChildren(b(e.children??[]),y(t,e.path??""),s,o,a,r,i,n),p=this.buildChildRouteName(e.name,r,n);return f.push(z(e,{path:P,name:p,children:L})),f}for(const P of s){const L=i?.[P],p=!!L,$=u?.[P];let N=R($||(e.path??""));p&&L&&($?N=R($):N=y(L,e.path??""));const v=M(P,n.defaultLocale,a)?A(P,N,n.customRegex):N,B=g(v),D=$?R($):p?L:y(t,e.path??""),I=this.createLocalizedChildren(b(e.children??[]),D,[P],o,a,P,{...i,[P]:D},n),U=this.buildLocalizedRouteName(C(e.name,e.path),P,o,!!u,n);f.push(z(e,{path:B,name:U,children:I}))}return f}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,d,c){const h=this.buildRoutePathForLocales(t,e.path??"",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=d??e.path??"",f=F(C(e.name??"",m),u,o,c.localizedRouteNamePrefix);return z(e,{path:h,name:f,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 ne(l){switch(l){case"no_prefix":return new se;case"prefix":return new le;case"prefix_and_default":return new ie;case"prefix_except_default":return new re;default:throw new Error(`Unknown route strategy: ${l}`)}}class ce{constructor(e){this.localizedPaths={};const{locales:t,defaultLocaleCode:s,strategy:o,globalLocaleRoutes:a,filesLocaleRoutes:r={},routeLocales:i={},noPrefixRedirect:n,excludePatterns:d,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=d,this.localizedRouteNamePrefix=c,this.customRegex=h,this.fallbackRedirectComponentPath=u,this.activeLocaleCodes=this.computeActiveLocaleCodes();const f={};for(const P in a){const L=x(P),p=a[P];if(typeof p=="object"){const $={};for(const N in p){const v=p[N];v&&($[N]=x(v))}f[L]=$}else f[L]=p}this.globalLocaleRoutes=f,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 te({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=ne(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=g(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,d=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(d)||"/";const h=g(d);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=ce;exports.buildEncodedPathAliases=V;exports.buildFullPath=A;exports.buildFullPathNoPrefix=q;exports.buildRouteName=F;exports.cloneArray=b;exports.extractLocalizedPaths=_;exports.isInternalPath=E;exports.isLocaleAllowedForUnlocalizedRoute=Z;exports.isLocaleDefault=T;exports.isPageRedirectOnly=K;exports.normalizePath=R;exports.normalizeRouteKey=x;exports.removeLeadingSlash=g;exports.shouldAddLocalePrefix=M;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { extractLocalizedPaths, LocalizedPathsMap } from './core/localized-paths';
2
2
  import { isLocaleAllowedForUnlocalizedRoute } from './locale-route-access';
3
3
  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, };
4
+ import { buildEncodedPathAliases, 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, buildEncodedPathAliases, buildFullPath, buildFullPathNoPrefix, };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { extractLocalizedPaths, LocalizedPathsMap } from './core/localized-paths';
2
2
  import { isLocaleAllowedForUnlocalizedRoute } from './locale-route-access';
3
3
  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, };
4
+ import { buildEncodedPathAliases, 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, buildEncodedPathAliases, buildFullPath, buildFullPathNoPrefix, };
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import w from "node:path";
2
- import { existsSync as E, mkdirSync as U, writeFileSync as B } from "node:fs";
1
+ import A from "node:path";
2
+ import { existsSync as E, mkdirSync as B, writeFileSync as I } from "node:fs";
3
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 = [
4
+ const $ = (l) => l.map((e) => ({ ...e })), U = (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, ""), q = (l, e, t) => t && l !== e.code, H = (l, e) => (typeof l == "string" ? l : l.code) === e.code, J = [
5
5
  /^\/sitemap.*\.xml$/,
6
6
  /^\/sitemap\.xml$/,
7
7
  /^\/robots\.txt$/,
@@ -15,7 +15,7 @@ const $ = (l) => l.map((e) => ({ ...e })), q = (l) => !!(l.redirect && !l.file),
15
15
  function D(l, e) {
16
16
  if (/(?:^|\/)__[^/]+/.test(l))
17
17
  return !0;
18
- for (const t of Q)
18
+ for (const t of J)
19
19
  if (t.test(l))
20
20
  return !0;
21
21
  if (e) {
@@ -30,48 +30,52 @@ function D(l, e) {
30
30
  }
31
31
  return !1;
32
32
  }
33
- function X(l, e) {
33
+ function Q(l, e) {
34
34
  const t = l.reduce((o, a) => {
35
35
  const r = o.find((i) => i.code === a.code);
36
36
  return r ? Object.assign(r, a) : o.push(a), o;
37
37
  }, []).filter((o) => !o.disabled), s = t.find((o) => o.code === e) ?? { code: e };
38
38
  return { locales: t, defaultLocale: s };
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) => {
44
44
  if (!l)
45
45
  return "";
46
- const e = w.posix.normalize(l).replace(/\/+$/, "");
46
+ const e = A.posix.normalize(l).replace(/\/+$/, "");
47
47
  return e === "." ? "" : e;
48
- }, g = (l) => l.startsWith("/") ? l.slice(1) : l;
48
+ }, y = (l) => l.startsWith("/") ? l.slice(1) : l;
49
49
  function G(...l) {
50
- return w.posix.join(...l);
50
+ return A.posix.join(...l);
51
51
  }
52
- function Y(l) {
52
+ function X(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 Y(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));
62
- }
63
59
  function Z(l) {
64
- const e = M(l);
60
+ const e = Y(l);
61
+ return e !== l ? [e] : [];
62
+ }
63
+ function w(l, e, t) {
64
+ const s = X(t?.toString()), o = s || (Array.isArray(l) ? l.join("|") : l), a = e;
65
+ return R(A.posix.join("/", `:locale(${o})`, a));
66
+ }
67
+ function ee(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 te = (l, e) => l ?? (e ?? "").replace(/[^a-z0-9]/gi, "-").replace(/^-+|-+$/g, "");
68
72
  function F(l) {
69
- return g(l) || "/";
73
+ return y(l) || "/";
70
74
  }
71
- function S(l, e, t, s = "") {
75
+ function k(l, e, t, s = "") {
72
76
  const o = {};
73
77
  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];
78
+ const r = te(a.name, a.path), i = R(G(s, a.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 {
@@ -80,29 +84,29 @@ function S(l, e, t, s = "") {
80
84
  }
81
85
  if (a.children?.length) {
82
86
  const h = R(G(s, a.path ?? ""));
83
- Object.assign(o, S(a.children, e, t, h));
87
+ Object.assign(o, k(a.children, e, t, h));
84
88
  }
85
89
  }), o;
86
90
  }
87
- function de(l, e, t, s) {
91
+ function me(l, e, t, s) {
88
92
  if (!l || Object.keys(l).length === 0)
89
93
  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);
94
+ const o = N(t), a = y(o) || "/", r = a === "/" ? "/" : a, i = l[o] ?? l[t] ?? l[a] ?? l[r] ?? (a !== "/" ? l[`/${a}`] : void 0);
91
95
  if (!Array.isArray(i) || i.length === 0)
92
96
  return !0;
93
97
  const n = e.map((c) => c.code), f = i.filter((c) => n.includes(c));
94
98
  return f.length === 0 ? !0 : f.includes(s);
95
99
  }
96
- function te(l) {
100
+ function ae(l) {
97
101
  const e = {};
98
102
  if (!l) return e;
99
103
  for (const t in l) {
100
- const s = x(t), o = l[t];
104
+ const s = N(t), o = l[t];
101
105
  if (typeof o == "object") {
102
106
  const a = {};
103
107
  for (const r in o) {
104
108
  const i = o[r];
105
- i && (a[r] = x(i));
109
+ i && (a[r] = N(i));
106
110
  }
107
111
  e[s] = a;
108
112
  } else
@@ -110,9 +114,9 @@ function te(l) {
110
114
  }
111
115
  return e;
112
116
  }
113
- class ae {
117
+ class se {
114
118
  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;
119
+ this.locales = e.locales, this.defaultLocale = this.findLocaleByCode(e.locales, e.defaultLocaleCode) ?? { code: e.defaultLocaleCode }, this.strategy = e.strategy, this.globalLocaleRoutes = ae(e.globalLocaleRoutes ?? {}), this.filesLocaleRoutes = e.filesLocaleRoutes ?? {}, this.routeLocales = e.routeLocales ?? {}, this.localizedPaths = k(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;
116
120
  }
117
121
  findLocaleByCode(e, t) {
118
122
  return e.find((s) => s.code === t);
@@ -146,29 +150,29 @@ class ae {
146
150
  return this.activeLocaleCodes.filter((s) => !this.localizedPaths[t]?.[s]);
147
151
  }
148
152
  }
149
- function z(l, e) {
153
+ function g(l, e) {
150
154
  const t = (e ?? "").trim();
151
- return t.startsWith("/") ? R(t) : R(w.posix.join(l || "", t));
155
+ return t.startsWith("/") ? R(t) : R(A.posix.join(l || "", t));
152
156
  }
153
- function p(l, e) {
157
+ function z(l, e) {
154
158
  const { path: t, name: s, children: o, meta: a, alias: r } = e, i = {
155
159
  ...l,
156
160
  path: t
157
161
  };
158
162
  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;
159
163
  }
160
- function se(l) {
164
+ function oe(l) {
161
165
  const e = l.alias, t = l.meta?.alias, s = e ?? t;
162
166
  return Array.isArray(s) ? s : [];
163
167
  }
164
168
  function _(l, e, t, s = "localized-") {
165
- const o = se(l);
169
+ const o = oe(l);
166
170
  if (!o.length) return [];
167
171
  const a = [];
168
172
  for (const r of o) {
169
- const i = A(e, r, t);
173
+ const i = w(e, r, t);
170
174
  a.push(
171
- p(l, {
175
+ z(l, {
172
176
  path: i,
173
177
  name: `${s}${l.name ?? ""}`,
174
178
  alias: void 0,
@@ -182,15 +186,15 @@ function _(l, e, t, s = "localized-") {
182
186
  }
183
187
  return a;
184
188
  }
185
- class k {
189
+ class S {
186
190
  processPage(e, t) {
187
191
  if (e.path === void 0)
188
192
  throw new Error("page.path is required");
189
- if (q(e))
193
+ if (U(e))
190
194
  return [e];
191
195
  if (e.path && D(e.path, t.excludePatterns))
192
196
  return [e];
193
- const s = e.path ?? "", o = b(e.name, e.path), a = x(s);
197
+ const s = e.path ?? "", o = b(e.name, e.path), a = N(s);
194
198
  return t.globalLocaleRoutes[o] === !1 || t.globalLocaleRoutes[a] === !1 ? [e] : this.generateVariants(e, t);
195
199
  }
196
200
  postProcess(e, t) {
@@ -213,15 +217,15 @@ class k {
213
217
  return e.flatMap((r) => this.localizeChildAllLocales(r, t, s, o, a));
214
218
  }
215
219
  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];
220
+ const r = g(s, e.path ?? ""), i = g(t, e.path ?? ""), n = F(i), f = a.localizedPaths[n];
217
221
  if (f)
218
222
  return o.flatMap((d) => {
219
- const P = f[d] ?? z(t, e.path ?? "");
223
+ const P = f[d] ?? g(t, e.path ?? "");
220
224
  return this.localizeChild(e, P, s, d, a, !0);
221
225
  });
222
- const c = R(e.path ?? ""), h = g(c), u = this.localizeChildrenAllLocales($(e.children ?? []), i, r, o, a), m = `${a.localizedRouteNamePrefix}${e.name ?? ""}`;
226
+ const c = R(e.path ?? ""), h = y(c), u = this.localizeChildrenAllLocales($(e.children ?? []), i, r, o, a), m = `${a.localizedRouteNamePrefix}${e.name ?? ""}`;
223
227
  return [
224
- p(e, {
228
+ z(e, {
225
229
  path: h,
226
230
  name: m,
227
231
  children: u
@@ -229,9 +233,9 @@ class k {
229
233
  ];
230
234
  }
231
235
  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}`;
236
+ const i = g(s, e.path ?? ""), n = a.getCustomPath(i, o), f = y(R(n || (e.path ?? ""))), c = n ?? g(t, e.path ?? ""), h = this.localizeChildren($(e.children ?? []), c, i, o, a, r), u = b(e.name, e.path), m = `${a.localizedRouteNamePrefix}${u}-${o}`;
233
237
  return [
234
- p(e, {
238
+ z(e, {
235
239
  path: f,
236
240
  name: m,
237
241
  children: h
@@ -248,12 +252,12 @@ class k {
248
252
  buildRoutePathForLocales(e, t, s, o, a, r, i) {
249
253
  if (o) {
250
254
  const n = e.includes(i);
251
- return r || !n ? A(e, s, a) : R(s);
255
+ return r || !n ? w(e, s, a) : R(s);
252
256
  }
253
- return A(e, t, a);
257
+ return w(e, t, a);
254
258
  }
255
259
  }
256
- class oe extends k {
260
+ class le extends S {
257
261
  generateVariants(e, t) {
258
262
  const s = e.path ?? "", o = b(e.name, e.path), a = t.getAllowedLocales(s, o), r = t.getCustomPathsForPage(s, o), i = $(e.children ?? []), n = [];
259
263
  if (n.push(e), r)
@@ -263,9 +267,9 @@ class oe extends k {
263
267
  const h = R(c), u = R(s);
264
268
  if (h === u)
265
269
  continue;
266
- const m = Z(c), d = j(o, f, !0), P = this.localizeChildrenForNoPrefix(i, h, s, s, f, t, 1);
270
+ const m = ee(c), d = j(o, f, !0), P = this.localizeChildrenForNoPrefix(i, h, s, s, f, t, 1);
267
271
  n.push(
268
- p(e, {
272
+ z(e, {
269
273
  path: m,
270
274
  name: d,
271
275
  children: P,
@@ -284,20 +288,20 @@ class oe extends k {
284
288
  */
285
289
  localizeChildrenForNoPrefix(e, t, s, o, a, r, i) {
286
290
  return e.map((n) => {
287
- const f = z(s, n.path ?? "");
291
+ const f = g(s, n.path ?? "");
288
292
  let c, h;
289
293
  if (i === 1) {
290
294
  const P = r.getCustomPath(f, a);
291
295
  if (P) {
292
296
  const L = R(P);
293
- c = g(L), h = L;
297
+ c = y(L), h = L;
294
298
  } else {
295
299
  const L = R(n.path ?? "");
296
- c = g(L), h = z(t, n.path ?? "");
300
+ c = y(L), h = g(t, n.path ?? "");
297
301
  }
298
302
  } else {
299
303
  const P = R(n.path ?? "");
300
- c = g(P), h = z(t, n.path ?? "");
304
+ c = y(P), h = g(t, n.path ?? "");
301
305
  }
302
306
  const u = this.localizeChildrenForNoPrefix(
303
307
  $(n.children ?? []),
@@ -308,7 +312,7 @@ class oe extends k {
308
312
  r,
309
313
  i + 1
310
314
  ), m = b(n.name, n.path), d = j(m, a, !0);
311
- return p(n, {
315
+ return z(n, {
312
316
  path: c,
313
317
  name: d,
314
318
  children: u
@@ -316,30 +320,30 @@ class oe extends k {
316
320
  });
317
321
  }
318
322
  }
319
- function le(l) {
323
+ function ie(l) {
320
324
  const e = l.alias ?? l.meta?.alias;
321
325
  return Array.isArray(e) ? e : [];
322
326
  }
323
- class ie extends k {
327
+ class re extends S {
324
328
  generateVariants(e, t) {
325
329
  const s = e.path ?? "", o = b(e.name, e.path), a = t.getAllowedLocales(s, o), r = t.getCustomPathsForPage(s, o), i = $(e.children ?? []), n = [];
326
330
  if (r)
327
331
  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);
332
+ const h = r[c], u = h ? R(h) : s, m = w(c, u, t.customRegex), d = j(o, c, !!h, t.localizedRouteNamePrefix), P = h ?? s, L = this.localizeChildren(i, P, s, c, t, !0), p = Z(m);
329
333
  n.push(
330
- p(e, {
334
+ z(e, {
331
335
  path: m,
332
336
  name: d,
333
337
  children: L,
334
- alias: [],
335
- meta: { alias: [] }
338
+ alias: p.length ? p : void 0,
339
+ meta: { alias: p.length ? p : [] }
336
340
  })
337
341
  );
338
342
  }
339
343
  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);
344
+ const c = w(a, s, t.customRegex), h = j(o, a[0], !1, t.localizedRouteNamePrefix), u = this.localizeChildrenAllLocales(i, s, s, a, t);
341
345
  n.push(
342
- p(e, {
346
+ z(e, {
343
347
  path: c,
344
348
  name: h,
345
349
  children: u,
@@ -348,12 +352,12 @@ class ie extends k {
348
352
  })
349
353
  );
350
354
  }
351
- const f = le(e);
355
+ const f = ie(e);
352
356
  if (f.length)
353
357
  for (const c of f) {
354
- const h = A(a, c, t.customRegex);
358
+ const h = w(a, c, t.customRegex);
355
359
  n.push(
356
- p(e, {
360
+ z(e, {
357
361
  path: h,
358
362
  name: `${t.localizedRouteNamePrefix}${e.name ?? ""}`,
359
363
  alias: void 0,
@@ -390,7 +394,7 @@ class ie extends k {
390
394
  }), s;
391
395
  }
392
396
  }
393
- class re extends k {
397
+ class ne extends S {
394
398
  generateVariants(e, t) {
395
399
  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;
396
400
  n.push(e);
@@ -488,7 +492,7 @@ class re extends k {
488
492
  const h = this.buildRoutePathForLocales(
489
493
  t,
490
494
  e.path ?? "",
491
- encodeURI(a),
495
+ a,
492
496
  o,
493
497
  r,
494
498
  i,
@@ -502,17 +506,17 @@ class re extends k {
502
506
  m,
503
507
  o,
504
508
  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, {
509
+ ), L = i || m !== c.defaultLocale.code, p = t.length === 1 ? this.localizeChildren(s, h, d, m, c, L) : this.localizeChildrenAllLocales(s, h, d, t, c);
510
+ return z(e, {
507
511
  path: h,
508
512
  name: P,
509
- children: y,
513
+ children: p,
510
514
  alias: [],
511
515
  meta: { alias: [] }
512
516
  });
513
517
  }
514
518
  }
515
- class ne extends k {
519
+ class ce extends S {
516
520
  generateVariants(e, t) {
517
521
  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
522
  if (a.includes(f)) {
@@ -527,7 +531,7 @@ class ne extends k {
527
531
  t
528
532
  );
529
533
  n.push(
530
- p(e, {
534
+ z(e, {
531
535
  path: m,
532
536
  name: e.name,
533
537
  children: P
@@ -609,31 +613,31 @@ class ne extends k {
609
613
  );
610
614
  }
611
615
  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 = [];
616
+ const f = R(e.path ?? ""), c = g(t, e.path ?? ""), h = F(c), u = n.localizedPaths[h], m = !!u, d = [];
613
617
  if (!m) {
614
- const P = g(f), L = this.createLocalizedChildren(
618
+ const P = y(f), L = this.createLocalizedChildren(
615
619
  $(e.children ?? []),
616
- z(t, e.path ?? ""),
620
+ g(t, e.path ?? ""),
617
621
  s,
618
622
  o,
619
623
  a,
620
624
  r,
621
625
  i,
622
626
  n
623
- ), y = this.buildChildRouteName(e.name, r, n);
627
+ ), p = this.buildChildRouteName(e.name, r, n);
624
628
  return d.push(
625
- p(e, {
629
+ z(e, {
626
630
  path: P,
627
- name: y,
631
+ name: p,
628
632
  children: L
629
633
  })
630
634
  ), d;
631
635
  }
632
636
  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(
637
+ const L = i?.[P], p = !!L, C = u?.[P];
638
+ let x = R(C || (e.path ?? ""));
639
+ p && L && (C ? x = R(C) : x = g(L, e.path ?? ""));
640
+ const v = q(P, n.defaultLocale, a) ? w(P, x, n.customRegex) : x, M = y(v), W = C ? R(C) : p ? L : g(t, e.path ?? ""), T = this.createLocalizedChildren(
637
641
  $(e.children ?? []),
638
642
  W,
639
643
  [P],
@@ -645,7 +649,7 @@ class ne extends k {
645
649
  [P]: W
646
650
  },
647
651
  n
648
- ), I = this.buildLocalizedRouteName(
652
+ ), V = this.buildLocalizedRouteName(
649
653
  b(e.name, e.path),
650
654
  P,
651
655
  o,
@@ -653,10 +657,10 @@ class ne extends k {
653
657
  n
654
658
  );
655
659
  d.push(
656
- p(e, {
657
- path: T,
658
- name: I,
659
- children: V
660
+ z(e, {
661
+ path: M,
662
+ name: V,
663
+ children: T
660
664
  })
661
665
  );
662
666
  }
@@ -669,7 +673,7 @@ class ne extends k {
669
673
  const h = this.buildRoutePathForLocales(
670
674
  t,
671
675
  e.path ?? "",
672
- encodeURI(a),
676
+ a,
673
677
  o,
674
678
  r,
675
679
  i,
@@ -684,7 +688,7 @@ class ne extends k {
684
688
  o,
685
689
  c.localizedRouteNamePrefix
686
690
  );
687
- return p(e, {
691
+ return z(e, {
688
692
  path: h,
689
693
  name: d,
690
694
  children: this.createLocalizedChildren(
@@ -702,24 +706,24 @@ class ne extends k {
702
706
  });
703
707
  }
704
708
  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;
709
+ return s ? o ? `${a.localizedRouteNamePrefix}${e}-${t}` : t && !H(t, a.defaultLocale) ? `${a.localizedRouteNamePrefix}${e}-${t}` : `${a.localizedRouteNamePrefix}${e}` : e;
706
710
  }
707
711
  }
708
- function ce(l) {
712
+ function ue(l) {
709
713
  switch (l) {
710
714
  case "no_prefix":
711
- return new oe();
715
+ return new le();
712
716
  case "prefix":
713
- return new ie();
714
- case "prefix_and_default":
715
717
  return new re();
716
- case "prefix_except_default":
718
+ case "prefix_and_default":
717
719
  return new ne();
720
+ case "prefix_except_default":
721
+ return new ce();
718
722
  default:
719
723
  throw new Error(`Unknown route strategy: ${l}`);
720
724
  }
721
725
  }
722
- class me {
726
+ class Pe {
723
727
  constructor(e) {
724
728
  this.localizedPaths = {};
725
729
  const {
@@ -734,20 +738,20 @@ class me {
734
738
  localizedRouteNamePrefix: c = "localized-",
735
739
  customRegexMatcher: h,
736
740
  fallbackRedirectComponentPath: u
737
- } = e, m = X(t, s);
741
+ } = e, m = Q(t, s);
738
742
  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
743
  const d = {};
740
744
  for (const P in a) {
741
- const L = x(P), y = a[P];
742
- if (typeof y == "object") {
745
+ const L = N(P), p = a[P];
746
+ if (typeof p == "object") {
743
747
  const C = {};
744
- for (const N in y) {
745
- const v = y[N];
746
- v && (C[N] = x(v));
748
+ for (const x in p) {
749
+ const v = p[x];
750
+ v && (C[x] = N(v));
747
751
  }
748
752
  d[L] = C;
749
753
  } else
750
- d[L] = y;
754
+ d[L] = p;
751
755
  }
752
756
  this.globalLocaleRoutes = d, this.rawGlobalLocaleRoutes = a ?? {}, this.filesLocaleRoutes = r ?? {}, this.routeLocales = i ?? {};
753
757
  }
@@ -755,7 +759,7 @@ class me {
755
759
  return this.locales.filter((e) => e.code !== this.defaultLocale.code || K(this.strategy) || O(this.strategy)).map((e) => e.code);
756
760
  }
757
761
  extendPages(e) {
758
- const t = new ae({
762
+ const t = new se({
759
763
  locales: this.locales,
760
764
  defaultLocaleCode: this.defaultLocale.code,
761
765
  strategy: this.strategy,
@@ -771,31 +775,31 @@ class me {
771
775
  rawGlobalLocaleRoutes: this.rawGlobalLocaleRoutes
772
776
  });
773
777
  this.localizedPaths = t.localizedPaths;
774
- const s = ce(this.strategy), o = [...e], a = [];
778
+ const s = ue(this.strategy), o = [...e], a = [];
775
779
  for (const i of o)
776
780
  a.push(...s.processPage(i, t));
777
781
  const r = s.postProcess(a, t);
778
782
  e.length = 0, e.push(...r);
779
783
  }
780
784
  extractLocalizedPaths(e, t = "") {
781
- return S(e, this.globalLocaleRoutes, this.filesLocaleRoutes, t);
785
+ return k(e, this.globalLocaleRoutes, this.filesLocaleRoutes, t);
782
786
  }
783
787
  /**
784
788
  * Creates global and per-page translation JSON files for the current resolved locales.
785
789
  */
786
790
  ensureTranslationFilesExist(e, t, s, o) {
787
791
  this.locales.forEach((a) => {
788
- const r = w.join(s, t, `${a.code}.json`);
792
+ const r = A.join(s, t, `${a.code}.json`);
789
793
  this.ensureFileExists(r), o || e.forEach((i) => {
790
- const n = w.join(s, t, "pages", `${i}/${a.code}.json`);
794
+ const n = A.join(s, t, "pages", `${i}/${a.code}.json`);
791
795
  this.ensureFileExists(n);
792
796
  });
793
797
  });
794
798
  }
795
799
  ensureFileExists(e) {
796
800
  try {
797
- const t = w.dirname(e);
798
- E(t) || U(t, { recursive: !0 }), E(e) || B(e, JSON.stringify({}), "utf-8");
801
+ const t = A.dirname(e);
802
+ E(t) || B(t, { recursive: !0 }), E(e) || I(e, JSON.stringify({}), "utf-8");
799
803
  } catch {
800
804
  }
801
805
  }
@@ -805,7 +809,7 @@ class me {
805
809
  * Used by nitro:config and prerender so route rules work with custom paths (e.g. /de/ueber-uns).
806
810
  */
807
811
  resolveLocalizedPath(e, t) {
808
- const s = x(e), o = g(s) || "/";
812
+ const s = N(e), o = y(s) || "/";
809
813
  let a;
810
814
  const r = this.globalLocaleRoutes[o], i = this.globalLocaleRoutes[s];
811
815
  r && typeof r == "object" && !Array.isArray(r) ? a = r[t] : i && typeof i == "object" && !Array.isArray(i) && (a = i[t]);
@@ -813,7 +817,7 @@ class me {
813
817
  let c = !1;
814
818
  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
819
  return R(f) || "/";
816
- const h = g(f);
820
+ const h = y(f);
817
821
  return h ? R(`/${t}/${h}`) : `/${t}`;
818
822
  }
819
823
  /**
@@ -838,18 +842,19 @@ class me {
838
842
  }
839
843
  }
840
844
  export {
841
- me as RouteGenerator,
842
- A as buildFullPath,
843
- Z as buildFullPathNoPrefix,
845
+ Pe as RouteGenerator,
846
+ Z as buildEncodedPathAliases,
847
+ w as buildFullPath,
848
+ ee as buildFullPathNoPrefix,
844
849
  j as buildRouteName,
845
850
  $ as cloneArray,
846
- S as extractLocalizedPaths,
851
+ k as extractLocalizedPaths,
847
852
  D as isInternalPath,
848
- de as isLocaleAllowedForUnlocalizedRoute,
849
- J as isLocaleDefault,
850
- q as isPageRedirectOnly,
853
+ me as isLocaleAllowedForUnlocalizedRoute,
854
+ H as isLocaleDefault,
855
+ U as isPageRedirectOnly,
851
856
  R as normalizePath,
852
- x as normalizeRouteKey,
853
- g as removeLeadingSlash,
854
- H as shouldAddLocalePrefix
857
+ N as normalizeRouteKey,
858
+ y as removeLeadingSlash,
859
+ q as shouldAddLocalePrefix
855
860
  };
@@ -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.8",
3
+ "version": "1.1.11",
4
4
  "description": "Locale-aware route generator for Nuxt i18n micro",
5
5
  "keywords": [
6
6
  "i18n",
@@ -43,6 +43,10 @@
43
43
  },
44
44
  "exports": {
45
45
  ".": {
46
+ "production": {
47
+ "types": "./dist/index.d.ts",
48
+ "default": "./dist/index.mjs"
49
+ },
46
50
  "import": {
47
51
  "types": "./dist/index.d.ts",
48
52
  "default": "./dist/index.mjs"
@@ -59,8 +63,8 @@
59
63
  },
60
64
  "dependencies": {
61
65
  "@nuxt/schema": "^3.18.1 || ^4.0.0",
62
- "@i18n-micro/core": "1.3.2",
63
- "@i18n-micro/types": "1.2.4"
66
+ "@i18n-micro/core": "1.3.4",
67
+ "@i18n-micro/types": "1.2.6"
64
68
  },
65
69
  "devDependencies": {
66
70
  "@types/jest": "^29.5.14",