@aura-stack/router 0.6.0-rc.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/router.cjs CHANGED
@@ -20,10 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/router.ts
21
21
  var router_exports = {};
22
22
  __export(router_exports, {
23
- createNode: () => createNode,
24
- createRouter: () => createRouter,
25
- insert: () => insert,
26
- search: () => search
23
+ createRouter: () => createRouter
27
24
  });
28
25
  module.exports = __toCommonJS(router_exports);
29
26
 
@@ -103,6 +100,162 @@ var InvalidZodSchemaError = class {
103
100
  }
104
101
  };
105
102
 
103
+ // src/trie.ts
104
+ var TrieNode = class {
105
+ param;
106
+ statics = /* @__PURE__ */ new Map();
107
+ endpoints = /* @__PURE__ */ new Map();
108
+ };
109
+ var TrieRouter = class {
110
+ root;
111
+ statics;
112
+ methods;
113
+ constructor() {
114
+ this.statics = /* @__PURE__ */ new Map();
115
+ this.methods = /* @__PURE__ */ new Set();
116
+ this.root = new TrieNode();
117
+ }
118
+ add(endpoint) {
119
+ const isDynamic = endpoint.route.includes(":");
120
+ const methods = Array.isArray(endpoint.method) ? endpoint.method : [endpoint.method];
121
+ if (!isDynamic) {
122
+ for (const method of methods) {
123
+ this.statics.set(`${method} ${endpoint.route}`, endpoint);
124
+ }
125
+ } else {
126
+ let node = this.root;
127
+ const route = endpoint.route;
128
+ const routeLength = route.length;
129
+ let prev = 0;
130
+ while (prev < routeLength) {
131
+ const curr = route.indexOf("/", prev);
132
+ const end = curr === -1 ? routeLength : curr;
133
+ if (end > prev) {
134
+ const segment = route.slice(prev, end);
135
+ if (segment[0] === ":") {
136
+ const name = segment.slice(1);
137
+ let param = node.param;
138
+ if (!param) {
139
+ param = { name, node: new TrieNode() };
140
+ node.param = param;
141
+ } else if (param.name !== name) {
142
+ throw new RouterError(
143
+ "BAD_REQUEST",
144
+ `Conflicting in the route by the dynamic segment "${param.name}" and "${name}"`
145
+ );
146
+ }
147
+ node = param.node;
148
+ } else {
149
+ let child = node.statics.get(segment);
150
+ if (!child) {
151
+ child = new TrieNode();
152
+ node.statics.set(segment, child);
153
+ }
154
+ node = child;
155
+ }
156
+ }
157
+ if (curr === -1) {
158
+ break;
159
+ }
160
+ prev = curr + 1;
161
+ }
162
+ for (const method of methods) {
163
+ node.endpoints.set(method, endpoint);
164
+ }
165
+ }
166
+ for (const method of methods) {
167
+ this.methods.add(method);
168
+ }
169
+ }
170
+ match(method, pathname) {
171
+ const staticEndpoint = this.statics.get(`${method} ${pathname}`);
172
+ if (staticEndpoint) {
173
+ return { endpoint: staticEndpoint, params: {} };
174
+ }
175
+ let node = this.root;
176
+ const params = {};
177
+ const pathLength = pathname.length;
178
+ let prev = 0;
179
+ while (prev < pathLength) {
180
+ const curr = pathname.indexOf("/", prev);
181
+ const end = curr === -1 ? pathLength : curr;
182
+ if (end > prev) {
183
+ const segment = pathname.slice(prev, end);
184
+ const staticNode = node.statics.get(segment);
185
+ if (staticNode) {
186
+ node = staticNode;
187
+ } else {
188
+ const param = node.param;
189
+ if (!param) {
190
+ return null;
191
+ }
192
+ params[param.name] = decodeURIComponent(segment);
193
+ node = param.node;
194
+ }
195
+ }
196
+ if (curr === -1) {
197
+ break;
198
+ }
199
+ prev = curr + 1;
200
+ }
201
+ const endpoint = node.endpoints.get(method);
202
+ if (!endpoint) {
203
+ return null;
204
+ }
205
+ return { endpoint, params };
206
+ }
207
+ };
208
+
209
+ // src/assert.ts
210
+ var supportedMethods = /* @__PURE__ */ new Set(["GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS", "HEAD", "TRACE", "CONNECT"]);
211
+ var supportedBodyMethods = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH"]);
212
+ var isSupportedMethod = (method) => {
213
+ if (Array.isArray(method)) {
214
+ return method.every((meth) => supportedMethods.has(meth));
215
+ }
216
+ return supportedMethods.has(method);
217
+ };
218
+ var isSupportedBodyMethod = (method) => {
219
+ return supportedBodyMethods.has(method);
220
+ };
221
+ var isRouterError = (error) => {
222
+ return error instanceof RouterError;
223
+ };
224
+ var isInvalidZodSchemaError = (error) => {
225
+ return error instanceof InvalidZodSchemaError;
226
+ };
227
+
228
+ // src/on-error.ts
229
+ var onError = async (error, request, config) => {
230
+ if (config.onError) {
231
+ try {
232
+ const response = await config.onError(error, request);
233
+ return response;
234
+ } catch {
235
+ return Response.json(
236
+ { message: "A critical failure occurred during error handling" },
237
+ { status: 500, statusText: statusText.INTERNAL_SERVER_ERROR }
238
+ );
239
+ }
240
+ }
241
+ if (isInvalidZodSchemaError(error)) {
242
+ const { errors, status, statusText: statusText2 } = error;
243
+ return Response.json(
244
+ {
245
+ message: "Invalid request data",
246
+ error: "validation_error",
247
+ details: errors
248
+ },
249
+ { status, statusText: statusText2 }
250
+ );
251
+ }
252
+ if (isRouterError(error)) {
253
+ const { message, status, statusText: statusText2 } = error;
254
+ return Response.json({ message }, { status, statusText: statusText2 });
255
+ }
256
+ return Response.json({ message: "Internal Server Error" }, { status: 500, statusText: statusText.INTERNAL_SERVER_ERROR });
257
+ };
258
+
106
259
  // src/headers.ts
