elit 3.1.2 → 3.1.4
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/build.d.mts +1 -1
- package/dist/cli.js +1 -1
- package/dist/{server-BvYkTRi4.d.ts → server-9dH1l8MG.d.ts} +15 -9
- package/dist/{server-XT4I28Cr.d.mts → server-jAa9yJM4.d.mts} +15 -9
- package/dist/server.d.mts +1 -1
- package/dist/server.d.ts +15 -9
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +104 -10
- package/dist/server.mjs +104 -10
- package/dist/types.d.mts +14 -8
- package/package.json +1 -1
- package/src/server.ts +141 -17
package/dist/build.d.mts
CHANGED
package/dist/cli.js
CHANGED
|
@@ -1412,7 +1412,7 @@ var require_package = __commonJS({
|
|
|
1412
1412
|
"package.json"(exports2, module2) {
|
|
1413
1413
|
module2.exports = {
|
|
1414
1414
|
name: "elit",
|
|
1415
|
-
version: "3.1.
|
|
1415
|
+
version: "3.1.4",
|
|
1416
1416
|
description: "Optimized lightweight library for creating DOM elements with reactive state",
|
|
1417
1417
|
main: "dist/index.js",
|
|
1418
1418
|
module: "dist/index.mjs",
|
|
@@ -180,7 +180,7 @@ interface BuildResult {
|
|
|
180
180
|
* - Deno: uses Deno.emit
|
|
181
181
|
*/
|
|
182
182
|
|
|
183
|
-
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD';
|
|
183
|
+
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD' | 'ALL';
|
|
184
184
|
interface ServerRouteContext {
|
|
185
185
|
req: IncomingMessage;
|
|
186
186
|
res: ServerResponse;
|
|
@@ -189,19 +189,25 @@ interface ServerRouteContext {
|
|
|
189
189
|
body: any;
|
|
190
190
|
headers: Record<string, string | string[] | undefined>;
|
|
191
191
|
user?: any;
|
|
192
|
+
send?(data: any): ServerResponse;
|
|
193
|
+
json?(data: any): ServerResponse;
|
|
194
|
+
status?(code: number): ServerResponse;
|
|
192
195
|
}
|
|
193
|
-
type ServerRouteHandler = (ctx: ServerRouteContext) => void | Promise<void>;
|
|
196
|
+
type ServerRouteHandler = (ctx: ServerRouteContext, next?: () => Promise<void>) => void | Promise<void>;
|
|
194
197
|
type Middleware = (ctx: ServerRouteContext, next: () => Promise<void>) => void | Promise<void>;
|
|
195
198
|
declare class ServerRouter {
|
|
196
199
|
private routes;
|
|
197
200
|
private middlewares;
|
|
198
|
-
use(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
201
|
+
use(...args: Array<any>): this;
|
|
202
|
+
all: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
203
|
+
get: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
204
|
+
post: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
205
|
+
put: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
206
|
+
delete: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
207
|
+
patch: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
208
|
+
options: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
209
|
+
head: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
210
|
+
private toMiddleware;
|
|
205
211
|
private addRoute;
|
|
206
212
|
private pathToRegex;
|
|
207
213
|
private parseQuery;
|
|
@@ -180,7 +180,7 @@ interface BuildResult {
|
|
|
180
180
|
* - Deno: uses Deno.emit
|
|
181
181
|
*/
|
|
182
182
|
|
|
183
|
-
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD';
|
|
183
|
+
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD' | 'ALL';
|
|
184
184
|
interface ServerRouteContext {
|
|
185
185
|
req: IncomingMessage;
|
|
186
186
|
res: ServerResponse;
|
|
@@ -189,19 +189,25 @@ interface ServerRouteContext {
|
|
|
189
189
|
body: any;
|
|
190
190
|
headers: Record<string, string | string[] | undefined>;
|
|
191
191
|
user?: any;
|
|
192
|
+
send?(data: any): ServerResponse;
|
|
193
|
+
json?(data: any): ServerResponse;
|
|
194
|
+
status?(code: number): ServerResponse;
|
|
192
195
|
}
|
|
193
|
-
type ServerRouteHandler = (ctx: ServerRouteContext) => void | Promise<void>;
|
|
196
|
+
type ServerRouteHandler = (ctx: ServerRouteContext, next?: () => Promise<void>) => void | Promise<void>;
|
|
194
197
|
type Middleware = (ctx: ServerRouteContext, next: () => Promise<void>) => void | Promise<void>;
|
|
195
198
|
declare class ServerRouter {
|
|
196
199
|
private routes;
|
|
197
200
|
private middlewares;
|
|
198
|
-
use(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
201
|
+
use(...args: Array<any>): this;
|
|
202
|
+
all: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
203
|
+
get: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
204
|
+
post: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
205
|
+
put: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
206
|
+
delete: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
207
|
+
patch: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
208
|
+
options: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
209
|
+
head: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
210
|
+
private toMiddleware;
|
|
205
211
|
private addRoute;
|
|
206
212
|
private pathToRegex;
|
|
207
213
|
private parseQuery;
|
package/dist/server.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import './http.mjs';
|
|
2
2
|
import './ws.mjs';
|
|
3
|
-
export { H as HttpMethod, M as Middleware, S as ServerRouteContext, b as ServerRouteHandler, c as ServerRouter, q as SharedState, p as SharedStateOptions, o as StateChangeHandler, u as StateManager, g as bodyLimit, i as cacheControl, d as clearImportMapCache, k as compress, e as cors, v as createDevServer, n as createProxyHandler, f as errorHandler, h as html, j as json, l as logger, r as rateLimit, m as security, s as status, t as text } from './server-
|
|
3
|
+
export { H as HttpMethod, M as Middleware, S as ServerRouteContext, b as ServerRouteHandler, c as ServerRouter, q as SharedState, p as SharedStateOptions, o as StateChangeHandler, u as StateManager, g as bodyLimit, i as cacheControl, d as clearImportMapCache, k as compress, e as cors, v as createDevServer, n as createProxyHandler, f as errorHandler, h as html, j as json, l as logger, r as rateLimit, m as security, s as status, t as text } from './server-jAa9yJM4.mjs';
|
|
4
4
|
import 'node:events';
|
|
5
5
|
import 'events';
|
|
6
6
|
import 'http';
|
package/dist/server.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { IncomingMessage, ServerResponse } from './http';
|
|
9
9
|
import { WebSocket } from './ws';
|
|
10
10
|
import type { DevServerOptions, DevServer, ProxyConfig } from './types';
|
|
11
|
-
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD';
|
|
11
|
+
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD' | 'ALL';
|
|
12
12
|
export interface ServerRouteContext {
|
|
13
13
|
req: IncomingMessage;
|
|
14
14
|
res: ServerResponse;
|
|
@@ -17,19 +17,25 @@ export interface ServerRouteContext {
|
|
|
17
17
|
body: any;
|
|
18
18
|
headers: Record<string, string | string[] | undefined>;
|
|
19
19
|
user?: any;
|
|
20
|
+
send?(data: any): ServerResponse;
|
|
21
|
+
json?(data: any): ServerResponse;
|
|
22
|
+
status?(code: number): ServerResponse;
|
|
20
23
|
}
|
|
21
|
-
export type ServerRouteHandler = (ctx: ServerRouteContext) => void | Promise<void>;
|
|
24
|
+
export type ServerRouteHandler = (ctx: ServerRouteContext, next?: () => Promise<void>) => void | Promise<void>;
|
|
22
25
|
export type Middleware = (ctx: ServerRouteContext, next: () => Promise<void>) => void | Promise<void>;
|
|
23
26
|
export declare class ServerRouter {
|
|
24
27
|
private routes;
|
|
25
28
|
private middlewares;
|
|
26
|
-
use(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
use(...args: Array<any>): this;
|
|
30
|
+
all: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
31
|
+
get: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
32
|
+
post: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
33
|
+
put: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
34
|
+
delete: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
35
|
+
patch: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
36
|
+
options: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
37
|
+
head: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
38
|
+
private toMiddleware;
|
|
33
39
|
private addRoute;
|
|
34
40
|
private pathToRegex;
|
|
35
41
|
private parseQuery;
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAgB,eAAe,EAAE,cAAc,EAA0B,MAAM,QAAQ,CAAC;AAE/F,OAAO,EAAmB,SAAS,EAAc,MAAM,MAAM,CAAC;AAM9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAA4B,WAAW,EAAE,MAAM,SAAS,CAAC;AAKlG,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -2662,6 +2662,8 @@ var ServerRouter = class {
|
|
|
2662
2662
|
constructor() {
|
|
2663
2663
|
this.routes = [];
|
|
2664
2664
|
this.middlewares = [];
|
|
2665
|
+
// Express-like .all() method - matches all HTTP methods
|
|
2666
|
+
this.all = (path, ...handlers) => this.addRoute("ALL", path, handlers);
|
|
2665
2667
|
// Support per-route middleware: accept middleware(s) before the final handler
|
|
2666
2668
|
this.get = (path, ...handlers) => this.addRoute("GET", path, handlers);
|
|
2667
2669
|
this.post = (path, ...handlers) => this.addRoute("POST", path, handlers);
|
|
@@ -2669,16 +2671,72 @@ var ServerRouter = class {
|
|
|
2669
2671
|
this.delete = (path, ...handlers) => this.addRoute("DELETE", path, handlers);
|
|
2670
2672
|
this.patch = (path, ...handlers) => this.addRoute("PATCH", path, handlers);
|
|
2671
2673
|
this.options = (path, ...handlers) => this.addRoute("OPTIONS", path, handlers);
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2674
|
+
this.head = (path, ...handlers) => this.addRoute("HEAD", path, handlers);
|
|
2675
|
+
}
|
|
2676
|
+
// Accept both internal Middleware and Express-style `(req, res, next?)` functions
|
|
2677
|
+
// Also support path-based middleware like Express: use(path, middleware)
|
|
2678
|
+
use(...args) {
|
|
2679
|
+
if (typeof args[0] === "string") {
|
|
2680
|
+
const path = args[0];
|
|
2681
|
+
const middlewares = args.slice(1);
|
|
2682
|
+
return this.addRoute("ALL", path, middlewares);
|
|
2683
|
+
}
|
|
2684
|
+
const mw = args[0];
|
|
2685
|
+
this.middlewares.push(this.toMiddleware(mw));
|
|
2675
2686
|
return this;
|
|
2676
2687
|
}
|
|
2688
|
+
// Convert Express-like handler/middleware to internal Middleware
|
|
2689
|
+
toMiddleware(fn) {
|
|
2690
|
+
if (fn.length === 2 && fn.name !== "bound ") {
|
|
2691
|
+
}
|
|
2692
|
+
return async (ctx, next) => {
|
|
2693
|
+
const f = fn;
|
|
2694
|
+
if (f.length >= 3) {
|
|
2695
|
+
const expressNext = () => {
|
|
2696
|
+
void next();
|
|
2697
|
+
};
|
|
2698
|
+
const res = f(ctx.req, ctx.res, expressNext);
|
|
2699
|
+
if (res && typeof res.then === "function") await res;
|
|
2700
|
+
return;
|
|
2701
|
+
}
|
|
2702
|
+
if (f.length === 2) {
|
|
2703
|
+
const res = f(ctx.req, ctx.res);
|
|
2704
|
+
if (res && typeof res.then === "function") await res;
|
|
2705
|
+
await next();
|
|
2706
|
+
return;
|
|
2707
|
+
}
|
|
2708
|
+
const out = fn(ctx);
|
|
2709
|
+
if (out && typeof out.then === "function") await out;
|
|
2710
|
+
await next();
|
|
2711
|
+
};
|
|
2712
|
+
}
|
|
2677
2713
|
addRoute(method, path, handlers) {
|
|
2678
2714
|
const { pattern, paramNames } = this.pathToRegex(path);
|
|
2679
2715
|
if (!handlers || handlers.length === 0) throw new Error("Route must include a handler");
|
|
2680
|
-
const
|
|
2681
|
-
const
|
|
2716
|
+
const rawMiddlewares = handlers.slice(0, handlers.length - 1);
|
|
2717
|
+
const rawLast = handlers[handlers.length - 1];
|
|
2718
|
+
const middlewares = rawMiddlewares.map((h) => this.toMiddleware(h));
|
|
2719
|
+
const last = (() => {
|
|
2720
|
+
const f = rawLast;
|
|
2721
|
+
if (typeof f !== "function") throw new Error("Route handler must be a function");
|
|
2722
|
+
if (f.length >= 2) {
|
|
2723
|
+
return async (ctx) => {
|
|
2724
|
+
if (f.length >= 3) {
|
|
2725
|
+
await new Promise((resolve2) => {
|
|
2726
|
+
try {
|
|
2727
|
+
f(ctx.req, ctx.res, () => resolve2());
|
|
2728
|
+
} catch (e) {
|
|
2729
|
+
resolve2();
|
|
2730
|
+
}
|
|
2731
|
+
});
|
|
2732
|
+
} else {
|
|
2733
|
+
const res = f(ctx.req, ctx.res);
|
|
2734
|
+
if (res && typeof res.then === "function") await res;
|
|
2735
|
+
}
|
|
2736
|
+
};
|
|
2737
|
+
}
|
|
2738
|
+
return f;
|
|
2739
|
+
})();
|
|
2682
2740
|
this.routes.push({ method, pattern, paramNames, handler: last, middlewares });
|
|
2683
2741
|
return this;
|
|
2684
2742
|
}
|
|
@@ -2744,7 +2802,8 @@ var ServerRouter = class {
|
|
|
2744
2802
|
async handle(req, res) {
|
|
2745
2803
|
const method = req.method, url = req.url || "/", path = url.split("?")[0];
|
|
2746
2804
|
for (const route of this.routes) {
|
|
2747
|
-
if (route.method !==
|
|
2805
|
+
if (route.method !== "ALL" && route.method !== method) continue;
|
|
2806
|
+
if (!route.pattern.test(path)) continue;
|
|
2748
2807
|
const match = path.match(route.pattern);
|
|
2749
2808
|
const params = Object.fromEntries(route.paramNames.map((name, i2) => [name, match[i2 + 1]]));
|
|
2750
2809
|
let body = {};
|
|
@@ -2757,11 +2816,46 @@ var ServerRouter = class {
|
|
|
2757
2816
|
return true;
|
|
2758
2817
|
}
|
|
2759
2818
|
}
|
|
2760
|
-
const ctx = {
|
|
2819
|
+
const ctx = {
|
|
2820
|
+
req,
|
|
2821
|
+
res,
|
|
2822
|
+
params,
|
|
2823
|
+
query: this.parseQuery(url),
|
|
2824
|
+
body,
|
|
2825
|
+
headers: req.headers,
|
|
2826
|
+
send: (data) => {
|
|
2827
|
+
if (!res.headersSent) {
|
|
2828
|
+
if (typeof data === "object") {
|
|
2829
|
+
res.setHeader("Content-Type", "application/json");
|
|
2830
|
+
res.end(JSON.stringify(data));
|
|
2831
|
+
} else {
|
|
2832
|
+
res.end(String(data));
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2835
|
+
return res;
|
|
2836
|
+
},
|
|
2837
|
+
json: (data) => {
|
|
2838
|
+
if (!res.headersSent) {
|
|
2839
|
+
res.setHeader("Content-Type", "application/json");
|
|
2840
|
+
res.end(JSON.stringify(data));
|
|
2841
|
+
}
|
|
2842
|
+
return res;
|
|
2843
|
+
},
|
|
2844
|
+
status: (code) => {
|
|
2845
|
+
if (!res.headersSent) {
|
|
2846
|
+
res.statusCode = code;
|
|
2847
|
+
}
|
|
2848
|
+
return res;
|
|
2849
|
+
}
|
|
2850
|
+
};
|
|
2761
2851
|
const routeMiddlewares = route.middlewares || [];
|
|
2762
|
-
const chain = [
|
|
2763
|
-
|
|
2764
|
-
|
|
2852
|
+
const chain = [
|
|
2853
|
+
...this.middlewares,
|
|
2854
|
+
...routeMiddlewares,
|
|
2855
|
+
async (c, n) => {
|
|
2856
|
+
await route.handler(c, n);
|
|
2857
|
+
}
|
|
2858
|
+
];
|
|
2765
2859
|
let i = 0;
|
|
2766
2860
|
const next = async () => {
|
|
2767
2861
|
if (i >= chain.length) return;
|
package/dist/server.mjs
CHANGED
|
@@ -2636,6 +2636,8 @@ var ServerRouter = class {
|
|
|
2636
2636
|
constructor() {
|
|
2637
2637
|
this.routes = [];
|
|
2638
2638
|
this.middlewares = [];
|
|
2639
|
+
// Express-like .all() method - matches all HTTP methods
|
|
2640
|
+
this.all = (path, ...handlers) => this.addRoute("ALL", path, handlers);
|
|
2639
2641
|
// Support per-route middleware: accept middleware(s) before the final handler
|
|
2640
2642
|
this.get = (path, ...handlers) => this.addRoute("GET", path, handlers);
|
|
2641
2643
|
this.post = (path, ...handlers) => this.addRoute("POST", path, handlers);
|
|
@@ -2643,16 +2645,72 @@ var ServerRouter = class {
|
|
|
2643
2645
|
this.delete = (path, ...handlers) => this.addRoute("DELETE", path, handlers);
|
|
2644
2646
|
this.patch = (path, ...handlers) => this.addRoute("PATCH", path, handlers);
|
|
2645
2647
|
this.options = (path, ...handlers) => this.addRoute("OPTIONS", path, handlers);
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2648
|
+
this.head = (path, ...handlers) => this.addRoute("HEAD", path, handlers);
|
|
2649
|
+
}
|
|
2650
|
+
// Accept both internal Middleware and Express-style `(req, res, next?)` functions
|
|
2651
|
+
// Also support path-based middleware like Express: use(path, middleware)
|
|
2652
|
+
use(...args) {
|
|
2653
|
+
if (typeof args[0] === "string") {
|
|
2654
|
+
const path = args[0];
|
|
2655
|
+
const middlewares = args.slice(1);
|
|
2656
|
+
return this.addRoute("ALL", path, middlewares);
|
|
2657
|
+
}
|
|
2658
|
+
const mw = args[0];
|
|
2659
|
+
this.middlewares.push(this.toMiddleware(mw));
|
|
2649
2660
|
return this;
|
|
2650
2661
|
}
|
|
2662
|
+
// Convert Express-like handler/middleware to internal Middleware
|
|
2663
|
+
toMiddleware(fn) {
|
|
2664
|
+
if (fn.length === 2 && fn.name !== "bound ") {
|
|
2665
|
+
}
|
|
2666
|
+
return async (ctx, next) => {
|
|
2667
|
+
const f = fn;
|
|
2668
|
+
if (f.length >= 3) {
|
|
2669
|
+
const expressNext = () => {
|
|
2670
|
+
void next();
|
|
2671
|
+
};
|
|
2672
|
+
const res = f(ctx.req, ctx.res, expressNext);
|
|
2673
|
+
if (res && typeof res.then === "function") await res;
|
|
2674
|
+
return;
|
|
2675
|
+
}
|
|
2676
|
+
if (f.length === 2) {
|
|
2677
|
+
const res = f(ctx.req, ctx.res);
|
|
2678
|
+
if (res && typeof res.then === "function") await res;
|
|
2679
|
+
await next();
|
|
2680
|
+
return;
|
|
2681
|
+
}
|
|
2682
|
+
const out = fn(ctx);
|
|
2683
|
+
if (out && typeof out.then === "function") await out;
|
|
2684
|
+
await next();
|
|
2685
|
+
};
|
|
2686
|
+
}
|
|
2651
2687
|
addRoute(method, path, handlers) {
|
|
2652
2688
|
const { pattern, paramNames } = this.pathToRegex(path);
|
|
2653
2689
|
if (!handlers || handlers.length === 0) throw new Error("Route must include a handler");
|
|
2654
|
-
const
|
|
2655
|
-
const
|
|
2690
|
+
const rawMiddlewares = handlers.slice(0, handlers.length - 1);
|
|
2691
|
+
const rawLast = handlers[handlers.length - 1];
|
|
2692
|
+
const middlewares = rawMiddlewares.map((h) => this.toMiddleware(h));
|
|
2693
|
+
const last = (() => {
|
|
2694
|
+
const f = rawLast;
|
|
2695
|
+
if (typeof f !== "function") throw new Error("Route handler must be a function");
|
|
2696
|
+
if (f.length >= 2) {
|
|
2697
|
+
return async (ctx) => {
|
|
2698
|
+
if (f.length >= 3) {
|
|
2699
|
+
await new Promise((resolve2) => {
|
|
2700
|
+
try {
|
|
2701
|
+
f(ctx.req, ctx.res, () => resolve2());
|
|
2702
|
+
} catch (e) {
|
|
2703
|
+
resolve2();
|
|
2704
|
+
}
|
|
2705
|
+
});
|
|
2706
|
+
} else {
|
|
2707
|
+
const res = f(ctx.req, ctx.res);
|
|
2708
|
+
if (res && typeof res.then === "function") await res;
|
|
2709
|
+
}
|
|
2710
|
+
};
|
|
2711
|
+
}
|
|
2712
|
+
return f;
|
|
2713
|
+
})();
|
|
2656
2714
|
this.routes.push({ method, pattern, paramNames, handler: last, middlewares });
|
|
2657
2715
|
return this;
|
|
2658
2716
|
}
|
|
@@ -2718,7 +2776,8 @@ var ServerRouter = class {
|
|
|
2718
2776
|
async handle(req, res) {
|
|
2719
2777
|
const method = req.method, url = req.url || "/", path = url.split("?")[0];
|
|
2720
2778
|
for (const route of this.routes) {
|
|
2721
|
-
if (route.method !==
|
|
2779
|
+
if (route.method !== "ALL" && route.method !== method) continue;
|
|
2780
|
+
if (!route.pattern.test(path)) continue;
|
|
2722
2781
|
const match = path.match(route.pattern);
|
|
2723
2782
|
const params = Object.fromEntries(route.paramNames.map((name, i2) => [name, match[i2 + 1]]));
|
|
2724
2783
|
let body = {};
|
|
@@ -2731,11 +2790,46 @@ var ServerRouter = class {
|
|
|
2731
2790
|
return true;
|
|
2732
2791
|
}
|
|
2733
2792
|
}
|
|
2734
|
-
const ctx = {
|
|
2793
|
+
const ctx = {
|
|
2794
|
+
req,
|
|
2795
|
+
res,
|
|
2796
|
+
params,
|
|
2797
|
+
query: this.parseQuery(url),
|
|
2798
|
+
body,
|
|
2799
|
+
headers: req.headers,
|
|
2800
|
+
send: (data) => {
|
|
2801
|
+
if (!res.headersSent) {
|
|
2802
|
+
if (typeof data === "object") {
|
|
2803
|
+
res.setHeader("Content-Type", "application/json");
|
|
2804
|
+
res.end(JSON.stringify(data));
|
|
2805
|
+
} else {
|
|
2806
|
+
res.end(String(data));
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
return res;
|
|
2810
|
+
},
|
|
2811
|
+
json: (data) => {
|
|
2812
|
+
if (!res.headersSent) {
|
|
2813
|
+
res.setHeader("Content-Type", "application/json");
|
|
2814
|
+
res.end(JSON.stringify(data));
|
|
2815
|
+
}
|
|
2816
|
+
return res;
|
|
2817
|
+
},
|
|
2818
|
+
status: (code) => {
|
|
2819
|
+
if (!res.headersSent) {
|
|
2820
|
+
res.statusCode = code;
|
|
2821
|
+
}
|
|
2822
|
+
return res;
|
|
2823
|
+
}
|
|
2824
|
+
};
|
|
2735
2825
|
const routeMiddlewares = route.middlewares || [];
|
|
2736
|
-
const chain = [
|
|
2737
|
-
|
|
2738
|
-
|
|
2826
|
+
const chain = [
|
|
2827
|
+
...this.middlewares,
|
|
2828
|
+
...routeMiddlewares,
|
|
2829
|
+
async (c, n) => {
|
|
2830
|
+
await route.handler(c, n);
|
|
2831
|
+
}
|
|
2832
|
+
];
|
|
2739
2833
|
let i = 0;
|
|
2740
2834
|
const next = async () => {
|
|
2741
2835
|
if (i >= chain.length) return;
|
package/dist/types.d.mts
CHANGED
|
@@ -156,19 +156,25 @@ interface ServerRouteContext {
|
|
|
156
156
|
body: any;
|
|
157
157
|
headers: Record<string, string | string[] | undefined>;
|
|
158
158
|
user?: any;
|
|
159
|
+
send?(data: any): ServerResponse;
|
|
160
|
+
json?(data: any): ServerResponse;
|
|
161
|
+
status?(code: number): ServerResponse;
|
|
159
162
|
}
|
|
160
|
-
type ServerRouteHandler = (ctx: ServerRouteContext) => void | Promise<void>;
|
|
163
|
+
type ServerRouteHandler = (ctx: ServerRouteContext, next?: () => Promise<void>) => void | Promise<void>;
|
|
161
164
|
type Middleware = (ctx: ServerRouteContext, next: () => Promise<void>) => void | Promise<void>;
|
|
162
165
|
declare class ServerRouter {
|
|
163
166
|
private routes;
|
|
164
167
|
private middlewares;
|
|
165
|
-
use(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
168
|
+
use(...args: Array<any>): this;
|
|
169
|
+
all: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
170
|
+
get: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
171
|
+
post: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
172
|
+
put: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
173
|
+
delete: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
174
|
+
patch: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
175
|
+
options: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
176
|
+
head: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
|
|
177
|
+
private toMiddleware;
|
|
172
178
|
private addRoute;
|
|
173
179
|
private pathToRegex;
|
|
174
180
|
private parseQuery;
|
package/package.json
CHANGED
package/src/server.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { dom } from './dom';
|
|
|
19
19
|
|
|
20
20
|
// ===== Router =====
|
|
21
21
|
|
|
22
|
-
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD';
|
|
22
|
+
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD' | 'ALL';
|
|
23
23
|
|
|
24
24
|
export interface ServerRouteContext {
|
|
25
25
|
req: IncomingMessage;
|
|
@@ -29,9 +29,13 @@ export interface ServerRouteContext {
|
|
|
29
29
|
body: any;
|
|
30
30
|
headers: Record<string, string | string[] | undefined>;
|
|
31
31
|
user?: any;
|
|
32
|
+
// Express-compatible response helpers
|
|
33
|
+
send?(data: any): ServerResponse;
|
|
34
|
+
json?(data: any): ServerResponse;
|
|
35
|
+
status?(code: number): ServerResponse;
|
|
32
36
|
}
|
|
33
37
|
|
|
34
|
-
export type ServerRouteHandler = (ctx: ServerRouteContext) => void | Promise<void>;
|
|
38
|
+
export type ServerRouteHandler = (ctx: ServerRouteContext, next?: () => Promise<void>) => void | Promise<void>;
|
|
35
39
|
export type Middleware = (ctx: ServerRouteContext, next: () => Promise<void>) => void | Promise<void>;
|
|
36
40
|
|
|
37
41
|
interface ServerRoute {
|
|
@@ -46,25 +50,107 @@ export class ServerRouter {
|
|
|
46
50
|
private routes: ServerRoute[] = [];
|
|
47
51
|
private middlewares: Middleware[] = [];
|
|
48
52
|
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
// Accept both internal Middleware and Express-style `(req, res, next?)` functions
|
|
54
|
+
// Also support path-based middleware like Express: use(path, middleware)
|
|
55
|
+
use(...args: Array<any>): this {
|
|
56
|
+
if (typeof args[0] === 'string') {
|
|
57
|
+
// Path-based middleware: use(path, ...middlewares)
|
|
58
|
+
const path = args[0];
|
|
59
|
+
const middlewares = args.slice(1);
|
|
60
|
+
return this.addRoute('ALL', path, middlewares);
|
|
61
|
+
}
|
|
62
|
+
// Global middleware
|
|
63
|
+
const mw = args[0];
|
|
64
|
+
this.middlewares.push(this.toMiddleware(mw));
|
|
51
65
|
return this;
|
|
52
66
|
}
|
|
53
67
|
|
|
68
|
+
// Express-like .all() method - matches all HTTP methods
|
|
69
|
+
all = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('ALL', path, handlers as any);
|
|
70
|
+
|
|
54
71
|
// Support per-route middleware: accept middleware(s) before the final handler
|
|
55
|
-
get = (path: string, ...handlers: Array<Middleware | ServerRouteHandler>): this => this.addRoute('GET', path, handlers as any);
|
|
56
|
-
post = (path: string, ...handlers: Array<Middleware | ServerRouteHandler>): this => this.addRoute('POST', path, handlers as any);
|
|
57
|
-
put = (path: string, ...handlers: Array<Middleware | ServerRouteHandler>): this => this.addRoute('PUT', path, handlers as any);
|
|
58
|
-
delete = (path: string, ...handlers: Array<Middleware | ServerRouteHandler>): this => this.addRoute('DELETE', path, handlers as any);
|
|
59
|
-
patch = (path: string, ...handlers: Array<Middleware | ServerRouteHandler>): this => this.addRoute('PATCH', path, handlers as any);
|
|
60
|
-
options = (path: string, ...handlers: Array<Middleware | ServerRouteHandler>): this => this.addRoute('OPTIONS', path, handlers as any);
|
|
61
|
-
|
|
62
|
-
|
|
72
|
+
get = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('GET', path, handlers as any);
|
|
73
|
+
post = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('POST', path, handlers as any);
|
|
74
|
+
put = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('PUT', path, handlers as any);
|
|
75
|
+
delete = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('DELETE', path, handlers as any);
|
|
76
|
+
patch = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('PATCH', path, handlers as any);
|
|
77
|
+
options = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('OPTIONS', path, handlers as any);
|
|
78
|
+
head = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('HEAD', path, handlers as any);
|
|
79
|
+
|
|
80
|
+
// Convert Express-like handler/middleware to internal Middleware
|
|
81
|
+
private toMiddleware(fn: Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)): Middleware {
|
|
82
|
+
// If it's already our Middleware, return as-is
|
|
83
|
+
if ((fn as Middleware).length === 2 && (fn as any).name !== 'bound ') {
|
|
84
|
+
// Cannot reliably detect, so always wrap to normalize behavior
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return async (ctx: ServerRouteContext, next: () => Promise<void>) => {
|
|
88
|
+
const f: any = fn;
|
|
89
|
+
|
|
90
|
+
// Express-style with (req, res, next)
|
|
91
|
+
if (f.length >= 3) {
|
|
92
|
+
// Provide a next that triggers our next
|
|
93
|
+
const expressNext = () => {
|
|
94
|
+
// call our next but don't await here
|
|
95
|
+
void next();
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const res = f(ctx.req, ctx.res, expressNext);
|
|
99
|
+
if (res && typeof res.then === 'function') await res;
|
|
100
|
+
// If express middleware didn't call next(), we simply return and stop the chain
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Express-style with (req, res) - treat as middleware that continues after completion
|
|
105
|
+
if (f.length === 2) {
|
|
106
|
+
const res = f(ctx.req, ctx.res);
|
|
107
|
+
if (res && typeof res.then === 'function') await res;
|
|
108
|
+
await next();
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Our internal handler style (ctx) => ... - call it and continue
|
|
113
|
+
const out = (fn as ServerRouteHandler)(ctx);
|
|
114
|
+
if (out && typeof out.then === 'function') await out;
|
|
115
|
+
await next();
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private addRoute(method: HttpMethod, path: string, handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this {
|
|
63
120
|
const { pattern, paramNames } = this.pathToRegex(path);
|
|
64
121
|
// Last item is the actual route handler, preceding items are middlewares
|
|
65
122
|
if (!handlers || handlers.length === 0) throw new Error('Route must include a handler');
|
|
66
|
-
const
|
|
67
|
-
const
|
|
123
|
+
const rawMiddlewares = handlers.slice(0, handlers.length - 1);
|
|
124
|
+
const rawLast = handlers[handlers.length - 1];
|
|
125
|
+
|
|
126
|
+
const middlewares = rawMiddlewares.map(h => this.toMiddleware(h as any));
|
|
127
|
+
|
|
128
|
+
// Normalize last handler: if it's express-like, wrap into ServerRouteHandler
|
|
129
|
+
const last = ((): ServerRouteHandler => {
|
|
130
|
+
const f: any = rawLast;
|
|
131
|
+
if (typeof f !== 'function') throw new Error('Route handler must be a function');
|
|
132
|
+
|
|
133
|
+
if (f.length >= 2) {
|
|
134
|
+
// Express-style final handler
|
|
135
|
+
return async (ctx: ServerRouteContext) => {
|
|
136
|
+
if (f.length >= 3) {
|
|
137
|
+
// expects next
|
|
138
|
+
await new Promise<void>((resolve) => {
|
|
139
|
+
try {
|
|
140
|
+
f(ctx.req, ctx.res, () => resolve());
|
|
141
|
+
} catch (e) { resolve(); }
|
|
142
|
+
});
|
|
143
|
+
} else {
|
|
144
|
+
const res = f(ctx.req, ctx.res);
|
|
145
|
+
if (res && typeof res.then === 'function') await res;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Already a ServerRouteHandler (ctx)
|
|
151
|
+
return f as ServerRouteHandler;
|
|
152
|
+
})();
|
|
153
|
+
|
|
68
154
|
this.routes.push({ method, pattern, paramNames, handler: last, middlewares });
|
|
69
155
|
return this;
|
|
70
156
|
}
|
|
@@ -147,7 +233,8 @@ export class ServerRouter {
|
|
|
147
233
|
const method = req.method as HttpMethod, url = req.url || '/', path = url.split('?')[0];
|
|
148
234
|
|
|
149
235
|
for (const route of this.routes) {
|
|
150
|
-
if (route.method !==
|
|
236
|
+
if (route.method !== 'ALL' && route.method !== method) continue;
|
|
237
|
+
if (!route.pattern.test(path)) continue;
|
|
151
238
|
const match = path.match(route.pattern)!;
|
|
152
239
|
const params = Object.fromEntries(route.paramNames.map((name, i) => [name, match[i + 1]]));
|
|
153
240
|
|
|
@@ -163,11 +250,48 @@ export class ServerRouter {
|
|
|
163
250
|
}
|
|
164
251
|
}
|
|
165
252
|
|
|
166
|
-
|
|
253
|
+
// Add Express-like response helpers to context
|
|
254
|
+
const ctx: ServerRouteContext = {
|
|
255
|
+
req,
|
|
256
|
+
res,
|
|
257
|
+
params,
|
|
258
|
+
query: this.parseQuery(url),
|
|
259
|
+
body,
|
|
260
|
+
headers: req.headers as any,
|
|
261
|
+
send: (data: any) => {
|
|
262
|
+
if (!res.headersSent) {
|
|
263
|
+
if (typeof data === 'object') {
|
|
264
|
+
res.setHeader('Content-Type', 'application/json');
|
|
265
|
+
res.end(JSON.stringify(data));
|
|
266
|
+
} else {
|
|
267
|
+
res.end(String(data));
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return res;
|
|
271
|
+
},
|
|
272
|
+
json: (data: any) => {
|
|
273
|
+
if (!res.headersSent) {
|
|
274
|
+
res.setHeader('Content-Type', 'application/json');
|
|
275
|
+
res.end(JSON.stringify(data));
|
|
276
|
+
}
|
|
277
|
+
return res;
|
|
278
|
+
},
|
|
279
|
+
status: (code: number) => {
|
|
280
|
+
if (!res.headersSent) {
|
|
281
|
+
res.statusCode = code;
|
|
282
|
+
}
|
|
283
|
+
return res;
|
|
284
|
+
}
|
|
285
|
+
};
|
|
167
286
|
|
|
168
287
|
// Build middleware chain: global middlewares -> route middlewares -> final handler
|
|
288
|
+
// Pass `next` to the final handler so it can optionally call await next()
|
|
169
289
|
const routeMiddlewares = route.middlewares || [];
|
|
170
|
-
const chain: Middleware[] = [
|
|
290
|
+
const chain: Middleware[] = [
|
|
291
|
+
...this.middlewares,
|
|
292
|
+
...routeMiddlewares,
|
|
293
|
+
async (c, n) => { await route.handler(c, n); }
|
|
294
|
+
];
|
|
171
295
|
|
|
172
296
|
let i = 0;
|
|
173
297
|
const next = async () => {
|