@real-router/validation-plugin 0.33.1 → 0.33.2
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/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/esm/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{getPluginApi as e,getRoutesApi as t}from"@real-router/core/api";import{internalDefect as n,putField as r,raiser as i}from"@real-router/core/utils";import{areParamValuesEqual as a,buildParamMeta as o,findMisChanneledKey as s,getInternals as c,validateRoute as l}from"@real-router/core/validation";import{events as u,resolveForwardChain as d}from"@real-router/core";const f=Object.freeze({maxDependencies:100,maxPlugins:50,maxListeners:1e4,warnListeners:1e3,maxLifecycleHandlers:200});function p(e){return{warn:Math.floor(e*.2),error:Math.floor(e*.5)}}function m(e){return typeof e==`string`}function h(e){return typeof e==`boolean`}function ee(e,t){return e in t}const g=Object.getPrototypeOf,_=Object.values,v=Object.hasOwn,te=Date,ne=Date.prototype.getTime;function re(e){if(Array.isArray(e))return!0;let t=g(e);return t===null||t===Object.prototype}function ie(e,t){let n=Array.isArray(e)?e:_(e);for(let e of n)t.push(e)}function ae(e){let t=typeof e;return t===`string`||t===`boolean`||t===`number`&&Number.isFinite(e)}var y=class{container;constructor(e){this.container=e}};function oe(e,t,n,r){return n.has(e)?!1:r.has(e)?!0:re(e)?(n.add(e),t.push(new y(e)),ie(e,t),!0):e instanceof te&&(ne.call(e),!0)}function se(e){let t=[e],n=new WeakSet,r=new WeakSet;for(;t.length>0;){let e=t.pop();if(e instanceof y)n.delete(e.container),r.add(e.container);else if(e!=null){if(typeof e==`object`){if(!oe(e,t,n,r))return!1}else if(!ae(e))return!1}}return!0}function b(e){if(e==null)return!0;let t=typeof e;return t===`string`||t===`boolean`||t===`number`&&Number.isFinite(e)}function x(e){try{return ce(e)}catch{return!1}}function ce(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=g(e);if(t!==null&&t!==Object.prototype)return!1;let n=!1;for(let t in e){if(!v(e,t))continue;let r=e[t];if(!b(r)){let e=typeof r;if(e===`function`||e===`symbol`)return!1;n=!0;break}}return!n||se(e)}const le=[`replace`,`reload`,`force`,`forceDeactivate`,`redirected`,`revalidate`];function ue(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;for(let e of le){let n=t[e];if(n!==void 0&&typeof n!=`boolean`)return!1}let n=t.signal;return n===void 0||n instanceof AbortSignal}const de=/\S/,fe=/^[A-Z_a-z][\w-]*(?:\.[A-Z_a-z][\w-]*)*$/;function S(e,t){return i(`router`,e).type`${t}`}function pe(e){return typeof e==`string`?e===``?!0:e.length>1e4?!1:e.startsWith(`@@`)?!0:fe.test(e):!1}function me(e){return pe(e.name)&&typeof e.path==`string`&&x(e.params)}function he(e){return typeof e!=`object`||!e?!1:me(e)}function C(e,t){if(typeof e!=`string`)throw S(t,`Route name must be a string, got ${typeof e}`);if(e!==``){if(!de.test(e))throw S(t,`Route name cannot contain only whitespace`);if(e.length>1e4)throw S(t,`Route name exceeds maximum length of 10000 characters. This is a technical safety limit.`);if(!e.startsWith(`@@`)&&!fe.test(e))throw S(t,`Invalid route name "${e}". Each segment must start with a letter or underscore, followed by letters, numbers, underscores, or hyphens. Segments are separated by dots (e.g., "users.profile").`)}}function w(e){if(e===null)return`null`;if(typeof e!=`object`)return typeof e;try{if(Array.isArray(e))return`array[${e.length}]`;let t=e.constructor;if(typeof t==`function`){let e=t.name;if(typeof e==`string`&&e!==``&&e!==`Object`)return e}}catch{}return`object`}const ge=Object.entries,_e=[`defaultParams`,`defaultSearch`],ve=e=>new Map(ge(e)),ye=(e,t)=>{let n=ge(e);return n.length!==t.size||n.some(([e,n])=>!t.has(e)||!Object.is(t.get(e),n))};var be=class{#e=new Map;#t=new Set;watch(e){for(let t of _e){let n=e[t],r=n?.deref();n!==void 0&&r!==void 0&&this.#e.set(t,{ref:n,before:ve(r)})}}check(e){for(let[t,{ref:n,before:r}]of this.#e){if(this.#t.has(t))continue;let i=n.deref();i!==void 0&&ye(i,r)&&(this.#t.add(t),e.warn(`router.navigateToDefault`,`mutating \`${t}\` after createRouter() no longer affects routing — the router copied it at construction. Use the callback form (\`${t}: () => ({ … })\`), which is resolved at the point of use.`))}}};const xe=i(`cloneRouter`),Se=i(`router`,`getDependency`),Ce=i(`router`,`setDependency`),T=Object.keys,we=Object.getOwnPropertyDescriptor,Te=Object.getPrototypeOf,Ee=Object;function De(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=Te(e);return t===null||t.constructor===Ee}function Oe(e,t){if(typeof e!=`string`)throw i(`router`,t).type`dependency name must be a string, got ${typeof e}`}function ke(e){if(typeof e!=`string`)throw Ce.type`dependency name must be a string, got ${typeof e}`}function Ae(e,t){if(!De(e))throw i(`router`,t).type`Invalid argument: expected plain object, received ${w(e)}`;for(let n of T(e))if(we(e,n)?.get)throw i(`router`,t).type`Getters not allowed: "${n}"`}function je(e,t,n,r){if(n===0)return;let a=new Set(t),o=0;for(let t of T(e))a.has(t)||(o+=1);let s=t.length;if(s+o>n)throw i(`router`,r).range`Dependency limit exceeded (${n}). Current: ${s}, this batch adds ${o}.`}function Me(e,t){if(e===void 0)throw Se.ref`dependency "${t}" not found`}function Ne(e,t,n,r){if(t===0)return;let{warn:a,error:o}=p(t);if(e>=t)throw i(`router`,n).range`Dependency limit exceeded (${t}). Current: ${e}.`;e===o?r.error(`router.${n}`,`${e} dependencies registered! This indicates architectural problems. Hard limit at ${t}.`):e===a&&r.warn(`router.${n}`,`${e} dependencies registered. Consider if all are necessary.`)}function Pe(e){if(e!==void 0){if(!De(e))throw xe.type`Invalid dependencies: expected plain object or undefined, received ${typeof e}`;for(let t of T(e))if(we(e,t)?.get)throw xe.type`Getters not allowed in dependencies: "${t}"`}}function Fe(e,t,n){n.warn(`router.${t}`,`Router dependency already exists and is being overwritten:`,e)}function Ie(e,t,n){n.warn(`router.${t}`,`Overwritten:`,e.join(`, `))}function Le(e,t){t.warn(`router.removeDependency`,`Attempted to remove non-existent dependency: "${typeof e==`string`?e:String(e)}"`)}const Re=i(`router`,`addEventListener`),ze=Object.values,Be=new Set(ze(u));function Ve(e){if(!Be.has(e))throw Re.type`Invalid event name: ${String(e)}. Must be one of: $start, $stop, $$start, $$leaveApprove, $$cancel, $$success, $$error`}function He(e,t){if(Ve(e),typeof t!=`function`)throw Re.type`callback must be a function, got ${typeof t}`}function Ue(e,t,n,r,i=f.maxListeners){if(i===0)return;let{warn:a,error:o}=p(i);e>=o?r.error(`router.${n}`,`${e} listeners registered for "${t}"! This is excessive. Hard limit at ${i}.`):e>=a&&r.warn(`router.${n}`,`${e} listeners registered for "${t}". Consider whether all are necessary — a growing count usually means a missing unsubscribe.`)}const E=i(`router`,`addRoute`),We=Object.keys;function D(e,t){return typeof e==`string`&&e!==``&&typeof t==`string`?`${e}.${t}`:t}function Ge(e,t){if(e!==void 0){if(typeof e!=`string`&&typeof e!=`function`)throw E.type`forwardTo must be a string or function for route "${t}", got ${w(e)}`;if(typeof e==`function`){let n=e.constructor.name===`AsyncFunction`,r=e.toString().includes(`__awaiter`);if(n||r)throw E.type`forwardTo callback cannot be async for route "${t}". Async functions break matchPath/buildPath.`}}}function Ke(e,t,n){if(e!==void 0&&(typeof e!=`object`||!e||Array.isArray(e)))throw E.type`${t} must be an object for route "${n}", got ${w(e)}`}function qe(e,t){if(e.canActivate!==void 0&&typeof e.canActivate!=`function`)throw E.type`canActivate must be a function for route "${t}", got ${w(e.canActivate)}`;if(e.canDeactivate!==void 0&&typeof e.canDeactivate!=`function`)throw E.type`canDeactivate must be a function for route "${t}", got ${w(e.canDeactivate)}`;Ke(e.defaultParams,`defaultParams`,t),Ke(e.defaultSearch,`defaultSearch`,t);let{decodeParams:n,encodeParams:r}=e;if(typeof n==`function`&&n.constructor.name===`AsyncFunction`)throw E.type`decodeParams cannot be async for route "${t}". Async functions break matchPath/buildPath.`;if(typeof r==`function`&&r.constructor.name===`AsyncFunction`)throw E.type`encodeParams cannot be async for route "${t}". Async functions break matchPath/buildPath.`;if(Ge(e.forwardTo,t),e.children)for(let n of e.children)qe(n,D(t,n.name))}function Je(e){let t=new Set;for(let n of e)for(let e of o(n).urlParams)t.add(e);return t}function Ye(e,t,r=``,i=[]){for(let n of e){let e=r?`${r}.${n.name}`:n.name,a=[...i,n.path];if(e===t)return a;if(n.children&&t.startsWith(`${e}.`))return Ye(n.children,t,e,a)}throw n.plain`collectPathsToRoute: route "${t}" not found`}function Xe(e,t=``){let n=new Set;for(let r of e){let e=t?`${t}.${r.name}`:r.name;if(n.add(e),r.children)for(let t of Xe(r.children,e))n.add(t)}return n}function Ze(e,t=``){let n=new Map;for(let r of e){let e=t?`${t}.${r.name}`:r.name;if(r.forwardTo&&typeof r.forwardTo==`string`&&n.set(e,r.forwardTo),r.children)for(let[t,i]of Ze(r.children,e))n.set(t,i)}return n}function Qe(e,t,n,r){return t?new Set(n.getUrlParams(e)):Je(r(e))}const $e=new Set;function et(e,t,n,r,i,a){let o=i.hasRoute(t),s=r.has(t);if(!o&&!s)throw E.ref`forwardTo target "${t}" does not exist for route "${e}"`;let c=new Set([...a,...Je(n(e))]),l=[...Qe(t,o,i,n)].filter(e=>!c.has(e));if(l.length>0)throw E.plain`forwardTo target "${t}" requires params [${l.join(`, `)}] that are not available in source route "${e}"`}function tt(e,t,n,i){let a=Xe(e,i),o=t=>Ye(e,i?t.slice(i.length+1):t),s=i?new Set(n.getUrlParams(i)):$e,c=Ze(e,i),l={...t};for(let[e,t]of c)r(l,e,t);for(let[e,t]of c)et(e,t,o,a,n,s);for(let e of We(l))d(e,l)}function nt(e,t){if(!h(e)&&typeof e!=`function`)throw i(`router`,t).type`Handler must be a boolean or factory function, got ${w(e)}`}function rt(e,t,n=f.maxLifecycleHandlers){if(n!==0&&e>=n)throw i(`router`,t).range`Lifecycle handler limit exceeded (${n}). This indicates too many routes with individual handlers. Consider using plugins for cross-cutting concerns.`}function it(e,t,n,r){if(n===0)return;let{warn:i,error:a}=p(n);e>=a?r.error(`router.${t}`,`${e} lifecycle handlers registered! This is excessive. Hard limit at ${n}.`):e>=i&&r.warn(`router.${t}`,`${e} lifecycle handlers registered. Consider consolidating logic.`)}function at(e,t,n,r){r.warn(`router.${n}`,`Overwriting existing ${t} handler for route "${e}"`)}function ot(e,t,n){n.warn(`router.${t}`,`Guard for "${e}" returned a Promise. Sync check cannot resolve async guards — returning false.`)}function st(e,t){return`Guard for "${e}" must answer true or false, got ${w(t)} — read as a refusal.`}function ct(e,t,n,r){r.warn(`router.${n}`,st(e,t))}function lt(e,t,n){n.warn(`router`,st(e,t))}const O=i(`router`,`start`),k=i(`router`,`navigateToState`),ut=i(`router`,`navigateToDefault`),dt=i(`router`,`navigate`),ft=Object.hasOwn,pt=Object.getPrototypeOf;function mt(e){if(typeof e!=`string`)throw dt.type`Invalid route name: expected string, got ${w(e)}`}function ht(e){if(e!==void 0&&(typeof e!=`object`||!e))throw ut.type`Invalid options: ${w(e)}. Expected NavigationOptions object.`}function gt(e){if(typeof e!=`object`||!e)throw k.type`Invalid state: ${w(e)}. Expected State object.`;let t=e;if(!m(t.name))throw k.type`Invalid state.name: ${w(t.name)}. Expected string.`;if(!x(t.params))throw k.type`Invalid state.params: ${w(t.params)}. Expected plain object.`;if(!m(t.path))throw k.type`Invalid state.path: ${w(t.path)}. Expected string.`}function _t(e,t){if(!ue(e))throw i(`router`,t).type`Invalid options: ${w(e)}. Expected NavigationOptions object.`}const vt=/[\u0000-\u001F\u007F]/;function yt(e,t){for(let n in e){if(!ft(e,n))continue;let r=e[n],a=typeof r;if(a===`symbol`||a===`bigint`)throw i(`router`,t).type`param "${n}" cannot be a ${a} — it does not round-trip through the URL path. Use a string, number, or boolean.`;if(a===`string`&&vt.test(r))throw i(`router`,t).type`param "${n}" must not contain control characters (NUL / C0 / DEL) — they corrupt the URL path.`}}function A(e,t){if(e===void 0)return;let n=e!==null&&pt(e);if(Array.isArray(e)||n!==null&&n!==Object.prototype)throw i(`router`,t).type`params must be a plain object, got ${w(e)}`}function j(e,t){if(e!==void 0&&(yt(e,t),!x(e)))throw i(`router`,t).type`params must be a plain object, got ${w(e)}`}function M(e,t){if(e!==void 0&&(typeof e!=`object`||!e||Array.isArray(e)))throw i(`router`,t).type`search must be a plain object, got ${w(e)}`}function bt(e){if(e!==void 0&&typeof e!=`string`)throw O.type`path must be a string, got ${w(e)}.`;if(typeof e==`string`){if(vt.test(e))throw O.type`path must not contain control characters (NUL / C0 / DEL).`;if(e!==``&&!e.startsWith(`/`))throw O.type`path must start with "/", got "${e}".`}}const xt=Object.entries,St=Object.hasOwn,N=Object.keys,Ct=Object.getPrototypeOf,P={trailingSlash:[`strict`,`never`,`always`,`preserve`],queryParamsMode:[`default`,`strict`,`loose`],urlParamsEncoding:[`default`,`uri`,`uriComponent`,`none`]},wt={arrayFormat:!0,booleanFormat:!0,nullFormat:!0,numberFormat:!0},Tt=new Set(N({defaultRoute:!0,defaultParams:!0,defaultSearch:!0,trailingSlash:!0,caseSensitive:!0,queryParamsMode:!0,queryParams:!0,urlParamsEncoding:!0,allowNotFound:!0,rewritePathOnMatch:!0,logger:!0,limits:!0})),Et={maxDependencies:{min:0,max:1e4},maxPlugins:{min:0,max:1e3},maxListeners:{min:0,max:1e5},warnListeners:{min:0,max:1e5},maxLifecycleHandlers:{min:0,max:1e4}};function Dt(e,t,n){if(typeof t!=`number`||!Number.isInteger(t))throw i(`router`,n).type`limit "${e}" must be an integer, got ${String(t)}`;let r=Et[e];if(t<r.min||t>r.max)throw i(`router`,n).range`limit "${e}" must be between ${r.min} and ${r.max}, got ${t}`}function Ot(e){let t=Ct(e);return t===null||t===Object.prototype}function kt(e,t){if(!e||typeof e!=`object`||!Ot(e))throw i(`router`,t).type`invalid limits: expected plain object, got ${typeof e}`;for(let[n,r]of xt(e)){if(!St(Et,n))throw i(`router`,t).type`unknown limit: "${n}"`;r!==void 0&&Dt(n,r,t)}let{warnListeners:n,maxListeners:r}=e;if(typeof n==`number`&&typeof r==`number`&&r>0&&n>r)throw i(`router`,t).range`"limits.warnListeners" (${n}) must not exceed "limits.maxListeners" (${r}) — the warning channel would be unreachable`}function F(e,t,n,r){if(e!==void 0&&(typeof e!=`string`||!n.includes(e))){let a=n.map(e=>`"${e}"`).join(`, `),o=typeof e==`string`?e:`(${typeof e})`;throw i(`router`,r).type`Invalid "${t}": "${o}". Must be one of: ${a}`}}function At(e,t){if(e!==void 0&&typeof e!=`string`&&typeof e!=`function`)throw i(`router`,t).type`Invalid "defaultRoute": expected string or function, got ${typeof e}`}function jt(e,t,n){if(e!==void 0&&typeof e!=`function`&&(!e||typeof e!=`object`||Array.isArray(e)||!Ot(e)))throw i(`router`,n).type`Invalid "${t}": expected plain object or function, got ${typeof e}`}function Mt(e,t){if(e===void 0)return;if(!e||typeof e!=`object`||Array.isArray(e))throw i(`router`,t).type`Invalid "queryParams": expected plain object`;let n=e;for(let e of N(n))if(!ee(e,wt))throw i(`router`,t).type`Invalid "queryParams.${e}": unknown option`}function Nt(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw i(`router`,t).type`Invalid options: expected plain object`;let n=e;for(let e of N(n))if(!Tt.has(e))throw i(`router`,t).type`Unknown option: "${e}"`;if(At(n.defaultRoute,t),jt(n.defaultParams,`defaultParams`,t),jt(n.defaultSearch,`defaultSearch`,t),F(n.trailingSlash,`trailingSlash`,P.trailingSlash,t),F(n.queryParamsMode,`queryParamsMode`,P.queryParamsMode,t),F(n.urlParamsEncoding,`urlParamsEncoding`,P.urlParamsEncoding,t),n.allowNotFound!==void 0&&typeof n.allowNotFound!=`boolean`)throw i(`router`,t).type`Invalid "allowNotFound": expected boolean, got ${typeof n.allowNotFound}`;if(n.rewritePathOnMatch!==void 0&&typeof n.rewritePathOnMatch!=`boolean`)throw i(`router`,t).type`Invalid "rewritePathOnMatch": expected boolean, got ${typeof n.rewritePathOnMatch}`;if(n.caseSensitive!==void 0&&typeof n.caseSensitive!=`boolean`)throw i(`router`,t).type`Invalid "caseSensitive": expected boolean, got ${typeof n.caseSensitive}`;Mt(n.queryParams,t),n.limits!==void 0&&kt(n.limits,t)}const I=i(`router`,`usePlugin`),Pt=Object.hasOwn,L=`router.usePlugin`,Ft={onStart:!0,onStop:!0,onTransitionStart:!0,onTransitionLeaveApprove:!0,onTransitionSuccess:!0,onTransitionError:!0,onTransitionCancel:!0};function It(e,t,n=f.maxPlugins){if(n!==0&&e+t>n)throw I.range`Plugin limit exceeded (${n}). Current: ${e}, Attempting to add: ${t}. This indicates an architectural problem. Consider consolidating plugins.`}function Lt(e,t){if(t.includes(e))throw I.plain`Plugin factory already registered. To re-register, first unsubscribe the existing plugin.`}function Rt(e,t,n){if(t===0)return;let{warn:r,error:i}=p(t);e>=i?n.error(L,`${e} plugins registered! This is excessive. Hard limit at ${t}.`):e>=r&&n.warn(L,`${e} plugins registered. Consider if all are necessary.`)}function zt(e){for(let t in e)if(!(t===`teardown`||Pt(Ft,t)))throw I.type`Unknown property '${t}'. Plugin must only contain event handlers and optional teardown.`}function Bt(e){e.warn(L,`Duplicate factory in batch, will be registered once`)}function Vt(e,t){t.warn(L,`Property '${e}' is not a function, skipping`)}function Ht(e,t){e===`onStart`&&t.warn(L,`Router already started, onStart will not be called`)}const Ut=i(`router`,`navigateToDefault`),R=i(`validation-plugin`),z=Object.entries,Wt=Object.getOwnPropertyDescriptor,Gt=Object.keys;function B(e,t,n=``){for(let r of e){let e=n?`${n}.${r.name}`:r.name;t(r,e),r.children&&B(r.children,t,e)}}function V(e,t){let n=[];return B(e,(e,r)=>{let i=t(e);i!==void 0&&n.push([r,i])}),n}function Kt(e,t){try{return d(e,t)}catch(e){let t=e.message.replace(/^\[router\] /u,``);throw R.plain({cause:e})`${t}`}}function H(e,t,n){let r=e;if(r.constructor.name===`AsyncFunction`||r.toString().includes(`__awaiter`))throw R.type`Route "${n}" ${t} cannot be async`}function qt(e){B(e,(e,t)=>{if(typeof e.name!=`string`||!e.name)throw R.type`validateExistingRoutes: route has invalid name: ${e.name}`;if(typeof e.path!=`string`)throw R.type`validateExistingRoutes: route "${t}" has non-string path (${typeof e.path})`})}function Jt(e,t){for(let[n,r]of z(e)){if(!t.hasRoute(r))throw R.plain`validateForwardToConsistency: forwardTo target "${r}" does not exist in tree (source route: "${n}")`;let e=new Set(t.getUrlParams(n)),i=[...new Set(t.getUrlParams(r))].filter(t=>!e.has(t));if(i.length>0)throw R.plain`validateForwardToConsistency: forwardTo target "${r}" requires params [${i.join(`, `)}] not available in source route "${n}"`}for(let t of Gt(e))Kt(t,e)}function Yt(e,t){for(let[n,r]of e)if(typeof r!=`object`||!r||Array.isArray(r))throw R.type`validateRoutePropertiesStore: route "${n}" ${t} must be a plain object, got ${Array.isArray(r)?`array`:typeof r}`}function Xt(e){let t=V(e,e=>e.decodeParams),n=V(e,e=>e.encodeParams),r=V(e,e=>typeof e.forwardTo==`string`?void 0:e.forwardTo);for(let[e,n]of t){if(typeof n!=`function`)throw R.type`validateRoutePropertiesStore: route "${e}" decoder must be a function, got ${typeof n}`;H(n,`decoder`,e)}for(let[e,t]of n){if(typeof t!=`function`)throw R.type`validateRoutePropertiesStore: route "${e}" encoder must be a function, got ${typeof t}`;H(t,`encoder`,e)}Yt(V(e,e=>e.defaultParams),`defaultParams`),Yt(V(e,e=>e.defaultSearch),`defaultSearch`);for(let[e,t]of r){if(typeof t!=`function`)throw R.type`validateRoutePropertiesStore: route "${e}" forwardTo callback must be a function, got ${typeof t}`;H(t,`forwardTo callback`,e)}}function Zt(e,t){for(let[n,r]of z(e))if(!t.hasRoute(r))throw R.plain`validateForwardToTargetsStore: forwardTo target "${r}" does not exist for route "${n}"`}function Qt(e,t){for(let t of Gt(e))if(Wt(e,t)?.get)throw R.type`validateDependenciesStructure: dependency "${t}" must not use a getter`;for(let[e,n]of z(t))if(!Number.isInteger(n))throw R.type`validateDependenciesStructure: deps.limits.${e} must be an integer, got ${String(n)}`}function $t(e,t,n){let r=e&&typeof e==`object`?e:{},i=(r.limits&&typeof r.limits==`object`?r.limits:{}).maxDependencies,a=typeof i==`number`?i:n;if(a>0&&t>a)throw R.range`validateLimitsConsistency: dependency count (${t}) exceeds maxDependencies limit (${a})`}function en(e,t){return typeof e==`string`&&e!==``&&!t.hasRoute(e)}function tn(e,t){if(en(e,t))throw R.plain`defaultRoute resolved to non-existent route: "${e}"`}function nn(e,t){if(en(e,t))throw Ut.plain`defaultRoute callback resolved to non-existent route: "${e}"`}function rn(e,t,n){for(let r of e)t.hasRoute(r)||n.warn(`router.start`,`Guard registered for route "${r}", which the route tree does not contain. It will never run unless that route is added. Check the name for a typo.`)}const U=i(`router`,`updateRoute`),W=i(`router`,`addRoute`),an=i(`router`,`shouldUpdateNode`),on=i(`router`,`matchPath`),sn=i(`router`,`buildPath`),G=i(`router`,`isActiveRoute`),cn=i(`router`,`setRootPath`);function K(e,t){if(e.startsWith(`@@`))throw i(`router`,t).plain`Route name "${e}" uses the reserved "${`@@`}" prefix. Routes with this prefix are internal and cannot be modified through the public API.`}function ln(e,t){for(let n of e)n&&typeof n==`object`&&typeof n.name==`string`&&(K(n.name,t),n.children&&ln(n.children,t))}function un(e){C(e,`removeRoute`)}function dn(e){if(typeof e!=`string`)throw cn.type`rootPath must be a string, got ${w(e)}`}function q(e){return e.constructor.name===`AsyncFunction`||String(e).includes(`__awaiter`)}function fn(e){let t=e;if(t.canActivate!==void 0&&typeof t.canActivate!=`function`)throw W.type`canActivate must be a function, got ${w(t.canActivate)}`;if(t.canDeactivate!==void 0&&typeof t.canDeactivate!=`function`)throw W.type`canDeactivate must be a function, got ${w(t.canDeactivate)}`}function pn(e,t){let n=e;if(typeof n.decodeParams==`function`&&q(n.decodeParams))throw W.type`decodeParams cannot be async for route "${String(t)}"`;if(typeof n.encodeParams==`function`&&q(n.encodeParams))throw W.type`encodeParams cannot be async for route "${String(t)}"`;if(typeof n.forwardTo==`function`&&q(n.forwardTo))throw W.type`forwardTo callback cannot be async for route "${String(t)}"`}function mn(e,t){for(let n of e){if(typeof n!=`object`||!n||Array.isArray(n))throw W.type`Route must be an object, got ${w(n)}`;qe(n,D(t,n.name))}}function hn(e){if(typeof e!=`string`||e===``)throw W.type`parent option must be a non-empty string, got ${w(e)}`;C(e,`addRoute`)}function gn(e,t,n,r){if(!m(e))throw G.type`name must be a string, got ${typeof e}`;if(A(t,`isActiveRoute`),n!==void 0&&typeof n!=`boolean`)throw G.type`strictEquality must be a boolean, got ${typeof n}`;if(r!==void 0&&typeof r!=`boolean`)throw G.type`ignoreQueryParams must be a boolean, got ${typeof r}`}function J(e,t,n){if(!m(e))throw i(`router`,n).type`Invalid routeName: ${w(e)}. Expected string.`;if(!x(t))throw i(`router`,n).type`Invalid routeParams: ${w(t)}. Expected plain object.`}function _n(e,t){if(C(e,`updateRoute`),e===``)throw U.ref`Invalid name: empty string. Cannot update root node.`;if(t===null)throw U.type`updates must be an object, got null`;if(typeof t!=`object`||Array.isArray(t))throw U.type`updates must be an object, got ${w(t)}`}function vn(e,t){if(e.constructor.name===`AsyncFunction`||e.toString().includes(`__awaiter`))throw U.type`${t} cannot be an async function`}function Y(e,t){if(e!=null){if(typeof e!=`function`)throw U.type`${t} must be a function or null, got ${typeof e}`;vn(e,t)}}function yn(e){let{forwardTo:t,defaultParams:n,defaultSearch:r,decodeParams:i,encodeParams:a,canActivate:o,canDeactivate:s}=e;if(t!=null){if(typeof t!=`string`&&typeof t!=`function`)throw U.type`forwardTo must be a string, function, or null, got ${w(t)}`;typeof t==`function`&&vn(t,`forwardTo callback`)}bn(n,`defaultParams`),bn(r,`defaultSearch`),Y(i,`decodeParams`),Y(a,`encodeParams`),Y(o,`canActivate`),Y(s,`canDeactivate`)}function bn(e,t){if(e!=null&&(typeof e!=`object`||Array.isArray(e)))throw U.type`${t} must be an object or null, got ${w(e)}`}function xn(e){if(!m(e)||e===``)throw sn.type`route must be a non-empty string, got ${typeof e==`string`?`""`:typeof e}`}function Sn(e){let t=new Set;return function(n,r){let i=s(r,e(n));if(i===void 0)return;let a=`${n} ${i}`;t.has(a)||(t.add(a),console.warn(`[router] Route "${n}" declares \`${i}\` as a query param, but it was given in the \`params\` bag — the path channel. The URL is built without it, so the href does not match what you asked for; a plain click throws, but a ⌘-click, a copied link and server-rendered markup all follow the wrong URL in silence. Pass it in \`search\` instead.`))}}function Cn(e){if(!m(e))throw on.type`path must be a string, got ${typeof e}`}function wn(e){if(!m(e))throw an.type`nodeName must be a string, got ${typeof e}`}function Tn(e,t,n,r,i){if(i){let e=t;for(let t of i.split(`.`))if(e=e.children.get(t),!e)throw W.ref`Parent route "${i}" does not exist`}let a=new Set,o=new Map;for(let n of e)l(n,`addRoute`,t,i??``,a,o);tt(e,r,n,i)}function En(e,t,n){let r=new Set(n.getUrlParams(e)),i=n.getUrlParams(t).filter(e=>!r.has(e));if(i.length>0)throw U.plain`forwardTo target "${t}" requires params [${i.join(`, `)}] that are not available in source route "${e}"`}function Dn(e,t,n){let r={...n,[e]:t};d(e,r)}function On(e,t,n,r){if(!n.hasRoute(e))throw U.ref`route "${e}" does not exist`;if(t!=null&&typeof t==`string`){if(!n.hasRoute(t))throw U.plain`forwardTo target "${t}" does not exist`;En(e,t,n),Dn(e,t,r)}}const X=i(`router`,`makeState`),kn=Object.entries;function An(e,t,n){if(!m(e))throw X.type`Invalid name: ${w(e)}. Expected string.`;if(t!==void 0&&!x(t))throw X.type`Invalid params: ${w(t)}. Expected plain object.`;if(n!==void 0&&!m(n))throw X.type`Invalid path: ${w(n)}. Expected string.`}function jn(){let e=new Set;return function(t,n){let r=`${t} ${n}`;e.has(r)||(e.add(r),console.warn(`[router] Query key "${n}" is not declared on route "${t}" (\`?${n}\`), so the current \`queryParamsMode\` will not print it — it was dropped from \`state.search\` rather than published beside a \`state.path\` that cannot show it. Declare it on the route path, or use \`queryParamsMode: "loose"\` to keep undeclared keys. A \`defaultSearch\` entry for "${n}" is dead config in this mode for the same reason.`))}}function Mn(){let e=new Set;return function(t,n){let r=`${t} ${n}`;e.has(r)||(e.add(r),console.warn(`[router] Param "${n}" is declared nowhere on route "${t}" — neither as a path slot (:${n}) nor as a query param (?${n}), so it stays in state.params but never reaches the URL. The state will not round-trip: matchPath(state.path) cannot recover it. Declare it on the route path if it belongs in the URL, or pass it through the search channel; keep it here only if it is deliberately app-level data.`))}}function Nn(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Pn(e,t){let n={params:{...t.params},search:{...t.search}};if(e===void 0)return n;let r=e(n),i=r.params??n.params,a=r.search??n.search;return Nn(i)&&Nn(a)?{params:i,search:a}:void 0}function Fn(e,t){try{return Pn(e,t)}catch{return}}function Z(e){return new Map(kn(e).filter(([,e])=>e!==void 0))}function Q(e){return Array.isArray(e)?e.some(e=>Q(e)):typeof e==`object`&&!!e}function In(e,t){try{return e(t)}catch{return}}function Ln(e,t){let n=n=>{let r=Z(e[n]);return new Map([...Z(t[n])].filter(([e])=>!r.has(e)))};return{params:n(`params`),search:n(`search`)}}function Rn(e,t){return Object.fromEntries(kn(e).filter(([e])=>!t.has(e)))}function zn(e,t,n){if(n.params.size+n.search.size===0)return n;try{let r=t(e.name,Rn(e.params,n.params),Rn(e.search,n.search)),i=e=>{let t=Z(r[e]??{});return new Map([...n[e]].filter(([e,n])=>t.has(e)&&a(t.get(e),n)))};return{params:i(`params`),search:i(`search`)}}catch{return{params:new Map,search:new Map}}}function Bn(e,t,n,r){let i=Fn(e.codec.encode,{...e.state,[t]:{...e.state[t],[n]:r}});return i!==void 0&&a(e.encoded[t][n],i[t][n])}function Vn(e,t,n){return e.credited[t].has(n)?void 0:`added`}function Hn(e,t,n,r,i){if(!Q(i))return a(r,i)?void 0:`changed`;if(!Bn(e,t,n,i))return`changed`;if(!a(r,i))return a(i,e.readAgain()?.[t][n])?`undecoded`:`keyless`}function Un(e,t){let n=Z(e.state[t]),r=Z(e.back[t]),i=[];for(let[a,o]of r){let r=n.has(a)?Hn(e,t,a,n.get(a),o):Vn(e,t,a);r!==void 0&&i.push([t,a,r])}for(let a of n.keys())!r.has(a)&&(t===`search`||e.pathSlots.includes(a))&&i.push([t,a,`dropped`]);return i}function Wn(e,t,n,r,i){let a=r(e.path);if(a?.name!==e.name)return[];let o=Pn(t.encode,e);if(o===void 0)return[];let s,c={state:e,codec:t,pathSlots:n,encoded:o,back:a,readAgain:()=>(s??={state:In(r,e.path)},s.state),credited:zn(a,i,Ln(e,a))};return[...Un(c,`params`),...Un(c,`search`)]}function Gn(e){return e.decode===void 0?`The route has an encodeParams and no decodeParams to undo it.`:e.encode===void 0?`With no encodeParams, decodeParams must return each value so that it prints as the URL shows it.`:`decodeParams must undo encodeParams.`}function Kn(e,t,n,r,i){let a=`Route "${e}": its codec`,o=`${a} changes "${n}" in state.${t}, so a link and a reload of the same URL commit different values.`;switch(r){case`added`:return`${a} adds "${n}" to state.${t}, so a link commits a state without it and a reload of the same URL commits one with it. Derive "${n}" in a forwardState interceptor instead: navigate and matchPath both run it.`;case`changed`:return`${o} ${Gn(i)}`;case`undecoded`:return`${o} encodeParams prints both as one piece of the URL, so a link must pass the value decodeParams returns for that piece.`;case`keyless`:return`${o} Two reloads of one URL decode values that never compare equal: give the value a key — a Date, or a plain object JSON.stringify prints in full.`;case`dropped`:return`${a} drops "${n}" from state.${t}, so a reload of the URL a link builds loses it. ${Gn(i)}`}}function qn(e,t,n){let r=new Set;return function(i,a,o){let s;try{s=Wn(i,a,o,t,n)}catch{return}for(let[t,n,o]of s){let s=`${i.name} ${t} ${n}`;r.has(s)||(r.add(s),e.warn(`router`,Kn(i.name,t,n,o,a)))}}}const Jn=i(`validation-plugin`),Yn=i(`router`,`addRoute`),$=i(`router`,`areStatesEqual`);function Xn(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Zn(e){return{hasRoute:t=>{let n=e.getTree();for(let e of t.split(`.`))if(n=n?.children.get(e),!n)return!1;return!0},getUrlParams:t=>e.getUrlParams(t)}}const Qn={hasRoute:()=>!1,getUrlParams:()=>[]};function $n(e){return{tree:{...e,children:new Map,nonAbsoluteChildren:[]},lookup:Qn,forwardMap:{}}}function er(e,t){let n=[];for(let r of e.getTree().children.keys())n.push(t.get(r));return n}function tr(e,t,n,r){let i=Sn(t=>e.getDeclaredQueryNames(t));return{routes:{validateBuildPathArgs(e,t){xn(e),i(e,t)},validateMatchPathArgs:Cn,validateIsActiveRouteArgs(e,t,n,r){gn(e,t,n,r),i(e,t)},validateShouldUpdateNodeArgs:wn,validateStateBuilderArgs:J,validateRouteName(e,t){C(e,t)},validateSetRootPathArgs:dn},options:{validateOptions:Nt,validateResolvedDefaultRoute(e){nn(e,t)}},dependencies:{validateDependencyName:Oe,validateSetDependencyArgs(e,t,n){ke(e)},validateDependenciesObject(t,n){Ae(t,n),je(t,e.getDependencyKeys(),e.getResolvedLimits().maxDependencies,n)},validateDependencyExists(e,t){Me(t,e)},validateDependencyCount(t,n,r){Ne(t,n,r,e.logger)},validateCloneArgs:Pe,warnOverwrite(t,n){Fe(t,n,e.logger)},warnBatchOverwrite(t,n){Ie(t,n,e.logger)},warnRemoveNonExistent(t){Le(t,e.logger)}},plugins:{validatePluginLimit(e,t){It(e,1,t?.maxPlugins)},validateNoDuplicatePlugins:Lt,validatePluginKeys:zt,validateCountThresholds(t){Rt(t,e.getOptions().limits?.maxPlugins??f.maxPlugins,e.logger)},warnBatchDuplicates(){Bt(e.logger)},warnPluginMethodType(t){Vt(t,e.logger)}},lifecycle:{validateHandlerLimit(t,n){rt(t,n,e.getOptions().limits?.maxLifecycleHandlers??f.maxLifecycleHandlers)},validateCountThresholds(t,n){it(t,n,e.getOptions().limits?.maxLifecycleHandlers??f.maxLifecycleHandlers,e.logger)},warnOverwrite(t,n,r){at(t,n,r,e.logger)},warnAsyncGuardSync(t,n){ot(t,n,e.logger)},warnNonBooleanGuardSync(t,n,r){ct(t,n,r,e.logger)},warnNonBooleanGuard(t,n){lt(t,n,e.logger)}},navigation:{validateNavigateToDefaultArgs(t){ht(t),n.check(e.logger)},validateNavigateToStateArgs:gt,validateNavigationOptions:_t,validateParamsShape:A,validateSearch:M,validateStartArgs:bt},state:{validateMakeStateArgs:An,reportDroppedQueryKey:jn(),reportUndeclaredParamKey:Mn(),reportCodecRoundTrip:qn(e.logger,r,e.forwardState),validateAreStatesEqualArgs(e,t,n){if(!he(e))throw $.type`Invalid state1: ${w(e)}. Expected State object.`;if(!he(t))throw $.type`Invalid state2: ${w(t)}. Expected State object.`;if(n!==void 0&&!h(n))throw $.type`Invalid ignoreQueryParams: ${w(n)}. Expected boolean.`;if(n===!1){if(!Xn(e.search))throw $.type`Invalid state1.search: ${w(e.search)}. Expected a plain object.`;if(!Xn(t.search))throw $.type`Invalid state2.search: ${w(t.search)}. Expected a plain object.`}}},eventBus:{validateListenerArgs(e,t){He(e,t)},validateCountThresholds(t,n,r){let i=e.getOptions().limits?.maxListeners??f.maxListeners;Ue(t,n,r,e.logger,i)}}}}function nr(){return n=>{let r=c(n),i=e(n);if(n.isActive())throw Jn.code(`VALIDATION_PLUGIN_AFTER_START`)`must be registered before router.start()`;if(r.validator!==null)throw Jn.code(`VALIDATION_PLUGIN_ALREADY_INSTALLED`)`is already installed on this router — a clone re-runs plugin factories, so it needs no usePlugin of its own`;let a=new be;a.watch(i.getAdoptedOrigins());let o=e=>r.matchPath(e,{...i.getOptions(),rewritePathOnMatch:!1}),s=Zn(i),l=tr(i,s,a,o),u=()=>{r.validator===l&&(r.validator=null)};r.validator=l;try{let e=er(i,t(n)),a=i.getForwardMap(),o=i.getResolvedLimits(),c=i.getOptions();qt(e),Jt(a,s),Xt(e),Zt(a,s),Qt(r.dependenciesGetStore().dependencies,o),$t(c,i.getDependencyKeys().length,o.maxDependencies),r.validator.options.validateOptions(c,`constructor (retrospective)`),typeof c.defaultRoute==`string`&&tn(c.defaultRoute,s)}catch(e){throw u(),e}let d=i.addInterceptor(`start`,(e,t)=>{try{rn(i.getExternalGuardNames(),s,i.logger)}catch{}return e(t)}),f=i.addCheck(`buildPath:params`,e=>{j(e,`buildPath`)}),p=i.addCheck(`buildPathResolved:params`,e=>{j(e,`buildPathResolved`)}),m=i.addCheck(`canNavigateTo:entry`,(e,t,n)=>{C(e,`canNavigateTo`),A(t,`canNavigateTo`),M(n,`canNavigateTo`)}),h=i.addCheck(`canNavigateTo:params`,e=>{j(e,`canNavigateTo`)}),ee=i.addCheck(`navigate:entry`,(e,t,n,r)=>{mt(e),A(t,`navigate`),M(n,`navigate`),_t(r,`navigate`)}),g=i.addCheck(`navigate:params`,e=>{j(e,`navigate`)}),_=(e,t)=>{for(let n of e){let e=D(t,n.name);fn(n),pn(n,e),n.children!==void 0&&_(n.children,e)}},v=(e,t,n,r)=>{if(_(e,typeof n==`string`&&s.hasRoute(n)?n:void 0),n!==void 0&&(hn(n),!s.hasRoute(n)))throw Yn.ref`Parent route "${n}" does not exist`;ln(e,t),mn(e,n);let i=r();Tn(e,i.tree,i.lookup,i.forwardMap,n)},te=i.addCheck(`addRoute:batch`,(e,t)=>{v(e,`addRoute`,t,()=>({tree:i.getTree(),lookup:s,forwardMap:i.getForwardMap()}))}),ne=i.addCheck(`replaceRoutes:batch`,e=>{v(e,`replaceRoutes`,void 0,()=>$n(i.getTree()))}),re=i.addCheck(`removeRoute:entry`,e=>{un(e),K(e,`removeRoute`)}),ie=i.addCheck(`updateRoute:entry`,(e,t)=>{let n=t;_n(e,t),K(e,`updateRoute`),yn({forwardTo:n.forwardTo,defaultParams:n.defaultParams,defaultSearch:n.defaultSearch,decodeParams:n.decodeParams,encodeParams:n.encodeParams,canActivate:n.canActivate,canDeactivate:n.canDeactivate}),On(e,n.forwardTo,s,i.getForwardMap())}),ae=i.addCheck(`hasRoute:entry`,e=>{C(e,`hasRoute`)}),y=i.addCheck(`getRoute:entry`,e=>{C(e,`getRoute`)}),oe=i.addCheck(`forwardState:entry`,(e,t,n)=>{J(e,t,`forwardState`),M(n,`forwardState`)}),se=i.addCheck(`buildNavigationState:state`,(e,t,n)=>{M(n,`buildNavigationState`),J(e,t,`buildNavigationState`)}),b=i.addCheck(`addActivateGuard:entry`,(e,t)=>{C(e,`addActivateGuard`),nt(t,`addActivateGuard`)}),x=i.addCheck(`addDeactivateGuard:entry`,(e,t)=>{C(e,`addDeactivateGuard`),nt(t,`addDeactivateGuard`)}),ce=i.addCheck(`removeActivateGuard:entry`,e=>{C(e,`removeActivateGuard`)}),le=i.addCheck(`removeDeactivateGuard:entry`,e=>{C(e,`removeDeactivateGuard`)}),ue=i.subscribeDiagnostic(`PLUGIN_AFTER_START`,e=>{Ht(e,i.logger)});return{teardown(){f(),p(),m(),h(),ee(),g(),te(),ne(),re(),ie(),ae(),y(),oe(),se(),b(),x(),ce(),le(),ue(),d(),u()}}}}export{nr as validationPlugin};
|
|
1
|
+
import{getPluginApi as e,getRoutesApi as t}from"@real-router/core/api";import{internalDefect as n,putField as r,raiser as i}from"@real-router/core/utils";import{areParamValuesEqual as a,buildParamMeta as o,findMisChanneledKey as s,getInternals as c,validateRoute as l}from"@real-router/core/validation";import{events as u,resolveForwardChain as d}from"@real-router/core";const f=Object.freeze({maxDependencies:100,maxPlugins:50,maxListeners:1e4,warnListeners:1e3,maxLifecycleHandlers:200});function p(e){return{warn:Math.floor(e*.2),error:Math.floor(e*.5)}}function m(e){return typeof e==`string`}function h(e){return typeof e==`boolean`}function ee(e,t){return e in t}const g=Object.getPrototypeOf,_=Object.values,v=Object.hasOwn,te=Date,ne=Date.prototype.getTime;function re(e){if(Array.isArray(e))return!0;let t=g(e);return t===null||t===Object.prototype}function ie(e,t){let n=Array.isArray(e)?e:_(e);for(let e of n)t.push(e)}function ae(e){let t=typeof e;return t===`string`||t===`boolean`||t===`number`&&Number.isFinite(e)}var y=class{container;constructor(e){this.container=e}};function oe(e,t,n,r){return n.has(e)?!1:r.has(e)?!0:re(e)?(n.add(e),t.push(new y(e)),ie(e,t),!0):e instanceof te&&(ne.call(e),!0)}function se(e){let t=[e],n=new WeakSet,r=new WeakSet;for(;t.length>0;){let e=t.pop();if(e instanceof y)n.delete(e.container),r.add(e.container);else if(e!=null){if(typeof e==`object`){if(!oe(e,t,n,r))return!1}else if(!ae(e))return!1}}return!0}function b(e){if(e==null)return!0;let t=typeof e;return t===`string`||t===`boolean`||t===`number`&&Number.isFinite(e)}function x(e){try{return ce(e)}catch{return!1}}function ce(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=g(e);if(t!==null&&t!==Object.prototype)return!1;let n=!1;for(let t in e){if(!v(e,t))continue;let r=e[t];if(!b(r)){let e=typeof r;if(e===`function`||e===`symbol`)return!1;n=!0;break}}return!n||se(e)}const le=[`replace`,`reload`,`force`,`forceDeactivate`,`redirected`,`revalidate`];function ue(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;for(let e of le){let n=t[e];if(n!==void 0&&typeof n!=`boolean`)return!1}let n=t.signal;return n===void 0||n instanceof AbortSignal}const de=/\S/,fe=/^[A-Z_a-z][\w-]*(?:\.[A-Z_a-z][\w-]*)*$/;function S(e,t){return i(`router`,e).type`${t}`}function pe(e){return typeof e==`string`?e===``?!0:e.length>1e4?!1:e.startsWith(`@@`)?!0:fe.test(e):!1}function me(e){return pe(e.name)&&typeof e.path==`string`&&x(e.params)}function he(e){return typeof e!=`object`||!e?!1:me(e)}function C(e,t){if(typeof e!=`string`)throw S(t,`Route name must be a string, got ${typeof e}`);if(e!==``){if(!de.test(e))throw S(t,`Route name cannot contain only whitespace`);if(e.length>1e4)throw S(t,`Route name exceeds maximum length of 10000 characters. This is a technical safety limit.`);if(!e.startsWith(`@@`)&&!fe.test(e))throw S(t,`Invalid route name "${e}". Each segment must start with a letter or underscore, followed by letters, numbers, underscores, or hyphens. Segments are separated by dots (e.g., "users.profile").`)}}function w(e){if(e===null)return`null`;if(typeof e!=`object`)return typeof e;try{if(Array.isArray(e))return`array[${e.length}]`;let t=e.constructor;if(typeof t==`function`){let e=t.name;if(typeof e==`string`&&e!==``&&e!==`Object`)return e}}catch{}return`object`}const ge=Object.entries,_e=[`defaultParams`,`defaultSearch`],ve=e=>new Map(ge(e)),ye=(e,t)=>{let n=ge(e);return n.length!==t.size||n.some(([e,n])=>!t.has(e)||!Object.is(t.get(e),n))};var be=class{#e=new Map;#t=new Set;watch(e){for(let t of _e){let n=e[t],r=n?.deref();n!==void 0&&r!==void 0&&this.#e.set(t,{ref:n,before:ve(r)})}}check(e){for(let[t,{ref:n,before:r}]of this.#e){if(this.#t.has(t))continue;let i=n.deref();i!==void 0&&ye(i,r)&&(this.#t.add(t),e.warn(`router.navigateToDefault`,`mutating \`${t}\` after createRouter() no longer affects routing — the router copied it at construction. Use the callback form (\`${t}: () => ({ … })\`), which is resolved at the point of use.`))}}};const xe=i(`cloneRouter`),Se=i(`router`,`getDependency`),Ce=i(`router`,`setDependency`),T=Object.keys,we=Object.getOwnPropertyDescriptor,Te=Object.getPrototypeOf,Ee=Object;function De(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=Te(e);return t===null||t.constructor===Ee}function Oe(e,t){if(typeof e!=`string`)throw i(`router`,t).type`dependency name must be a string, got ${typeof e}`}function ke(e){if(typeof e!=`string`)throw Ce.type`dependency name must be a string, got ${typeof e}`}function Ae(e,t){if(!De(e))throw i(`router`,t).type`Invalid argument: expected plain object, received ${w(e)}`;for(let n of T(e))if(we(e,n)?.get)throw i(`router`,t).type`Getters not allowed: "${n}"`}function je(e,t,n,r){if(n===0)return;let a=new Set(t),o=0;for(let t of T(e))a.has(t)||(o+=1);let s=t.length;if(s+o>n)throw i(`router`,r).range`Dependency limit exceeded (${n}). Current: ${s}, this batch adds ${o}.`}function Me(e,t){if(e===void 0)throw Se.ref`dependency "${t}" not found`}function Ne(e,t,n,r){if(t===0)return;let{warn:a,error:o}=p(t);if(e>=t)throw i(`router`,n).range`Dependency limit exceeded (${t}). Current: ${e}.`;e===o?r.error(`router.${n}`,`${e} dependencies registered! This indicates architectural problems. Hard limit at ${t}.`):e===a&&r.warn(`router.${n}`,`${e} dependencies registered. Consider if all are necessary.`)}function Pe(e){if(e!==void 0){if(!De(e))throw xe.type`Invalid dependencies: expected plain object or undefined, received ${typeof e}`;for(let t of T(e))if(we(e,t)?.get)throw xe.type`Getters not allowed in dependencies: "${t}"`}}function Fe(e,t,n){n.warn(`router.${t}`,`Router dependency already exists and is being overwritten:`,e)}function Ie(e,t,n){n.warn(`router.${t}`,`Overwritten:`,e.join(`, `))}function Le(e,t){t.warn(`router.removeDependency`,`Attempted to remove non-existent dependency: "${typeof e==`string`?e:String(e)}"`)}const Re=i(`router`,`addEventListener`),ze=Object.values,Be=new Set(ze(u));function Ve(e){if(!Be.has(e))throw Re.type`Invalid event name: ${String(e)}. Must be one of: $start, $stop, $$start, $$leaveApprove, $$cancel, $$success, $$error`}function He(e,t){if(Ve(e),typeof t!=`function`)throw Re.type`callback must be a function, got ${typeof t}`}function Ue(e,t,n,r,i=f.maxListeners){if(i===0)return;let{warn:a,error:o}=p(i);e>=o?r.error(`router.${n}`,`${e} listeners registered for "${t}"! This is excessive. Hard limit at ${i}.`):e>=a&&r.warn(`router.${n}`,`${e} listeners registered for "${t}". Consider whether all are necessary — a growing count usually means a missing unsubscribe.`)}const E=i(`router`,`addRoute`),We=Object.keys;function D(e,t){return typeof e==`string`&&e!==``&&typeof t==`string`?`${e}.${t}`:t}function Ge(e,t){if(e!==void 0){if(typeof e!=`string`&&typeof e!=`function`)throw E.type`forwardTo must be a string or function for route "${t}", got ${w(e)}`;if(typeof e==`function`){let n=e.constructor.name===`AsyncFunction`,r=e.toString().includes(`__awaiter`);if(n||r)throw E.type`forwardTo callback cannot be async for route "${t}". Async functions break matchPath/buildPath.`}}}function Ke(e,t,n){if(e!==void 0&&(typeof e!=`object`||!e||Array.isArray(e)))throw E.type`${t} must be an object for route "${n}", got ${w(e)}`}function qe(e,t){if(e.canActivate!==void 0&&typeof e.canActivate!=`function`)throw E.type`canActivate must be a function for route "${t}", got ${w(e.canActivate)}`;if(e.canDeactivate!==void 0&&typeof e.canDeactivate!=`function`)throw E.type`canDeactivate must be a function for route "${t}", got ${w(e.canDeactivate)}`;Ke(e.defaultParams,`defaultParams`,t),Ke(e.defaultSearch,`defaultSearch`,t);let{decodeParams:n,encodeParams:r}=e;if(typeof n==`function`&&n.constructor.name===`AsyncFunction`)throw E.type`decodeParams cannot be async for route "${t}". Async functions break matchPath/buildPath.`;if(typeof r==`function`&&r.constructor.name===`AsyncFunction`)throw E.type`encodeParams cannot be async for route "${t}". Async functions break matchPath/buildPath.`;if(Ge(e.forwardTo,t),e.children)for(let n of e.children)qe(n,D(t,n.name))}function Je(e){let t=new Set;for(let n of e)for(let e of o(n).urlParams)t.add(e);return t}function Ye(e,t,r=``,i=[]){for(let n of e){let e=r?`${r}.${n.name}`:n.name,a=[...i,n.path];if(e===t)return a;if(n.children&&t.startsWith(`${e}.`))return Ye(n.children,t,e,a)}throw n.plain`collectPathsToRoute: route "${t}" not found`}function Xe(e,t=``){let n=new Set;for(let r of e){let e=t?`${t}.${r.name}`:r.name;if(n.add(e),r.children)for(let t of Xe(r.children,e))n.add(t)}return n}function Ze(e,t=``){let n=new Map;for(let r of e){let e=t?`${t}.${r.name}`:r.name;if(r.forwardTo&&typeof r.forwardTo==`string`&&n.set(e,r.forwardTo),r.children)for(let[t,i]of Ze(r.children,e))n.set(t,i)}return n}function Qe(e,t,n,r){return t?new Set(n.getUrlParams(e)):Je(r(e))}const $e=new Set;function et(e,t,n,r,i,a){let o=i.hasRoute(t),s=r.has(t);if(!o&&!s)throw E.ref`forwardTo target "${t}" does not exist for route "${e}"`;let c=new Set([...a,...Je(n(e))]),l=[...Qe(t,o,i,n)].filter(e=>!c.has(e));if(l.length>0)throw E.plain`forwardTo target "${t}" requires params [${l.join(`, `)}] that are not available in source route "${e}"`}function tt(e,t,n,i){let a=Xe(e,i),o=t=>Ye(e,i?t.slice(i.length+1):t),s=i?new Set(n.getUrlParams(i)):$e,c=Ze(e,i),l={...t};for(let[e,t]of c)r(l,e,t);for(let[e,t]of c)et(e,t,o,a,n,s);for(let e of We(l))d(e,l)}function nt(e,t){if(!h(e)&&typeof e!=`function`)throw i(`router`,t).type`Handler must be a boolean or factory function, got ${w(e)}`}function rt(e,t,n=f.maxLifecycleHandlers){if(n!==0&&e>=n)throw i(`router`,t).range`Lifecycle handler limit exceeded (${n}). This indicates too many routes with individual handlers. Consider using plugins for cross-cutting concerns.`}function it(e,t,n,r){if(n===0)return;let{warn:i,error:a}=p(n);e>=a?r.error(`router.${t}`,`${e} lifecycle handlers registered! This is excessive. Hard limit at ${n}.`):e>=i&&r.warn(`router.${t}`,`${e} lifecycle handlers registered. Consider consolidating logic.`)}function at(e,t,n,r){r.warn(`router.${n}`,`Overwriting existing ${t} handler for route "${e}"`)}function ot(e,t,n){n.warn(`router.${t}`,`Guard for "${e}" returned a Promise. Sync check cannot resolve async guards — returning false.`)}function st(e,t){return`Guard for "${e}" must answer true or false, got ${w(t)} — read as a refusal.`}function ct(e,t,n,r){r.warn(`router.${n}`,st(e,t))}function lt(e,t,n){n.warn(`router`,st(e,t))}const O=i(`router`,`start`),k=i(`router`,`navigateToState`),ut=i(`router`,`navigateToDefault`),dt=i(`router`,`navigate`),ft=Object.hasOwn,pt=Object.getPrototypeOf;function mt(e){if(typeof e!=`string`)throw dt.type`Invalid route name: expected string, got ${w(e)}`}function ht(e){if(e!==void 0&&(typeof e!=`object`||!e))throw ut.type`Invalid options: ${w(e)}. Expected NavigationOptions object.`}function gt(e){if(typeof e!=`object`||!e)throw k.type`Invalid state: ${w(e)}. Expected State object.`;let t=e;if(!m(t.name))throw k.type`Invalid state.name: ${w(t.name)}. Expected string.`;if(!x(t.params))throw k.type`Invalid state.params: ${w(t.params)}. Expected plain object.`;if(!m(t.path))throw k.type`Invalid state.path: ${w(t.path)}. Expected string.`}function _t(e,t){if(!ue(e))throw i(`router`,t).type`Invalid options: ${w(e)}. Expected NavigationOptions object.`}const vt=/[\u0000-\u001F\u007F]/;function yt(e,t){for(let n in e){if(!ft(e,n))continue;let r=e[n],a=typeof r;if(a===`symbol`||a===`bigint`)throw i(`router`,t).type`param "${n}" cannot be a ${a} — it does not round-trip through the URL path. Use a string, number, or boolean.`;if(a===`string`&&vt.test(r))throw i(`router`,t).type`param "${n}" must not contain control characters (NUL / C0 / DEL) — they corrupt the URL path.`}}function A(e,t){if(e===void 0)return;let n=e!==null&&pt(e);if(Array.isArray(e)||n!==null&&n!==Object.prototype)throw i(`router`,t).type`params must be a plain object, got ${w(e)}`}function j(e,t){if(e!==void 0&&(yt(e,t),!x(e)))throw i(`router`,t).type`params must be a plain object, got ${w(e)}`}function M(e,t){if(e!==void 0&&(typeof e!=`object`||!e||Array.isArray(e)))throw i(`router`,t).type`search must be a plain object, got ${w(e)}`}function bt(e){if(e!==void 0&&typeof e!=`string`)throw O.type`path must be a string, got ${w(e)}.`;if(typeof e==`string`){if(vt.test(e))throw O.type`path must not contain control characters (NUL / C0 / DEL).`;if(e!==``&&!e.startsWith(`/`))throw O.type`path must start with "/", got "${e}".`}}const xt=Object.entries,St=Object.hasOwn,N=Object.keys,Ct=Object.getPrototypeOf,P={trailingSlash:[`strict`,`never`,`always`,`preserve`],queryParamsMode:[`default`,`strict`,`loose`],urlParamsEncoding:[`default`,`uri`,`uriComponent`,`none`]},wt={arrayFormat:!0,booleanFormat:!0,nullFormat:!0,numberFormat:!0},Tt=new Set(N({defaultRoute:!0,defaultParams:!0,defaultSearch:!0,trailingSlash:!0,caseSensitive:!0,queryParamsMode:!0,queryParams:!0,urlParamsEncoding:!0,allowNotFound:!0,rewritePathOnMatch:!0,logger:!0,limits:!0})),Et={maxDependencies:{min:0,max:1e4},maxPlugins:{min:0,max:1e3},maxListeners:{min:0,max:1e5},warnListeners:{min:0,max:1e5},maxLifecycleHandlers:{min:0,max:1e4}};function Dt(e,t,n){if(typeof t!=`number`||!Number.isInteger(t))throw i(`router`,n).type`limit "${e}" must be an integer, got ${String(t)}`;let r=Et[e];if(t<r.min||t>r.max)throw i(`router`,n).range`limit "${e}" must be between ${r.min} and ${r.max}, got ${t}`}function Ot(e){let t=Ct(e);return t===null||t===Object.prototype}function kt(e,t){if(!e||typeof e!=`object`||!Ot(e))throw i(`router`,t).type`invalid limits: expected plain object, got ${typeof e}`;for(let[n,r]of xt(e)){if(!St(Et,n))throw i(`router`,t).type`unknown limit: "${n}"`;r!==void 0&&Dt(n,r,t)}let{warnListeners:n,maxListeners:r}=e;if(typeof n==`number`&&typeof r==`number`&&r>0&&n>r)throw i(`router`,t).range`"limits.warnListeners" (${n}) must not exceed "limits.maxListeners" (${r}) — the warning channel would be unreachable`}function F(e,t,n,r){if(e!==void 0&&(typeof e!=`string`||!n.includes(e))){let a=n.map(e=>`"${e}"`).join(`, `),o=typeof e==`string`?e:`(${typeof e})`;throw i(`router`,r).type`Invalid "${t}": "${o}". Must be one of: ${a}`}}function At(e,t){if(e!==void 0&&typeof e!=`string`&&typeof e!=`function`)throw i(`router`,t).type`Invalid "defaultRoute": expected string or function, got ${typeof e}`}function jt(e,t,n){if(e!==void 0&&typeof e!=`function`&&(!e||typeof e!=`object`||Array.isArray(e)||!Ot(e)))throw i(`router`,n).type`Invalid "${t}": expected plain object or function, got ${typeof e}`}function Mt(e,t){if(e===void 0)return;if(!e||typeof e!=`object`||Array.isArray(e))throw i(`router`,t).type`Invalid "queryParams": expected plain object`;let n=e;for(let e of N(n))if(!ee(e,wt))throw i(`router`,t).type`Invalid "queryParams.${e}": unknown option`}function Nt(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw i(`router`,t).type`Invalid options: expected plain object`;let n=e;for(let e of N(n))if(!Tt.has(e))throw i(`router`,t).type`Unknown option: "${e}"`;if(At(n.defaultRoute,t),jt(n.defaultParams,`defaultParams`,t),jt(n.defaultSearch,`defaultSearch`,t),F(n.trailingSlash,`trailingSlash`,P.trailingSlash,t),F(n.queryParamsMode,`queryParamsMode`,P.queryParamsMode,t),F(n.urlParamsEncoding,`urlParamsEncoding`,P.urlParamsEncoding,t),n.allowNotFound!==void 0&&typeof n.allowNotFound!=`boolean`)throw i(`router`,t).type`Invalid "allowNotFound": expected boolean, got ${typeof n.allowNotFound}`;if(n.rewritePathOnMatch!==void 0&&typeof n.rewritePathOnMatch!=`boolean`)throw i(`router`,t).type`Invalid "rewritePathOnMatch": expected boolean, got ${typeof n.rewritePathOnMatch}`;if(n.caseSensitive!==void 0&&typeof n.caseSensitive!=`boolean`)throw i(`router`,t).type`Invalid "caseSensitive": expected boolean, got ${typeof n.caseSensitive}`;Mt(n.queryParams,t),n.limits!==void 0&&kt(n.limits,t)}const I=i(`router`,`usePlugin`),Pt=Object.hasOwn,L=`router.usePlugin`,Ft={onStart:!0,onStop:!0,onTransitionStart:!0,onTransitionLeaveApprove:!0,onTransitionSuccess:!0,onTransitionError:!0,onTransitionCancel:!0};function It(e,t,n=f.maxPlugins){if(n!==0&&e+t>n)throw I.range`Plugin limit exceeded (${n}). Current: ${e}, Attempting to add: ${t}. This indicates an architectural problem. Consider consolidating plugins.`}function Lt(e,t){if(t.includes(e))throw I.plain`Plugin factory already registered. To re-register, first unsubscribe the existing plugin.`}function Rt(e,t,n){if(t===0)return;let{warn:r,error:i}=p(t);e>=i?n.error(L,`${e} plugins registered! This is excessive. Hard limit at ${t}.`):e>=r&&n.warn(L,`${e} plugins registered. Consider if all are necessary.`)}function zt(e){for(let t in e)if(!(t===`teardown`||Pt(Ft,t)))throw I.type`Unknown property '${t}'. Plugin must only contain event handlers and optional teardown.`}function Bt(e){e.warn(L,`Duplicate factory in batch, will be registered once`)}function Vt(e,t){t.warn(L,`Property '${e}' is not a function, skipping`)}function Ht(e,t){e===`onStart`&&t.warn(L,`Router already started, onStart will not be called`)}const Ut=i(`router`,`navigateToDefault`),R=i(`validation-plugin`),z=Object.entries,Wt=Object.getOwnPropertyDescriptor,Gt=Object.keys;function B(e,t,n=``){for(let r of e){let e=n?`${n}.${r.name}`:r.name;t(r,e),r.children&&B(r.children,t,e)}}function V(e,t){let n=[];return B(e,(e,r)=>{let i=t(e);i!==void 0&&n.push([r,i])}),n}function Kt(e,t){try{return d(e,t)}catch(e){let t=e.message.replace(/^\[router\] /u,``);throw R.plain({cause:e})`${t}`}}function H(e,t,n){let r=e;if(r.constructor.name===`AsyncFunction`||r.toString().includes(`__awaiter`))throw R.type`Route "${n}" ${t} cannot be async`}function qt(e){B(e,(e,t)=>{if(typeof e.name!=`string`||!e.name)throw R.type`validateExistingRoutes: route has invalid name: ${e.name}`;if(typeof e.path!=`string`)throw R.type`validateExistingRoutes: route "${t}" has non-string path (${typeof e.path})`})}function Jt(e,t){for(let[n,r]of z(e)){if(!t.hasRoute(r))throw R.plain`validateForwardToConsistency: forwardTo target "${r}" does not exist in tree (source route: "${n}")`;let e=new Set(t.getUrlParams(n)),i=[...new Set(t.getUrlParams(r))].filter(t=>!e.has(t));if(i.length>0)throw R.plain`validateForwardToConsistency: forwardTo target "${r}" requires params [${i.join(`, `)}] not available in source route "${n}"`}for(let t of Gt(e))Kt(t,e)}function Yt(e,t){for(let[n,r]of e)if(typeof r!=`object`||!r||Array.isArray(r))throw R.type`validateRoutePropertiesStore: route "${n}" ${t} must be a plain object, got ${Array.isArray(r)?`array`:typeof r}`}function Xt(e){let t=V(e,e=>e.decodeParams),n=V(e,e=>e.encodeParams),r=V(e,e=>typeof e.forwardTo==`string`?void 0:e.forwardTo);for(let[e,n]of t){if(typeof n!=`function`)throw R.type`validateRoutePropertiesStore: route "${e}" decoder must be a function, got ${typeof n}`;H(n,`decoder`,e)}for(let[e,t]of n){if(typeof t!=`function`)throw R.type`validateRoutePropertiesStore: route "${e}" encoder must be a function, got ${typeof t}`;H(t,`encoder`,e)}Yt(V(e,e=>e.defaultParams),`defaultParams`),Yt(V(e,e=>e.defaultSearch),`defaultSearch`);for(let[e,t]of r){if(typeof t!=`function`)throw R.type`validateRoutePropertiesStore: route "${e}" forwardTo callback must be a function, got ${typeof t}`;H(t,`forwardTo callback`,e)}}function Zt(e,t){for(let[n,r]of z(e))if(!t.hasRoute(r))throw R.plain`validateForwardToTargetsStore: forwardTo target "${r}" does not exist for route "${n}"`}function Qt(e,t){for(let t of Gt(e))if(Wt(e,t)?.get)throw R.type`validateDependenciesStructure: dependency "${t}" must not use a getter`;for(let[e,n]of z(t))if(!Number.isInteger(n))throw R.type`validateDependenciesStructure: deps.limits.${e} must be an integer, got ${String(n)}`}function $t(e,t,n){let r=e&&typeof e==`object`?e:{},i=(r.limits&&typeof r.limits==`object`?r.limits:{}).maxDependencies,a=typeof i==`number`?i:n;if(a>0&&t>a)throw R.range`validateLimitsConsistency: dependency count (${t}) exceeds maxDependencies limit (${a})`}function en(e,t){return typeof e==`string`&&e!==``&&!t.hasRoute(e)}function tn(e,t){if(en(e,t))throw R.plain`defaultRoute resolved to non-existent route: "${e}"`}function nn(e,t){if(en(e,t))throw Ut.plain`defaultRoute callback resolved to non-existent route: "${e}"`}function rn(e,t,n){for(let r of e)t.hasRoute(r)||n.warn(`router.start`,`Guard registered for route "${r}", which the route tree does not contain. It will never run unless that route is added. Check the name for a typo.`)}const U=i(`router`,`updateRoute`),W=i(`router`,`addRoute`),an=i(`router`,`shouldUpdateNode`),on=i(`router`,`matchPath`),sn=i(`router`,`buildPath`),G=i(`router`,`isActiveRoute`),cn=i(`router`,`setRootPath`);function K(e,t){if(e.startsWith(`@@`))throw i(`router`,t).plain`Route name "${e}" uses the reserved "${`@@`}" prefix. Routes with this prefix are internal and cannot be modified through the public API.`}function ln(e,t){for(let n of e)n&&typeof n==`object`&&typeof n.name==`string`&&(K(n.name,t),n.children&&ln(n.children,t))}function un(e){C(e,`removeRoute`)}function dn(e){if(typeof e!=`string`)throw cn.type`rootPath must be a string, got ${w(e)}`}function q(e){return e.constructor.name===`AsyncFunction`||String(e).includes(`__awaiter`)}function fn(e){let t=e;if(t.canActivate!==void 0&&typeof t.canActivate!=`function`)throw W.type`canActivate must be a function, got ${w(t.canActivate)}`;if(t.canDeactivate!==void 0&&typeof t.canDeactivate!=`function`)throw W.type`canDeactivate must be a function, got ${w(t.canDeactivate)}`}function pn(e,t){let n=e;if(typeof n.decodeParams==`function`&&q(n.decodeParams))throw W.type`decodeParams cannot be async for route "${String(t)}"`;if(typeof n.encodeParams==`function`&&q(n.encodeParams))throw W.type`encodeParams cannot be async for route "${String(t)}"`;if(typeof n.forwardTo==`function`&&q(n.forwardTo))throw W.type`forwardTo callback cannot be async for route "${String(t)}"`}function mn(e,t){for(let n of e){if(typeof n!=`object`||!n||Array.isArray(n))throw W.type`Route must be an object, got ${w(n)}`;qe(n,D(t,n.name))}}function hn(e){if(typeof e!=`string`||e===``)throw W.type`parent option must be a non-empty string, got ${w(e)}`;C(e,`addRoute`)}function gn(e,t,n,r){if(!m(e))throw G.type`name must be a string, got ${typeof e}`;if(A(t,`isActiveRoute`),n!==void 0&&typeof n!=`boolean`)throw G.type`strictEquality must be a boolean, got ${typeof n}`;if(r!==void 0&&typeof r!=`boolean`)throw G.type`ignoreQueryParams must be a boolean, got ${typeof r}`}function J(e,t,n){if(!m(e))throw i(`router`,n).type`Invalid routeName: ${w(e)}. Expected string.`;if(!x(t))throw i(`router`,n).type`Invalid routeParams: ${w(t)}. Expected plain object.`}function _n(e,t){if(C(e,`updateRoute`),e===``)throw U.ref`Invalid name: empty string. Cannot update root node.`;if(t===null)throw U.type`updates must be an object, got null`;if(typeof t!=`object`||Array.isArray(t))throw U.type`updates must be an object, got ${w(t)}`}function vn(e,t){if(e.constructor.name===`AsyncFunction`||e.toString().includes(`__awaiter`))throw U.type`${t} cannot be an async function`}function Y(e,t){if(e!=null){if(typeof e!=`function`)throw U.type`${t} must be a function or null, got ${typeof e}`;vn(e,t)}}function yn(e){let{forwardTo:t,defaultParams:n,defaultSearch:r,decodeParams:i,encodeParams:a,canActivate:o,canDeactivate:s}=e;if(t!=null){if(typeof t!=`string`&&typeof t!=`function`)throw U.type`forwardTo must be a string, function, or null, got ${w(t)}`;typeof t==`function`&&vn(t,`forwardTo callback`)}bn(n,`defaultParams`),bn(r,`defaultSearch`),Y(i,`decodeParams`),Y(a,`encodeParams`),Y(o,`canActivate`),Y(s,`canDeactivate`)}function bn(e,t){if(e!=null&&(typeof e!=`object`||Array.isArray(e)))throw U.type`${t} must be an object or null, got ${w(e)}`}function xn(e){if(!m(e)||e===``)throw sn.type`route must be a non-empty string, got ${typeof e==`string`?`""`:typeof e}`}function Sn(e){let t=new Set;return function(n,r){let i=s(r,e(n));if(i===void 0)return;let a=`${n} ${i}`;t.has(a)||(t.add(a),console.warn(`[router] Route "${n}" declares \`${i}\` as a query param, but it was given in the \`params\` bag — the path channel. The URL is built without it, so the href does not match what you asked for; a plain click throws, but a ⌘-click, a copied link and server-rendered markup all follow the wrong URL in silence. Pass it in \`search\` instead.`))}}function Cn(e){if(!m(e))throw on.type`path must be a string, got ${typeof e}`}function wn(e){if(!m(e))throw an.type`nodeName must be a string, got ${typeof e}`}function Tn(e,t,n,r,i){if(i){let e=t;for(let t of i.split(`.`))if(e=e.children.get(t),!e)throw W.ref`Parent route "${i}" does not exist`}let a=new Set,o=new Map;for(let n of e)l(n,`addRoute`,t,i??``,a,o);tt(e,r,n,i)}function En(e,t,n){let r=new Set(n.getUrlParams(e)),i=n.getUrlParams(t).filter(e=>!r.has(e));if(i.length>0)throw U.plain`forwardTo target "${t}" requires params [${i.join(`, `)}] that are not available in source route "${e}"`}function Dn(e,t,n){let r={...n,[e]:t};d(e,r)}function On(e,t,n,r){if(!n.hasRoute(e))throw U.ref`route "${e}" does not exist`;if(t!=null&&typeof t==`string`){if(!n.hasRoute(t))throw U.plain`forwardTo target "${t}" does not exist`;En(e,t,n),Dn(e,t,r)}}const X=i(`router`,`makeState`),kn=Object.entries;function An(e,t,n){if(!m(e))throw X.type`Invalid name: ${w(e)}. Expected string.`;if(t!==void 0&&!x(t))throw X.type`Invalid params: ${w(t)}. Expected plain object.`;if(n!==void 0&&!m(n))throw X.type`Invalid path: ${w(n)}. Expected string.`}function jn(){let e=new Set;return function(t,n){let r=`${t} ${n}`;e.has(r)||(e.add(r),console.warn(`[router] Query key "${n}" is not declared on route "${t}" (\`?${n}\`), so the current \`queryParamsMode\` will not print it — it was dropped from \`state.search\` rather than published beside a \`state.path\` that cannot show it. Declare it on the route path, or use \`queryParamsMode: "loose"\` to keep undeclared keys. A \`defaultSearch\` entry for "${n}" is dead config in this mode for the same reason.`))}}function Mn(){let e=new Set;return function(t,n){let r=`${t} ${n}`;e.has(r)||(e.add(r),console.warn(`[router] Param "${n}" is declared nowhere on route "${t}" — neither as a path slot (:${n}) nor as a query param (?${n}), so it stays in state.params but never reaches the URL. The state will not round-trip: matchPath(state.path) cannot recover it. Declare it on the route path if it belongs in the URL, or pass it through the search channel; keep it here only if it is deliberately app-level data.`))}}function Nn(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Pn(e,t){let n={params:{...t.params},search:{...t.search}};if(e===void 0)return n;let r=e(n),i=r.params??n.params,a=r.search??n.search;return Nn(i)&&Nn(a)?{params:i,search:a}:void 0}function Fn(e,t){try{return Pn(e,t)}catch{return}}function Z(e){return new Map(kn(e).filter(([,e])=>e!==void 0))}function Q(e){return Array.isArray(e)?e.some(e=>Q(e)):typeof e==`object`&&!!e}function In(e,t){try{return e(t)}catch{return}}function Ln(e,t){let n=n=>{let r=Z(e[n]);return new Map([...Z(t[n])].filter(([e])=>!r.has(e)))};return{params:n(`params`),search:n(`search`)}}function Rn(e,t){return Object.fromEntries(kn(e).filter(([e])=>!t.has(e)))}function zn(e,t,n){if(n.params.size+n.search.size===0)return n;try{let r=t(e.name,Rn(e.params,n.params),Rn(e.search,n.search)),i=e=>{let t=Z(r[e]??{});return new Map([...n[e]].filter(([e,n])=>t.has(e)&&a(t.get(e),n)))};return{params:i(`params`),search:i(`search`)}}catch{return{params:new Map,search:new Map}}}function Bn(e,t,n,r){let i=Fn(e.codec.encode,{...e.state,[t]:{...e.state[t],[n]:r}});return i!==void 0&&a(e.encoded[t][n],i[t][n])}function Vn(e,t,n){return e.credited[t].has(n)?void 0:`added`}function Hn(e,t,n,r,i){if(!Q(i))return a(r,i)?void 0:`changed`;if(!Bn(e,t,n,i))return`changed`;if(!a(r,i))return a(i,e.readAgain()?.[t][n])?`undecoded`:`keyless`}function Un(e,t){let n=Z(e.state[t]),r=Z(e.back[t]),i=[];for(let[a,o]of r){let r=n.has(a)?Hn(e,t,a,n.get(a),o):Vn(e,t,a);r!==void 0&&i.push([t,a,r])}for(let a of n.keys())!r.has(a)&&(t===`search`||e.pathSlots.includes(a))&&i.push([t,a,`dropped`]);return i}function Wn(e,t,n,r,i){let a=r(e.path);if(a?.name!==e.name)return[];let o=Pn(t.encode,e);if(o===void 0)return[];let s,c={state:e,codec:t,pathSlots:n,encoded:o,back:a,readAgain:()=>(s??={state:In(r,e.path)},s.state),credited:zn(a,i,Ln(e,a))};return[...Un(c,`params`),...Un(c,`search`)]}function Gn(e){return e.decode===void 0?`The route has an encodeParams and no decodeParams to undo it.`:e.encode===void 0?`With no encodeParams, decodeParams must return each value so that it prints as the URL shows it.`:`decodeParams must undo encodeParams.`}function Kn(e,t,n,r,i){let a=`Route "${e}": its codec`,o=`${a} changes "${n}" in state.${t}, so a link and a reload of the same URL commit different values.`;switch(r){case`added`:return`${a} adds "${n}" to state.${t}, so a link commits a state without it and a reload of the same URL commits one with it. Derive "${n}" in a forwardState interceptor instead: navigate and matchPath both run it.`;case`changed`:return`${o} ${Gn(i)}`;case`undecoded`:return`${o} encodeParams prints both as one piece of the URL, so a link must pass the value decodeParams returns for that piece.`;case`keyless`:return`${o} Two reloads of one URL decode values that never compare equal: give the value a key — a Date, or a plain object JSON.stringify prints in full.`;case`dropped`:return`${a} drops "${n}" from state.${t}, so a reload of the URL a link builds loses it. ${Gn(i)}`}}function qn(e,t,n){let r=new Set;return function(i,a,o){let s;try{s=Wn(i,a,o,t,n)}catch{return}for(let[t,n,o]of s){let s=`${i.name} ${t} ${n}`;r.has(s)||(r.add(s),e.warn(`router`,Kn(i.name,t,n,o,a)))}}}const Jn=i(`validation-plugin`),Yn=i(`router`,`addRoute`),$=i(`router`,`areStatesEqual`);function Xn(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Zn(e){return{hasRoute:t=>{let n=e.getTree();for(let e of t.split(`.`))if(n=n?.children.get(e),!n)return!1;return!0},getUrlParams:t=>e.getUrlParams(t)}}const Qn={hasRoute:()=>!1,getUrlParams:()=>[]};function $n(e){return{tree:{...e,children:new Map,nonAbsoluteChildren:[]},lookup:Qn,forwardMap:{}}}function er(e,t){let n=[];for(let r of e.getTree().children.keys())n.push(t.get(r));return n}function tr(e,t,n,r){let i=Sn(t=>e.getDeclaredQueryNames(t));return{routes:{validateBuildPathArgs(e,t){xn(e),i(e,t)},validateMatchPathArgs:Cn,validateIsActiveRouteArgs(e,t,n,r){gn(e,t,n,r),i(e,t)},validateShouldUpdateNodeArgs:wn,validateStateBuilderArgs:J,validateRouteName(e,t){C(e,t)},validateSetRootPathArgs:dn},options:{validateOptions:Nt,validateResolvedDefaultRoute(e){nn(e,t)}},dependencies:{validateDependencyName:Oe,validateSetDependencyArgs(e,t,n){ke(e)},validateDependenciesObject(t,n){Ae(t,n),je(t,e.getDependencyKeys(),e.getResolvedLimits().maxDependencies,n)},validateDependencyExists(e,t){Me(t,e)},validateDependencyCount(t,n,r){Ne(t,n,r,e.logger)},validateCloneArgs:Pe,warnOverwrite(t,n){Fe(t,n,e.logger)},warnBatchOverwrite(t,n){Ie(t,n,e.logger)},warnRemoveNonExistent(t){Le(t,e.logger)}},plugins:{validatePluginLimit(e,t,n){It(e,t,n?.maxPlugins)},validateNoDuplicatePlugins:Lt,validatePluginKeys:zt,validateCountThresholds(t){Rt(t,e.getOptions().limits?.maxPlugins??f.maxPlugins,e.logger)},warnBatchDuplicates(){Bt(e.logger)},warnPluginMethodType(t){Vt(t,e.logger)}},lifecycle:{validateHandlerLimit(t,n){rt(t,n,e.getOptions().limits?.maxLifecycleHandlers??f.maxLifecycleHandlers)},validateCountThresholds(t,n){it(t,n,e.getOptions().limits?.maxLifecycleHandlers??f.maxLifecycleHandlers,e.logger)},warnOverwrite(t,n,r){at(t,n,r,e.logger)},warnAsyncGuardSync(t,n){ot(t,n,e.logger)},warnNonBooleanGuardSync(t,n,r){ct(t,n,r,e.logger)},warnNonBooleanGuard(t,n){lt(t,n,e.logger)}},navigation:{validateNavigateToDefaultArgs(t){ht(t),n.check(e.logger)},validateNavigateToStateArgs:gt,validateNavigationOptions:_t,validateParamsShape:A,validateSearch:M,validateStartArgs:bt},state:{validateMakeStateArgs:An,reportDroppedQueryKey:jn(),reportUndeclaredParamKey:Mn(),reportCodecRoundTrip:qn(e.logger,r,e.forwardState),validateAreStatesEqualArgs(e,t,n){if(!he(e))throw $.type`Invalid state1: ${w(e)}. Expected State object.`;if(!he(t))throw $.type`Invalid state2: ${w(t)}. Expected State object.`;if(n!==void 0&&!h(n))throw $.type`Invalid ignoreQueryParams: ${w(n)}. Expected boolean.`;if(n===!1){if(!Xn(e.search))throw $.type`Invalid state1.search: ${w(e.search)}. Expected a plain object.`;if(!Xn(t.search))throw $.type`Invalid state2.search: ${w(t.search)}. Expected a plain object.`}}},eventBus:{validateListenerArgs(e,t){He(e,t)},validateCountThresholds(t,n,r){let i=e.getOptions().limits?.maxListeners??f.maxListeners;Ue(t,n,r,e.logger,i)}}}}function nr(){return n=>{let r=c(n),i=e(n);if(n.isActive())throw Jn.code(`VALIDATION_PLUGIN_AFTER_START`)`must be registered before router.start()`;if(r.validator!==null)throw Jn.code(`VALIDATION_PLUGIN_ALREADY_INSTALLED`)`is already installed on this router — a clone re-runs plugin factories, so it needs no usePlugin of its own`;let a=new be;a.watch(i.getAdoptedOrigins());let o=e=>r.matchPath(e,{...i.getOptions(),rewritePathOnMatch:!1}),s=Zn(i),l=tr(i,s,a,o),u=()=>{r.validator===l&&(r.validator=null)};r.validator=l;try{let e=er(i,t(n)),a=i.getForwardMap(),o=i.getResolvedLimits(),c=i.getOptions();qt(e),Jt(a,s),Xt(e),Zt(a,s),Qt(r.dependenciesGetStore().dependencies,o),$t(c,i.getDependencyKeys().length,o.maxDependencies),r.validator.options.validateOptions(c,`constructor (retrospective)`),typeof c.defaultRoute==`string`&&tn(c.defaultRoute,s)}catch(e){throw u(),e}let d=i.addInterceptor(`start`,(e,t)=>{try{rn(i.getExternalGuardNames(),s,i.logger)}catch{}return e(t)}),f=i.addCheck(`buildPath:params`,e=>{j(e,`buildPath`)}),p=i.addCheck(`buildPathResolved:params`,e=>{j(e,`buildPathResolved`)}),m=i.addCheck(`canNavigateTo:entry`,(e,t,n)=>{C(e,`canNavigateTo`),A(t,`canNavigateTo`),M(n,`canNavigateTo`)}),h=i.addCheck(`canNavigateTo:params`,e=>{j(e,`canNavigateTo`)}),ee=i.addCheck(`navigate:entry`,(e,t,n,r)=>{mt(e),A(t,`navigate`),M(n,`navigate`),_t(r,`navigate`)}),g=i.addCheck(`navigate:params`,e=>{j(e,`navigate`)}),_=(e,t)=>{for(let n of e){let e=D(t,n.name);fn(n),pn(n,e),n.children!==void 0&&_(n.children,e)}},v=(e,t,n,r)=>{if(_(e,typeof n==`string`&&s.hasRoute(n)?n:void 0),n!==void 0&&(hn(n),!s.hasRoute(n)))throw Yn.ref`Parent route "${n}" does not exist`;ln(e,t),mn(e,n);let i=r();Tn(e,i.tree,i.lookup,i.forwardMap,n)},te=i.addCheck(`addRoute:batch`,(e,t)=>{v(e,`addRoute`,t,()=>({tree:i.getTree(),lookup:s,forwardMap:i.getForwardMap()}))}),ne=i.addCheck(`replaceRoutes:batch`,e=>{v(e,`replaceRoutes`,void 0,()=>$n(i.getTree()))}),re=i.addCheck(`removeRoute:entry`,e=>{un(e),K(e,`removeRoute`)}),ie=i.addCheck(`updateRoute:entry`,(e,t)=>{let n=t;_n(e,t),K(e,`updateRoute`),yn({forwardTo:n.forwardTo,defaultParams:n.defaultParams,defaultSearch:n.defaultSearch,decodeParams:n.decodeParams,encodeParams:n.encodeParams,canActivate:n.canActivate,canDeactivate:n.canDeactivate}),On(e,n.forwardTo,s,i.getForwardMap())}),ae=i.addCheck(`hasRoute:entry`,e=>{C(e,`hasRoute`)}),y=i.addCheck(`getRoute:entry`,e=>{C(e,`getRoute`)}),oe=i.addCheck(`forwardState:entry`,(e,t,n)=>{J(e,t,`forwardState`),M(n,`forwardState`)}),se=i.addCheck(`buildNavigationState:state`,(e,t,n)=>{M(n,`buildNavigationState`),J(e,t,`buildNavigationState`)}),b=i.addCheck(`addActivateGuard:entry`,(e,t)=>{C(e,`addActivateGuard`),nt(t,`addActivateGuard`)}),x=i.addCheck(`addDeactivateGuard:entry`,(e,t)=>{C(e,`addDeactivateGuard`),nt(t,`addDeactivateGuard`)}),ce=i.addCheck(`removeActivateGuard:entry`,e=>{C(e,`removeActivateGuard`)}),le=i.addCheck(`removeDeactivateGuard:entry`,e=>{C(e,`removeDeactivateGuard`)}),ue=i.subscribeDiagnostic(`PLUGIN_AFTER_START`,e=>{Ht(e,i.logger)});return{teardown(){f(),p(),m(),h(),ee(),g(),te(),ne(),re(),ie(),ae(),y(),oe(),se(),b(),x(),ce(),le(),ue(),d(),u()}}}}export{nr as validationPlugin};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|