107
260
  var import_cookie = require("cookie");
108
261
  var HeadersBuilder = class {
@@ -138,22 +291,6 @@ var HeadersBuilder = class {
138
291
  }
139
292
  };
140
293
 
141
- // src/assert.ts
142
- var supportedMethods = /* @__PURE__ */ new Set(["GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS", "HEAD", "TRACE", "CONNECT"]);
143
- var supportedBodyMethods = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH"]);
144
- var isSupportedMethod = (method) => {
145
- return supportedMethods.has(method);
146
- };
147
- var isSupportedBodyMethod = (method) => {
148
- return supportedBodyMethods.has(method);
149
- };
150
- var isRouterError = (error) => {
151
- return error instanceof RouterError;
152
- };
153
- var isInvalidZodSchemaError = (error) => {
154
- return error instanceof InvalidZodSchemaError;
155
- };
156
-
157
294
  // src/context.ts
158
295
  var formatZodError = (error) => {
159
296
  if (!error.issues || error.issues.length === 0) {
@@ -232,9 +369,9 @@ var createContentTypeRegex = (contentTypes, contenType) => {
232
369
  };
233
370
 
234
371
  // src/middlewares.ts
235
- var executeGlobalMiddlewares = async (context, middlewares) => {
236
- if (!middlewares) return context;
237
- for (const middleware of middlewares) {
372
+ var executeGlobalMiddlewares = async (context, use) => {
373
+ if (!use) return context;
374
+ for (const middleware of use) {
238
375
  if (typeof middleware !== "function") {
239
376
  throw new RouterError("BAD_REQUEST", "Global middlewares must be functions");
240
377
  }
@@ -249,10 +386,10 @@ var executeGlobalMiddlewares = async (context, middlewares) => {
249
386
  }
250
387
  return context;
251
388
  };
252
- var executeMiddlewares = async (context, middlewares = []) => {
389
+ var executeMiddlewares = async (context, use = []) => {
253
390
  try {
254
391
  let ctx = context;
255
- for (const middleware of middlewares) {
392
+ for (const middleware of use) {
256
393
  if (typeof middleware !== "function") {
257
394
  throw new RouterError("BAD_REQUEST", "Middleware must be a function");
258
395
  }
@@ -265,103 +402,24 @@ var executeMiddlewares = async (context, middlewares = []) => {
265
402
  };
266
403
 
267
404
  // src/router.ts
268
- var createNode = () => ({
269
- statics: /* @__PURE__ */ new Map(),
270
- endpoints: /* @__PURE__ */ new Map()
271
- });
272
- var insert = (root, endpoint) => {
273
- if (!root || !endpoint) return;
274
- let node = root;
275
- const segments = endpoint.route === "/" ? [] : endpoint.route.split("/").filter(Boolean);
276
- for (const segment of segments) {
277
- if (segment.startsWith(":")) {
278
- const name = segment.slice(1);
279
- if (!node.param) {
280
- node.param = { name, node: createNode() };
281
- } else if (node.param.name !== name) {
282
- throw new RouterError(
283
- "BAD_REQUEST",
284
- `Conflicting in the route by the dynamic segment "${node.param.name}" and "${name}"`
285
- );
286
- }
287
- node = node.param.node;
288
- } else {
289
- if (!node.statics.has(segment)) {
290
- node.statics.set(segment, createNode());
291
- }
292
- node = node.statics.get(segment);
293
- }
294
- }
295
- if (node.endpoints.has(endpoint.method)) {
296
- throw new RouterError("BAD_REQUEST", `Duplicate endpoint for ${endpoint?.method} ${endpoint?.route}`);
297
- }
298
- node.endpoints.set(endpoint.method, endpoint);
299
- };
300
- var search = (method, root, pathname) => {
301
- let node = root;
302
- const params = {};
303
- const segments = pathname === "/" ? [] : pathname.split("/").filter(Boolean);
304
- for (const segment of segments) {
305
- if (node?.statics.has(segment)) {
306
- node = node.statics.get(segment);
307
- } else if (node?.param) {
308
- params[node.param.name] = decodeURIComponent(segment);
309
- node = node.param.node;
310
- } else {
311
- throw new RouterError("NOT_FOUND", `No route found for path: ${pathname}`);
312
- }
313
- }
314
- if (!node.endpoints.has(method)) {
315
- throw new RouterError("NOT_FOUND", `No route found for path: ${pathname}`);
316
- }
317
- return { endpoint: node.endpoints.get(method), params };
318
- };
319
- var handleError = async (error, request, config) => {
320
- if (config.onError) {
321
- try {
322
- const response = await config.onError(error, request);
323
- return response;
324
- } catch {
325
- return Response.json(
326
- { message: "A critical failure occurred during error handling" },
327
- { status: 500, statusText: statusText.INTERNAL_SERVER_ERROR }
328
- );
329
- }
330
- }
331
- if (isInvalidZodSchemaError(error)) {
332
- const { errors, status, statusText: statusText2 } = error;
333
- return Response.json(
334
- {
335
- message: "Invalid request data",
336
- error: "validation_error",
337
- details: errors
338
- },
339
- { status, statusText: statusText2 }
340
- );
341
- }
342
- if (isRouterError(error)) {
343
- const { message, status, statusText: statusText2 } = error;
344
- return Response.json({ message }, { status, statusText: statusText2 });
345
- }
346
- return Response.json({ message: "Internal Server Error" }, { status: 500, statusText: statusText.INTERNAL_SERVER_ERROR });
347
- };
348
- var handleRequest = async (method, request, config, root) => {
405
+ var handleRequest = async (method, request, config, router) => {
349
406
  try {
350
407
  if (!isSupportedMethod(request.method)) {
351
408
  throw new RouterError("METHOD_NOT_ALLOWED", `The HTTP method '${request.method}' is not supported`);
352
409
  }
353
410
  const globalContext = { request, context: config.context ?? {} };
354
- const globalRequestContext = await executeGlobalMiddlewares(globalContext, config.middlewares);
411
+ const globalRequestContext = await executeGlobalMiddlewares(globalContext, config.use);
355
412
  if (globalRequestContext instanceof Response) return globalRequestContext;
356
413
  const url = new URL(globalRequestContext.request.url);
357
414
  const pathnameWithBase = url.pathname;
358
415
  if (globalRequestContext.request.method !== method) {
359
416
  throw new RouterError("METHOD_NOT_ALLOWED", `The HTTP method '${globalRequestContext.request.method}' is not allowed`);
360
417
  }
361
- const { endpoint, params } = search(method, root, pathnameWithBase);
362
- if (endpoint.method !== globalRequestContext.request.method) {
363
- throw new RouterError("METHOD_NOT_ALLOWED", `The HTTP method '${globalRequestContext.request.method}' is not allowed`);
418
+ const node = router.match(method, pathnameWithBase);
419
+ if (!node) {
420
+ throw new RouterError("NOT_FOUND", `No route found for path: ${pathnameWithBase}`);
364
421
  }
422
+ const { endpoint, params } = node;
365
423
  const dynamicParams = getRouteParams(params, endpoint.config);
366
424
  const body = await getBody(globalRequestContext.request, endpoint.config);
367
425
  const searchParams = getSearchParams(globalRequestContext.request.url, endpoint.config);
@@ -377,31 +435,31 @@ var handleRequest = async (method, request, config, root) => {
377
435
  route: endpoint.route,
378
436
  context: config.context ?? {}
379
437
  };
380
- context = await executeMiddlewares(context, endpoint.config.middlewares);
438
+ context = await executeMiddlewares(context, endpoint.config.use);
381
439
  const response = await endpoint.handler(context);
382
440
  return response;
383
441
  } catch (error) {
384
- return handleError(error, request, config);
442
+ return onError(error, request, config);
385
443
  }
386
444
  };
387
445
  var createRouter = (endpoints, config = {}) => {
388
- const root = createNode();
446
+ const router = new TrieRouter();
389
447
  const server = {};
390
448
  const methods = /* @__PURE__ */ new Set();
391
449
  for (const endpoint of endpoints) {
392
450
  const withBasePath = config.basePath ? `${config.basePath}${endpoint.route}` : endpoint.route;
393
- insert(root, { ...endpoint, route: withBasePath });
394
- methods.add(endpoint.method);
451
+ router.add({ ...endpoint, route: withBasePath });
452
+ const endpointMethods = Array.isArray(endpoint.method) ? endpoint.method : [endpoint.method];
453
+ for (const method of endpointMethods) {
454
+ methods.add(method);
455
+ }
395
456
  }
396
457
  for (const method of methods) {
397
- server[method] = (request) => handleRequest(method, request, config, root);
458
+ server[method] = (request) => handleRequest(method, request, config, router);
398
459
  }
399
460
  return server;
400
461
  };
401
462
  // Annotate the CommonJS export names for ESM import in node:
402
463
  0 && (module.exports = {
403
- createNode,
404
- createRouter,
405
- insert,
406
- search
464
+ createRouter
407
465
  });
package/dist/router.d.ts CHANGED
@@ -1,31 +1,9 @@
1
- import { RouteEndpoint, RouterConfig, Router, HTTPMethod, RoutePattern, EndpointSchemas, MiddlewareFunction } from './types.js';
1
+ import { RouteEndpoint, RouterConfig, Router } from './types.js';
2
2
  import 'zod';
3
3
  import './error.js';
4
4
  import './headers.js';
5
5
  import 'cookie';
6
- import 'http';
7
6
 
8
- interface TrieNode {
9
- statics: Map<string, TrieNode>;
10
- param?: {
11
- name: string;
12
- node: TrieNode;
13
- };
14
- endpoints: Map<HTTPMethod, RouteEndpoint>;
15
- }
16
- declare const createNode: () => TrieNode;
17
- declare const insert: (root: TrieNode, endpoint: RouteEndpoint) => void;
18
- declare const search: (method: HTTPMethod, root: TrieNode, pathname: string) => {
19
- endpoint: RouteEndpoint<HTTPMethod, RoutePattern, {
20
- schemas?: EndpointSchemas | undefined;
21
- middlewares?: MiddlewareFunction<{} | {
22
- [x: string]: string;
23
- }, {
24
- schemas: EndpointSchemas;
25
- }>[] | undefined;
26
- }>;
27
- params: Record<string, string>;
28
- };
29
7
  /**
30
8
  * Creates the entry point for the server, handling the endpoints defined in the router.
31
9
  * It groups endpoints by HTTP method and matches incoming requests to the appropriate endpoint.
@@ -37,4 +15,4 @@ declare const search: (method: HTTPMethod, root: TrieNode, pathname: string) =>
37
15
  */
38
16
  declare const createRouter: <const Endpoints extends RouteEndpoint[]>(endpoints: Endpoints, config?: RouterConfig) => Router<Endpoints>;
39
17
 
40
- export { createNode, createRouter, insert, search };
18
+ export { createRouter };
package/dist/router.js CHANGED
@@ -1,17 +1,13 @@
1
1
  import {
2
- createNode,
3
- createRouter,
4
- insert,
5
- search
6
- } from "./chunk-WJXMLTGP.js";
7
- import "./chunk-6CIHAUKJ.js";
8
- import "./chunk-SY4MM2AG.js";
9
- import "./chunk-3X2BFSRT.js";
2
+ createRouter
3
+ } from "./chunk-3ATEFJBU.js";
4
+ import "./chunk-JAYQXZDB.js";
5
+ import "./chunk-VRGPOTTV.js";
6
+ import "./chunk-FS3EN7NZ.js";
7
+ import "./chunk-HHL2LY22.js";
8
+ import "./chunk-NFASFT4W.js";
10
9
  import "./chunk-FJYSN2I6.js";
11
10
  import "./chunk-6JNMFP4L.js";
12
11
  export {
13
- createNode,
14
- createRouter,
15
- insert,
16
- search
12
+ createRouter
17
13
  };
package/dist/trie.cjs ADDED
@@ -0,0 +1,203 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/trie.ts
21
+ var trie_exports = {};
22
+ __export(trie_exports, {
23
+ TrieNode: () => TrieNode,
24
+ TrieRouter: () => TrieRouter
25
+ });
26
+ module.exports = __toCommonJS(trie_exports);
27
+
28
+ // src/error.ts
29
+ var statusCode = {
30
+ OK: 200,
31
+ CREATED: 201,
32
+ ACCEPTED: 202,
33
+ NO_CONTENT: 204,
34
+ MULTIPLE_CHOICES: 300,
35
+ MOVED_PERMANENTLY: 301,
36
+ FOUND: 302,
37
+ SEE_OTHER: 303,
38
+ NOT_MODIFIED: 304,
39
+ TEMPORARY_REDIRECT: 307,
40
+ BAD_REQUEST: 400,
41
+ UNAUTHORIZED: 401,
42
+ PAYMENT_REQUIRED: 402,
43
+ FORBIDDEN: 403,
44
+ NOT_FOUND: 404,
45
+ METHOD_NOT_ALLOWED: 405,
46
+ NOT_ACCEPTABLE: 406,
47
+ PROXY_AUTHENTICATION_REQUIRED: 407,
48
+ UNPROCESSABLE_ENTITY: 422,
49
+ INTERNAL_SERVER_ERROR: 500,
50
+ NOT_IMPLEMENTED: 501,
51
+ BAD_GATEWAY: 502,
52
+ SERVICE_UNAVAILABLE: 503,
53
+ HTTP_VERSION_NOT_SUPPORTED: 505
54
+ };
55
+ var statusText = Object.keys(statusCode).reduce(
56
+ (previous, status) => {
57
+ return { ...previous, [status]: status };
58
+ },
59
+ {}
60
+ );
61
+ var AuraStackRouterError = class extends Error {
62
+ /**
63
+ * The HTTP status code associated with the error.
64
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status
65
+ * @example
66
+ * NOT_FOUND: 404
67
+ * METHOD_NOT_ALLOWED: 405
68
+ * INTERNAL_SERVER_ERROR: 500
69
+ */
70
+ status;
71
+ /**
72
+ * The HTTP status text associated with the status code of the error.
73
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status
74
+ * @example
75
+ * NOT_FOUND: NOT_FOUND
76
+ * METHOD_NOT_ALLOWED: METHOD_NOT_ALLOWED
77
+ * INTERNAL_SERVER_ERROR: INTERNAL_SERVER_ERROR
78
+ */
79
+ statusText;
80
+ constructor(type, message, name) {
81
+ super(message);
82
+ this.name = name ?? "RouterError";
83
+ this.status = statusCode[type];
84
+ this.statusText = statusText[type];
85
+ }
86
+ };
87
+ var RouterError = class extends AuraStackRouterError {
88
+ constructor(type, message, name) {
89
+ super(type, message, name);
90
+ this.name = name ?? "RouterError";
91
+ }
92
+ };
93
+
94
+ // src/trie.ts
95
+ var TrieNode = class {
96
+ param;
97
+ statics = /* @__PURE__ */ new Map();
98
+ endpoints = /* @__PURE__ */ new Map();
99
+ };
100
+ var TrieRouter = class {
101
+ root;
102
+ statics;
103
+ methods;
104
+ constructor() {
105
+ this.statics = /* @__PURE__ */ new Map();
106
+ this.methods = /* @__PURE__ */ new Set();
107
+ this.root = new TrieNode();
108
+ }
109
+ add(endpoint) {
110
+ const isDynamic = endpoint.route.includes(":");
111
+ const methods = Array.isArray(endpoint.method) ? endpoint.method : [endpoint.method];
112
+ if (!isDynamic) {
113
+ for (const method of methods) {
114
+ this.statics.set(`${method} ${endpoint.route}`, endpoint);
115
+ }
116
+ } else {
117
+ let node = this.root;
118
+ const route = endpoint.route;
119
+ const routeLength = route.length;
120
+ let prev = 0;
121
+ while (prev < routeLength) {
122
+ const curr = route.indexOf("/", prev);
123
+ const end = curr === -1 ? routeLength : curr;
124
+ if (end > prev) {
125
+ const segment = route.slice(prev, end);
126
+ if (segment[0] === ":") {
127
+ const name = segment.slice(1);
128
+ let param = node.param;
129
+ if (!param) {
130
+ param = { name, node: new TrieNode() };
131
+ node.param = param;
132
+ } else if (param.name !== name) {
133
+ throw new RouterError(
134
+ "BAD_REQUEST",
135
+ `Conflicting in the route by the dynamic segment "${param.name}" and "${name}"`
136
+ );
137
+ }
138
+ node = param.node;
139
+ } else {
140
+ let child = node.statics.get(segment);
141
+ if (!child) {
142
+ child = new TrieNode();
143
+ node.statics.set(segment, child);
144
+ }
145
+ node = child;
146
+ }
147
+ }
148
+ if (curr === -1) {
149
+ break;
150
+ }
151
+ prev = curr + 1;
152
+ }
153
+ for (const method of methods) {
154
+ node.endpoints.set(method, endpoint);
155
+ }
156
+ }
157
+ for (const method of methods) {
158
+ this.methods.add(method);
159
+ }
160
+ }
161
+ match(method, pathname) {
162
+ const staticEndpoint = this.statics.get(`${method} ${pathname}`);
163
+ if (staticEndpoint) {
164
+ return { endpoint: staticEndpoint, params: {} };
165
+ }
166
+ let node = this.root;
167
+ const params = {};
168
+ const pathLength = pathname.length;
169
+ let prev = 0;
170
+ while (prev < pathLength) {
171
+ const curr = pathname.indexOf("/", prev);
172
+ const end = curr === -1 ? pathLength : curr;
173
+ if (end > prev) {
174
+ const segment = pathname.slice(prev, end);
175
+ const staticNode = node.statics.get(segment);
176
+ if (staticNode) {
177
+ node = staticNode;
178
+ } else {
179
+ const param = node.param;
180
+ if (!param) {
181
+ return null;
182
+ }
183
+ params[param.name] = decodeURIComponent(segment);
184
+ node = param.node;
185
+ }
186
+ }
187
+ if (curr === -1) {
188
+ break;
189
+ }
190
+ prev = curr + 1;
191
+ }
192
+ const endpoint = node.endpoints.get(method);
193
+ if (!endpoint) {
194
+ return null;
195
+ }
196
+ return { endpoint, params };
197
+ }
198
+ };
199
+ // Annotate the CommonJS export names for ESM import in node:
200
+ 0 && (module.exports = {
201
+ TrieNode,
202
+ TrieRouter
203
+ });
package/dist/trie.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ import { HTTPMethod, RouteEndpoint, RoutePattern, EndpointSchemas, MiddlewareFunction } from './types.js';
2
+ import 'zod';
3
+ import './error.js';
4
+ import './headers.js';
5
+ import 'cookie';
6
+
7
+ declare class TrieNode {
8
+ param?: {
9
+ name: string;
10
+ node: TrieNode;
11
+ } | undefined;
12
+ statics: Map<string, TrieNode>;
13
+ endpoints: Map<HTTPMethod, RouteEndpoint>;
14
+ }
15
+ declare class TrieRouter {
16
+ private root;
17
+ private statics;
18
+ private methods;
19
+ constructor();
20
+ add(endpoint: RouteEndpoint): void;
21
+ match(method: HTTPMethod, pathname: string): {
22
+ endpoint: RouteEndpoint<HTTPMethod | HTTPMethod[], RoutePattern, {
23
+ schemas?: EndpointSchemas | undefined;
24
+ use?: MiddlewareFunction<{} | {
25
+ [x: string]: string;
26
+ }, {
27
+ schemas: EndpointSchemas;
28
+ }>[] | undefined;
29
+ }>;
30
+ params: Record<string, string>;
31
+ } | null;
32
+ }
33
+
34
+ export { TrieNode, TrieRouter };
package/dist/trie.js ADDED
@@ -0,0 +1,9 @@
1
+ import {
2
+ TrieNode,
3
+ TrieRouter
4
+ } from "./chunk-FS3EN7NZ.js";
5
+ import "./chunk-FJYSN2I6.js";
6
+ export {
7
+ TrieNode,
8
+ TrieRouter
9
+ };