@i18n-micro/route-strategy 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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");function $(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 O(...l){return w.posix.join(...l)}function H(l){if(!(typeof l>"u"))return l.startsWith("/")&&l.endsWith("/")?l?.slice(1,-1):l}function K(l){return!l||!/[\u0080-\uFFFF]/.test(l)?l:l.split("/").map(e=>!e||e.startsWith(":")||!/[\u0080-\uFFFF]/.test(e)?e:encodeURI(e)).join("/")}function N(l,e,t){const a=H(t?.toString()),o=a||(Array.isArray(l)?l.join("|"):l),s=K(e);return R(w.posix.join("/",`:locale(${o})`,s))}function M(l){const e=K(l);return R(e)}const b=l=>l.map(e=>({...e})),T=l=>!!(l.redirect&&!l.file),F=(l,e,t,a="localized-")=>t?`${a}${l}-${e}`:`${a}${l}`,C=(l,e)=>l??(e??"").replace(/[^a-z0-9]/gi,"-").replace(/^-+|-+$/g,""),V=(l,e,t,a)=>t&&!(l===e.code&&!a),I=(l,e,t)=>(typeof l=="string"?l:l.code)===e.code&&!t,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 E(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 i=o.find(r=>r.code===s.code);return i?Object.assign(i,s):o.push(s),o},[]).filter(o=>!o.disabled),a=t.find(o=>o.code===e)??{code:e};return{locales:t,defaultLocale:a}}const X=(l,e)=>l??(e??"").replace(/[^a-z0-9]/gi,"-").replace(/^-+|-+$/g,"");function j(l){return g(l)||"/"}function _(l,e,t,a=""){const o={};return l.forEach(s=>{const i=X(s.name,s.path),r=R(O(a,s.path??"")),n=j(r),d=$(r),c=e[n]||e[d]||e[i];if(c)typeof c=="object"&&(o[n]=c);else{const h=t[i];h&&typeof h=="object"&&!Array.isArray(h)&&(o[n]=h)}if(s.children?.length){const h=R(O(a,s.path??""));Object.assign(o,_(s.children,e,t,h))}}),o}function Y(l){const e={};if(!l)return e;for(const t in l){const a=$(t),o=l[t];if(typeof o=="object"){const s={};for(const i in o){const r=o[i];r&&(s[i]=$(r))}e[a]=s}else e[a]=o}return e}class Z{constructor(e){this.locales=e.locales,this.defaultLocale=this.findLocaleByCode(e.locales,e.defaultLocaleCode)??{code:e.defaultLocaleCode},this.strategy=e.strategy,this.globalLocaleRoutes=Y(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(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=j(e);return this.localizedPaths[a]?.[t]}getCustomPathsForPage(e,t){const a=j(e);return this.localizedPaths[a]??this.localizedPaths[t]}hasLocaleRestrictions(e,t){return!!(this.routeLocales[e]??this.routeLocales[t])}filterLocaleCodesWithoutCustomPaths(e){const t=j(e);return this.activeLocaleCodes.filter(a=>!this.localizedPaths[t]?.[a])}}function z(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:a,children:o,meta:s,alias:i}=e,r={...l,path:t};return a!==void 0&&(r.name=a),o!==void 0&&(r.children=o),s!==void 0&&(r.meta={...l.meta,...s}),i!==void 0?(r.alias=i,r.meta={...r.meta,alias:i}):"alias"in e&&(r.alias=void 0,r.meta={...r.meta,alias:void 0}),r}function ee(l){const e=l.alias,t=l.meta?.alias,a=e??t;return Array.isArray(a)?a:[]}function D(l,e,t,a="localized-"){const o=ee(l);if(!o.length)return[];const s=[];for(const i of o){const r=N(e,i,t);s.push(p(l,{path:r,name:`${a}${l.name??""}`,alias:void 0,meta:{alias:void 0},children:l.children}))}return s}class W{processPage(e,t){if(e.path===void 0)throw new Error("page.path is required");if(T(e))return[e];if(e.path&&E(e.path,t.excludePatterns))return[e];const a=e.path??"",o=C(e.name,e.path),s=$(a);return t.globalLocaleRoutes[o]===!1||t.globalLocaleRoutes[s]===!1?[e]:this.generateVariants(e,t)}postProcess(e,t){return e}localizeChildren(e,t,a,o,s,i){return e.flatMap(r=>this.localizeChild(r,t,a,o,s,i))}localizeChildrenAllLocales(e,t,a,o,s){return e.flatMap(i=>this.localizeChildAllLocales(i,t,a,o,s))}localizeChildAllLocales(e,t,a,o,s){const i=z(a,e.path??""),r=z(t,e.path??""),n=j(r),d=s.localizedPaths[n];if(d)return o.flatMap(f=>{const P=d[f]??z(t,e.path??"");return this.localizeChild(e,P,a,f,s,!0)});const c=R(e.path??""),h=g(c),u=this.localizeChildrenAllLocales(b(e.children??[]),r,i,o,s),m=`${s.localizedRouteNamePrefix}${e.name??""}`;return[p(e,{path:h,name:m,children:u})]}localizeChild(e,t,a,o,s,i){const r=z(a,e.path??""),n=s.getCustomPath(r,o),d=g(R(n||(e.path??""))),c=n??z(t,e.path??""),h=this.localizeChildren(b(e.children??[]),c,r,o,s,i),u=C(e.name,e.path),m=`${s.localizedRouteNamePrefix}${u}-${o}`;return[p(e,{path:d,name:m,children:h})]}buildRoutePathForLocales(e,t,a,o,s,i,r){if(o){const n=e.includes(r);return i||!n?N(e,a,s):R(a)}return N(e,t,s)}}class te extends W{generateVariants(e,t){const a=e.path??"",o=C(e.name,e.path),s=t.getAllowedLocales(a,o),i=t.getCustomPathsForPage(a,o),r=b(e.children??[]),n=[];if(n.push(e),i)for(const d of s){const c=i[d];if(!c)continue;const h=R(c),u=R(a);if(h===u)continue;const m=M(c),f=F(o,d,!0),P=this.localizeChildrenForNoPrefix(r,h,a,a,d,t,1);n.push(p(e,{path:m,name:f,children:P,alias:[],meta:{alias:[]}})),t.noPrefixRedirect&&d===t.defaultLocale.code&&h!==u&&(e.redirect=h)}return n.push(...D(e,s,t.customRegex,t.localizedRouteNamePrefix)),n}localizeChildrenForNoPrefix(e,t,a,o,s,i,r){return e.map(n=>{const d=z(a,n.path??"");let c,h;if(r===1){const P=i.getCustomPath(d,s);if(P){const L=R(P);c=g(L),h=L}else{const L=R(n.path??"");c=g(L),h=z(t,n.path??"")}}else{const P=R(n.path??"");c=g(P),h=z(t,n.path??"")}const u=this.localizeChildrenForNoPrefix(b(n.children??[]),h,d,o,s,i,r+1),m=C(n.name,n.path),f=F(m,s,!0);return p(n,{path:c,name:f,children:u})})}}function ae(l){const e=l.alias??l.meta?.alias;return Array.isArray(e)?e:[]}class se extends W{generateVariants(e,t){const a=e.path??"",o=C(e.name,e.path),s=t.getAllowedLocales(a,o),i=t.getCustomPathsForPage(a,o),r=b(e.children??[]),n=[];if(i)for(const c of s){const h=i[c],u=h?R(h):a,m=N(c,u,t.customRegex),f=F(o,c,!!h,t.localizedRouteNamePrefix),P=h??a,L=this.localizeChildren(r,P,a,c,t,!0);n.push(p(e,{path:m,name:f,children:L,alias:[],meta:{alias:[]}}))}else{const c=N(s,a,t.customRegex),h=F(o,s[0],!1,t.localizedRouteNamePrefix),u=this.localizeChildrenAllLocales(r,a,a,s,t);n.push(p(e,{path:c,name:h,children:u,alias:[],meta:{alias:[]}}))}const d=ae(e);if(d.length)for(const c of d){const h=N(s,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 a=e.filter(o=>{if(o.name==="index"&&o.path==="/")return!1;const s=o.path??"";return!!(s&&E(s,t.excludePatterns)||t.globalLocaleRoutes[o.name??""]===!1||/^\/:locale/.test(s)||s==="/")});return t.fallbackRedirectComponentPath&&a.push({path:"/:pathMatch(.*)*",name:"custom-fallback-route",file:t.fallbackRedirectComponentPath,meta:{globalLocaleRoutes:t.rawGlobalLocaleRoutes??t.globalLocaleRoutes}}),a}}class oe extends W{generateVariants(e,t){const a=e.path??"",o=C(e.name,e.path),s=t.getAllowedLocales(a,o),i=t.getCustomPathsForPage(a,o),r=b(e.children??[]),n=[],d=t.defaultLocale.code;n.push(e);const c=t.locales.filter(u=>s.includes(u.code));if(c.length>0)if(i)for(const u of c){const m=i[u.code];if(m)if(u.code===d){const f=this.createLocalizedRoute(e,[u.code],r,!0,m,t.customRegex,!1,u.code,a,t);f&&n.push(f);const P=this.createLocalizedRoute(e,[u.code],r,!0,m,t.customRegex,!0,u.code,a,t);P&&n.push(P)}else{const f=this.createLocalizedRoute(e,[u.code],r,!0,m,t.customRegex,!1,u.code,a,t);f&&n.push(f)}else{const f=this.createLocalizedRoute(e,[u.code],r,!1,"",t.customRegex,!1,u.code,a,t);f&&n.push(f)}}else{const u=c.map(f=>f.code),m=this.createLocalizedRoute(e,u,r,!1,"",t.customRegex,!1,!0,a,t);m&&n.push(m)}const h=D(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 i=s.name??"";typeof i=="string"&&i.startsWith(t.localizedRouteNamePrefix)?o.push(s):a.push(s)}return[...a,...o]}createLocalizedRoute(e,t,a,o,s="",i,r=!1,n=!1,d,c){const h=this.buildRoutePathForLocales(t,e.path??"",encodeURI(s),o,i,r,c.defaultLocale.code);if(!h||!(o&&s)&&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=r||m!==c.defaultLocale.code,y=t.length===1?this.localizeChildren(a,h,f,m,c,L):this.localizeChildrenAllLocales(a,h,f,t,c);return p(e,{path:h,name:P,children:y,alias:[],meta:{alias:[]}})}}class le extends W{generateVariants(e,t){const a=e.path??"",o=C(e.name,e.path),s=t.getAllowedLocales(a,o),i=t.getCustomPathsForPage(a,o),r=b(e.children??[]),n=[],d=t.defaultLocale.code;if(s.includes(d)){const u=i?.[d],m=u?R(u):a,f=u?{[d]:u}:{},P=this.createLocalizedChildren(r,a,[d],!1,!1,!1,f,t);n.push(p(e,{path:m,name:e.name,children:P}))}const c=t.locales.filter(u=>s.includes(u.code)&&u.code!==d);if(c.length)if(i)for(const u of c){const m=i[u.code];if(m){const f=this.createLocalizedRoute(e,[u.code],r,!0,m,t.customRegex,!1,u.code,a,t);f&&n.push(f)}else{const f=this.createLocalizedRoute(e,[u.code],r,!1,"",t.customRegex,!1,u.code,a,t);f&&n.push(f)}}else{const u=c.map(f=>f.code),m=this.createLocalizedRoute(e,u,r,!1,"",t.customRegex,!1,!0,a,t);m&&n.push(m)}const h=D(e,s,t.customRegex,t.localizedRouteNamePrefix);return h.length&&n.push(...h),n}postProcess(e,t){const a=[],o=[];for(const i of e){const r=i.name??"";typeof r=="string"&&r.startsWith(t.localizedRouteNamePrefix)?o.push(i):a.push(i)}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,i=!1,r={},n){return e.flatMap(d=>this.createLocalizedVariants(d,t,a,o,s,i,r,n))}createLocalizedVariants(e,t,a,o,s,i=!1,r,n){const d=R(e.path??""),c=z(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??[]),z(t,e.path??""),a,o,s,i,r,n),y=this.buildChildRouteName(e.name,i,n);return f.push(p(e,{path:P,name:y,children:L})),f}for(const P of a){const L=r?.[P],y=!!L,x=u?.[P];let A=R(x||(e.path??""));y&&L&&(x?A=R(x):A=z(L,e.path??""));const v=V(P,n.defaultLocale,s,!1)?N(P,A,n.customRegex):A,q=g(v),G=x?R(x):y?L:z(t,e.path??""),B=this.createLocalizedChildren(b(e.children??[]),G,[P],o,s,P,{...r,[P]:G},n),U=this.buildLocalizedRouteName(C(e.name,e.path),P,o,!!u,n);f.push(p(e,{path:q,name:U,children:B}))}return f}buildChildRouteName(e,t,a){return t===!0?`${a.localizedRouteNamePrefix}${e}`:typeof t=="string"?`${a.localizedRouteNamePrefix}${e}-${t}`:e}createLocalizedRoute(e,t,a,o,s="",i,r=!1,n=!1,d,c){const h=this.buildRoutePathForLocales(t,e.path??"",encodeURI(s),o,i,r,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 p(e,{path:h,name:f,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&&!I(t,s.defaultLocale,!1)?`${s.localizedRouteNamePrefix}${e}-${t}`:`${s.localizedRouteNamePrefix}${e}`:e}}function ie(l){switch(l){case"no_prefix":return new te;case"prefix":return new se;case"prefix_and_default":return new oe;case"prefix_except_default":return new le;default:throw new Error(`Unknown route strategy: ${l}`)}}class re{constructor(e){this.localizedPaths={};const{locales:t,defaultLocaleCode:a,strategy:o,globalLocaleRoutes:s,filesLocaleRoutes:i={},routeLocales:r={},noPrefixRedirect:n,excludePatterns:d,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=d,this.localizedRouteNamePrefix=c,this.customRegex=h,this.fallbackRedirectComponentPath=u,this.activeLocaleCodes=this.computeActiveLocaleCodes();const f={};for(const P in s){const L=$(P),y=s[P];if(typeof y=="object"){const x={};for(const A in y){const v=y[A];v&&(x[A]=$(v))}f[L]=x}else f[L]=y}this.globalLocaleRoutes=f,this.rawGlobalLocaleRoutes=s??{},this.filesLocaleRoutes=i??{},this.routeLocales=r??{}}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 Z({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=ie(this.strategy),o=[...e],s=[];for(const r of o)s.push(...a.processPage(r,t));const i=a.postProcess(s,t);e.length=0,e.push(...i)}extractLocalizedPaths(e,t=""){return _(e,this.globalLocaleRoutes,this.filesLocaleRoutes,t)}ensureTranslationFilesExist(e,t,a,o){this.locales.forEach(s=>{const i=w.join(a,t,`${s.code}.json`);this.ensureFileExists(i),o||e.forEach(r=>{const n=w.join(a,t,"pages",`${r}/${s.code}.json`);this.ensureFileExists(n)})})}ensureFileExists(e){const t=w.dirname(e);S.existsSync(t)||S.mkdirSync(t,{recursive:!0}),S.existsSync(e)||S.writeFileSync(e,JSON.stringify({}),"utf-8")}resolveLocalizedPath(e,t){const a=$(e),o=g(a)||"/";let s;const i=this.globalLocaleRoutes[o],r=this.globalLocaleRoutes[a];i&&typeof i=="object"&&!Array.isArray(i)?s=i[t]:r&&typeof r=="object"&&!Array.isArray(r)&&(s=r[t]);const n=!!s,d=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(d)||"/";const h=g(d);return h?R(`/${t}/${h}`):`/${t}`}generateDataRoutes(e,t,a){const o=[],s=e.map(i=>i.name).filter(i=>typeof i=="string"&&i.length>0);for(const i of this.locales)if(o.push(`/${t}/general/${i.code}/data.json`),!a)for(const r of s)o.push(`/${t}/${r}/${i.code}/data.json`);return o}}exports.RouteGenerator=re;exports.buildFullPath=N;exports.buildFullPathNoPrefix=M;exports.buildRouteName=F;exports.cloneArray=b;exports.extractLocalizedPaths=_;exports.isInternalPath=E;exports.isLocaleDefault=I;exports.isPageRedirectOnly=T;exports.normalizePath=R;exports.normalizeRouteKey=$;exports.removeLeadingSlash=g;exports.shouldAddLocalePrefix=V;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const w=require("node:path"),S=require("node:fs"),k=require("@i18n-micro/core");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 O(...l){return w.posix.join(...l)}function H(l){if(!(typeof l>"u"))return l.startsWith("/")&&l.endsWith("/")?l?.slice(1,-1):l}function K(l){return!l||!/[\u0080-\uFFFF]/.test(l)?l:l.split("/").map(e=>!e||e.startsWith(":")||!/[\u0080-\uFFFF]/.test(e)?e:encodeURI(e)).join("/")}function N(l,e,t){const a=H(t?.toString()),o=a||(Array.isArray(l)?l.join("|"):l),s=K(e);return R(w.posix.join("/",`:locale(${o})`,s))}function M(l){const e=K(l);return R(e)}const b=l=>l.map(e=>({...e})),T=l=>!!(l.redirect&&!l.file),F=(l,e,t,a="localized-")=>t?`${a}${l}-${e}`:`${a}${l}`,C=(l,e)=>l??(e??"").replace(/[^a-z0-9]/gi,"-").replace(/^-+|-+$/g,""),V=(l,e,t,a)=>t&&!(l===e.code&&!a),I=(l,e,t)=>(typeof l=="string"?l:l.code)===e.code&&!t,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 E(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 i=o.find(r=>r.code===s.code);return i?Object.assign(i,s):o.push(s),o},[]).filter(o=>!o.disabled),a=t.find(o=>o.code===e)??{code:e};return{locales:t,defaultLocale:a}}const X=(l,e)=>l??(e??"").replace(/[^a-z0-9]/gi,"-").replace(/^-+|-+$/g,"");function j(l){return g(l)||"/"}function _(l,e,t,a=""){const o={};return l.forEach(s=>{const i=X(s.name,s.path),r=R(O(a,s.path??"")),c=j(r),d=x(r),n=e[c]||e[d]||e[i];if(n)typeof n=="object"&&(o[c]=n);else{const h=t[i];h&&typeof h=="object"&&!Array.isArray(h)&&(o[c]=h)}if(s.children?.length){const h=R(O(a,s.path??""));Object.assign(o,_(s.children,e,t,h))}}),o}function Y(l){const e={};if(!l)return e;for(const t in l){const a=x(t),o=l[t];if(typeof o=="object"){const s={};for(const i in o){const r=o[i];r&&(s[i]=x(r))}e[a]=s}else e[a]=o}return e}class Z{constructor(e){this.locales=e.locales,this.defaultLocale=this.findLocaleByCode(e.locales,e.defaultLocaleCode)??{code:e.defaultLocaleCode},this.strategy=e.strategy,this.globalLocaleRoutes=Y(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(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=j(e);return this.localizedPaths[a]?.[t]}getCustomPathsForPage(e,t){const a=j(e);return this.localizedPaths[a]??this.localizedPaths[t]}hasLocaleRestrictions(e,t){return!!(this.routeLocales[e]??this.routeLocales[t])}filterLocaleCodesWithoutCustomPaths(e){const t=j(e);return this.activeLocaleCodes.filter(a=>!this.localizedPaths[t]?.[a])}}function z(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:a,children:o,meta:s,alias:i}=e,r={...l,path:t};return a!==void 0&&(r.name=a),o!==void 0&&(r.children=o),s!==void 0&&(r.meta={...l.meta,...s}),i!==void 0?(r.alias=i,r.meta={...r.meta,alias:i}):"alias"in e&&(r.alias=void 0,r.meta={...r.meta,alias:void 0}),r}function ee(l){const e=l.alias,t=l.meta?.alias,a=e??t;return Array.isArray(a)?a:[]}function D(l,e,t,a="localized-"){const o=ee(l);if(!o.length)return[];const s=[];for(const i of o){const r=N(e,i,t);s.push(p(l,{path:r,name:`${a}${l.name??""}`,alias:void 0,meta:{alias:void 0},children:l.children}))}return s}class W{processPage(e,t){if(e.path===void 0)throw new Error("page.path is required");if(T(e))return[e];if(e.path&&E(e.path,t.excludePatterns))return[e];const a=e.path??"",o=C(e.name,e.path),s=x(a);return t.globalLocaleRoutes[o]===!1||t.globalLocaleRoutes[s]===!1?[e]:this.generateVariants(e,t)}postProcess(e,t){return e}localizeChildren(e,t,a,o,s,i){return e.flatMap(r=>this.localizeChild(r,t,a,o,s,i))}localizeChildrenAllLocales(e,t,a,o,s){return e.flatMap(i=>this.localizeChildAllLocales(i,t,a,o,s))}localizeChildAllLocales(e,t,a,o,s){const i=z(a,e.path??""),r=z(t,e.path??""),c=j(r),d=s.localizedPaths[c];if(d)return o.flatMap(f=>{const P=d[f]??z(t,e.path??"");return this.localizeChild(e,P,a,f,s,!0)});const n=R(e.path??""),h=g(n),u=this.localizeChildrenAllLocales(b(e.children??[]),r,i,o,s),m=`${s.localizedRouteNamePrefix}${e.name??""}`;return[p(e,{path:h,name:m,children:u})]}localizeChild(e,t,a,o,s,i){const r=z(a,e.path??""),c=s.getCustomPath(r,o),d=g(R(c||(e.path??""))),n=c??z(t,e.path??""),h=this.localizeChildren(b(e.children??[]),n,r,o,s,i),u=C(e.name,e.path),m=`${s.localizedRouteNamePrefix}${u}-${o}`;return[p(e,{path:d,name:m,children:h})]}buildRoutePathForLocales(e,t,a,o,s,i,r){if(o){const c=e.includes(r);return i||!c?N(e,a,s):R(a)}return N(e,t,s)}}class te extends W{generateVariants(e,t){const a=e.path??"",o=C(e.name,e.path),s=t.getAllowedLocales(a,o),i=t.getCustomPathsForPage(a,o),r=b(e.children??[]),c=[];if(c.push(e),i)for(const d of s){const n=i[d];if(!n)continue;const h=R(n),u=R(a);if(h===u)continue;const m=M(n),f=F(o,d,!0),P=this.localizeChildrenForNoPrefix(r,h,a,a,d,t,1);c.push(p(e,{path:m,name:f,children:P,alias:[],meta:{alias:[]}})),t.noPrefixRedirect&&d===t.defaultLocale.code&&h!==u&&(e.redirect=h)}return c.push(...D(e,s,t.customRegex,t.localizedRouteNamePrefix)),c}localizeChildrenForNoPrefix(e,t,a,o,s,i,r){return e.map(c=>{const d=z(a,c.path??"");let n,h;if(r===1){const P=i.getCustomPath(d,s);if(P){const L=R(P);n=g(L),h=L}else{const L=R(c.path??"");n=g(L),h=z(t,c.path??"")}}else{const P=R(c.path??"");n=g(P),h=z(t,c.path??"")}const u=this.localizeChildrenForNoPrefix(b(c.children??[]),h,d,o,s,i,r+1),m=C(c.name,c.path),f=F(m,s,!0);return p(c,{path:n,name:f,children:u})})}}function ae(l){const e=l.alias??l.meta?.alias;return Array.isArray(e)?e:[]}class se extends W{generateVariants(e,t){const a=e.path??"",o=C(e.name,e.path),s=t.getAllowedLocales(a,o),i=t.getCustomPathsForPage(a,o),r=b(e.children??[]),c=[];if(i)for(const n of s){const h=i[n],u=h?R(h):a,m=N(n,u,t.customRegex),f=F(o,n,!!h,t.localizedRouteNamePrefix),P=h??a,L=this.localizeChildren(r,P,a,n,t,!0);c.push(p(e,{path:m,name:f,children:L,alias:[],meta:{alias:[]}}))}else{const n=N(s,a,t.customRegex),h=F(o,s[0],!1,t.localizedRouteNamePrefix),u=this.localizeChildrenAllLocales(r,a,a,s,t);c.push(p(e,{path:n,name:h,children:u,alias:[],meta:{alias:[]}}))}const d=ae(e);if(d.length)for(const n of d){const h=N(s,n,t.customRegex);c.push(p(e,{path:h,name:`${t.localizedRouteNamePrefix}${e.name??""}`,alias:void 0,meta:{alias:void 0}}))}return c}postProcess(e,t){const a=e.filter(s=>{if(s.name==="index"&&s.path==="/")return!1;const i=s.path??"";return!!(i&&E(i,t.excludePatterns)||t.globalLocaleRoutes[s.name??""]===!1||/^\/:locale/.test(i)||i==="/")}),o=t.defaultLocale.code;for(const[s,i]of Object.entries(t.globalLocaleRoutes)){if(i===!1||typeof i!="object")continue;const r=i[o];if(!r)continue;const c=s.startsWith("/")?s:`/${s}`,d=`/${o}${r.startsWith("/")?r:`/${r}`}`;c!==d&&a.push({path:c,name:`redirect-${s.replace(/\//g,"-")}`,redirect:d})}return t.fallbackRedirectComponentPath&&a.push({path:"/:pathMatch(.*)*",name:"custom-fallback-route",file:t.fallbackRedirectComponentPath,meta:{globalLocaleRoutes:t.rawGlobalLocaleRoutes??t.globalLocaleRoutes}}),a}}class oe extends W{generateVariants(e,t){const a=e.path??"",o=C(e.name,e.path),s=t.getAllowedLocales(a,o),i=t.getCustomPathsForPage(a,o),r=b(e.children??[]),c=[],d=t.defaultLocale.code;c.push(e);const n=t.locales.filter(u=>s.includes(u.code));if(n.length>0)if(i)for(const u of n){const m=i[u.code];if(m)if(u.code===d){const f=this.createLocalizedRoute(e,[u.code],r,!0,m,t.customRegex,!1,u.code,a,t);f&&c.push(f);const P=this.createLocalizedRoute(e,[u.code],r,!0,m,t.customRegex,!0,u.code,a,t);P&&c.push(P)}else{const f=this.createLocalizedRoute(e,[u.code],r,!0,m,t.customRegex,!1,u.code,a,t);f&&c.push(f)}else{const f=this.createLocalizedRoute(e,[u.code],r,!1,"",t.customRegex,!1,u.code,a,t);f&&c.push(f)}}else{const u=n.map(f=>f.code),m=this.createLocalizedRoute(e,u,r,!1,"",t.customRegex,!1,!0,a,t);m&&c.push(m)}const h=D(e,s,t.customRegex,t.localizedRouteNamePrefix);return h.length&&c.push(...h),c}postProcess(e,t){const a=[],o=[];for(const s of e){const i=s.name??"";typeof i=="string"&&i.startsWith(t.localizedRouteNamePrefix)?o.push(s):a.push(s)}return[...a,...o]}createLocalizedRoute(e,t,a,o,s="",i,r=!1,c=!1,d,n){const h=this.buildRoutePathForLocales(t,e.path??"",encodeURI(s),o,i,r,n.defaultLocale.code);if(!h||!(o&&s)&&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,n.localizedRouteNamePrefix),L=r||m!==n.defaultLocale.code,y=t.length===1?this.localizeChildren(a,h,f,m,n,L):this.localizeChildrenAllLocales(a,h,f,t,n);return p(e,{path:h,name:P,children:y,alias:[],meta:{alias:[]}})}}class le extends W{generateVariants(e,t){const a=e.path??"",o=C(e.name,e.path),s=t.getAllowedLocales(a,o),i=t.getCustomPathsForPage(a,o),r=b(e.children??[]),c=[],d=t.defaultLocale.code;if(s.includes(d)){const u=i?.[d],m=u?R(u):a,f=u?{[d]:u}:{},P=this.createLocalizedChildren(r,a,[d],!1,!1,!1,f,t);c.push(p(e,{path:m,name:e.name,children:P}))}const n=t.locales.filter(u=>s.includes(u.code)&&u.code!==d);if(n.length)if(i)for(const u of n){const m=i[u.code];if(m){const f=this.createLocalizedRoute(e,[u.code],r,!0,m,t.customRegex,!1,u.code,a,t);f&&c.push(f)}else{const f=this.createLocalizedRoute(e,[u.code],r,!1,"",t.customRegex,!1,u.code,a,t);f&&c.push(f)}}else{const u=n.map(f=>f.code),m=this.createLocalizedRoute(e,u,r,!1,"",t.customRegex,!1,!0,a,t);m&&c.push(m)}const h=D(e,s,t.customRegex,t.localizedRouteNamePrefix);return h.length&&c.push(...h),c}postProcess(e,t){const a=[],o=[];for(const i of e){const r=i.name??"";typeof r=="string"&&r.startsWith(t.localizedRouteNamePrefix)?o.push(i):a.push(i)}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,i=!1,r={},c){return e.flatMap(d=>this.createLocalizedVariants(d,t,a,o,s,i,r,c))}createLocalizedVariants(e,t,a,o,s,i=!1,r,c){const d=R(e.path??""),n=z(t,e.path??""),h=j(n),u=c.localizedPaths[h],m=!!u,f=[];if(!m){const P=g(d),L=this.createLocalizedChildren(b(e.children??[]),z(t,e.path??""),a,o,s,i,r,c),y=this.buildChildRouteName(e.name,i,c);return f.push(p(e,{path:P,name:y,children:L})),f}for(const P of a){const L=r?.[P],y=!!L,$=u?.[P];let A=R($||(e.path??""));y&&L&&($?A=R($):A=z(L,e.path??""));const v=V(P,c.defaultLocale,s,!1)?N(P,A,c.customRegex):A,q=g(v),G=$?R($):y?L:z(t,e.path??""),B=this.createLocalizedChildren(b(e.children??[]),G,[P],o,s,P,{...r,[P]:G},c),U=this.buildLocalizedRouteName(C(e.name,e.path),P,o,!!u,c);f.push(p(e,{path:q,name:U,children:B}))}return f}buildChildRouteName(e,t,a){return t===!0?`${a.localizedRouteNamePrefix}${e}`:typeof t=="string"?`${a.localizedRouteNamePrefix}${e}-${t}`:e}createLocalizedRoute(e,t,a,o,s="",i,r=!1,c=!1,d,n){const h=this.buildRoutePathForLocales(t,e.path??"",encodeURI(s),o,i,r,n.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,n.localizedRouteNamePrefix);return p(e,{path:h,name:f,children:this.createLocalizedChildren(a,m,t,!0,!1,c,{[u]:s},n),alias:[],meta:{alias:[]}})}buildLocalizedRouteName(e,t,a,o=!1,s){return a?o?`${s.localizedRouteNamePrefix}${e}-${t}`:t&&!I(t,s.defaultLocale,!1)?`${s.localizedRouteNamePrefix}${e}-${t}`:`${s.localizedRouteNamePrefix}${e}`:e}}function ie(l){switch(l){case"no_prefix":return new te;case"prefix":return new se;case"prefix_and_default":return new oe;case"prefix_except_default":return new le;default:throw new Error(`Unknown route strategy: ${l}`)}}class re{constructor(e){this.localizedPaths={};const{locales:t,defaultLocaleCode:a,strategy:o,globalLocaleRoutes:s,filesLocaleRoutes:i={},routeLocales:r={},noPrefixRedirect:c,excludePatterns:d,localizedRouteNamePrefix:n="localized-",customRegexMatcher:h,fallbackRedirectComponentPath:u}=e,m=Q(t,a);this.locales=m.locales,this.defaultLocale=m.defaultLocale,this.strategy=o,this.noPrefixRedirect=c,this.excludePatterns=d,this.localizedRouteNamePrefix=n,this.customRegex=h,this.fallbackRedirectComponentPath=u,this.activeLocaleCodes=this.computeActiveLocaleCodes();const f={};for(const P in s){const L=x(P),y=s[P];if(typeof y=="object"){const $={};for(const A in y){const v=y[A];v&&($[A]=x(v))}f[L]=$}else f[L]=y}this.globalLocaleRoutes=f,this.rawGlobalLocaleRoutes=s??{},this.filesLocaleRoutes=i??{},this.routeLocales=r??{}}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 Z({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=ie(this.strategy),o=[...e],s=[];for(const r of o)s.push(...a.processPage(r,t));const i=a.postProcess(s,t);e.length=0,e.push(...i)}extractLocalizedPaths(e,t=""){return _(e,this.globalLocaleRoutes,this.filesLocaleRoutes,t)}ensureTranslationFilesExist(e,t,a,o){this.locales.forEach(s=>{const i=w.join(a,t,`${s.code}.json`);this.ensureFileExists(i),o||e.forEach(r=>{const c=w.join(a,t,"pages",`${r}/${s.code}.json`);this.ensureFileExists(c)})})}ensureFileExists(e){const t=w.dirname(e);S.existsSync(t)||S.mkdirSync(t,{recursive:!0}),S.existsSync(e)||S.writeFileSync(e,JSON.stringify({}),"utf-8")}resolveLocalizedPath(e,t){const a=x(e),o=g(a)||"/";let s;const i=this.globalLocaleRoutes[o],r=this.globalLocaleRoutes[a];i&&typeof i=="object"&&!Array.isArray(i)?s=i[t]:r&&typeof r=="object"&&!Array.isArray(r)&&(s=r[t]);const c=!!s,d=s?R(s):R(a)||"";let n=!1;if(this.strategy==="no_prefix"?n=!1:this.strategy==="prefix"||this.strategy==="prefix_and_default"?n=!0:this.strategy==="prefix_except_default"&&(n=t!==this.defaultLocale.code),t===this.defaultLocale.code&&!c&&(this.strategy==="prefix_except_default"||this.strategy==="no_prefix")&&(n=!1),!n)return R(d)||"/";const h=g(d);return h?R(`/${t}/${h}`):`/${t}`}generateDataRoutes(e,t,a){const o=[],s=e.map(i=>i.name).filter(i=>typeof i=="string"&&i.length>0);for(const i of this.locales)if(o.push(`/${t}/general/${i.code}/data.json`),!a)for(const r of s)o.push(`/${t}/${r}/${i.code}/data.json`);return o}}exports.RouteGenerator=re;exports.buildFullPath=N;exports.buildFullPathNoPrefix=M;exports.buildRouteName=F;exports.cloneArray=b;exports.extractLocalizedPaths=_;exports.isInternalPath=E;exports.isLocaleDefault=I;exports.isPageRedirectOnly=T;exports.normalizePath=R;exports.normalizeRouteKey=x;exports.removeLeadingSlash=g;exports.shouldAddLocalePrefix=V;
package/dist/index.mjs CHANGED
@@ -71,12 +71,12 @@ function F(l) {
71
71
  function S(l, e, t, a = "") {
72
72
  const o = {};
73
73
  return l.forEach((s) => {
74
- const i = ee(s.name, s.path), r = R(G(a, s.path ?? "")), n = F(r), d = w(r), c = e[n] || e[d] || e[i];
75
- if (c)
76
- typeof c == "object" && (o[n] = c);
74
+ const i = ee(s.name, s.path), r = R(G(a, s.path ?? "")), c = F(r), d = w(r), n = e[c] || e[d] || e[i];
75
+ if (n)
76
+ typeof n == "object" && (o[c] = n);
77
77
  else {
78
78
  const h = t[i];
79
- h && typeof h == "object" && !Array.isArray(h) && (o[n] = h);
79
+ h && typeof h == "object" && !Array.isArray(h) && (o[c] = h);
80
80
  }
81
81
  if (s.children?.length) {
82
82
  const h = R(G(a, s.path ?? ""));
@@ -212,13 +212,13 @@ class k {
212
212
  return e.flatMap((i) => this.localizeChildAllLocales(i, t, a, o, s));
213
213
  }
214
214
  localizeChildAllLocales(e, t, a, o, s) {
215
- const i = z(a, e.path ?? ""), r = z(t, e.path ?? ""), n = F(r), d = s.localizedPaths[n];
215
+ const i = z(a, e.path ?? ""), r = z(t, e.path ?? ""), c = F(r), d = s.localizedPaths[c];
216
216
  if (d)
217
217
  return o.flatMap((f) => {
218
218
  const P = d[f] ?? z(t, e.path ?? "");
219
219
  return this.localizeChild(e, P, a, f, s, !0);
220
220
  });
221
- const c = R(e.path ?? ""), h = y(c), u = this.localizeChildrenAllLocales(
221
+ const n = R(e.path ?? ""), h = y(n), u = this.localizeChildrenAllLocales(
222
222
  $(e.children ?? []),
223
223
  r,
224
224
  i,
@@ -234,9 +234,9 @@ class k {
234
234
  ];
235
235
  }
236
236
  localizeChild(e, t, a, o, s, i) {
237
- const r = z(a, e.path ?? ""), n = s.getCustomPath(r, o), d = y(R(n || (e.path ?? ""))), c = n ?? z(t, e.path ?? ""), h = this.localizeChildren(
237
+ const r = z(a, e.path ?? ""), c = s.getCustomPath(r, o), d = y(R(c || (e.path ?? ""))), n = c ?? z(t, e.path ?? ""), h = this.localizeChildren(
238
238
  $(e.children ?? []),
239
- c,
239
+ n,
240
240
  r,
241
241
  o,
242
242
  s,
@@ -259,23 +259,23 @@ class k {
259
259
  */
260
260
  buildRoutePathForLocales(e, t, a, o, s, i, r) {
261
261
  if (o) {
262
- const n = e.includes(r);
263
- return i || !n ? A(e, a, s) : R(a);
262
+ const c = e.includes(r);
263
+ return i || !c ? A(e, a, s) : R(a);
264
264
  }
265
265
  return A(e, t, s);
266
266
  }
267
267
  }
268
268
  class oe extends k {
269
269
  generateVariants(e, t) {
270
- const a = e.path ?? "", o = b(e.name, e.path), s = t.getAllowedLocales(a, o), i = t.getCustomPathsForPage(a, o), r = $(e.children ?? []), n = [];
271
- if (n.push(e), i)
270
+ const a = e.path ?? "", o = b(e.name, e.path), s = t.getAllowedLocales(a, o), i = t.getCustomPathsForPage(a, o), r = $(e.children ?? []), c = [];
271
+ if (c.push(e), i)
272
272
  for (const d of s) {
273
- const c = i[d];
274
- if (!c) continue;
275
- const h = R(c), u = R(a);
273
+ const n = i[d];
274
+ if (!n) continue;
275
+ const h = R(n), u = R(a);
276
276
  if (h === u)
277
277
  continue;
278
- const m = H(c), f = j(o, d, !0), P = this.localizeChildrenForNoPrefix(
278
+ const m = H(n), f = j(o, d, !0), P = this.localizeChildrenForNoPrefix(
279
279
  r,
280
280
  h,
281
281
  a,
@@ -284,7 +284,7 @@ class oe extends k {
284
284
  t,
285
285
  1
286
286
  );
287
- n.push(
287
+ c.push(
288
288
  p(e, {
289
289
  path: m,
290
290
  name: f,
@@ -294,7 +294,7 @@ class oe extends k {
294
294
  })
295
295
  ), t.noPrefixRedirect && d === t.defaultLocale.code && h !== u && (e.redirect = h);
296
296
  }
297
- return n.push(..._(e, s, t.customRegex, t.localizedRouteNamePrefix)), n;
297
+ return c.push(..._(e, s, t.customRegex, t.localizedRouteNamePrefix)), c;
298
298
  }
299
299
  /**
300
300
  * Localizes the children tree for the no_prefix strategy.
@@ -303,33 +303,33 @@ class oe extends k {
303
303
  * - on deeper levels, path stays as a segment (item, detail, etc.).
304
304
  */
305
305
  localizeChildrenForNoPrefix(e, t, a, o, s, i, r) {
306
- return e.map((n) => {
307
- const d = z(a, n.path ?? "");
308
- let c, h;
306
+ return e.map((c) => {
307
+ const d = z(a, c.path ?? "");
308
+ let n, h;
309
309
  if (r === 1) {
310
310
  const P = i.getCustomPath(d, s);
311
311
  if (P) {
312
312
  const L = R(P);
313
- c = y(L), h = L;
313
+ n = y(L), h = L;
314
314
  } else {
315
- const L = R(n.path ?? "");
316
- c = y(L), h = z(t, n.path ?? "");
315
+ const L = R(c.path ?? "");
316
+ n = y(L), h = z(t, c.path ?? "");
317
317
  }
318
318
  } else {
319
- const P = R(n.path ?? "");
320
- c = y(P), h = z(t, n.path ?? "");
319
+ const P = R(c.path ?? "");
320
+ n = y(P), h = z(t, c.path ?? "");
321
321
  }
322
322
  const u = this.localizeChildrenForNoPrefix(
323
- $(n.children ?? []),
323
+ $(c.children ?? []),
324
324
  h,
325
325
  d,
326
326
  o,
327
327
  s,
328
328
  i,
329
329
  r + 1
330
- ), m = b(n.name, n.path), f = j(m, s, !0);
331
- return p(n, {
332
- path: c,
330
+ ), m = b(c.name, c.path), f = j(m, s, !0);
331
+ return p(c, {
332
+ path: n,
333
333
  name: f,
334
334
  children: u
335
335
  });
@@ -342,18 +342,18 @@ function le(l) {
342
342
  }
343
343
  class ie extends k {
344
344
  generateVariants(e, t) {
345
- const a = e.path ?? "", o = b(e.name, e.path), s = t.getAllowedLocales(a, o), i = t.getCustomPathsForPage(a, o), r = $(e.children ?? []), n = [];
345
+ const a = e.path ?? "", o = b(e.name, e.path), s = t.getAllowedLocales(a, o), i = t.getCustomPathsForPage(a, o), r = $(e.children ?? []), c = [];
346
346
  if (i)
347
- for (const c of s) {
348
- const h = i[c], u = h ? R(h) : a, m = A(c, u, t.customRegex), f = j(o, c, !!h, t.localizedRouteNamePrefix), P = h ?? a, L = this.localizeChildren(
347
+ for (const n of s) {
348
+ const h = i[n], u = h ? R(h) : a, m = A(n, u, t.customRegex), f = j(o, n, !!h, t.localizedRouteNamePrefix), P = h ?? a, L = this.localizeChildren(
349
349
  r,
350
350
  P,
351
351
  a,
352
- c,
352
+ n,
353
353
  t,
354
354
  !0
355
355
  );
356
- n.push(
356
+ c.push(
357
357
  p(e, {
358
358
  path: m,
359
359
  name: f,
@@ -364,16 +364,16 @@ class ie extends k {
364
364
  );
365
365
  }
366
366
  else {
367
- const c = A(s, a, t.customRegex), h = j(o, s[0], !1, t.localizedRouteNamePrefix), u = this.localizeChildrenAllLocales(
367
+ const n = A(s, a, t.customRegex), h = j(o, s[0], !1, t.localizedRouteNamePrefix), u = this.localizeChildrenAllLocales(
368
368
  r,
369
369
  a,
370
370
  a,
371
371
  s,
372
372
  t
373
373
  );
374
- n.push(
374
+ c.push(
375
375
  p(e, {
376
- path: c,
376
+ path: n,
377
377
  name: h,
378
378
  children: u,
379
379
  alias: [],
@@ -383,9 +383,9 @@ class ie extends k {
383
383
  }
384
384
  const d = le(e);
385
385
  if (d.length)
386
- for (const c of d) {
387
- const h = A(s, c, t.customRegex);
388
- n.push(
386
+ for (const n of d) {
387
+ const h = A(s, n, t.customRegex);
388
+ c.push(
389
389
  p(e, {
390
390
  path: h,
391
391
  name: `${t.localizedRouteNamePrefix}${e.name ?? ""}`,
@@ -394,14 +394,25 @@ class ie extends k {
394
394
  })
395
395
  );
396
396
  }
397
- return n;
397
+ return c;
398
398
  }
399
399
  postProcess(e, t) {
400
- const a = e.filter((o) => {
401
- if (o.name === "index" && o.path === "/") return !1;
402
- const s = o.path ?? "";
403
- return !!(s && M(s, t.excludePatterns) || t.globalLocaleRoutes[o.name ?? ""] === !1 || /^\/:locale/.test(s) || s === "/");
404
- });
400
+ const a = e.filter((s) => {
401
+ if (s.name === "index" && s.path === "/") return !1;
402
+ const i = s.path ?? "";
403
+ return !!(i && M(i, t.excludePatterns) || t.globalLocaleRoutes[s.name ?? ""] === !1 || /^\/:locale/.test(i) || i === "/");
404
+ }), o = t.defaultLocale.code;
405
+ for (const [s, i] of Object.entries(t.globalLocaleRoutes)) {
406
+ if (i === !1 || typeof i != "object") continue;
407
+ const r = i[o];
408
+ if (!r) continue;
409
+ const c = s.startsWith("/") ? s : `/${s}`, d = `/${o}${r.startsWith("/") ? r : `/${r}`}`;
410
+ c !== d && a.push({
411
+ path: c,
412
+ name: `redirect-${s.replace(/\//g, "-")}`,
413
+ redirect: d
414
+ });
415
+ }
405
416
  return t.fallbackRedirectComponentPath && a.push({
406
417
  path: "/:pathMatch(.*)*",
407
418
  name: "custom-fallback-route",
@@ -414,12 +425,12 @@ class ie extends k {
414
425
  }
415
426
  class re extends k {
416
427
  generateVariants(e, t) {
417
- const a = e.path ?? "", o = b(e.name, e.path), s = t.getAllowedLocales(a, o), i = t.getCustomPathsForPage(a, o), r = $(e.children ?? []), n = [], d = t.defaultLocale.code;
418
- n.push(e);
419
- const c = t.locales.filter((u) => s.includes(u.code));
420
- if (c.length > 0)
428
+ const a = e.path ?? "", o = b(e.name, e.path), s = t.getAllowedLocales(a, o), i = t.getCustomPathsForPage(a, o), r = $(e.children ?? []), c = [], d = t.defaultLocale.code;
429
+ c.push(e);
430
+ const n = t.locales.filter((u) => s.includes(u.code));
431
+ if (n.length > 0)
421
432
  if (i)
422
- for (const u of c) {
433
+ for (const u of n) {
423
434
  const m = i[u.code];
424
435
  if (m)
425
436
  if (u.code === d) {
@@ -435,7 +446,7 @@ class re extends k {
435
446
  a,
436
447
  t
437
448
  );
438
- f && n.push(f);
449
+ f && c.push(f);
439
450
  const P = this.createLocalizedRoute(
440
451
  e,
441
452
  [u.code],
@@ -448,7 +459,7 @@ class re extends k {
448
459
  a,
449
460
  t
450
461
  );
451
- P && n.push(P);
462
+ P && c.push(P);
452
463
  } else {
453
464
  const f = this.createLocalizedRoute(
454
465
  e,
@@ -462,7 +473,7 @@ class re extends k {
462
473
  a,
463
474
  t
464
475
  );
465
- f && n.push(f);
476
+ f && c.push(f);
466
477
  }
467
478
  else {
468
479
  const f = this.createLocalizedRoute(
@@ -477,11 +488,11 @@ class re extends k {
477
488
  a,
478
489
  t
479
490
  );
480
- f && n.push(f);
491
+ f && c.push(f);
481
492
  }
482
493
  }
483
494
  else {
484
- const u = c.map((f) => f.code), m = this.createLocalizedRoute(
495
+ const u = n.map((f) => f.code), m = this.createLocalizedRoute(
485
496
  e,
486
497
  u,
487
498
  r,
@@ -493,10 +504,10 @@ class re extends k {
493
504
  a,
494
505
  t
495
506
  );
496
- m && n.push(m);
507
+ m && c.push(m);
497
508
  }
498
509
  const h = _(e, s, t.customRegex, t.localizedRouteNamePrefix);
499
- return h.length && n.push(...h), n;
510
+ return h.length && c.push(...h), c;
500
511
  }
501
512
  postProcess(e, t) {
502
513
  const a = [], o = [];
@@ -506,7 +517,7 @@ class re extends k {
506
517
  }
507
518
  return [...a, ...o];
508
519
  }
509
- createLocalizedRoute(e, t, a, o, s = "", i, r = !1, n = !1, d, c) {
520
+ createLocalizedRoute(e, t, a, o, s = "", i, r = !1, c = !1, d, n) {
510
521
  const h = this.buildRoutePathForLocales(
511
522
  t,
512
523
  e.path ?? "",
@@ -514,12 +525,12 @@ class re extends k {
514
525
  o,
515
526
  i,
516
527
  r,
517
- c.defaultLocale.code
528
+ n.defaultLocale.code
518
529
  );
519
530
  if (!h || !(o && s) && h === e.path || t.length === 0) return null;
520
531
  const m = t[0];
521
532
  if (!m) return null;
522
- const f = d ?? e.path ?? "", P = j(b(e.name ?? "", f), m, o, c.localizedRouteNamePrefix), L = r || m !== c.defaultLocale.code, g = t.length === 1 ? this.localizeChildren(a, h, f, m, c, L) : this.localizeChildrenAllLocales(a, h, f, t, c);
533
+ const f = d ?? e.path ?? "", P = j(b(e.name ?? "", f), m, o, n.localizedRouteNamePrefix), L = r || m !== n.defaultLocale.code, g = t.length === 1 ? this.localizeChildren(a, h, f, m, n, L) : this.localizeChildrenAllLocales(a, h, f, t, n);
523
534
  return p(e, {
524
535
  path: h,
525
536
  name: P,
@@ -529,9 +540,9 @@ class re extends k {
529
540
  });
530
541
  }
531
542
  }
532
- class ne extends k {
543
+ class ce extends k {
533
544
  generateVariants(e, t) {
534
- const a = e.path ?? "", o = b(e.name, e.path), s = t.getAllowedLocales(a, o), i = t.getCustomPathsForPage(a, o), r = $(e.children ?? []), n = [], d = t.defaultLocale.code;
545
+ const a = e.path ?? "", o = b(e.name, e.path), s = t.getAllowedLocales(a, o), i = t.getCustomPathsForPage(a, o), r = $(e.children ?? []), c = [], d = t.defaultLocale.code;
535
546
  if (s.includes(d)) {
536
547
  const u = i?.[d], m = u ? R(u) : a, f = u ? { [d]: u } : {}, P = this.createLocalizedChildren(
537
548
  r,
@@ -543,7 +554,7 @@ class ne extends k {
543
554
  f,
544
555
  t
545
556
  );
546
- n.push(
557
+ c.push(
547
558
  p(e, {
548
559
  path: m,
549
560
  name: e.name,
@@ -551,12 +562,12 @@ class ne extends k {
551
562
  })
552
563
  );
553
564
  }
554
- const c = t.locales.filter(
565
+ const n = t.locales.filter(
555
566
  (u) => s.includes(u.code) && u.code !== d
556
567
  );
557
- if (c.length)
568
+ if (n.length)
558
569
  if (i)
559
- for (const u of c) {
570
+ for (const u of n) {
560
571
  const m = i[u.code];
561
572
  if (m) {
562
573
  const f = this.createLocalizedRoute(
@@ -571,7 +582,7 @@ class ne extends k {
571
582
  a,
572
583
  t
573
584
  );
574
- f && n.push(f);
585
+ f && c.push(f);
575
586
  } else {
576
587
  const f = this.createLocalizedRoute(
577
588
  e,
@@ -585,11 +596,11 @@ class ne extends k {
585
596
  a,
586
597
  t
587
598
  );
588
- f && n.push(f);
599
+ f && c.push(f);
589
600
  }
590
601
  }
591
602
  else {
592
- const u = c.map((f) => f.code), m = this.createLocalizedRoute(
603
+ const u = n.map((f) => f.code), m = this.createLocalizedRoute(
593
604
  e,
594
605
  u,
595
606
  r,
@@ -601,10 +612,10 @@ class ne extends k {
601
612
  a,
602
613
  t
603
614
  );
604
- m && n.push(m);
615
+ m && c.push(m);
605
616
  }
606
617
  const h = _(e, s, t.customRegex, t.localizedRouteNamePrefix);
607
- return h.length && n.push(...h), n;
618
+ return h.length && c.push(...h), c;
608
619
  }
609
620
  postProcess(e, t) {
610
621
  const a = [], o = [];
@@ -622,7 +633,7 @@ class ne extends k {
622
633
  }
623
634
  }), s;
624
635
  }
625
- createLocalizedChildren(e, t, a, o = !0, s = !1, i = !1, r = {}, n) {
636
+ createLocalizedChildren(e, t, a, o = !0, s = !1, i = !1, r = {}, c) {
626
637
  return e.flatMap(
627
638
  (d) => this.createLocalizedVariants(
628
639
  d,
@@ -632,12 +643,12 @@ class ne extends k {
632
643
  s,
633
644
  i,
634
645
  r,
635
- n
646
+ c
636
647
  )
637
648
  );
638
649
  }
639
- createLocalizedVariants(e, t, a, o, s, i = !1, r, n) {
640
- const d = R(e.path ?? ""), c = z(t, e.path ?? ""), h = F(c), u = n.localizedPaths[h], m = !!u, f = [];
650
+ createLocalizedVariants(e, t, a, o, s, i = !1, r, c) {
651
+ const d = R(e.path ?? ""), n = z(t, e.path ?? ""), h = F(n), u = c.localizedPaths[h], m = !!u, f = [];
641
652
  if (!m) {
642
653
  const P = y(d), L = this.createLocalizedChildren(
643
654
  $(e.children ?? []),
@@ -647,8 +658,8 @@ class ne extends k {
647
658
  s,
648
659
  i,
649
660
  r,
650
- n
651
- ), g = this.buildChildRouteName(e.name, i, n);
661
+ c
662
+ ), g = this.buildChildRouteName(e.name, i, c);
652
663
  return f.push(
653
664
  p(e, {
654
665
  path: P,
@@ -663,10 +674,10 @@ class ne extends k {
663
674
  g && L && (C ? x = R(C) : x = z(L, e.path ?? ""));
664
675
  const v = Q(
665
676
  P,
666
- n.defaultLocale,
677
+ c.defaultLocale,
667
678
  s,
668
679
  !1
669
- ) ? A(P, x, n.customRegex) : x, T = y(v), W = C ? R(C) : g ? L : z(t, e.path ?? ""), V = this.createLocalizedChildren(
680
+ ) ? A(P, x, c.customRegex) : x, T = y(v), W = C ? R(C) : g ? L : z(t, e.path ?? ""), V = this.createLocalizedChildren(
670
681
  $(e.children ?? []),
671
682
  W,
672
683
  [P],
@@ -677,13 +688,13 @@ class ne extends k {
677
688
  ...r,
678
689
  [P]: W
679
690
  },
680
- n
691
+ c
681
692
  ), I = this.buildLocalizedRouteName(
682
693
  b(e.name, e.path),
683
694
  P,
684
695
  o,
685
696
  !!u,
686
- n
697
+ c
687
698
  );
688
699
  f.push(
689
700
  p(e, {
@@ -698,7 +709,7 @@ class ne extends k {
698
709
  buildChildRouteName(e, t, a) {
699
710
  return t === !0 ? `${a.localizedRouteNamePrefix}${e}` : typeof t == "string" ? `${a.localizedRouteNamePrefix}${e}-${t}` : e;
700
711
  }
701
- createLocalizedRoute(e, t, a, o, s = "", i, r = !1, n = !1, d, c) {
712
+ createLocalizedRoute(e, t, a, o, s = "", i, r = !1, c = !1, d, n) {
702
713
  const h = this.buildRoutePathForLocales(
703
714
  t,
704
715
  e.path ?? "",
@@ -706,12 +717,12 @@ class ne extends k {
706
717
  o,
707
718
  i,
708
719
  r,
709
- c.defaultLocale.code
720
+ n.defaultLocale.code
710
721
  );
711
722
  if (!h || h === e.path || t.length === 0) return null;
712
723
  const u = t[0];
713
724
  if (!u) return null;
714
- const m = d ?? e.path ?? "", f = j(b(e.name ?? "", m), u, o, c.localizedRouteNamePrefix);
725
+ const m = d ?? e.path ?? "", f = j(b(e.name ?? "", m), u, o, n.localizedRouteNamePrefix);
715
726
  return p(e, {
716
727
  path: h,
717
728
  name: f,
@@ -721,9 +732,9 @@ class ne extends k {
721
732
  t,
722
733
  !0,
723
734
  !1,
724
- n,
735
+ c,
725
736
  { [u]: s },
726
- c
737
+ n
727
738
  ),
728
739
  alias: [],
729
740
  meta: { alias: [] }
@@ -733,7 +744,7 @@ class ne extends k {
733
744
  return a ? o ? `${s.localizedRouteNamePrefix}${e}-${t}` : t && !X(t, s.defaultLocale, !1) ? `${s.localizedRouteNamePrefix}${e}-${t}` : `${s.localizedRouteNamePrefix}${e}` : e;
734
745
  }
735
746
  }
736
- function ce(l) {
747
+ function ne(l) {
737
748
  switch (l) {
738
749
  case "no_prefix":
739
750
  return new oe();
@@ -742,7 +753,7 @@ function ce(l) {
742
753
  case "prefix_and_default":
743
754
  return new re();
744
755
  case "prefix_except_default":
745
- return new ne();
756
+ return new ce();
746
757
  default:
747
758
  throw new Error(`Unknown route strategy: ${l}`);
748
759
  }
@@ -757,13 +768,13 @@ class de {
757
768
  globalLocaleRoutes: s,
758
769
  filesLocaleRoutes: i = {},
759
770
  routeLocales: r = {},
760
- noPrefixRedirect: n,
771
+ noPrefixRedirect: c,
761
772
  excludePatterns: d,
762
- localizedRouteNamePrefix: c = "localized-",
773
+ localizedRouteNamePrefix: n = "localized-",
763
774
  customRegexMatcher: h,
764
775
  fallbackRedirectComponentPath: u
765
776
  } = e, m = Z(t, a);
766
- 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();
777
+ this.locales = m.locales, this.defaultLocale = m.defaultLocale, this.strategy = o, this.noPrefixRedirect = c, this.excludePatterns = d, this.localizedRouteNamePrefix = n, this.customRegex = h, this.fallbackRedirectComponentPath = u, this.activeLocaleCodes = this.computeActiveLocaleCodes();
767
778
  const f = {};
768
779
  for (const P in s) {
769
780
  const L = w(P), g = s[P];
@@ -799,7 +810,7 @@ class de {
799
810
  rawGlobalLocaleRoutes: this.rawGlobalLocaleRoutes
800
811
  });
801
812
  this.localizedPaths = t.localizedPaths;
802
- const a = ce(this.strategy), o = [...e], s = [];
813
+ const a = ne(this.strategy), o = [...e], s = [];
803
814
  for (const r of o)
804
815
  s.push(...a.processPage(r, t));
805
816
  const i = a.postProcess(s, t);
@@ -820,8 +831,8 @@ class de {
820
831
  this.locales.forEach((s) => {
821
832
  const i = N.join(a, t, `${s.code}.json`);
822
833
  this.ensureFileExists(i), o || e.forEach((r) => {
823
- const n = N.join(a, t, "pages", `${r}/${s.code}.json`);
824
- this.ensureFileExists(n);
834
+ const c = N.join(a, t, "pages", `${r}/${s.code}.json`);
835
+ this.ensureFileExists(c);
825
836
  });
826
837
  });
827
838
  }
@@ -839,9 +850,9 @@ class de {
839
850
  let s;
840
851
  const i = this.globalLocaleRoutes[o], r = this.globalLocaleRoutes[a];
841
852
  i && typeof i == "object" && !Array.isArray(i) ? s = i[t] : r && typeof r == "object" && !Array.isArray(r) && (s = r[t]);
842
- const n = !!s, d = s ? R(s) : R(a) || "";
843
- let c = !1;
844
- 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)
853
+ const c = !!s, d = s ? R(s) : R(a) || "";
854
+ let n = !1;
855
+ if (this.strategy === "no_prefix" ? n = !1 : this.strategy === "prefix" || this.strategy === "prefix_and_default" ? n = !0 : this.strategy === "prefix_except_default" && (n = t !== this.defaultLocale.code), t === this.defaultLocale.code && !c && (this.strategy === "prefix_except_default" || this.strategy === "no_prefix") && (n = !1), !n)
845
856
  return R(d) || "/";
846
857
  const h = y(d);
847
858
  return h ? R(`/${t}/${h}`) : `/${t}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@i18n-micro/route-strategy",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Locale-aware route generator for Nuxt i18n micro",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -55,8 +55,8 @@
55
55
  "sideEffects": false,
56
56
  "dependencies": {
57
57
  "@nuxt/schema": "^3.18.1 || ^4.0.0",
58
- "@i18n-micro/types": "1.1.0",
59
- "@i18n-micro/core": "1.1.0"
58
+ "@i18n-micro/core": "1.1.1",
59
+ "@i18n-micro/types": "1.1.0"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/jest": "^29.5.14",