@route-forge/core 1.4.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -6
- package/dist/codegen.d.cts +1 -1
- package/dist/codegen.d.ts +1 -1
- package/dist/index.cjs +618 -508
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -50
- package/dist/index.d.ts +61 -50
- package/dist/index.js +618 -508
- package/dist/index.js.map +1 -1
- package/dist/route-forge.global.js +618 -508
- package/dist/route-forge.global.js.map +1 -1
- package/dist/route-forge.global.min.js +2 -2
- package/dist/{types-BFlrOTrN.d.cts → types-C51rXaiY.d.cts} +6 -17
- package/dist/{types-BFlrOTrN.d.ts → types-C51rXaiY.d.ts} +6 -17
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var RouteForge=(function(exports){'use strict';var Fe="route-forge:";function Ue(o){return o==="memory"||typeof globalThis>"u"?null:o==="sessionStorage"?globalThis.sessionStorage??null:o==="localStorage"?globalThis.localStorage??null:null}var z=class{constructor(t){this.memory=new Map;this.storage=t.storage,this.fallbackTtl=t.ttl,this.backend=Ue(t.storage);}key(t){return `${Fe}${t}`}get(t){if(this.storage==="memory"||!this.backend)return this.getFromMemory(t);let n=this.backend.getItem(this.key(t));if(n)try{let r=JSON.parse(n);if(this.isExpired(r)){this.del(t);return}return r}catch{return}return this.getFromMemory(t)}getFromMemory(t){let n=this.memory.get(t);if(n){if(this.isExpired(n)){this.memory.delete(t);return}return n}}set(t){let n;t.cache!==void 0&&t.cache!==null?n=t.cache>0?Math.min(t.cache,this.fallbackTtl):t.cache:n=this.fallbackTtl;let r={level:t.level,routes:t.routes,ttl:n,cachedAt:Date.now()};if(this.storage==="memory"||!this.backend){this.memory.set(t.level,r);return}try{this.backend.setItem(this.key(t.level),JSON.stringify(r));}catch{this.memory.set(t.level,r);}}del(t){if(this.memory.delete(t),this.backend)try{this.backend.removeItem(this.key(t));}catch{}}clear(){if(this.memory.clear(),this.backend)try{let t=[];for(let n=0;n<this.backend.length;n++){let r=this.backend.key(n);r&&r.startsWith(Fe)&&t.push(r);}for(let n of t)this.backend.removeItem(n);}catch{}}isExpired(t){return t.ttl===null||t.ttl===0?false:Date.now()-t.cachedAt>t.ttl*1e3}};var w=class extends Error{constructor(t,n){super(t),this.name=this.constructor.name,this.code=n.code,n.route!==void 0&&(this.route=n.route),n.level!==void 0&&(this.level=n.level),n.context!==void 0&&(this.context=n.context),n.cause!==void 0&&(this.cause=n.cause);}},A=class extends w{constructor(t,n){super(`Route "${t}" not found${n?` in level "${n}"`:""}`,{code:"RF_FE_001",route:t,level:n});}},J=class extends w{constructor(t){super(`Level "${t}" not declared in options.levels`,{code:"RF_FE_002",level:t});}},V=class extends w{constructor(t,n){super(`Missing path parameter(s) ${n.join(", ")} for route "${t}"`,{code:"RF_FE_003",route:t,context:{missingParams:n}});}},j=class extends w{constructor(t){super(`Adapter "${t}" not available; install axios or use 'builtin'`,{code:"RF_FE_005",context:{adapter:t}});}},Q=class extends w{constructor(t){super("Request interceptor must return a RequestConfig object",{code:"RF_FE_006",route:t});}},D=class extends w{constructor(t,n,r,d){super(t,{code:"RF_FE_007",route:n,level:r,cause:d});}},L=class extends w{constructor(t,n){super(t,{code:"RF_FE_008",route:n.route,level:n.level,context:{status:n.status,url:n.url,method:n.method},cause:n.cause});}},_=class extends w{constructor(t,n,r){super(`Request aborted${t?` for route "${t}"`:""}`,{code:"RF_FE_009",route:t,level:n,cause:r});}};var O=class{constructor(){this.handlers=[];this.nextId=0;}use(t,n){let r=this.nextId++;return this.handlers.push({id:r,onFulfilled:t,onRejected:n}),r}eject(t){let n=this.handlers.findIndex(r=>r.id===t);n>=0&&this.handlers.splice(n,1);}clear(){this.handlers=[];}forEach(t){for(let n of this.handlers)t(n);}get size(){return this.handlers.length}};async function te(o,t){let n=[];o.forEach(d=>n.push(d)),n.reverse();let r=Promise.resolve(t);for(let d of n){let f=d.onFulfilled,R=d.onRejected;r=r.then(async g=>{if(!f)return g;let q=await f(g);if(q===null||typeof q!="object")throw new Q;return q},g=>R?R(g):Promise.reject(g));}return r}async function ne(o,t){let n=[];o.forEach(d=>n.push(d));let r=t;for(let d of n){let f=d.onFulfilled,R=d.onRejected;r=r.then(g=>f?f(g):g,g=>R?R(g):Promise.reject(g));}return r}function re(){return new O}function Be(o){return o===null?false:typeof FormData<"u"&&o instanceof FormData||typeof URLSearchParams<"u"&&o instanceof URLSearchParams||typeof Blob<"u"&&o instanceof Blob||typeof ArrayBuffer<"u"&&(o instanceof ArrayBuffer||ArrayBuffer.isView(o))||typeof ReadableStream<"u"&&o instanceof ReadableStream}function He(o){let t=o;return !!t&&t.name==="AbortError"}function Ne(...o){let t=o.filter(r=>!!r);if(t.length===0)return;if(t.length===1)return t[0];if(typeof AbortSignal<"u"&&typeof AbortSignal.any=="function")return AbortSignal.any(t);let n=new AbortController;for(let r of t){if(r.aborted)return n.abort(r.reason),n.signal;r.addEventListener("abort",()=>n.abort(r.reason),{once:true});}return n.signal}function le(o){let t=o?.request??re(),n=o?.response??re();async function r(a){let h=Ne(a.signal,a.timeout&&a.timeout>0?AbortSignal.timeout(a.timeout):void 0),y=a.url;if(a.paramsSerializer&&a.params){let C=a.paramsSerializer(a.params);C&&(y=y.includes("?")?`${y}&${C}`:`${y}?${C}`);}let x=new Headers(a.headers),E={method:a.method,headers:x};h&&(E.signal=h),a.body!==void 0&&!["GET","HEAD"].includes(a.method.toUpperCase())&&(typeof a.body=="string"||Be(a.body)?E.body=a.body:(E.body=JSON.stringify(a.body),x.has("Content-Type")||x.set("Content-Type","application/json")));let v;try{v=await fetch(y,E);}catch(C){throw He(C)?C:new D(C instanceof Error?C.message:String(C),a.route,a.level,C)}let se=await v.text(),M=se;if((v.headers.get("content-type")??"").includes("application/json"))try{M=JSON.parse(se);}catch{}let Y={route:a.route,level:a.level,method:a.method,url:y,status:v.status,headers:v.headers,data:M,config:a};if(v.status>=200&&v.status<300)return Y;throw new L(`HTTP ${v.status} for route "${a.route}" (${a.method} ${y})`,{route:a.route,level:a.level,status:v.status,url:y,method:a.method})}async function d(a){let h=await te(t,a),y=Promise.resolve(h).then(r);return ne(n,y)}return {request:d,requestRaw:r,interceptors:{request:t,response:n},runsInterceptors:true,get:(a,h)=>d({...h,url:a,method:"GET"}),post:(a,h)=>d({...h,url:a,method:"POST"}),put:(a,h)=>d({...h,url:a,method:"PUT"}),patch:(a,h)=>d({...h,url:a,method:"PATCH"}),delete:(a,h)=>d({...h,url:a,method:"DELETE"})}}function xe(o){if(!o)return new Headers;let t=typeof o.toJSON=="function"?o.toJSON():o;try{return new Headers(t)}catch{return new Headers}}async function fe(){let o,t="axios";try{let r=await import(t);o=r.default??r;}catch{typeof globalThis<"u"&&globalThis.axios&&(o=globalThis.axios);}if(!o||typeof o.request!="function")return null;async function n(r){let d={...r.headers};try{let f=await o.request({url:r.url,method:r.method,headers:d,data:r.body,timeout:r.timeout,signal:r.signal});return {route:r.route,level:r.level,method:r.method,url:r.url,status:f.status,headers:xe(f.headers),data:f.data,config:r}}catch(f){if(f&&f.response){let R=f.response;return {route:r.route,level:r.level,method:r.method,url:r.url,status:R.status,headers:xe(R.headers),data:R.data,config:r}}throw f}}return {request:n,interceptors:void 0}}async function ge(o){let{adapter:t}=o;if(t&&typeof t=="object")return {request:r=>t.request(r),interceptors:t.interceptors};if(t==="builtin")return le(o.forgeInterceptors);if(t==="axios"){let r=await fe();if(!r)throw new j("axios");return r}let n=await fe().catch(()=>null);return n||le(o.forgeInterceptors)}async function pe(o,t,n,r,d="."){if(!r)return n;let f=`${n}${d}${r}`;if(!r.startsWith(`${n}${d}`)||(await o.load(t),o.hasRoute(t,f)))return f;if(o.hasRoute(t,r))return r;throw new A(f,t)}function oe(o,t,n,r,d="."){if(!r)return n;let f=`${n}${d}${r}`;if(!r.startsWith(`${n}${d}`)||o.hasRoute(t,f))return f;if(o.hasRoute(t,r))return r;throw new A(f,t)}function Ee(o,t){for(let n of Object.keys(t)){let r=t[n];Object.defineProperty(o,n,{value:r!==null&&typeof r=="object"?Object.freeze(r):r,writable:false,enumerable:false,configurable:false});}return o}var Z=class{constructor(){this.count=0;this.subscribers=new Set;}start(){this.count++,this.notify();}stop(){this.count=Math.max(0,this.count-1),this.notify();}isLoading(){return this.count>0}getCount(){return this.count}subscribe(t){return this.subscribers.add(t),()=>{this.subscribers.delete(t);}}notify(){let t={loading:this.count>0,count:this.count};for(let n of this.subscribers)try{n(t);}catch{}}};var We=3e4,Je=3600,K="unassigned";function Ge(o){if(!o.endpoint)throw new TypeError("options.endpoint is required");let{adapter:t="auto",timeout:n=We,baseURL:r="",interceptors:d,cache:f={}}=o,R=new Z,g=o.levels,q=o.eager,I=o.endpoint,a=g??[],h=q??[],y=I,x="",E,v=false,M=(async()=>{try{let e=I,s=await fetch(e,{method:"GET"});return s.ok?await s.json():(console.warn(`[route-forge] summary endpoint ${e} unreachable (HTTP ${s.status}); falling back to explicit options`),null)}catch(e){if(g&&g.length>0)return console.warn(`[route-forge] summary endpoint unreachable: ${e.message}; using explicit levels`),null;throw new J("(auto-discovery)")}})().then(e=>{if(e===null)return;let s=e.schemaVersion??1;s>1&&console.warn(`[route-forge] backend schemaVersion=${s} > client supported 1; some features may be unavailable`),e.config.endpoint_prefix&&e.config.endpoint_prefix!==I&&(console.warn(`[route-forge] backend endpoint_prefix "${e.config.endpoint_prefix}" overrides frontend endpoint "${I}"`),y=e.config.endpoint_prefix),e.config.url_prefix&&(x=e.config.url_prefix.endsWith("/")?e.config.url_prefix.slice(0,-1):e.config.url_prefix);let i=Object.keys(e.levels);v=i.includes(K),Array.isArray(e.unassigned)&&e.unassigned.length>0&&!v&&(E=e.unassigned);let u=i.slice();if(E&&!v&&u.push(K),g&&g.length>0){let c=g.filter(k=>u.includes(k)),p=g.filter(k=>!u.includes(k));p.length>0&&console.warn(`[route-forge] levels not in backend summary and dropped: ${p.join(", ")}`),a=c;}else a=u;let l=i.filter(c=>e.levels[c]?.load==="eager");q?h=[...new Set([...l,...q])]:h=l;}),X=null;M.catch(e=>{X=e;});let Y=false,C,he=new Promise(e=>{C=e;}),Ae=f.ttl??Je,Ie=f.storage??"memory",F=new z({storage:Ie,ttl:Ae}),U=new O,B=new O;if(d?.request)for(let e of d.request)if(typeof e=="function")U.use(e);else {let[s,i]=e;U.use(s,i);}if(d?.response)for(let e of d.response)if(typeof e=="function")B.use(e);else {let[s,i]=e;B.use(s,i);}let Te=ge({adapter:t,forgeInterceptors:{request:U,response:B}}),me=false,Re=null;async function ye(){return me||(Re=await Te.catch(e=>{if(e instanceof j)throw e;return ge({adapter:"builtin",forgeInterceptors:{request:U,response:B}})}),me=true),Re}let H=new Map,T=new Map;function $e(e){if(!a.includes(e))throw new J(e)}function be(){if(!Y&&!g?.length)throw new w("Route data not available. Auto-discovery has not completed. Use forge.ready() or forge.use(level) first.",{code:"RF_FE_010"})}function ae(e){let s=r.endsWith("/")?r.slice(0,-1):r,i=y.startsWith("/")?y:`/${y}`;return `${s}${i}/${encodeURIComponent(e)}`}async function Se(e){let s=await ye(),i={route:`__forge__.load.${e}`,level:e,method:"GET",url:ae(e),headers:{Accept:"application/json"},params:{},timeout:n,meta:{name:`__forge__.load.${e}`,uri:ae(e),methods:["GET"],parameters:[],level:e}},l=await(s.requestRaw??s.request)(i);if(!l||l.status<200||l.status>=300)throw new L(`Failed to load level "${e}": HTTP ${l?.status}`,{level:e,status:l?.status,url:ae(e),method:"GET"});return l.data}async function Le(e){if(X)throw X;if($e(e),F.get(e))return;let s=H.get(e);if(s)return s;let i=T.get(e)??0,u=(async()=>{try{if(e===K&&!v&&E){let c={};for(let p of E)c[p.name]={...p,level:K};F.set({level:K,routes:c,cache:null});return}let l=await Se(e);(T.get(e)??0)===i&&F.set(l);}finally{H.delete(e);}})();return H.set(e,u),u}async function N(e){await M;let s=Array.isArray(e)?e:[e];await Promise.all(s.map(Le));}function W(e,s,i){be();let u=ie(e,s);if(!u)throw new A(s,e);return we(u,i??{})}function we(e,s){let i=e.parameter_defaults??{},u=[],l={};for(let b of e.parameters){let P=s[b];P==null&&b in i&&(P=i[b]),P==null?e.uri.includes(`{${b}?}`)||u.push(b):l[b]=P;}if(u.length>0)throw new V(e.name,u);let c=e.uri.replace(/\{([^{}]+)\}/g,(b,P)=>{let G=P.endsWith("?"),$=G?P.slice(0,-1):P;if(l[$]!==void 0){let S=l[$];if(typeof S=="object")throw new w(`Path parameter "${$}" must be a primitive value (string, number, boolean), got ${typeof S}`,{code:"RF_FE_003",route:e.name,context:{param:$,value:S}});return encodeURIComponent(String(S))}return G?"":b});if(c=c.replace(/\/+/g,"/").replace(/\/$/,""),/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(x)){let b=x.endsWith("/")?x.slice(0,-1):x;return c.startsWith("/")?`${b}${c}`:`${b}/${c}`}let p=r.endsWith("/")?r.slice(0,-1):r,k=x;return c.startsWith("/")?`${p}${k}${c}`:`${p}${k}/${c}`}function ie(e,s){let u=F.get(e)?.routes[s];if(u)return {...u,level:e}}function ue(e,s,i={}){let u,l=false,c,k=(async()=>{u=new AbortController,l&&u.abort(c),await M,await N(e);let b=ie(e,s);if(!b)throw new A(s,e);return Me(b,i,u.signal)})();return k.abort=()=>{u?u.abort():l=true;},k}async function Me(e,s,i){let{pathParams:u,query:l,body:c,headers:p,timeout:k}=Qe(s);if(i?.aborted)throw new _(e.name,e.level,i.reason);let b=ze(e),P=Ve(we(e,u),l),G={route:e.name,level:e.level??"",method:b,url:P,headers:{Accept:"application/json",...p??{}},body:c,params:u,timeout:k??n,signal:i,meta:e},$=await ye(),S=$.runsInterceptors?G:await te(U,G);if(S.signal?.aborted)throw new _(e.name,e.level,S.signal.reason);R.start();try{let qe=$.request(S).then(m=>{if(m.status<200||m.status>=300)throw new L(`HTTP ${m.status} for route "${m.route}" (${m.method} ${m.url})`,{route:m.route,level:m.level,status:m.status,url:m.url,method:m.method});return m},m=>{throw m instanceof w?m:Ze(m,i)?new _(e.name,e.level,m):new D(m instanceof Error?m.message:String(m),e.name,e.level,m)});return $.runsInterceptors?await qe:await ne(B,qe)}finally{R.stop();}}function ve(e){if(e===void 0){F.clear(),H.clear();for(let s of a)T.set(s,(T.get(s)??0)+1);}else if(Array.isArray(e))for(let s of e)F.del(s),H.delete(s),T.set(s,(T.get(s)??0)+1);else F.del(e),H.delete(e),T.set(e,(T.get(e)??0)+1);}function Ce(e){return e?F.get(e)!==void 0:a.length>0&&a.every(s=>F.get(s)!==void 0)}function ce(e,s){return be(),ie(e,s)!==void 0}function ke(e){if(e!==void 0){let u=F.get(e)?.routes??{},l={};for(let[c,p]of Object.entries(u))l[c]=JSON.parse(JSON.stringify(p));return l}let s={};for(let i of a){let u=F.get(i);if(u){let l={};for(let[c,p]of Object.entries(u.routes))l[c]=JSON.parse(JSON.stringify(p));s[i]=l;}}return s}M.then(()=>{if(Y=true,o.onSummaryReady?.(),h.length>0)return Promise.all(h.map(e=>N(e))).catch(e=>{console.warn(`[route-forge] eager load failed: ${e.message}`);})}).then(()=>{C(ee);}).catch(()=>{});function je(e,s){return e?he.then(e,s).then(()=>ee):he}let de={load:N,hasRoute:ce};function De(e,s){let i=N(e);i.catch(()=>{});let u=s?(c,p)=>pe(de,e,s,c).then(k=>ue(e,k,p)):(c,p)=>ue(e,c,p),l=u;return Ee(l,{level:e,...s!==void 0?{prefix:s}:{},api:u,route:s?(c,p)=>W(e,oe(de,e,s,c),p):(c,p)=>W(e,c,p),url:s?(c,p)=>W(e,oe(de,e,s,c),p):(c,p)=>W(e,c,p),hasRoute:c=>ce(e,c),getRoutes:()=>ke(e),load:()=>N(e),invalidate:()=>ve(e),isLoaded:()=>Ce(e),isLoading:()=>R.isLoading(),onLoadingChange:c=>R.subscribe(c)}),Object.defineProperty(l,"levelLoaded",{value:i,writable:false,enumerable:true,configurable:true}),l}function _e(e,s,i,u){let l=s.then(()=>e);return i?l.then(i,u).then(()=>e):l}function Oe(e,s,i){Object.defineProperty(e,"onLevelLoaded",{value:(u,l)=>_e(e,s,u,l),writable:false,enumerable:false,configurable:false}),Object.defineProperty(e,"useRoutePrefix",{value:u=>Pe(i,u),writable:false,enumerable:false,configurable:false});}function Pe(e,s){let i=De(e,s),u=i.levelLoaded;return Oe(i,u,e),i}let ee={api:ue,load:N,route:W,url:W,invalidate:ve,isLoaded:Ce,hasRoute:ce,getRoutes:ke,isLoading:()=>R.isLoading(),onLoadingChange:e=>R.subscribe(e),interceptors:{request:U,response:B},ready:je,use(e,s){return e===void 0?ee:Pe(e,s)}};return ee}function ze(o){return (o.methods.find(n=>n.toUpperCase()!=="HEAD")??o.methods[0]??"GET").toUpperCase()}function Ve(o,t){if(!t)return o;let n=new URLSearchParams;for(let[d,f]of Object.entries(t))f!=null&&n.append(d,String(f));let r=n.toString();return r?o.includes("?")?`${o}&${r}`:`${o}?${r}`:o}function Qe(o){let{params:t,query:n,body:r,headers:d,timeout:f,...R}=o,g=t?{...t}:{};for(let[h,y]of Object.entries(R))h in g||(g[h]=y);let q,I,a;return n!==void 0&&(typeof n=="object"&&n!==null?q=n:"query"in g||(g.query=n)),r!==void 0&&(typeof r!="string"&&typeof r!="number"?I=r:"body"in g||(g.body=r)),d!==void 0&&(typeof d=="object"&&d!==null?a=d:"headers"in g||(g.headers=d)),{pathParams:g,query:q,body:I,headers:a,timeout:f}}function Ze(o,t){if(t?.aborted)return true;let n=o;return n?n.name==="AbortError"||n.code==="ERR_CANCELED":false}
|
|
2
|
-
exports.AdapterNotFoundError=
|
|
1
|
+
var RouteForge=(function(exports){'use strict';var V="route-forge:";function Le(r){return r==="memory"||typeof globalThis>"u"?null:r==="sessionStorage"?globalThis.sessionStorage??null:r==="localStorage"?globalThis.localStorage??null:null}var B=class{constructor(e){this.memory=new Map;this.onStorageEvent=e=>{e.key&&e.key.startsWith(V)&&this.memory.delete(e.key.slice(V.length));};this.storage=e.storage,this.fallbackTtl=e.ttl,this.backend=Le(e.storage),this.backend&&typeof globalThis.addEventListener=="function"&&globalThis.addEventListener("storage",this.onStorageEvent);}key(e){return `${V}${e}`}get(e){if(this.storage==="memory"||!this.backend)return this.getFromMemory(e);let t=this.getFromMemory(e);if(t)return t;let n=this.backend.getItem(this.key(e));if(n)try{let o=JSON.parse(n);if(this.isExpired(o)){this.del(e);return}return this.memory.set(e,o),o}catch{return}}getFromMemory(e){let t=this.memory.get(e);if(t){if(this.isExpired(t)){this.memory.delete(e);return}return t}}set(e){let t;e.cache!==void 0&&e.cache!==null?t=e.cache>0?Math.min(e.cache,this.fallbackTtl):e.cache:t=this.fallbackTtl;let n={level:e.level,routes:e.routes,ttl:t,cachedAt:Date.now()};if(this.memory.set(e.level,n),!(this.storage==="memory"||!this.backend))try{this.backend.setItem(this.key(e.level),JSON.stringify(n));}catch{}}del(e){if(this.memory.delete(e),this.backend)try{this.backend.removeItem(this.key(e));}catch{}}clear(){if(this.memory.clear(),this.backend)try{let e=[];for(let t=0;t<this.backend.length;t++){let n=this.backend.key(t);n&&n.startsWith(V)&&e.push(n);}for(let t of e)this.backend.removeItem(t);}catch{}}isExpired(e){return e.ttl===null||e.ttl===0?false:Date.now()-e.cachedAt>e.ttl*1e3}};var C=class extends Error{constructor(e,t){super(e),this.name=this.constructor.name,this.code=t.code,t.route!==void 0&&(this.route=t.route),t.level!==void 0&&(this.level=t.level),t.context!==void 0&&(this.context=t.context),t.cause!==void 0&&(this.cause=t.cause);}},x=class extends C{constructor(e,t){super(`Route "${e}" not found${t?` in level "${t}"`:""}`,{code:"RF_FE_001",route:e,level:t});}},L=class extends C{constructor(e){super(`Level "${e}" not declared in options.levels`,{code:"RF_FE_002",level:e});}},N=class extends C{constructor(e,t){super(`Missing path parameter(s) ${t.join(", ")} for route "${e}"`,{code:"RF_FE_003",route:e,context:{missingParams:t}});}},A=class extends C{constructor(e){super(`Adapter "${e}" not available; install axios or use 'builtin'`,{code:"RF_FE_005",context:{adapter:e}});}},G=class extends C{constructor(e){super("Request interceptor must return a RequestConfig object",{code:"RF_FE_006",route:e});}},I=class extends C{constructor(e,t,n,o){super(e,{code:"RF_FE_007",route:t,level:n,cause:o});}},E=class extends C{constructor(e,t){super(e,{code:"RF_FE_008",route:t.route,level:t.level,context:{status:t.status,url:t.url,method:t.method},cause:t.cause});}},M=class extends C{constructor(e,t,n){super(`Request aborted${e?` for route "${e}"`:""}`,{code:"RF_FE_009",route:e,level:t,cause:n});}};var D=class{constructor(){this.handlers=[];this.nextId=0;}use(e,t){let n=this.nextId++;return this.handlers.push({id:n,onFulfilled:e,onRejected:t}),n}eject(e){let t=this.handlers.findIndex(n=>n.id===e);t>=0&&this.handlers.splice(t,1);}clear(){this.handlers=[];}forEach(e){for(let t of this.handlers)e(t);}get size(){return this.handlers.length}};async function Q(r,e){let t=[];r.forEach(o=>t.push(o)),t.reverse();let n=Promise.resolve(e);for(let o of t){let s=o.onFulfilled,c=o.onRejected;n=n.then(async u=>{if(!s)return u;let g=await s(u);if(g===null||typeof g!="object")throw new G;return g},u=>c?c(u):Promise.reject(u));}return n}async function Z(r,e){let t=[];r.forEach(o=>t.push(o));let n=e;for(let o of t){let s=o.onFulfilled,c=o.onRejected;n=n.then(u=>s?s(u):u,u=>c?c(u):Promise.reject(u));}return n}function K(){return new D}function oe(r,e){if(e?.aborted)return true;let t=r;return t?t.name==="AbortError"||t.code==="ERR_CANCELED":false}function Ae(...r){let e=r.filter(n=>!!n);if(e.length===0)return;if(e.length===1)return e[0];if(typeof AbortSignal<"u"&&typeof AbortSignal.any=="function")return AbortSignal.any(e);let t=new AbortController;for(let n of e){if(n.aborted)return t.abort(n.reason),t.signal;n.addEventListener("abort",()=>t.abort(n.reason),{once:true});}return t.signal}function Ie(r){return r===null?false:typeof FormData<"u"&&r instanceof FormData||typeof URLSearchParams<"u"&&r instanceof URLSearchParams||typeof Blob<"u"&&r instanceof Blob||typeof ArrayBuffer<"u"&&(r instanceof ArrayBuffer||ArrayBuffer.isView(r))||typeof ReadableStream<"u"&&r instanceof ReadableStream}async function he(r){let e=Ae(r.signal,r.timeout&&r.timeout>0?AbortSignal.timeout(r.timeout):void 0),t=r.url;if(r.paramsSerializer&&r.params){let i=r.paramsSerializer(r.params);i&&(t=t.includes("?")?`${t}&${i}`:`${t}?${i}`);}let n=new Headers(r.headers),o={method:r.method,headers:n};e&&(o.signal=e),r.body!==void 0&&!["GET","HEAD"].includes(r.method.toUpperCase())&&(typeof r.body=="string"||Ie(r.body)?o.body=r.body:(o.body=JSON.stringify(r.body),n.has("Content-Type")||n.set("Content-Type","application/json")));let s;try{s=await fetch(t,o);}catch(i){throw oe(i)?i:new I(i instanceof Error?i.message:String(i),r.route,r.level,i)}let c=await s.text(),u=c;if((s.headers.get("content-type")??"").includes("application/json"))try{u=JSON.parse(c);}catch{}let p={route:r.route,level:r.level,method:r.method,url:t,status:s.status,headers:s.headers,data:u,config:r};if(s.status>=200&&s.status<300)return p;throw new E(`HTTP ${s.status} for route "${r.route}" (${r.method} ${t})`,{route:r.route,level:r.level,status:s.status,url:t,method:r.method})}function se(r){let e=r?.request??K(),t=r?.response??K(),n=he;async function o(i){let f=await Q(e,i),l=Promise.resolve(f).then(n);return Z(t,l)}return {request:o,requestRaw:n,interceptors:{request:e,response:t},runsInterceptors:true,get:(i,f)=>o({...f,url:i,method:"GET"}),post:(i,f)=>o({...f,url:i,method:"POST"}),put:(i,f)=>o({...f,url:i,method:"PUT"}),patch:(i,f)=>o({...f,url:i,method:"PATCH"}),delete:(i,f)=>o({...f,url:i,method:"DELETE"})}}function me(r){if(!r)return new Headers;let e=typeof r.toJSON=="function"?r.toJSON():r;try{return new Headers(e)}catch{return new Headers}}async function ie(){let r,e="axios";try{let n=await import(e);r=n.default??n;}catch{typeof globalThis<"u"&&globalThis.axios&&(r=globalThis.axios);}if(!r||typeof r.request!="function")return null;async function t(n){let o={...n.headers};try{let s=await r.request({url:n.url,method:n.method,headers:o,data:n.body,timeout:n.timeout,signal:n.signal});return {route:n.route,level:n.level,method:n.method,url:n.url,status:s.status,headers:me(s.headers),data:s.data,config:n}}catch(s){if(s&&s.response){let c=s.response;return {route:n.route,level:n.level,method:n.method,url:n.url,status:c.status,headers:me(c.headers),data:c.data,config:n}}throw s}}return {request:t,interceptors:void 0}}async function ae(r){let{adapter:e}=r;if(e&&typeof e=="object")return {request:n=>e.request(n),interceptors:e.interceptors};if(e==="builtin")return se(r.forgeInterceptors);if(e==="axios"){let n=await ie();if(!n)throw new A("axios");return n}let t=await ie().catch(()=>null);return t||se(r.forgeInterceptors)}var W=class{constructor(){this.count=0;this.subscribers=new Set;}start(){this.count++,this.notify();}stop(){this.count=Math.max(0,this.count-1),this.notify();}isLoading(){return this.count>0}getCount(){return this.count}subscribe(e){return this.subscribers.add(e),()=>{this.subscribers.delete(e);}}notify(){let e={loading:this.count>0,count:this.count};for(let t of this.subscribers)try{t(e);}catch{}}};function Re(r,e){let t=e.baseURL.endsWith("/")?e.baseURL.slice(0,-1):e.baseURL,n=e.endpoint.startsWith("/")?e.endpoint:`/${e.endpoint}`;return `${t}${n}/${encodeURIComponent(r)}`}function X(r,e,t){let n=r.parameter_defaults??{},o=[],s={};for(let p of r.parameters){let i=e[p];i==null&&p in n&&(i=n[p]),i==null?r.uri.includes(`{${p}?}`)||o.push(p):s[p]=i;}if(o.length>0)throw new N(r.name,o);let c=r.uri.replace(/\{([^{}]+)\}/g,(p,i)=>{let f=i.endsWith("?"),l=f?i.slice(0,-1):i;if(s[l]!==void 0){let k=s[l];if(typeof k=="object")throw new C(`Path parameter "${l}" must be a primitive value (string, number, boolean), got ${typeof k}`,{code:"RF_FE_003",route:r.name,context:{param:l,value:k}});return encodeURIComponent(String(k))}return f?"":p});if(c=c.replace(/\/+/g,"/").replace(/\/$/,""),/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(t.urlPrefix)){let p=t.urlPrefix.endsWith("/")?t.urlPrefix.slice(0,-1):t.urlPrefix;return c.startsWith("/")?`${p}${c}`:`${p}/${c}`}let u=t.baseURL.endsWith("/")?t.baseURL.slice(0,-1):t.baseURL,g=t.urlPrefix;return c.startsWith("/")?`${u}${g}${c}`:`${u}${g}/${c}`}function ye(r){return (r.methods.find(t=>t.toUpperCase()!=="HEAD")??r.methods[0]??"GET").toUpperCase()}function ve(r,e){if(!e)return r;let t=new URLSearchParams;for(let[o,s]of Object.entries(e))s!=null&&t.append(o,String(s));let n=t.toString();return n?r.includes("?")?`${r}&${n}`:`${r}?${n}`:r}function be(r){let{params:e,query:t,body:n,headers:o,timeout:s,...c}=r,u=e?{...e}:{};for(let[f,l]of Object.entries(c))f in u||(u[f]=l);let g,p,i;return t!==void 0&&(typeof t=="object"&&t!==null?g=t:"query"in u||(u.query=t)),n!==void 0&&(typeof n!="string"&&typeof n!="number"?p=n:"body"in u||(u.body=n)),o!==void 0&&(typeof o=="object"&&o!==null?i=o:"headers"in u||(u.headers=o)),{pathParams:u,query:g,body:p,headers:i,timeout:s}}var j="unassigned";async function we(r,e,t){let{explicitLevels:n,explicitEndpoint:o}=r;try{let s=e.endsWith("/")?e.slice(0,-1):e,c=o.startsWith("/")?o:`/${o}`;return await t("__forge__.summary",`${s}${c}`)}catch(s){if(n&&n.length>0)return console.warn(`[route-forge] summary endpoint unreachable: ${s.message}; using explicit levels`),null;throw new L("(auto-discovery)")}}function Ce(r,e,t){let{explicitLevels:n,explicitEager:o,explicitEndpoint:s}=t,c=r.schemaVersion??1;c>1&&console.warn(`[route-forge] backend schemaVersion=${c} > client supported 1; some features may be unavailable`),r.config.endpoint_prefix&&r.config.endpoint_prefix!==s&&(console.warn(`[route-forge] backend endpoint_prefix "${r.config.endpoint_prefix}" overrides frontend endpoint "${s}"`),e.endpoint=r.config.endpoint_prefix),r.config.url_prefix&&(e.urlPrefix=r.config.url_prefix.endsWith("/")?r.config.url_prefix.slice(0,-1):r.config.url_prefix);let u=Object.keys(r.levels);e.backendHasUnassignedLevel=u.includes(j),Array.isArray(r.unassigned)&&r.unassigned.length>0&&!e.backendHasUnassignedLevel&&(e.summaryUnassigned=r.unassigned);let g=u.slice();if(e.summaryUnassigned&&!e.backendHasUnassignedLevel&&g.push(j),n&&n.length>0){let i=n.filter(l=>g.includes(l)),f=n.filter(l=>!g.includes(l));f.length>0&&console.warn(`[route-forge] levels not in backend summary and dropped: ${f.join(", ")}`),e.levels=i;}else e.levels=g;let p=u.filter(i=>r.levels[i]?.load==="eager");if(!o)e.eager=p;else {let i=new Set([...p,...o]);e.eager=[...i];}}var Y=class{constructor(e){this.inflight=new Map;this.invalidationGens=new Map;this.cache=e.cache,this.state=e.state,this.baseURL=e.baseURL,this.fetchMeta=e.fetchMeta,this.autoDiscoveryPromise=e.autoDiscoveryPromise,this.getAutoDiscoveryError=e.getAutoDiscoveryError;}assertLevelDeclared(e){if(!this.state.levels.includes(e))throw new L(e)}async fetchLevel(e){return await this.fetchMeta(`__forge__.load.${e}`,Re(e,{baseURL:this.baseURL,endpoint:this.state.endpoint}),e)}async loadOne(e){let t=this.getAutoDiscoveryError();if(t)throw t;if(this.assertLevelDeclared(e),this.cache.get(e))return;let n=this.inflight.get(e);if(n)return n;let o=this.invalidationGens.get(e)??0,s=(async()=>{try{if(e===j&&!this.state.backendHasUnassignedLevel&&this.state.summaryUnassigned){let u={};for(let g of this.state.summaryUnassigned)u[g.name]={...g,level:j};this.cache.set({level:j,routes:u,cache:null});return}let c=await this.fetchLevel(e);(this.invalidationGens.get(e)??0)===o&&this.cache.set(c);}finally{this.inflight.delete(e);}})();return this.inflight.set(e,s),s}async load(e){await this.autoDiscoveryPromise;let t=Array.isArray(e)?e:[e];await Promise.all(t.map(n=>this.loadOne(n)));}invalidate(e){if(e===void 0){this.cache.clear(),this.inflight.clear();for(let t of this.state.levels)this.invalidationGens.set(t,(this.invalidationGens.get(t)??0)+1);}else if(Array.isArray(e))for(let t of e)this.cache.del(t),this.inflight.delete(t),this.invalidationGens.set(t,(this.invalidationGens.get(t)??0)+1);else this.cache.del(e),this.inflight.delete(e),this.invalidationGens.set(e,(this.invalidationGens.get(e)??0)+1);}isLoaded(e){return e?this.cache.get(e)!==void 0:this.state.levels.length>0&&this.state.levels.every(t=>this.cache.get(t)!==void 0)}findRouteMeta(e,t){let o=this.cache.get(e)?.routes[t];if(o)return {...o,level:e}}getRoutes(e){if(e!==void 0){let o=this.cache.get(e)?.routes??{},s={};for(let[c,u]of Object.entries(o))s[c]=JSON.parse(JSON.stringify(u));return s}let t={};for(let n of this.state.levels){let o=this.cache.get(n);if(o){let s={};for(let[c,u]of Object.entries(o.routes))s[c]=JSON.parse(JSON.stringify(u));t[n]=s;}}return t}};function ke(r){let{ensureAdapter:e,requestInterceptors:t,responseInterceptors:n,load:o,findRouteMeta:s,baseURL:c,state:u,timeout:g,loadingTracker:p,autoDiscoveryPromise:i}=r;async function f(l,k,d){let{pathParams:R,query:b,body:w,headers:P,timeout:m}=be(k);if(d?.aborted)throw new M(l.name,l.level,d.reason);let y=ye(l),q=ve(X(l,R,{baseURL:c,urlPrefix:u.urlPrefix}),b),U={route:l.name,level:l.level??"",method:y,url:q,headers:{Accept:"application/json",...P??{}},body:w,params:R,timeout:m??g,signal:d,meta:l},S=await e(),T=S.runsInterceptors?U:await Q(t,U);if(T.signal?.aborted)throw new M(l.name,l.level,T.signal.reason);p.start();try{let O=S.request(T).then(h=>{if(h.status<200||h.status>=300)throw new E(`HTTP ${h.status} for route "${h.route}" (${h.method} ${h.url})`,{route:h.route,level:h.level,status:h.status,url:h.url,method:h.method});return h},h=>{throw h instanceof C?h:oe(h,d)?new M(l.name,l.level,h):new I(h instanceof Error?h.message:String(h),l.name,l.level,h)});return S.runsInterceptors?await O:await Z(n,O)}finally{p.stop();}}return function(k,d,R={}){let b,w=false,P,y=(async()=>{b=new AbortController,w&&b.abort(P),await i,await o(k);let q=s(k,d);if(!q)throw new x(d,k);return f(q,R,b.signal)})();return y.abort=()=>{b?b.abort():w=true;},y}}async function ue(r,e,t,n,o="."){if(!n)return t;let s=`${t}${o}${n}`;if(!n.startsWith(`${t}${o}`)||(await r.load(e),r.hasRoute(e,s)))return s;if(r.hasRoute(e,n))return n;throw new x(s,e)}function ee(r,e,t,n,o="."){if(!n)return t;let s=`${t}${o}${n}`;if(!n.startsWith(`${t}${o}`)||r.hasRoute(e,s))return s;if(r.hasRoute(e,n))return n;throw new x(s,e)}function Pe(r,e){for(let t of Object.keys(e)){let n=e[t];Object.defineProperty(r,t,{value:n!==null&&typeof n=="object"?Object.freeze(n):n,writable:false,enumerable:false,configurable:false});}return r}function Fe(r){let{load:e,api:t,route:n,hasRoute:o,getRoutes:s,invalidate:c,isLoaded:u,loadingTracker:g}=r,p={load:e,hasRoute:o};function i(d,R){let b=e(d);b.catch(()=>{});let w=R?(m,y)=>ue(p,d,R,m).then(q=>t(d,q,y)):(m,y)=>t(d,m,y),P=w;return Pe(P,{level:d,...R!==void 0?{prefix:R}:{},api:w,route:R?(m,y)=>n(d,ee(p,d,R,m),y):(m,y)=>n(d,m,y),url:R?(m,y)=>n(d,ee(p,d,R,m),y):(m,y)=>n(d,m,y),hasRoute:m=>o(d,m),getRoutes:()=>s(d),load:()=>e(d),invalidate:()=>c(d),isLoaded:()=>u(d),isLoading:()=>g.isLoading(),onLoadingChange:m=>g.subscribe(m)}),Object.defineProperty(P,"levelLoaded",{value:b,writable:false,enumerable:true,configurable:true}),P}function f(d,R,b,w){let P=R.then(()=>d);return b?P.then(b,w).then(()=>d):P}function l(d,R,b){Object.defineProperty(d,"onLevelLoaded",{value:(w,P)=>f(d,R,w,P),writable:false,enumerable:false,configurable:false}),Object.defineProperty(d,"useRoutePrefix",{value:w=>k(b,w),writable:false,enumerable:false,configurable:false});}function k(d,R){let b=i(d,R),w=b.levelLoaded;return l(b,w,d),b}return k}var Me=3e4,De=3600;function Se(r){if(!r.endpoint)throw new TypeError("options.endpoint is required");let{adapter:e="auto",timeout:t=Me,baseURL:n="",interceptors:o,cache:s={}}=r,c=new W,u=r.levels,g=r.eager,p=r.endpoint,i={levels:u??[],eager:g??[],endpoint:p,urlPrefix:"",summaryUnassigned:void 0,backendHasUnassignedLevel:false},f={explicitLevels:u,explicitEager:g,explicitEndpoint:p},l=false,k,d,R=new Promise((a,v)=>{k=a,d=v;});R.catch(()=>{});let b=s.ttl??De,w=s.storage??"memory",P=new B({storage:w,ttl:b}),m=new D,y=new D;if(o?.request)for(let a of o.request)if(typeof a=="function")m.use(a);else {let[v,F]=a;m.use(v,F);}if(o?.response)for(let a of o.response)if(typeof a=="function")y.use(a);else {let[v,F]=a;y.use(v,F);}let q=ae({adapter:e,forgeInterceptors:{request:m,response:y}}),U=false,S=null;async function T(){return U||(S=await q.catch(a=>{if(a instanceof A)throw a;return ae({adapter:"builtin",forgeInterceptors:{request:m,response:y}})}),U=true),S}function O(){if(!l&&!u?.length)throw new C("Route data not available. Auto-discovery has not completed. Use forge.ready() or forge.use(level) first.",{code:"RF_FE_010"})}async function te(a,v,F=""){let H=await T(),qe={route:a,level:F,method:"GET",url:v,headers:{Accept:"application/json"},params:{},timeout:t,meta:{name:a,uri:v,methods:["GET"],parameters:[],level:F}},_=await(H.requestRaw??H.request)(qe);if(!_||_.status<200||_.status>=300)throw new E(`Failed to fetch "${a}": HTTP ${_?.status}`,{level:F,status:_?.status,url:v,method:"GET"});return _.data}let h=we(f,n,te).then(a=>{a!==null&&Ce(a,i,f);}),ce=null;h.catch(a=>{ce=a;});let $=new Y({cache:P,state:i,baseURL:n,fetchMeta:te,autoDiscoveryPromise:h,getAutoDiscoveryError:()=>ce}),J=a=>$.load(a),re=(a,v)=>$.findRouteMeta(a,v),de=a=>$.invalidate(a),le=a=>$.isLoaded(a);function pe(a){return a===void 0?$.getRoutes():$.getRoutes(a)}function ne(a,v,F){O();let H=re(a,v);if(!H)throw new x(v,a);return X(H,F??{},{baseURL:n,urlPrefix:i.urlPrefix})}let ge=ke({ensureAdapter:T,requestInterceptors:m,responseInterceptors:y,load:J,findRouteMeta:re,baseURL:n,state:i,timeout:t,loadingTracker:c,autoDiscoveryPromise:h});function fe(a,v){return O(),re(a,v)!==void 0}h.then(()=>{if(l=true,i.eager.length>0)return Promise.allSettled(i.eager.map(a=>J(a))).then(a=>{a.forEach((v,F)=>{v.status==="rejected"&&console.error(`[route-forge] eager load failed for level "${i.eager[F]}":`,v.reason);});})}).then(()=>{k(z);}).catch(a=>{d(a);});function xe(a,v){return a?R.then(a,v).then(()=>z):R}let Ee=Fe({load:J,api:ge,route:ne,hasRoute:fe,getRoutes:pe,invalidate:de,isLoaded:le,loadingTracker:c}),z={api:ge,load:J,route:ne,url:ne,invalidate:de,isLoaded:le,hasRoute:fe,getRoutes:pe,isLoading:()=>c.isLoading(),onLoadingChange:a=>c.subscribe(a),interceptors:{request:m,response:y},ready:xe,use(a,v){return a===void 0?z:Ee(a,v)}};return z}
|
|
2
|
+
exports.AdapterNotFoundError=A;exports.ForgeError=C;exports.HTTPError=E;exports.InterceptorManagerImpl=D;exports.InvalidInterceptorReturnError=G;exports.LoadingTracker=W;exports.MissingRouteParamError=N;exports.NetworkError=I;exports.RequestAbortedError=M;exports.RouteCache=B;exports.UnknownLevelError=L;exports.UnknownRouteError=x;exports.createInterceptorManager=K;exports.createRouteForge=Se;exports.resolveRouteName=ue;exports.resolveRouteNameSync=ee;return exports;})({});
|
|
@@ -75,7 +75,11 @@ interface RouteMeta {
|
|
|
75
75
|
parameter_defaults?: Record<string, unknown>;
|
|
76
76
|
/** 所属层级(前端填充,便于隔离缓存) */
|
|
77
77
|
level?: string;
|
|
78
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* 后端 manifest 契约字段:路由级缓存 TTL(秒)。
|
|
80
|
+
* 当前前端按层级消费 TTL(LevelRoutesResponse.cache,见 cache.ts),
|
|
81
|
+
* 路由级字段为后端契约预留——将来支持路由级缓存时无需改类型。
|
|
82
|
+
*/
|
|
79
83
|
cache?: number | null;
|
|
80
84
|
}
|
|
81
85
|
/**
|
|
@@ -334,16 +338,6 @@ interface RouteForgeOptions {
|
|
|
334
338
|
strict?: boolean;
|
|
335
339
|
timeout?: number;
|
|
336
340
|
baseURL?: string;
|
|
337
|
-
/**
|
|
338
|
-
* 摘要端点(auto-discovery)完成后的回调。
|
|
339
|
-
* 推荐用法:在回调中 mount 应用,确保 route() / hasRoute() 等同步方法可用。
|
|
340
|
-
* @example
|
|
341
|
-
* createRouteForgePlugin({
|
|
342
|
-
* endpoint: '/_forge/routes',
|
|
343
|
-
* onSummaryReady: () => app.mount('#app'),
|
|
344
|
-
* });
|
|
345
|
-
*/
|
|
346
|
-
onSummaryReady?: () => void;
|
|
347
341
|
}
|
|
348
342
|
/**
|
|
349
343
|
* 二级路由类型映射(可由 codegen 生成或通过 module augmentation 增强)
|
|
@@ -445,10 +439,5 @@ interface UseForgeApiBoundReturn<L extends string, PendingType = unknown, ErrorT
|
|
|
445
439
|
error: ErrorType;
|
|
446
440
|
call: UseForgeApiBoundCall<L>;
|
|
447
441
|
}
|
|
448
|
-
/** useForgeByPrefix 返回类型 */
|
|
449
|
-
interface UseForgeByPrefixReturn {
|
|
450
|
-
api: (suffix: string, params?: ApiCallParams) => Promise<unknown>;
|
|
451
|
-
route: (suffix: string, params?: Record<string, unknown>) => string;
|
|
452
|
-
}
|
|
453
442
|
|
|
454
|
-
export { type AdapterOption as A, type BoundForge as B, type CacheStorage as C, type Fetcher as F, type InterceptorManager as I, type LevelRoutesResponse as L, type RouteMeta as R, type SummaryResponse as S, type UseForgeApiBoundCall as U, type
|
|
443
|
+
export { type AdapterOption as A, type BoundForge as B, type CacheStorage as C, type Fetcher as F, type InterceptorManager as I, type LevelRoutesResponse as L, type RouteMeta as R, type SummaryResponse as S, type UseForgeApiBoundCall as U, type RouteForgeOptions as a, type RouteForge as b, type InterceptorHandler as c, type ApiCallParams as d, type ForgeApiParams as e, type ForgeApiResponse as f, type ForgeRequest as g, type ForgeRouteMap as h, type ForgeRouteName as i, type LoadingChangeCallback as j, type LoadingChangeEvent as k, LoadingTracker as l, type RequestConfig as m, type ResponseData as n, type UseForgeApiBoundReturn as o, type UseForgeApiCall as p, type UseForgeApiReturn as q };
|
|
@@ -75,7 +75,11 @@ interface RouteMeta {
|
|
|
75
75
|
parameter_defaults?: Record<string, unknown>;
|
|
76
76
|
/** 所属层级(前端填充,便于隔离缓存) */
|
|
77
77
|
level?: string;
|
|
78
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* 后端 manifest 契约字段:路由级缓存 TTL(秒)。
|
|
80
|
+
* 当前前端按层级消费 TTL(LevelRoutesResponse.cache,见 cache.ts),
|
|
81
|
+
* 路由级字段为后端契约预留——将来支持路由级缓存时无需改类型。
|
|
82
|
+
*/
|
|
79
83
|
cache?: number | null;
|
|
80
84
|
}
|
|
81
85
|
/**
|
|
@@ -334,16 +338,6 @@ interface RouteForgeOptions {
|
|
|
334
338
|
strict?: boolean;
|
|
335
339
|
timeout?: number;
|
|
336
340
|
baseURL?: string;
|
|
337
|
-
/**
|
|
338
|
-
* 摘要端点(auto-discovery)完成后的回调。
|
|
339
|
-
* 推荐用法:在回调中 mount 应用,确保 route() / hasRoute() 等同步方法可用。
|
|
340
|
-
* @example
|
|
341
|
-
* createRouteForgePlugin({
|
|
342
|
-
* endpoint: '/_forge/routes',
|
|
343
|
-
* onSummaryReady: () => app.mount('#app'),
|
|
344
|
-
* });
|
|
345
|
-
*/
|
|
346
|
-
onSummaryReady?: () => void;
|
|
347
341
|
}
|
|
348
342
|
/**
|
|
349
343
|
* 二级路由类型映射(可由 codegen 生成或通过 module augmentation 增强)
|
|
@@ -445,10 +439,5 @@ interface UseForgeApiBoundReturn<L extends string, PendingType = unknown, ErrorT
|
|
|
445
439
|
error: ErrorType;
|
|
446
440
|
call: UseForgeApiBoundCall<L>;
|
|
447
441
|
}
|
|
448
|
-
/** useForgeByPrefix 返回类型 */
|
|
449
|
-
interface UseForgeByPrefixReturn {
|
|
450
|
-
api: (suffix: string, params?: ApiCallParams) => Promise<unknown>;
|
|
451
|
-
route: (suffix: string, params?: Record<string, unknown>) => string;
|
|
452
|
-
}
|
|
453
442
|
|
|
454
|
-
export { type AdapterOption as A, type BoundForge as B, type CacheStorage as C, type Fetcher as F, type InterceptorManager as I, type LevelRoutesResponse as L, type RouteMeta as R, type SummaryResponse as S, type UseForgeApiBoundCall as U, type
|
|
443
|
+
export { type AdapterOption as A, type BoundForge as B, type CacheStorage as C, type Fetcher as F, type InterceptorManager as I, type LevelRoutesResponse as L, type RouteMeta as R, type SummaryResponse as S, type UseForgeApiBoundCall as U, type RouteForgeOptions as a, type RouteForge as b, type InterceptorHandler as c, type ApiCallParams as d, type ForgeApiParams as e, type ForgeApiResponse as f, type ForgeRequest as g, type ForgeRouteMap as h, type ForgeRouteName as i, type LoadingChangeCallback as j, type LoadingChangeEvent as k, LoadingTracker as l, type RequestConfig as m, type ResponseData as n, type UseForgeApiBoundReturn as o, type UseForgeApiCall as p, type UseForgeApiReturn as q };
|