UNPKG

@resolid/flex-routes

Version:

React Router flex file-system routes

15 lines (11 loc) 4.36 kB
import {getAppDirectory}from'@react-router/dev/routes';import {makeRe}from'minimatch';import {join,relative,extname,win32}from'path';import {readdir}from'fs/promises';var k="$",P="[",C="]",_="(",$=")",I=async(s,c,n=s)=>{for(let i of await readdir(s,{withFileTypes:true,encoding:"utf8"})){let e=join(s,i.name);i.isDirectory()?await I(e,c,n):i.isFile()&&c(relative(n,e));}},A=s=>{let c=[],n=[],i=0,e="",t="",l="NORMAL",a=(o,R)=>{if(o){if(R.includes("*")||R.includes(":")||R.includes("?"))throw new Error("\u8DEF\u7531\u6587\u4EF6\u6216\u76EE\u5F55\u4E2D\u4E0D\u80FD\u5B58\u5728 `*` `:` `?` \u7279\u6B8A\u5B57\u7B26");c.push(o),n.push(R);}};for(;i<s.length;){let o=s[i];switch(i++,l){case "NORMAL":{if(o&&[".","/"].includes(o)){a(e,t),e="",t="",l="NORMAL";break}if(o===P){l="ESCAPE",t+=o;break}if(o===_){l="OPTIONAL",t+=o;break}if(!e&&o==k){i===s.length?(e+="*",t+=o):(e+=":",t+=o);break}e+=o,t+=o;break}case "ESCAPE":{if(o===C){l="NORMAL",t+=o;break}e+=o,t+=o;break}case "OPTIONAL":{if(o===$){e+="?",t+=o,l="NORMAL";break}if(o===P){l="OPTIONAL_ESCAPE",t+=o;break}if(!e&&o===k){i===s.length?(e+="*",t+=o):(e+=":",t+=o);break}e+=o,t+=o;break}case "OPTIONAL_ESCAPE":{if(o===C){l="OPTIONAL",t+=o;break}e+=o,t+=o;break}}}return a(e,t),[c,n]},M=(s,c,n)=>{let i=[],e=n?s.slice(0,-1):s;for(let t=0;t<e.length;t++){let l=c[t],a=e[t];a.startsWith("_")&&l.startsWith("_")||(a.endsWith("_")&&l.endsWith("_")&&(a=a.slice(0,-1)),i.push(a));}return i.length?i.join("/"):void 0},x=Symbol("PrefixLookupTrieEndSymbol"),E=class{root={[x]:false};add(c){if(!c)throw new Error("Cannot add empty string to PrefixLookupTrie");let n=this.root;for(let i of c)n[i]||(n[i]={[x]:false}),n=n[i];n[x]=true;}findAndRemove(c,n){let i=this.root;for(let e of c){if(!i[e])return [];i=i[e];}return this.#t([],i,c,n)}#t(c,n,i,e){for(let t of Object.keys(n))this.#t(c,n[t],i+t,e);return n[x]&&e(i)&&(n[x]=false,c.push(i)),c}},S=s=>s.split(win32.sep).join("/");var L=(s,c="root")=>{let n={};for(let e in s){let t=s[e];n[e]={id:t.id,file:t.file,path:t.path,index:t.index,caseSensitive:t.caseSensitive};}let i=[];for(let e in n){let t=n[e],l=s[t.id].parentId;if(l===c)i.push(t);else {let a=l&&n[l];a&&(a.children=a.children||[],a.children.push(t));}}return i},O=(s,c)=>{let n={},i=new Map,e=new Map;for(let f of c){let r=S(join(s,f)),u=r.slice(0,-extname(r).length),d=u.slice(-7)=="_layout"?u.slice(0,-8):u,p=i.get(d);if(p){let h=e.get(d)??[p];h.push(r),e.set(d,h);continue}i.set(d,r);}let t=new E,l=Array.from(i).sort(([f],[r])=>r.length-f.length);for(let[f,r]of l){let[u,d]=A(f.slice(s.length+1)),p=f.slice(-6)=="_index",h=M(u,d,p);n[f]={file:r,id:f,path:h},p&&(n[f].index=true);let g=t.findAndRemove(f,m=>[".","/"].includes(m.slice(f.length).charAt(0)));if(t.add(f),g.length>0)for(let m of g)n[m].parentId=f;}let a=new Map;for(let[f]of l){let r=n[f];if(!r.parentId)continue;let u=a.get(r.parentId)||[];u.push(r),a.set(r.parentId,u);}let o=new Map,R=new Map;for(let[f]of l){let r=n[f],u=r.path||"",d=r.parentId?n[r.parentId]:null,p=r.path;d?.path&&p&&(p=p.slice(d.path.length).replace(/^\//,"").replace(/\/$/,"")),r.parentId||(r.parentId="root"),r.path=p||void 0;let h=r.id.replace(new RegExp(`^${s}/`),"").split(/[./]/).pop();if(h&&h[0]=="_"&&h!=="_index")continue;let g=u+(r.index?"?index":""),m=o.get(g);if(o.set(g,r),m&&(u||r.index)){let y=R.get(u);y||(y=[m]),y.push(r),R.set(u,y);}}if(e.size>0)for(let[f,r]of e.entries()){let[u,...d]=r,p=d.map(h=>`\u2B55 ${h}`).join(` `);console.error(`!Route ID \u51B2\u7A81: "${f}" \u4E0B\u5217\u8DEF\u7531\u90FD\u5B9A\u4E49\u4E86\u76F8\u540C\u7684\u8DEF\u7531 ID\uFF0C\u4F46\u53EA\u6709\u7B2C\u4E00\u4E2A\u4F1A\u751F\u6548 \u{1F7E2} ${u} ${p} `);}if(R.size>0)for(let[f,r]of R.entries()){for(let g=1;g<r.length;g++)delete n[r[g].id];let[u,...d]=r.map(g=>g.file),p=f[0]=="/"?f:`/${f}`,h=d.map(g=>`\u2B55 ${g}`).join(` `);console.error(`! Route \u8DEF\u5F84\u51B2\u7A81: "${p}" \u4E0B\u5217\u8DEF\u7531\u90FD\u5B9A\u4E49\u4E86\u76F8\u540C\u7684 URL\uFF0C\u4F46\u53EA\u6709\u7B2C\u4E00\u4E2A\u4F1A\u751F\u6548 \u{1F7E2} ${u} ${h} `);}return n};var q=[".js",".jsx",".ts",".tsx",".md",".mdx"],tt=async(s={})=>{let{routesDirectory:c="routes",ignoredRouteFiles:n=[]}=s,i=getAppDirectory(),e=n.map(a=>makeRe(a)).filter(a=>!!a),t=[];await I(join(i,c),a=>{e.some(o=>o.test(a))||q.includes(extname(a))&&t.push(a);});let l=O(c,t);return L(l)};export{tt as flexRoutes};