@bepalo/router 1.11.32 → 1.12.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/framework.d.ts +2 -4
- package/dist/cjs/framework.d.ts.map +1 -1
- package/dist/cjs/framework.js +4 -6
- package/dist/cjs/framework.js.map +1 -1
- package/dist/cjs/helpers.d.ts +2 -2
- package/dist/cjs/helpers.d.ts.map +1 -1
- package/dist/cjs/helpers.js +1 -1
- package/dist/cjs/helpers.js.map +1 -1
- package/dist/cjs/index.d.ts +5 -5
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +5 -5
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/middlewares.d.ts +2 -2
- package/dist/cjs/middlewares.d.ts.map +1 -1
- package/dist/cjs/middlewares.js +24 -24
- package/dist/cjs/middlewares.js.map +1 -1
- package/dist/cjs/router.d.ts +2 -2
- package/dist/cjs/router.d.ts.map +1 -1
- package/dist/cjs/router.js +8 -8
- package/dist/cjs/router.js.map +1 -1
- package/dist/cjs/types.d.ts +1 -1
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/upload-stream.d.ts +1 -1
- package/dist/cjs/upload-stream.d.ts.map +1 -1
- package/dist/cjs/upload-stream.js +7 -7
- package/dist/cjs/upload-stream.js.map +1 -1
- package/dist/framework.d.ts +2 -4
- package/dist/framework.d.ts.map +1 -1
- package/dist/framework.js +4 -6
- package/dist/framework.js.map +1 -1
- package/dist/helpers.d.ts +2 -2
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +1 -1
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/middlewares.d.ts +2 -2
- package/dist/middlewares.d.ts.map +1 -1
- package/dist/middlewares.js +24 -24
- package/dist/middlewares.js.map +1 -1
- package/dist/router.d.ts +2 -2
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +8 -8
- package/dist/router.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/upload-stream.d.ts +1 -1
- package/dist/upload-stream.d.ts.map +1 -1
- package/dist/upload-stream.js +7 -7
- package/dist/upload-stream.js.map +1 -1
- package/package.json +8 -1
- package/src/framework.deno.ts +194 -0
- package/src/framework.ts +197 -0
- package/src/helpers.ts +829 -0
- package/src/index.ts +5 -0
- package/src/list.ts +462 -0
- package/src/middlewares.deno.ts +855 -0
- package/src/middlewares.ts +851 -0
- package/src/router.ts +993 -0
- package/src/tree.ts +139 -0
- package/src/types.ts +197 -0
- package/src/upload-stream.ts +661 -0
- package/dist/cjs/framework.deno.d.ts +0 -31
- package/dist/cjs/framework.deno.d.ts.map +0 -1
- package/dist/cjs/framework.deno.js +0 -245
- package/dist/cjs/framework.deno.js.map +0 -1
- package/dist/framework.deno.d.ts +0 -31
- package/dist/framework.deno.d.ts.map +0 -1
- package/dist/framework.deno.js +0 -245
- package/dist/framework.deno.js.map +0 -1
package/src/tree.ts
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
export class TreeNode<V> {
|
|
2
|
+
children: Map<string, TreeNode<V>> = new Map();
|
|
3
|
+
constructor(public value?: V) {}
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
type TreeObj<V> = Record<string, V | Record<string, V>>;
|
|
7
|
+
|
|
8
|
+
function getTreeObj<V>(
|
|
9
|
+
node: TreeNode<V>,
|
|
10
|
+
onHit?: (node: TreeNode<V>) => void,
|
|
11
|
+
): TreeObj<V> {
|
|
12
|
+
const obj: TreeObj<V> = {};
|
|
13
|
+
if (node.value) {
|
|
14
|
+
obj[""] = node.value;
|
|
15
|
+
if (onHit) {
|
|
16
|
+
onHit(node);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
for (const [keyPart, child] of node.children) {
|
|
20
|
+
obj[keyPart] = getTreeObj(child, onHit) as Record<string, V>;
|
|
21
|
+
}
|
|
22
|
+
return obj;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class Tree<V> {
|
|
26
|
+
#root?: TreeNode<V>;
|
|
27
|
+
|
|
28
|
+
get root(): TreeNode<V> | undefined {
|
|
29
|
+
return this.#root;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
tree(onHit?: (node: TreeNode<V>) => void): TreeObj<V> {
|
|
33
|
+
const tr: TreeObj<V> = this.#root ? getTreeObj(this.#root, onHit) : {};
|
|
34
|
+
return tr;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
constructor() {}
|
|
38
|
+
|
|
39
|
+
getAll(key: Array<string>): Array<V> {
|
|
40
|
+
let node = this.#root;
|
|
41
|
+
const values: Array<V> = [];
|
|
42
|
+
const klen_1 = key.length - 1;
|
|
43
|
+
for (let i = 0; i < key.length && node != null; i++) {
|
|
44
|
+
const keyPart = key[i];
|
|
45
|
+
if (keyPart !== "") {
|
|
46
|
+
const superGlob = node.children.get("**");
|
|
47
|
+
if (superGlob?.value != null) {
|
|
48
|
+
values.unshift(superGlob.value);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (i < klen_1) {
|
|
52
|
+
let nextNode = node.children.get(keyPart);
|
|
53
|
+
if (nextNode == null) {
|
|
54
|
+
nextNode = node.children.get("*");
|
|
55
|
+
}
|
|
56
|
+
node = nextNode;
|
|
57
|
+
} else {
|
|
58
|
+
const glob = node.children.get("*");
|
|
59
|
+
if (glob?.value) values.unshift(glob.value);
|
|
60
|
+
const value = node.children.get(keyPart)?.value;
|
|
61
|
+
if (value) values.unshift(value);
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return values;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get(key: Array<string>): V | undefined {
|
|
69
|
+
let node = this.#root;
|
|
70
|
+
const klen_1 = key.length - 1;
|
|
71
|
+
for (let i = 0; i < key.length && node != null; i++) {
|
|
72
|
+
const keyPart = key[i];
|
|
73
|
+
if (i < klen_1) {
|
|
74
|
+
let nextNode = node.children.get(keyPart);
|
|
75
|
+
if (nextNode == null) {
|
|
76
|
+
nextNode = node.children.get("*");
|
|
77
|
+
}
|
|
78
|
+
node = nextNode;
|
|
79
|
+
} else {
|
|
80
|
+
const value =
|
|
81
|
+
node.children.get(keyPart)?.value ?? node.children.get("*")?.value;
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
has(key: Array<string>): boolean {
|
|
89
|
+
let node = this.#root;
|
|
90
|
+
const klen_1 = key.length - 1;
|
|
91
|
+
for (let i = 0; i < key.length && node != null; i++) {
|
|
92
|
+
const keyPart = key[i];
|
|
93
|
+
if (i < klen_1) {
|
|
94
|
+
let nextNode = node.children.get(keyPart);
|
|
95
|
+
if (nextNode == null) {
|
|
96
|
+
nextNode = node.children.get("*");
|
|
97
|
+
}
|
|
98
|
+
node = nextNode;
|
|
99
|
+
} else {
|
|
100
|
+
return node.children.get(keyPart)?.value != null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
set(key: Array<string>, value: V): void {
|
|
107
|
+
if (this.#root == null) {
|
|
108
|
+
this.#root = new TreeNode();
|
|
109
|
+
}
|
|
110
|
+
let node = this.#root;
|
|
111
|
+
const klen_1 = key.length - 1;
|
|
112
|
+
for (let i = 0; i < key.length; i++) {
|
|
113
|
+
if (i < klen_1) {
|
|
114
|
+
const keyPart = key[i];
|
|
115
|
+
const curNode = node.children.get(keyPart);
|
|
116
|
+
if (!curNode) {
|
|
117
|
+
const newNode = new TreeNode<V>();
|
|
118
|
+
node.children.set(keyPart, newNode);
|
|
119
|
+
node = newNode;
|
|
120
|
+
} else {
|
|
121
|
+
node = curNode;
|
|
122
|
+
}
|
|
123
|
+
} else {
|
|
124
|
+
const keyPart = key[i];
|
|
125
|
+
const curNode = node.children.get(keyPart);
|
|
126
|
+
if (curNode) {
|
|
127
|
+
curNode.value = value;
|
|
128
|
+
node = curNode;
|
|
129
|
+
} else {
|
|
130
|
+
const newNode = new TreeNode<V>(value);
|
|
131
|
+
node.children.set(keyPart, newNode);
|
|
132
|
+
node = newNode;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export default Tree;
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import Router, { RouterContext } from "./router.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Standard HTTP methods supported by the router.
|
|
5
|
+
* These methods correspond to HTTP/1.1 request methods.
|
|
6
|
+
*
|
|
7
|
+
* @typedef {"HEAD"|"OPTIONS"|"GET"|"POST"|"PUT"|"PATCH"|"DELETE"} HttpMethod
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const method: HttpMethod = "GET";
|
|
11
|
+
* const method: HttpMethod = "POST";
|
|
12
|
+
*/
|
|
13
|
+
export type HttpMethod =
|
|
14
|
+
| "HEAD"
|
|
15
|
+
| "OPTIONS"
|
|
16
|
+
| "GET"
|
|
17
|
+
| "POST"
|
|
18
|
+
| "PUT"
|
|
19
|
+
| "PATCH"
|
|
20
|
+
| "DELETE";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* HTTP path pattern type.
|
|
24
|
+
* Represents valid HTTP paths starting with a forward slash.
|
|
25
|
+
*
|
|
26
|
+
* @typedef {`/${string}`} HttpPath
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* const path: HttpPath = "/";
|
|
30
|
+
* const path: HttpPath = "/api/users";
|
|
31
|
+
* const path: HttpPath = "/users/:id";
|
|
32
|
+
* const path: HttpPath = "/static/**";
|
|
33
|
+
*/
|
|
34
|
+
export type HttpPath = `/${string}`;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Combined HTTP method and path pattern.
|
|
38
|
+
* Used for route registration with method-specific routing.
|
|
39
|
+
*
|
|
40
|
+
* @typedef {`${HttpMethod} ${HttpPath}`} MethodPath
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* const route: MethodPath = "GET /api/users";
|
|
44
|
+
* const route: MethodPath = "POST /api/users";
|
|
45
|
+
* const route: MethodPath = "DELETE /api/users/:id";
|
|
46
|
+
*/
|
|
47
|
+
export type MethodPath = `${HttpMethod | "ALL" | "CRUD"} ${HttpPath}`;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Types of handlers in the router pipeline.
|
|
51
|
+
* Each handler type has a specific role in request processing:
|
|
52
|
+
* - `filter`: Runs before handlers, can intercept requests
|
|
53
|
+
* - `hook`: Runs before filters, can't return responses
|
|
54
|
+
* - `handler`: Main request handlers
|
|
55
|
+
* - `fallback`: Runs when no handler matches
|
|
56
|
+
* - `catcher`: Error handlers for exceptions
|
|
57
|
+
* - `after`: Runs after response is created
|
|
58
|
+
*
|
|
59
|
+
* @typedef {"filter"|"hook"|"handler"|"fallback"|"catcher"|"after"} HandlerType
|
|
60
|
+
*
|
|
61
|
+
*/
|
|
62
|
+
export type HandlerType =
|
|
63
|
+
| "filter"
|
|
64
|
+
| "hook"
|
|
65
|
+
| "handler"
|
|
66
|
+
| "fallback"
|
|
67
|
+
| "catcher"
|
|
68
|
+
| "after";
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Possible return types from route handlers.
|
|
72
|
+
* Handlers can:
|
|
73
|
+
* - Return a Response object to send immediately
|
|
74
|
+
* - Return void/undefined to continue to next handler
|
|
75
|
+
* - Return false to stop processing (for filters)
|
|
76
|
+
* - Return a Promise of any of the above
|
|
77
|
+
*
|
|
78
|
+
* @typedef {Response|void|boolean|Promise<Response|void|boolean>} HandlerResponse
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* // Return a Response
|
|
82
|
+
* (req, ctx) => new Response("Hello");
|
|
83
|
+
*
|
|
84
|
+
* // Return void (continue)
|
|
85
|
+
* (req, ctx) => { ctx.user = getUser(); }
|
|
86
|
+
*
|
|
87
|
+
* // Return false (stop processing)
|
|
88
|
+
* (req, ctx) => { if (!authorized) return false; }
|
|
89
|
+
*
|
|
90
|
+
* // Return Promise
|
|
91
|
+
* async (req, ctx) => {
|
|
92
|
+
* const data = await fetchData();
|
|
93
|
+
* return json(data);
|
|
94
|
+
* }
|
|
95
|
+
*/
|
|
96
|
+
export type HandlerResponse =
|
|
97
|
+
| Response
|
|
98
|
+
| void
|
|
99
|
+
| boolean
|
|
100
|
+
| Promise<Response | void | boolean>;
|
|
101
|
+
|
|
102
|
+
export type BoundHandler<XContext = {}> = (
|
|
103
|
+
this: Router<XContext>,
|
|
104
|
+
req: Request,
|
|
105
|
+
ctx: RouterContext<XContext>,
|
|
106
|
+
) => HandlerResponse;
|
|
107
|
+
|
|
108
|
+
export type FreeHandler<XContext = {}> = (
|
|
109
|
+
req: Request,
|
|
110
|
+
ctx: RouterContext<XContext>,
|
|
111
|
+
) => HandlerResponse;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Generic handler function type.
|
|
115
|
+
* Represents a function that processes HTTP requests.
|
|
116
|
+
*
|
|
117
|
+
* @template Context - The context type available to the handler
|
|
118
|
+
* @callback Handler
|
|
119
|
+
* @param {Request} req - The incoming HTTP request
|
|
120
|
+
* @param {Context} ctx - The request context with params, headers, etc.
|
|
121
|
+
* @returns {HandlerResponse} The handler's response
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* // Simple handler that returns JSON
|
|
125
|
+
* const userHandler: Handler<MyContext> = async (req, ctx) => {
|
|
126
|
+
* const users = await getUsers();
|
|
127
|
+
* return json(users);
|
|
128
|
+
* };
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* // Handler that modifies context and continues
|
|
132
|
+
* const authHandler: Handler<MyContext> = (req, ctx) => {
|
|
133
|
+
* const token = req.headers.get("Authorization");
|
|
134
|
+
* if (token) {
|
|
135
|
+
* ctx.user = decodeToken(token);
|
|
136
|
+
* }
|
|
137
|
+
* // Return nothing to continue to next handler
|
|
138
|
+
* };
|
|
139
|
+
*/
|
|
140
|
+
export type Handler<XContext = {}> =
|
|
141
|
+
| FreeHandler<XContext>
|
|
142
|
+
| BoundHandler<XContext>;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Array of handler functions executed in sequence.
|
|
146
|
+
* Used to group multiple handlers for a route.
|
|
147
|
+
*
|
|
148
|
+
* @template Context - The context type available to handlers
|
|
149
|
+
* @typedef {Array<Handler<Context>>} Pipeline
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* // Pipeline with multiple handlers
|
|
153
|
+
* const userPipeline: Pipeline<MyContext> = [
|
|
154
|
+
* rateLimiter, // Apply rate limiting
|
|
155
|
+
* authMiddleware, // Check authentication
|
|
156
|
+
* validateInput, // Validate request body
|
|
157
|
+
* userHandler // Main request logic
|
|
158
|
+
* ];
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* // Register pipeline with router
|
|
162
|
+
* router.handle("GET /users", userPipeline);
|
|
163
|
+
*/
|
|
164
|
+
export type Pipeline<Context = {}> = Array<Handler<Context>>;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* HTTP header tuple.
|
|
168
|
+
*
|
|
169
|
+
* @typedef {[string, string]} HeaderTuple
|
|
170
|
+
*
|
|
171
|
+
*/
|
|
172
|
+
export type HeaderTuple = [string, string];
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Generic SocketAddress structure
|
|
176
|
+
*
|
|
177
|
+
* @typedef {{address:string;family:string;port:number;}} SocketAddress
|
|
178
|
+
*/
|
|
179
|
+
export interface SocketAddress {
|
|
180
|
+
address: string;
|
|
181
|
+
family: string;
|
|
182
|
+
port: number;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Router Context for certain error
|
|
187
|
+
*
|
|
188
|
+
* @typedef {{error:Error}} CTXError
|
|
189
|
+
*/
|
|
190
|
+
export type CTXError = { error: Error };
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Router Context for sharing client address
|
|
194
|
+
*
|
|
195
|
+
* @typedef {{address:SocketAddress}} CTXAddress
|
|
196
|
+
*/
|
|
197
|
+
export type CTXAddress = { address: SocketAddress };
|