@kevisual/router 0.0.4 → 0.0.5
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-browser.js +2 -1
- package/dist/router-simple.d.ts +25 -0
- package/dist/router-simple.js +457 -0
- package/dist/router.js +2 -1
- package/package.json +6 -1
package/dist/router-browser.js
CHANGED
|
@@ -5745,10 +5745,11 @@ class QueryRouter {
|
|
|
5745
5745
|
catch (e) {
|
|
5746
5746
|
if (route?.isDebug) {
|
|
5747
5747
|
console.error('=====debug====:middlerware error');
|
|
5748
|
+
console.error('=====debug====:', e);
|
|
5748
5749
|
console.error('=====debug====:[path:key]:', `${route.path}-${route.key}`);
|
|
5749
5750
|
console.error('=====debug====:', e.message);
|
|
5750
5751
|
}
|
|
5751
|
-
if (e instanceof CustomError) {
|
|
5752
|
+
if (e instanceof CustomError || e?.code) {
|
|
5752
5753
|
ctx.code = e.code;
|
|
5753
5754
|
ctx.message = e.message;
|
|
5754
5755
|
ctx.body = null;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Key } from 'path-to-regexp';
|
|
2
|
+
import { ServerResponse, IncomingMessage } from 'http';
|
|
3
|
+
|
|
4
|
+
type Req = IncomingMessage & {
|
|
5
|
+
params?: Record<string, string>;
|
|
6
|
+
};
|
|
7
|
+
interface Route {
|
|
8
|
+
method: string;
|
|
9
|
+
regexp: RegExp;
|
|
10
|
+
keys: Key[];
|
|
11
|
+
handlers: Array<(req: Req, res: ServerResponse) => Promise<void> | void>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* SimpleRouter
|
|
15
|
+
*/
|
|
16
|
+
declare class SimpleRouter {
|
|
17
|
+
routes: Route[];
|
|
18
|
+
constructor();
|
|
19
|
+
use(method: string, route: string, ...fns: Array<(req: Req, res: ServerResponse) => Promise<void> | void>): this;
|
|
20
|
+
get(route: string, ...fns: Array<(req: Req, res: ServerResponse) => Promise<void> | void>): this;
|
|
21
|
+
post(route: string, ...fns: Array<(req: Req, res: ServerResponse) => Promise<void> | void>): this;
|
|
22
|
+
parse(req: Req, res: ServerResponse): Promise<void> | "not_found";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { SimpleRouter };
|
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
var dist = {};
|
|
2
|
+
|
|
3
|
+
var hasRequiredDist;
|
|
4
|
+
|
|
5
|
+
function requireDist () {
|
|
6
|
+
if (hasRequiredDist) return dist;
|
|
7
|
+
hasRequiredDist = 1;
|
|
8
|
+
Object.defineProperty(dist, "__esModule", { value: true });
|
|
9
|
+
dist.TokenData = void 0;
|
|
10
|
+
dist.parse = parse;
|
|
11
|
+
dist.compile = compile;
|
|
12
|
+
dist.match = match;
|
|
13
|
+
dist.pathToRegexp = pathToRegexp;
|
|
14
|
+
dist.stringify = stringify;
|
|
15
|
+
const DEFAULT_DELIMITER = "/";
|
|
16
|
+
const NOOP_VALUE = (value) => value;
|
|
17
|
+
const ID_START = /^[$_\p{ID_Start}]$/u;
|
|
18
|
+
const ID_CONTINUE = /^[$\u200c\u200d\p{ID_Continue}]$/u;
|
|
19
|
+
const DEBUG_URL = "https://git.new/pathToRegexpError";
|
|
20
|
+
const SIMPLE_TOKENS = {
|
|
21
|
+
// Groups.
|
|
22
|
+
"{": "{",
|
|
23
|
+
"}": "}",
|
|
24
|
+
// Reserved.
|
|
25
|
+
"(": "(",
|
|
26
|
+
")": ")",
|
|
27
|
+
"[": "[",
|
|
28
|
+
"]": "]",
|
|
29
|
+
"+": "+",
|
|
30
|
+
"?": "?",
|
|
31
|
+
"!": "!",
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Escape text for stringify to path.
|
|
35
|
+
*/
|
|
36
|
+
function escapeText(str) {
|
|
37
|
+
return str.replace(/[{}()\[\]+?!:*]/g, "\\$&");
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Escape a regular expression string.
|
|
41
|
+
*/
|
|
42
|
+
function escape(str) {
|
|
43
|
+
return str.replace(/[.+*?^${}()[\]|/\\]/g, "\\$&");
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Tokenize input string.
|
|
47
|
+
*/
|
|
48
|
+
function* lexer(str) {
|
|
49
|
+
const chars = [...str];
|
|
50
|
+
let i = 0;
|
|
51
|
+
function name() {
|
|
52
|
+
let value = "";
|
|
53
|
+
if (ID_START.test(chars[++i])) {
|
|
54
|
+
value += chars[i];
|
|
55
|
+
while (ID_CONTINUE.test(chars[++i])) {
|
|
56
|
+
value += chars[i];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (chars[i] === '"') {
|
|
60
|
+
let pos = i;
|
|
61
|
+
while (i < chars.length) {
|
|
62
|
+
if (chars[++i] === '"') {
|
|
63
|
+
i++;
|
|
64
|
+
pos = 0;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
if (chars[i] === "\\") {
|
|
68
|
+
value += chars[++i];
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
value += chars[i];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (pos) {
|
|
75
|
+
throw new TypeError(`Unterminated quote at ${pos}: ${DEBUG_URL}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (!value) {
|
|
79
|
+
throw new TypeError(`Missing parameter name at ${i}: ${DEBUG_URL}`);
|
|
80
|
+
}
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
while (i < chars.length) {
|
|
84
|
+
const value = chars[i];
|
|
85
|
+
const type = SIMPLE_TOKENS[value];
|
|
86
|
+
if (type) {
|
|
87
|
+
yield { type, index: i++, value };
|
|
88
|
+
}
|
|
89
|
+
else if (value === "\\") {
|
|
90
|
+
yield { type: "ESCAPED", index: i++, value: chars[i++] };
|
|
91
|
+
}
|
|
92
|
+
else if (value === ":") {
|
|
93
|
+
const value = name();
|
|
94
|
+
yield { type: "PARAM", index: i, value };
|
|
95
|
+
}
|
|
96
|
+
else if (value === "*") {
|
|
97
|
+
const value = name();
|
|
98
|
+
yield { type: "WILDCARD", index: i, value };
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
yield { type: "CHAR", index: i, value: chars[i++] };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return { type: "END", index: i, value: "" };
|
|
105
|
+
}
|
|
106
|
+
class Iter {
|
|
107
|
+
constructor(tokens) {
|
|
108
|
+
this.tokens = tokens;
|
|
109
|
+
}
|
|
110
|
+
peek() {
|
|
111
|
+
if (!this._peek) {
|
|
112
|
+
const next = this.tokens.next();
|
|
113
|
+
this._peek = next.value;
|
|
114
|
+
}
|
|
115
|
+
return this._peek;
|
|
116
|
+
}
|
|
117
|
+
tryConsume(type) {
|
|
118
|
+
const token = this.peek();
|
|
119
|
+
if (token.type !== type)
|
|
120
|
+
return;
|
|
121
|
+
this._peek = undefined; // Reset after consumed.
|
|
122
|
+
return token.value;
|
|
123
|
+
}
|
|
124
|
+
consume(type) {
|
|
125
|
+
const value = this.tryConsume(type);
|
|
126
|
+
if (value !== undefined)
|
|
127
|
+
return value;
|
|
128
|
+
const { type: nextType, index } = this.peek();
|
|
129
|
+
throw new TypeError(`Unexpected ${nextType} at ${index}, expected ${type}: ${DEBUG_URL}`);
|
|
130
|
+
}
|
|
131
|
+
text() {
|
|
132
|
+
let result = "";
|
|
133
|
+
let value;
|
|
134
|
+
while ((value = this.tryConsume("CHAR") || this.tryConsume("ESCAPED"))) {
|
|
135
|
+
result += value;
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Tokenized path instance.
|
|
142
|
+
*/
|
|
143
|
+
class TokenData {
|
|
144
|
+
constructor(tokens) {
|
|
145
|
+
this.tokens = tokens;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
dist.TokenData = TokenData;
|
|
149
|
+
/**
|
|
150
|
+
* Parse a string for the raw tokens.
|
|
151
|
+
*/
|
|
152
|
+
function parse(str, options = {}) {
|
|
153
|
+
const { encodePath = NOOP_VALUE } = options;
|
|
154
|
+
const it = new Iter(lexer(str));
|
|
155
|
+
function consume(endType) {
|
|
156
|
+
const tokens = [];
|
|
157
|
+
while (true) {
|
|
158
|
+
const path = it.text();
|
|
159
|
+
if (path)
|
|
160
|
+
tokens.push({ type: "text", value: encodePath(path) });
|
|
161
|
+
const param = it.tryConsume("PARAM");
|
|
162
|
+
if (param) {
|
|
163
|
+
tokens.push({
|
|
164
|
+
type: "param",
|
|
165
|
+
name: param,
|
|
166
|
+
});
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
const wildcard = it.tryConsume("WILDCARD");
|
|
170
|
+
if (wildcard) {
|
|
171
|
+
tokens.push({
|
|
172
|
+
type: "wildcard",
|
|
173
|
+
name: wildcard,
|
|
174
|
+
});
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
const open = it.tryConsume("{");
|
|
178
|
+
if (open) {
|
|
179
|
+
tokens.push({
|
|
180
|
+
type: "group",
|
|
181
|
+
tokens: consume("}"),
|
|
182
|
+
});
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
it.consume(endType);
|
|
186
|
+
return tokens;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const tokens = consume("END");
|
|
190
|
+
return new TokenData(tokens);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Compile a string to a template function for the path.
|
|
194
|
+
*/
|
|
195
|
+
function compile(path, options = {}) {
|
|
196
|
+
const { encode = encodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
|
|
197
|
+
const data = path instanceof TokenData ? path : parse(path, options);
|
|
198
|
+
const fn = tokensToFunction(data.tokens, delimiter, encode);
|
|
199
|
+
return function path(data = {}) {
|
|
200
|
+
const [path, ...missing] = fn(data);
|
|
201
|
+
if (missing.length) {
|
|
202
|
+
throw new TypeError(`Missing parameters: ${missing.join(", ")}`);
|
|
203
|
+
}
|
|
204
|
+
return path;
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function tokensToFunction(tokens, delimiter, encode) {
|
|
208
|
+
const encoders = tokens.map((token) => tokenToFunction(token, delimiter, encode));
|
|
209
|
+
return (data) => {
|
|
210
|
+
const result = [""];
|
|
211
|
+
for (const encoder of encoders) {
|
|
212
|
+
const [value, ...extras] = encoder(data);
|
|
213
|
+
result[0] += value;
|
|
214
|
+
result.push(...extras);
|
|
215
|
+
}
|
|
216
|
+
return result;
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Convert a single token into a path building function.
|
|
221
|
+
*/
|
|
222
|
+
function tokenToFunction(token, delimiter, encode) {
|
|
223
|
+
if (token.type === "text")
|
|
224
|
+
return () => [token.value];
|
|
225
|
+
if (token.type === "group") {
|
|
226
|
+
const fn = tokensToFunction(token.tokens, delimiter, encode);
|
|
227
|
+
return (data) => {
|
|
228
|
+
const [value, ...missing] = fn(data);
|
|
229
|
+
if (!missing.length)
|
|
230
|
+
return [value];
|
|
231
|
+
return [""];
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
const encodeValue = encode || NOOP_VALUE;
|
|
235
|
+
if (token.type === "wildcard" && encode !== false) {
|
|
236
|
+
return (data) => {
|
|
237
|
+
const value = data[token.name];
|
|
238
|
+
if (value == null)
|
|
239
|
+
return ["", token.name];
|
|
240
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
241
|
+
throw new TypeError(`Expected "${token.name}" to be a non-empty array`);
|
|
242
|
+
}
|
|
243
|
+
return [
|
|
244
|
+
value
|
|
245
|
+
.map((value, index) => {
|
|
246
|
+
if (typeof value !== "string") {
|
|
247
|
+
throw new TypeError(`Expected "${token.name}/${index}" to be a string`);
|
|
248
|
+
}
|
|
249
|
+
return encodeValue(value);
|
|
250
|
+
})
|
|
251
|
+
.join(delimiter),
|
|
252
|
+
];
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
return (data) => {
|
|
256
|
+
const value = data[token.name];
|
|
257
|
+
if (value == null)
|
|
258
|
+
return ["", token.name];
|
|
259
|
+
if (typeof value !== "string") {
|
|
260
|
+
throw new TypeError(`Expected "${token.name}" to be a string`);
|
|
261
|
+
}
|
|
262
|
+
return [encodeValue(value)];
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Transform a path into a match function.
|
|
267
|
+
*/
|
|
268
|
+
function match(path, options = {}) {
|
|
269
|
+
const { decode = decodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
|
|
270
|
+
const { regexp, keys } = pathToRegexp(path, options);
|
|
271
|
+
const decoders = keys.map((key) => {
|
|
272
|
+
if (decode === false)
|
|
273
|
+
return NOOP_VALUE;
|
|
274
|
+
if (key.type === "param")
|
|
275
|
+
return decode;
|
|
276
|
+
return (value) => value.split(delimiter).map(decode);
|
|
277
|
+
});
|
|
278
|
+
return function match(input) {
|
|
279
|
+
const m = regexp.exec(input);
|
|
280
|
+
if (!m)
|
|
281
|
+
return false;
|
|
282
|
+
const path = m[0];
|
|
283
|
+
const params = Object.create(null);
|
|
284
|
+
for (let i = 1; i < m.length; i++) {
|
|
285
|
+
if (m[i] === undefined)
|
|
286
|
+
continue;
|
|
287
|
+
const key = keys[i - 1];
|
|
288
|
+
const decoder = decoders[i - 1];
|
|
289
|
+
params[key.name] = decoder(m[i]);
|
|
290
|
+
}
|
|
291
|
+
return { path, params };
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
function pathToRegexp(path, options = {}) {
|
|
295
|
+
const { delimiter = DEFAULT_DELIMITER, end = true, sensitive = false, trailing = true, } = options;
|
|
296
|
+
const keys = [];
|
|
297
|
+
const sources = [];
|
|
298
|
+
const flags = sensitive ? "" : "i";
|
|
299
|
+
const paths = Array.isArray(path) ? path : [path];
|
|
300
|
+
const items = paths.map((path) => path instanceof TokenData ? path : parse(path, options));
|
|
301
|
+
for (const { tokens } of items) {
|
|
302
|
+
for (const seq of flatten(tokens, 0, [])) {
|
|
303
|
+
const regexp = sequenceToRegExp(seq, delimiter, keys);
|
|
304
|
+
sources.push(regexp);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
let pattern = `^(?:${sources.join("|")})`;
|
|
308
|
+
if (trailing)
|
|
309
|
+
pattern += `(?:${escape(delimiter)}$)?`;
|
|
310
|
+
pattern += end ? "$" : `(?=${escape(delimiter)}|$)`;
|
|
311
|
+
const regexp = new RegExp(pattern, flags);
|
|
312
|
+
return { regexp, keys };
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Generate a flat list of sequence tokens from the given tokens.
|
|
316
|
+
*/
|
|
317
|
+
function* flatten(tokens, index, init) {
|
|
318
|
+
if (index === tokens.length) {
|
|
319
|
+
return yield init;
|
|
320
|
+
}
|
|
321
|
+
const token = tokens[index];
|
|
322
|
+
if (token.type === "group") {
|
|
323
|
+
const fork = init.slice();
|
|
324
|
+
for (const seq of flatten(token.tokens, 0, fork)) {
|
|
325
|
+
yield* flatten(tokens, index + 1, seq);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
init.push(token);
|
|
330
|
+
}
|
|
331
|
+
yield* flatten(tokens, index + 1, init);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Transform a flat sequence of tokens into a regular expression.
|
|
335
|
+
*/
|
|
336
|
+
function sequenceToRegExp(tokens, delimiter, keys) {
|
|
337
|
+
let result = "";
|
|
338
|
+
let backtrack = "";
|
|
339
|
+
let isSafeSegmentParam = true;
|
|
340
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
341
|
+
const token = tokens[i];
|
|
342
|
+
if (token.type === "text") {
|
|
343
|
+
result += escape(token.value);
|
|
344
|
+
backtrack += token.value;
|
|
345
|
+
isSafeSegmentParam || (isSafeSegmentParam = token.value.includes(delimiter));
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
if (token.type === "param" || token.type === "wildcard") {
|
|
349
|
+
if (!isSafeSegmentParam && !backtrack) {
|
|
350
|
+
throw new TypeError(`Missing text after "${token.name}": ${DEBUG_URL}`);
|
|
351
|
+
}
|
|
352
|
+
if (token.type === "param") {
|
|
353
|
+
result += `(${negate(delimiter, isSafeSegmentParam ? "" : backtrack)}+)`;
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
result += `([\\s\\S]+)`;
|
|
357
|
+
}
|
|
358
|
+
keys.push(token);
|
|
359
|
+
backtrack = "";
|
|
360
|
+
isSafeSegmentParam = false;
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return result;
|
|
365
|
+
}
|
|
366
|
+
function negate(delimiter, backtrack) {
|
|
367
|
+
if (backtrack.length < 2) {
|
|
368
|
+
if (delimiter.length < 2)
|
|
369
|
+
return `[^${escape(delimiter + backtrack)}]`;
|
|
370
|
+
return `(?:(?!${escape(delimiter)})[^${escape(backtrack)}])`;
|
|
371
|
+
}
|
|
372
|
+
if (delimiter.length < 2) {
|
|
373
|
+
return `(?:(?!${escape(backtrack)})[^${escape(delimiter)}])`;
|
|
374
|
+
}
|
|
375
|
+
return `(?:(?!${escape(backtrack)}|${escape(delimiter)})[\\s\\S])`;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Stringify token data into a path string.
|
|
379
|
+
*/
|
|
380
|
+
function stringify(data) {
|
|
381
|
+
return data.tokens
|
|
382
|
+
.map(function stringifyToken(token, index, tokens) {
|
|
383
|
+
if (token.type === "text")
|
|
384
|
+
return escapeText(token.value);
|
|
385
|
+
if (token.type === "group") {
|
|
386
|
+
return `{${token.tokens.map(stringifyToken).join("")}}`;
|
|
387
|
+
}
|
|
388
|
+
const isSafe = isNameSafe(token.name) && isNextNameSafe(tokens[index + 1]);
|
|
389
|
+
const key = isSafe ? token.name : JSON.stringify(token.name);
|
|
390
|
+
if (token.type === "param")
|
|
391
|
+
return `:${key}`;
|
|
392
|
+
if (token.type === "wildcard")
|
|
393
|
+
return `*${key}`;
|
|
394
|
+
throw new TypeError(`Unexpected token: ${token}`);
|
|
395
|
+
})
|
|
396
|
+
.join("");
|
|
397
|
+
}
|
|
398
|
+
function isNameSafe(name) {
|
|
399
|
+
const [first, ...rest] = name;
|
|
400
|
+
if (!ID_START.test(first))
|
|
401
|
+
return false;
|
|
402
|
+
return rest.every((char) => ID_CONTINUE.test(char));
|
|
403
|
+
}
|
|
404
|
+
function isNextNameSafe(token) {
|
|
405
|
+
if ((token === null || token === void 0 ? void 0 : token.type) !== "text")
|
|
406
|
+
return true;
|
|
407
|
+
return !ID_CONTINUE.test(token.value[0]);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return dist;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
var distExports = requireDist();
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* SimpleRouter
|
|
417
|
+
*/
|
|
418
|
+
class SimpleRouter {
|
|
419
|
+
routes = [];
|
|
420
|
+
constructor() {
|
|
421
|
+
// console.log('AppSimple initialized');
|
|
422
|
+
}
|
|
423
|
+
use(method, route, ...fns) {
|
|
424
|
+
const handlers = Array.isArray(fns) ? fns.flat() : [];
|
|
425
|
+
const pattern = distExports.pathToRegexp(route);
|
|
426
|
+
this.routes.push({ method: method.toLowerCase(), regexp: pattern.regexp, keys: pattern.keys, handlers });
|
|
427
|
+
return this;
|
|
428
|
+
}
|
|
429
|
+
get(route, ...fns) {
|
|
430
|
+
return this.use('get', route, ...fns);
|
|
431
|
+
}
|
|
432
|
+
post(route, ...fns) {
|
|
433
|
+
return this.use('post', route, ...fns);
|
|
434
|
+
}
|
|
435
|
+
parse(req, res) {
|
|
436
|
+
const { pathname } = new URL(req.url, 'http://localhost');
|
|
437
|
+
const method = req.method.toLowerCase();
|
|
438
|
+
const route = this.routes.find((route) => {
|
|
439
|
+
const matchResult = route.regexp.exec(pathname);
|
|
440
|
+
if (matchResult && route.method === method) {
|
|
441
|
+
const params = {};
|
|
442
|
+
route.keys.forEach((key, i) => {
|
|
443
|
+
params[key.name] = matchResult[i + 1];
|
|
444
|
+
});
|
|
445
|
+
req.params = params;
|
|
446
|
+
return true;
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
if (route) {
|
|
450
|
+
const { handlers } = route;
|
|
451
|
+
return handlers.reduce((promiseChain, handler) => promiseChain.then(() => Promise.resolve(handler(req, res))), Promise.resolve());
|
|
452
|
+
}
|
|
453
|
+
return 'not_found';
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
export { SimpleRouter };
|
package/dist/router.js
CHANGED
|
@@ -5764,10 +5764,11 @@ class QueryRouter {
|
|
|
5764
5764
|
catch (e) {
|
|
5765
5765
|
if (route?.isDebug) {
|
|
5766
5766
|
console.error('=====debug====:middlerware error');
|
|
5767
|
+
console.error('=====debug====:', e);
|
|
5767
5768
|
console.error('=====debug====:[path:key]:', `${route.path}-${route.key}`);
|
|
5768
5769
|
console.error('=====debug====:', e.message);
|
|
5769
5770
|
}
|
|
5770
|
-
if (e instanceof CustomError) {
|
|
5771
|
+
if (e instanceof CustomError || e?.code) {
|
|
5771
5772
|
ctx.code = e.code;
|
|
5772
5773
|
ctx.message = e.message;
|
|
5773
5774
|
ctx.body = null;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "@kevisual/router",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.5",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"url": "git+https://github.com/abearxiong/kevisual-router.git"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
+
"path-to-regexp": "^8.2.0",
|
|
44
45
|
"selfsigned": "^2.4.1",
|
|
45
46
|
"ws": "^8.18.0"
|
|
46
47
|
},
|
|
@@ -59,6 +60,10 @@
|
|
|
59
60
|
"./sign": {
|
|
60
61
|
"import": "./dist/router-sign.js",
|
|
61
62
|
"require": "./dist/router-sign.js"
|
|
63
|
+
},
|
|
64
|
+
"./simple": {
|
|
65
|
+
"import": "./dist/router-simple.js",
|
|
66
|
+
"require": "./dist/router-simple.js"
|
|
62
67
|
}
|
|
63
68
|
}
|
|
64
69
|
}
|