@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/assert.cjs +3 -0
- package/dist/assert.d.ts +1 -2
- package/dist/assert.js +1 -1
- package/dist/chunk-3ATEFJBU.js +87 -0
- package/dist/chunk-FS3EN7NZ.js +114 -0
- package/dist/{chunk-SY4MM2AG.js → chunk-HHL2LY22.js} +1 -1
- package/dist/{chunk-SP2NSNB2.js → chunk-ISIML7WX.js} +7 -4
- package/dist/{chunk-6CIHAUKJ.js → chunk-JAYQXZDB.js} +5 -5
- package/dist/{chunk-3X2BFSRT.js → chunk-NFASFT4W.js} +3 -0
- package/dist/chunk-VRGPOTTV.js +42 -0
- package/dist/{chunk-5F6FUKTB.js → chunk-ZTWC6PXG.js} +1 -1
- package/dist/client.cjs +7 -4
- package/dist/client.d.ts +0 -1
- package/dist/client.js +1 -1
- package/dist/context.d.ts +0 -1
- package/dist/context.js +2 -2
- package/dist/endpoint.cjs +3 -0
- package/dist/endpoint.d.ts +3 -4
- package/dist/endpoint.js +2 -2
- package/dist/index.cjs +167 -100
- package/dist/index.d.ts +1 -2
- package/dist/index.js +8 -6
- package/dist/middlewares.cjs +5 -5
- package/dist/middlewares.d.ts +3 -4
- package/dist/middlewares.js +1 -1
- package/dist/on-error.cjs +144 -0
- package/dist/on-error.d.ts +9 -0
- package/dist/on-error.js +8 -0
- package/dist/router.cjs +178 -120
- package/dist/router.d.ts +2 -24
- package/dist/router.js +8 -12
- package/dist/trie.cjs +203 -0
- package/dist/trie.d.ts +34 -0
- package/dist/trie.js +9 -0
- package/dist/types.d.ts +91 -14
- package/package.json +4 -1
- package/dist/chunk-WJXMLTGP.js +0 -163
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
|
-
|
|
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,
|
|
236
|
-
if (!
|
|
237
|
-
for (const middleware of
|
|
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,
|
|
389
|
+
var executeMiddlewares = async (context, use = []) => {
|
|
253
390
|
try {
|
|
254
391
|
let ctx = context;
|
|
255
|
-
for (const middleware of
|
|
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
|
|
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.
|
|
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
|
|
362
|
-
if (
|
|
363
|
-
throw new RouterError("
|
|
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.
|
|
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
|
|
442
|
+
return onError(error, request, config);
|
|
385
443
|
}
|
|
386
444
|
};
|
|
387
445
|
var createRouter = (endpoints, config = {}) => {
|
|
388
|
-
const
|
|
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
|
-
|
|
394
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
|
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 {
|
|
18
|
+
export { createRouter };
|
package/dist/router.js
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
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
|
-
|
|
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 };
|