feat: init
This commit is contained in:
58
node_modules/rou3/dist/compiler.d.mts
generated
vendored
Normal file
58
node_modules/rou3/dist/compiler.d.mts
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
interface RouterContext<T = unknown> {
|
||||
root: Node<T>;
|
||||
static: Record<string, Node<T> | undefined>;
|
||||
}
|
||||
type ParamsIndexMap = Array<[Index: number, name: string | RegExp, optional: boolean]>;
|
||||
type MethodData<T = unknown> = {
|
||||
data: T;
|
||||
paramsMap?: ParamsIndexMap;
|
||||
paramsRegexp: RegExp[];
|
||||
};
|
||||
interface Node<T = unknown> {
|
||||
key: string;
|
||||
static?: Record<string, Node<T>>;
|
||||
param?: Node<T>;
|
||||
wildcard?: Node<T>;
|
||||
hasRegexParam?: boolean;
|
||||
methods?: Record<string, MethodData<T>[] | undefined>;
|
||||
}
|
||||
type MatchedRoute<T = unknown> = {
|
||||
data: T;
|
||||
params?: Record<string, string>;
|
||||
};
|
||||
interface RouterCompilerOptions<T = any> {
|
||||
matchAll?: boolean;
|
||||
serialize?: (data: T) => string;
|
||||
}
|
||||
/**
|
||||
* Compiles the router instance into a faster route-matching function.
|
||||
*
|
||||
* **IMPORTANT:** `compileRouter` requires eval support with `new Function()` in the runtime for JIT compilation.
|
||||
*
|
||||
* @example
|
||||
* import { createRouter, addRoute } from "rou3";
|
||||
* import { compileRouter } from "rou3/compiler";
|
||||
* const router = createRouter();
|
||||
* // [add some routes]
|
||||
* const findRoute = compileRouter(router);
|
||||
* const matchAll = compileRouter(router, { matchAll: true });
|
||||
* findRoute("GET", "/path/foo/bar");
|
||||
*
|
||||
* @param router - The router context to compile.
|
||||
*/
|
||||
declare function compileRouter<T, O extends RouterCompilerOptions<T> = RouterCompilerOptions<T>>(router: RouterContext<T>, opts?: O): (method: string, path: string) => O["matchAll"] extends true ? MatchedRoute<T>[] : MatchedRoute<T> | undefined;
|
||||
/**
|
||||
* Compile the router instance into a compact runnable code.
|
||||
*
|
||||
* **IMPORTANT:** Route data must be serializable to JSON (i.e., no functions or classes) or implement the `toJSON()` method to render custom code or you can pass custom `serialize` function in options.
|
||||
*
|
||||
* @example
|
||||
* import { createRouter, addRoute } from "rou3";
|
||||
* import { compileRouterToString } from "rou3/compiler";
|
||||
* const router = createRouter();
|
||||
* // [add some routes with serializable data]
|
||||
* const compilerCode = compileRouterToString(router, "findRoute");
|
||||
* // "const findRoute=(m, p) => {}"
|
||||
*/
|
||||
declare function compileRouterToString(router: RouterContext, functionName?: string, opts?: RouterCompilerOptions): string;
|
||||
export { RouterCompilerOptions, compileRouter, compileRouterToString };
|
||||
140
node_modules/rou3/dist/compiler.mjs
generated
vendored
Normal file
140
node_modules/rou3/dist/compiler.mjs
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* Compiles the router instance into a faster route-matching function.
|
||||
*
|
||||
* **IMPORTANT:** `compileRouter` requires eval support with `new Function()` in the runtime for JIT compilation.
|
||||
*
|
||||
* @example
|
||||
* import { createRouter, addRoute } from "rou3";
|
||||
* import { compileRouter } from "rou3/compiler";
|
||||
* const router = createRouter();
|
||||
* // [add some routes]
|
||||
* const findRoute = compileRouter(router);
|
||||
* const matchAll = compileRouter(router, { matchAll: true });
|
||||
* findRoute("GET", "/path/foo/bar");
|
||||
*
|
||||
* @param router - The router context to compile.
|
||||
*/
|
||||
function compileRouter(router, opts) {
|
||||
const ctx = {
|
||||
opts: opts || {},
|
||||
router,
|
||||
data: []
|
||||
};
|
||||
const compiled = compileRouteMatch(ctx);
|
||||
return new Function(...ctx.data.map((_, i) => `$${i}`), `return(m,p)=>{${compiled}}`)(...ctx.data);
|
||||
}
|
||||
/**
|
||||
* Compile the router instance into a compact runnable code.
|
||||
*
|
||||
* **IMPORTANT:** Route data must be serializable to JSON (i.e., no functions or classes) or implement the `toJSON()` method to render custom code or you can pass custom `serialize` function in options.
|
||||
*
|
||||
* @example
|
||||
* import { createRouter, addRoute } from "rou3";
|
||||
* import { compileRouterToString } from "rou3/compiler";
|
||||
* const router = createRouter();
|
||||
* // [add some routes with serializable data]
|
||||
* const compilerCode = compileRouterToString(router, "findRoute");
|
||||
* // "const findRoute=(m, p) => {}"
|
||||
*/
|
||||
function compileRouterToString(router, functionName, opts) {
|
||||
const ctx = {
|
||||
opts: opts || {},
|
||||
router,
|
||||
data: [],
|
||||
compileToString: true
|
||||
};
|
||||
let compiled = `(m,p)=>{${compileRouteMatch(ctx)}}`;
|
||||
if (ctx.data.length > 0) compiled = `/* @__PURE__ */ (() => { ${`const ${ctx.data.map((v, i) => `$${i}=${v}`).join(",")};`}; return ${compiled}})()`;
|
||||
return functionName ? `const ${functionName}=${compiled};` : compiled;
|
||||
}
|
||||
function compileRouteMatch(ctx) {
|
||||
let code = "";
|
||||
const staticNodes = /* @__PURE__ */ new Set();
|
||||
for (const key in ctx.router.static) {
|
||||
const node = ctx.router.static[key];
|
||||
if (node?.methods) {
|
||||
staticNodes.add(node);
|
||||
code += `if(p===${JSON.stringify(key.replace(/\/$/, "") || "/")}){${compileMethodMatch(ctx, node.methods, [], -1)}}`;
|
||||
}
|
||||
}
|
||||
const match = compileNode(ctx, ctx.router.root, [], 0, staticNodes);
|
||||
if (match) code += `let s=p.split("/"),l=s.length-1;${match}`;
|
||||
if (!code) return ctx.opts?.matchAll ? `return [];` : "";
|
||||
return `${ctx.opts?.matchAll ? `let r=[];` : ""}if(p.charCodeAt(p.length-1)===47)p=p.slice(0,-1)||"/";${code}${ctx.opts?.matchAll ? "return r;" : ""}`;
|
||||
}
|
||||
function compileMethodMatch(ctx, methods, params, currentIdx) {
|
||||
let code = "";
|
||||
for (const key in methods) {
|
||||
const matchers = methods[key];
|
||||
if (matchers && matchers?.length > 0) {
|
||||
if (key !== "") code += `if(m==="${key}")${matchers.length > 1 ? "{" : ""}`;
|
||||
const _matchers = matchers.map((m) => compileFinalMatch(ctx, m, currentIdx, params)).sort((a, b) => b.weight - a.weight);
|
||||
for (const matcher of _matchers) code += matcher.code;
|
||||
if (key !== "") code += matchers.length > 1 ? "}" : "";
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
function compileFinalMatch(ctx, data, currentIdx, params) {
|
||||
let ret = `{data:${serializeData(ctx, data.data)}`;
|
||||
const conditions = [];
|
||||
const { paramsMap, paramsRegexp } = data;
|
||||
if (paramsMap && paramsMap.length > 0) {
|
||||
if (!paramsMap[paramsMap.length - 1][2] && currentIdx !== -1) conditions.push(`l>=${currentIdx}`);
|
||||
for (let i = 0; i < paramsRegexp.length; i++) {
|
||||
const regexp = paramsRegexp[i];
|
||||
if (!regexp) continue;
|
||||
conditions.push(`${regexp.toString()}.test(s[${i + 1}])`);
|
||||
}
|
||||
ret += ",params:{";
|
||||
for (let i = 0; i < paramsMap.length; i++) {
|
||||
const map = paramsMap[i];
|
||||
ret += typeof map[1] === "string" ? `${JSON.stringify(map[1])}:${params[i]},` : `...(${map[1].toString()}.exec(${params[i]}))?.groups,`;
|
||||
}
|
||||
ret += "}";
|
||||
}
|
||||
return {
|
||||
code: (conditions.length > 0 ? `if(${conditions.join("&&")})` : "") + (ctx.opts?.matchAll ? `r.unshift(${ret}});` : `return ${ret}};`),
|
||||
weight: conditions.length
|
||||
};
|
||||
}
|
||||
function compileNode(ctx, node, params, startIdx, staticNodes) {
|
||||
let code = "";
|
||||
if (node.methods && !staticNodes.has(node)) {
|
||||
const match = compileMethodMatch(ctx, node.methods, params, node.key === "*" ? startIdx : -1);
|
||||
if (match) {
|
||||
const hasLastOptionalParam = node.key === "*";
|
||||
code += `if(l===${startIdx}${hasLastOptionalParam ? `||l===${startIdx - 1}` : ""}){${match}}`;
|
||||
}
|
||||
}
|
||||
if (node.static) for (const key in node.static) {
|
||||
const match = compileNode(ctx, node.static[key], params, startIdx + 1, staticNodes);
|
||||
if (match) code += `if(s[${startIdx + 1}]===${JSON.stringify(key)}){${match}}`;
|
||||
}
|
||||
if (node.param) {
|
||||
const match = compileNode(ctx, node.param, [...params, `s[${startIdx + 1}]`], startIdx + 1, staticNodes);
|
||||
if (match) code += match;
|
||||
}
|
||||
if (node.wildcard) {
|
||||
const { wildcard } = node;
|
||||
if (wildcard.static || wildcard.param || wildcard.wildcard) throw new Error("Compiler mode does not support patterns after wildcard");
|
||||
if (wildcard.methods) {
|
||||
const match = compileMethodMatch(ctx, wildcard.methods, [...params, `s.slice(${startIdx + 1}).join('/')`], startIdx);
|
||||
if (match) code += match;
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
function serializeData(ctx, value) {
|
||||
if (ctx.compileToString) if (ctx.opts?.serialize) value = ctx.opts.serialize(value);
|
||||
else if (typeof value?.toJSON === "function") value = value.toJSON();
|
||||
else value = JSON.stringify(value);
|
||||
let index = ctx.data.indexOf(value);
|
||||
if (index === -1) {
|
||||
ctx.data.push(value);
|
||||
index = ctx.data.length - 1;
|
||||
}
|
||||
return `$${index}`;
|
||||
}
|
||||
|
||||
export { compileRouter, compileRouterToString };
|
||||
54
node_modules/rou3/dist/index.d.mts
generated
vendored
Normal file
54
node_modules/rou3/dist/index.d.mts
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
interface RouterContext<T = unknown> {
|
||||
root: Node<T>;
|
||||
static: Record<string, Node<T> | undefined>;
|
||||
}
|
||||
type ParamsIndexMap = Array<[Index: number, name: string | RegExp, optional: boolean]>;
|
||||
type MethodData<T = unknown> = {
|
||||
data: T;
|
||||
paramsMap?: ParamsIndexMap;
|
||||
paramsRegexp: RegExp[];
|
||||
};
|
||||
interface Node<T = unknown> {
|
||||
key: string;
|
||||
static?: Record<string, Node<T>>;
|
||||
param?: Node<T>;
|
||||
wildcard?: Node<T>;
|
||||
hasRegexParam?: boolean;
|
||||
methods?: Record<string, MethodData<T>[] | undefined>;
|
||||
}
|
||||
type MatchedRoute<T = unknown> = {
|
||||
data: T;
|
||||
params?: Record<string, string>;
|
||||
};
|
||||
type ExtractWildcards<TPath extends string, Count extends readonly unknown[] = []> = TPath extends `${string}**:${infer Rest}` ? Rest extends `${infer Param}/${infer Tail}` ? Param | ExtractWildcards<Tail, Count> : Rest : TPath extends `${string}*${infer Rest}` ? Rest extends `*` ? `_` : `_${Count["length"]}` | ExtractWildcards<Rest, [...Count, unknown]> : TPath extends `${string}/${infer Rest}` ? ExtractWildcards<Rest, Count> : never;
|
||||
type ExtractNamedParams<TPath extends string> = TPath extends `${infer _Start}:${infer Rest}` ? Rest extends `${infer Param}/${infer Tail}` ? Param | ExtractNamedParams<`/${Tail}`> : Rest extends `${infer Param}*${infer Tail}` ? Param | ExtractNamedParams<`/${Tail}`> : Rest : TPath extends `/${infer Rest}` ? ExtractNamedParams<Rest> : never;
|
||||
type InferRouteParams<TPath extends string> = { [K in ExtractNamedParams<TPath> | ExtractWildcards<TPath>]: string };
|
||||
/**
|
||||
* Create a new router context.
|
||||
*/
|
||||
declare function createRouter<T = unknown>(): RouterContext<T>;
|
||||
/**
|
||||
* Add a route to the router context.
|
||||
*/
|
||||
declare function addRoute<T>(ctx: RouterContext<T>, method: string | undefined, path: string, data?: T): void;
|
||||
/**
|
||||
* Find a route by path.
|
||||
*/
|
||||
declare function findRoute<T = unknown>(ctx: RouterContext<T>, method: string | undefined, path: string, opts?: {
|
||||
params?: boolean;
|
||||
}): MatchedRoute<T> | undefined;
|
||||
/**
|
||||
* Remove a route from the router context.
|
||||
*/
|
||||
declare function removeRoute<T>(ctx: RouterContext<T>, method: string, path: string): void;
|
||||
/**
|
||||
* Find all route patterns that match the given path.
|
||||
*/
|
||||
declare function findAllRoutes<T>(ctx: RouterContext<T>, method: string | undefined, path: string, opts?: {
|
||||
params?: boolean;
|
||||
}): MatchedRoute<T>[];
|
||||
declare function routeToRegExp(route?: string): RegExp;
|
||||
declare const NullProtoObj: {
|
||||
new (): any;
|
||||
};
|
||||
export { type InferRouteParams, type MatchedRoute, NullProtoObj, type RouterContext, addRoute, createRouter, findAllRoutes, findRoute, removeRoute, routeToRegExp };
|
||||
265
node_modules/rou3/dist/index.mjs
generated
vendored
Normal file
265
node_modules/rou3/dist/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
const NullProtoObj = /* @__PURE__ */ (() => {
|
||||
const e = function() {};
|
||||
return e.prototype = Object.create(null), Object.freeze(e.prototype), e;
|
||||
})();
|
||||
|
||||
/**
|
||||
* Create a new router context.
|
||||
*/
|
||||
function createRouter() {
|
||||
return {
|
||||
root: { key: "" },
|
||||
static: new NullProtoObj()
|
||||
};
|
||||
}
|
||||
|
||||
function splitPath(path) {
|
||||
const [_, ...s] = path.split("/");
|
||||
return s[s.length - 1] === "" ? s.slice(0, -1) : s;
|
||||
}
|
||||
function getMatchParams(segments, paramsMap) {
|
||||
const params = new NullProtoObj();
|
||||
for (const [index, name] of paramsMap) {
|
||||
const segment = index < 0 ? segments.slice(-(index + 1)).join("/") : segments[index];
|
||||
if (typeof name === "string") params[name] = segment;
|
||||
else {
|
||||
const match = segment.match(name);
|
||||
if (match) for (const key in match.groups) params[key] = match.groups[key];
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a route to the router context.
|
||||
*/
|
||||
function addRoute(ctx, method = "", path, data) {
|
||||
method = method.toUpperCase();
|
||||
if (path.charCodeAt(0) !== 47) path = `/${path}`;
|
||||
path = path.replace(/\\:/g, "%3A");
|
||||
const segments = splitPath(path);
|
||||
let node = ctx.root;
|
||||
let _unnamedParamIndex = 0;
|
||||
const paramsMap = [];
|
||||
const paramsRegexp = [];
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
let segment = segments[i];
|
||||
if (segment.startsWith("**")) {
|
||||
if (!node.wildcard) node.wildcard = { key: "**" };
|
||||
node = node.wildcard;
|
||||
paramsMap.push([
|
||||
-(i + 1),
|
||||
segment.split(":")[1] || "_",
|
||||
segment.length === 2
|
||||
]);
|
||||
break;
|
||||
}
|
||||
if (segment === "*" || segment.includes(":")) {
|
||||
if (!node.param) node.param = { key: "*" };
|
||||
node = node.param;
|
||||
if (segment === "*") paramsMap.push([
|
||||
i,
|
||||
`_${_unnamedParamIndex++}`,
|
||||
true
|
||||
]);
|
||||
else if (segment.includes(":", 1)) {
|
||||
const regexp = getParamRegexp(segment);
|
||||
paramsRegexp[i] = regexp;
|
||||
node.hasRegexParam = true;
|
||||
paramsMap.push([
|
||||
i,
|
||||
regexp,
|
||||
false
|
||||
]);
|
||||
} else paramsMap.push([
|
||||
i,
|
||||
segment.slice(1),
|
||||
false
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
if (segment === "\\*") segment = segments[i] = "*";
|
||||
else if (segment === "\\*\\*") segment = segments[i] = "**";
|
||||
const child = node.static?.[segment];
|
||||
if (child) node = child;
|
||||
else {
|
||||
const staticNode = { key: segment };
|
||||
if (!node.static) node.static = new NullProtoObj();
|
||||
node.static[segment] = staticNode;
|
||||
node = staticNode;
|
||||
}
|
||||
}
|
||||
const hasParams = paramsMap.length > 0;
|
||||
if (!node.methods) node.methods = new NullProtoObj();
|
||||
node.methods[method] ??= [];
|
||||
node.methods[method].push({
|
||||
data: data || null,
|
||||
paramsRegexp,
|
||||
paramsMap: hasParams ? paramsMap : void 0
|
||||
});
|
||||
if (!hasParams) ctx.static["/" + segments.join("/")] = node;
|
||||
}
|
||||
function getParamRegexp(segment) {
|
||||
const regex = segment.replace(/:(\w+)/g, (_, id) => `(?<${id}>[^/]+)`).replace(/\./g, "\\.");
|
||||
return /* @__PURE__ */ new RegExp(`^${regex}$`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a route by path.
|
||||
*/
|
||||
function findRoute(ctx, method = "", path, opts) {
|
||||
if (path.charCodeAt(path.length - 1) === 47) path = path.slice(0, -1);
|
||||
const staticNode = ctx.static[path];
|
||||
if (staticNode && staticNode.methods) {
|
||||
const staticMatch = staticNode.methods[method] || staticNode.methods[""];
|
||||
if (staticMatch !== void 0) return staticMatch[0];
|
||||
}
|
||||
const segments = splitPath(path);
|
||||
const match = _lookupTree(ctx, ctx.root, method, segments, 0)?.[0];
|
||||
if (match === void 0) return;
|
||||
if (opts?.params === false) return match;
|
||||
return {
|
||||
data: match.data,
|
||||
params: match.paramsMap ? getMatchParams(segments, match.paramsMap) : void 0
|
||||
};
|
||||
}
|
||||
function _lookupTree(ctx, node, method, segments, index) {
|
||||
if (index === segments.length) {
|
||||
if (node.methods) {
|
||||
const match = node.methods[method] || node.methods[""];
|
||||
if (match) return match;
|
||||
}
|
||||
if (node.param && node.param.methods) {
|
||||
const match = node.param.methods[method] || node.param.methods[""];
|
||||
if (match) {
|
||||
const pMap = match[0].paramsMap;
|
||||
if (pMap?.[pMap?.length - 1]?.[2]) return match;
|
||||
}
|
||||
}
|
||||
if (node.wildcard && node.wildcard.methods) {
|
||||
const match = node.wildcard.methods[method] || node.wildcard.methods[""];
|
||||
if (match) {
|
||||
const pMap = match[0].paramsMap;
|
||||
if (pMap?.[pMap?.length - 1]?.[2]) return match;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
const segment = segments[index];
|
||||
if (node.static) {
|
||||
const staticChild = node.static[segment];
|
||||
if (staticChild) {
|
||||
const match = _lookupTree(ctx, staticChild, method, segments, index + 1);
|
||||
if (match) return match;
|
||||
}
|
||||
}
|
||||
if (node.param) {
|
||||
const match = _lookupTree(ctx, node.param, method, segments, index + 1);
|
||||
if (match) {
|
||||
if (node.param.hasRegexParam) {
|
||||
const exactMatch = match.find((m) => m.paramsRegexp[index]?.test(segment)) || match.find((m) => !m.paramsRegexp[index]);
|
||||
return exactMatch ? [exactMatch] : void 0;
|
||||
}
|
||||
return match;
|
||||
}
|
||||
}
|
||||
if (node.wildcard && node.wildcard.methods) return node.wildcard.methods[method] || node.wildcard.methods[""];
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a route from the router context.
|
||||
*/
|
||||
function removeRoute(ctx, method, path) {
|
||||
const segments = splitPath(path);
|
||||
return _remove(ctx.root, method || "", segments, 0);
|
||||
}
|
||||
function _remove(node, method, segments, index) {
|
||||
if (index === segments.length) {
|
||||
if (node.methods && method in node.methods) {
|
||||
delete node.methods[method];
|
||||
if (Object.keys(node.methods).length === 0) node.methods = void 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const segment = segments[index];
|
||||
if (segment === "*") {
|
||||
if (node.param) {
|
||||
_remove(node.param, method, segments, index + 1);
|
||||
if (_isEmptyNode(node.param)) node.param = void 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (segment.startsWith("**")) {
|
||||
if (node.wildcard) {
|
||||
_remove(node.wildcard, method, segments, index + 1);
|
||||
if (_isEmptyNode(node.wildcard)) node.wildcard = void 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const childNode = node.static?.[segment];
|
||||
if (childNode) {
|
||||
_remove(childNode, method, segments, index + 1);
|
||||
if (_isEmptyNode(childNode)) {
|
||||
delete node.static[segment];
|
||||
if (Object.keys(node.static).length === 0) node.static = void 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
function _isEmptyNode(node) {
|
||||
return node.methods === void 0 && node.static === void 0 && node.param === void 0 && node.wildcard === void 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all route patterns that match the given path.
|
||||
*/
|
||||
function findAllRoutes(ctx, method = "", path, opts) {
|
||||
if (path.charCodeAt(path.length - 1) === 47) path = path.slice(0, -1);
|
||||
const segments = splitPath(path);
|
||||
const matches = _findAll(ctx, ctx.root, method, segments, 0);
|
||||
if (opts?.params === false) return matches;
|
||||
return matches.map((m) => {
|
||||
return {
|
||||
data: m.data,
|
||||
params: m.paramsMap ? getMatchParams(segments, m.paramsMap) : void 0
|
||||
};
|
||||
});
|
||||
}
|
||||
function _findAll(ctx, node, method, segments, index, matches = []) {
|
||||
const segment = segments[index];
|
||||
if (node.wildcard && node.wildcard.methods) {
|
||||
const match = node.wildcard.methods[method] || node.wildcard.methods[""];
|
||||
if (match) matches.push(...match);
|
||||
}
|
||||
if (node.param) {
|
||||
_findAll(ctx, node.param, method, segments, index + 1, matches);
|
||||
if (index === segments.length && node.param.methods) {
|
||||
const match = node.param.methods[method] || node.param.methods[""];
|
||||
if (match) {
|
||||
const pMap = match[0].paramsMap;
|
||||
if (pMap?.[pMap?.length - 1]?.[2]) matches.push(...match);
|
||||
}
|
||||
}
|
||||
}
|
||||
const staticChild = node.static?.[segment];
|
||||
if (staticChild) _findAll(ctx, staticChild, method, segments, index + 1, matches);
|
||||
if (index === segments.length && node.methods) {
|
||||
const match = node.methods[method] || node.methods[""];
|
||||
if (match) matches.push(...match);
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
function routeToRegExp(route = "/") {
|
||||
const reSegments = [];
|
||||
let idCtr = 0;
|
||||
for (const segment of route.split("/")) {
|
||||
if (!segment) continue;
|
||||
if (segment === "*") reSegments.push(`(?<_${idCtr++}>[^/]*)`);
|
||||
else if (segment.startsWith("**")) reSegments.push(segment === "**" ? "?(?<_>.*)" : `?(?<${segment.slice(3)}>.+)`);
|
||||
else if (segment.includes(":")) reSegments.push(segment.replace(/:(\w+)/g, (_, id) => `(?<${id}>[^/]+)`).replace(/\./g, "\\."));
|
||||
else reSegments.push(segment);
|
||||
}
|
||||
return /* @__PURE__ */ new RegExp(`^/${reSegments.join("/")}/?$`);
|
||||
}
|
||||
|
||||
export { NullProtoObj, addRoute, createRouter, findAllRoutes, findRoute, removeRoute, routeToRegExp };
|
||||
Reference in New Issue
Block a user