elit 3.1.1 → 3.1.3

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 CHANGED
@@ -1,4 +1,4 @@
1
- import { B as BuildOptions, a as BuildResult } from './server-BgWmjg9q.mjs';
1
+ import { B as BuildOptions, a as BuildResult } from './server-QfJoaxeO.mjs';
2
2
  import './http.mjs';
3
3
  import 'node:events';
4
4
  import './ws.mjs';
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.1",
1415
+ version: "3.1.3",
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",
@@ -188,19 +188,21 @@ interface ServerRouteContext {
188
188
  query: Record<string, string>;
189
189
  body: any;
190
190
  headers: Record<string, string | string[] | undefined>;
191
+ user?: any;
191
192
  }
192
- type ServerRouteHandler = (ctx: ServerRouteContext) => void | Promise<void>;
193
+ type ServerRouteHandler = (ctx: ServerRouteContext, next?: () => Promise<void>) => void | Promise<void>;
193
194
  type Middleware = (ctx: ServerRouteContext, next: () => Promise<void>) => void | Promise<void>;
194
195
  declare class ServerRouter {
195
196
  private routes;
196
197
  private middlewares;
197
- use(middleware: Middleware): this;
198
- get: (path: string, handler: ServerRouteHandler) => this;
199
- post: (path: string, handler: ServerRouteHandler) => this;
200
- put: (path: string, handler: ServerRouteHandler) => this;
201
- delete: (path: string, handler: ServerRouteHandler) => this;
202
- patch: (path: string, handler: ServerRouteHandler) => this;
203
- options: (path: string, handler: ServerRouteHandler) => this;
198
+ use(mw: Middleware | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)): this;
199
+ private toMiddleware;
200
+ get: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
201
+ post: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
202
+ put: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
203
+ delete: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
204
+ patch: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
205
+ options: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
204
206
  private addRoute;
205
207
  private pathToRegex;
206
208
  private parseQuery;
@@ -188,19 +188,21 @@ interface ServerRouteContext {
188
188
  query: Record<string, string>;
189
189
  body: any;
190
190
  headers: Record<string, string | string[] | undefined>;
191
+ user?: any;
191
192
  }
192
- type ServerRouteHandler = (ctx: ServerRouteContext) => void | Promise<void>;
193
+ type ServerRouteHandler = (ctx: ServerRouteContext, next?: () => Promise<void>) => void | Promise<void>;
193
194
  type Middleware = (ctx: ServerRouteContext, next: () => Promise<void>) => void | Promise<void>;
194
195
  declare class ServerRouter {
195
196
  private routes;
196
197
  private middlewares;
197
- use(middleware: Middleware): this;
198
- get: (path: string, handler: ServerRouteHandler) => this;
199
- post: (path: string, handler: ServerRouteHandler) => this;
200
- put: (path: string, handler: ServerRouteHandler) => this;
201
- delete: (path: string, handler: ServerRouteHandler) => this;
202
- patch: (path: string, handler: ServerRouteHandler) => this;
203
- options: (path: string, handler: ServerRouteHandler) => this;
198
+ use(mw: Middleware | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)): this;
199
+ private toMiddleware;
200
+ get: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
201
+ post: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
202
+ put: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
203
+ delete: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
204
+ patch: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
205
+ options: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
204
206
  private addRoute;
205
207
  private pathToRegex;
206
208
  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-BgWmjg9q.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-QfJoaxeO.mjs';
4
4
  import 'node:events';
5
5
  import 'events';
6
6
  import 'http';
package/dist/server.d.ts CHANGED
@@ -16,19 +16,21 @@ export interface ServerRouteContext {
16
16
  query: Record<string, string>;
17
17
  body: any;
18
18
  headers: Record<string, string | string[] | undefined>;
19
+ user?: any;
19
20
  }
20
- export type ServerRouteHandler = (ctx: ServerRouteContext) => void | Promise<void>;
21
+ export type ServerRouteHandler = (ctx: ServerRouteContext, next?: () => Promise<void>) => void | Promise<void>;
21
22
  export type Middleware = (ctx: ServerRouteContext, next: () => Promise<void>) => void | Promise<void>;
22
23
  export declare class ServerRouter {
23
24
  private routes;
24
25
  private middlewares;
25
- use(middleware: Middleware): this;
26
- get: (path: string, handler: ServerRouteHandler) => this;
27
- post: (path: string, handler: ServerRouteHandler) => this;
28
- put: (path: string, handler: ServerRouteHandler) => this;
29
- delete: (path: string, handler: ServerRouteHandler) => this;
30
- patch: (path: string, handler: ServerRouteHandler) => this;
31
- options: (path: string, handler: ServerRouteHandler) => this;
26
+ use(mw: Middleware | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)): this;
27
+ private toMiddleware;
28
+ get: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
29
+ post: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
30
+ put: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
31
+ delete: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
32
+ patch: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
33
+ options: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
32
34
  private addRoute;
33
35
  private pathToRegex;
34
36
  private parseQuery;
@@ -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;AAE1F,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,eAAe,CAAC;IACrB,GAAG,EAAE,cAAc,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,IAAI,EAAE,GAAG,CAAC;IACV,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;CACxD;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AACnF,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAStG,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,WAAW,CAAoB;IAEvC,GAAG,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAKjC,GAAG,GAAI,MAAM,MAAM,EAAE,SAAS,kBAAkB,KAAG,IAAI,CAAwC;IAC/F,IAAI,GAAI,MAAM,MAAM,EAAE,SAAS,kBAAkB,KAAG,IAAI,CAAyC;IACjG,GAAG,GAAI,MAAM,MAAM,EAAE,SAAS,kBAAkB,KAAG,IAAI,CAAwC;IAC/F,MAAM,GAAI,MAAM,MAAM,EAAE,SAAS,kBAAkB,KAAG,IAAI,CAA2C;IACrG,KAAK,GAAI,MAAM,MAAM,EAAE,SAAS,kBAAkB,KAAG,IAAI,CAA0C;IACnG,OAAO,GAAI,MAAM,MAAM,EAAE,SAAS,kBAAkB,KAAG,IAAI,CAA4C;IAEvG,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,UAAU;YAMJ,SAAS;IA8DjB,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;CAsC1E;AAED,eAAO,MAAM,IAAI,GAAI,KAAK,cAAc,EAAE,MAAM,GAAG,EAAE,eAAY,mBAAmG,CAAC;AACrK,eAAO,MAAM,IAAI,GAAI,KAAK,cAAc,EAAE,MAAM,MAAM,EAAE,eAAY,mBAA6E,CAAC;AAClJ,eAAO,MAAM,IAAI,GAAI,KAAK,cAAc,EAAE,MAAM,MAAM,EAAE,eAAY,mBAA4E,CAAC;AACjJ,eAAO,MAAM,MAAM,GAAI,KAAK,cAAc,EAAE,MAAM,MAAM,EAAE,gBAAY,mBAAsH,CAAC;AAuG7L;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AA2QD,wBAAgB,IAAI,CAAC,OAAO,GAAE;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACZ,GAAG,UAAU,CAqBlB;AAED,wBAAgB,MAAM,CAAC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;CAAO,GAAG,UAAU,CAUnF;AAED,wBAAgB,YAAY,IAAI,UAAU,CAYzC;AAED,wBAAgB,SAAS,CAAC,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,UAAU,CAqBzG;AAED,wBAAgB,SAAS,CAAC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,UAAU,CAYtE;AAED,wBAAgB,YAAY,CAAC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,UAAU,CAM5F;AAED,wBAAgB,QAAQ,IAAI,UAAU,CAiCrC;AAED,wBAAgB,QAAQ,IAAI,UAAU,CAQrC;AAgBD,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,WAAW,EAAE,IAC9C,KAAK,eAAe,EAAE,KAAK,cAAc,KAAG,OAAO,CAAC,OAAO,CAAC,CAkF3E;AAID,MAAM,MAAM,kBAAkB,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,IAAI,CAAC;AAE1E,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,GAAG;IACzC,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC;CAClC;AAED,qBAAa,WAAW,CAAC,CAAC,GAAG,GAAG;aAOZ,GAAG,EAAE,MAAM;IAN7B,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,cAAc,CAAoC;IAC1D,OAAO,CAAC,OAAO,CAAwB;gBAGrB,GAAG,EAAE,MAAM,EAC3B,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAMhC,IAAI,KAAK,IAAI,CAAC,CAEb;IAED,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,EAapB;IAED,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI;IAIxC,SAAS,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI;IAK9B,WAAW,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI;IAIhC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAKpD,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,MAAM;IAMd,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED,KAAK,IAAI,IAAI;CAId;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAuC;IAErD,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;IAOtE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS;IAI/C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAS5B,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI;IAI3C,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI;IAI7C,cAAc,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI;IAInC,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAKhD,IAAI,IAAI,MAAM,EAAE;IAIhB,KAAK,IAAI,IAAI;CAId;AA0BD,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAyuBpE"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -2662,20 +2662,72 @@ var ServerRouter = class {
2662
2662
  constructor() {
2663
2663
  this.routes = [];
2664
2664
  this.middlewares = [];
2665
- this.get = (path, handler) => this.addRoute("GET", path, handler);
2666
- this.post = (path, handler) => this.addRoute("POST", path, handler);
2667
- this.put = (path, handler) => this.addRoute("PUT", path, handler);
2668
- this.delete = (path, handler) => this.addRoute("DELETE", path, handler);
2669
- this.patch = (path, handler) => this.addRoute("PATCH", path, handler);
2670
- this.options = (path, handler) => this.addRoute("OPTIONS", path, handler);
2671
- }
2672
- use(middleware) {
2673
- this.middlewares.push(middleware);
2665
+ // Support per-route middleware: accept middleware(s) before the final handler
2666
+ this.get = (path, ...handlers) => this.addRoute("GET", path, handlers);
2667
+ this.post = (path, ...handlers) => this.addRoute("POST", path, handlers);
2668
+ this.put = (path, ...handlers) => this.addRoute("PUT", path, handlers);
2669
+ this.delete = (path, ...handlers) => this.addRoute("DELETE", path, handlers);
2670
+ this.patch = (path, ...handlers) => this.addRoute("PATCH", path, handlers);
2671
+ this.options = (path, ...handlers) => this.addRoute("OPTIONS", path, handlers);
2672
+ }
2673
+ // Accept both internal Middleware and Express-style `(req, res, next?)` functions
2674
+ use(mw) {
2675
+ this.middlewares.push(this.toMiddleware(mw));
2674
2676
  return this;
2675
2677
  }
2676
- addRoute(method, path, handler) {
2678
+ // Convert Express-like handler/middleware to internal Middleware
2679
+ toMiddleware(fn) {
2680
+ if (fn.length === 2 && fn.name !== "bound ") {
2681
+ }
2682
+ return async (ctx, next) => {
2683
+ const f = fn;
2684
+ if (f.length >= 3) {
2685
+ const expressNext = () => {
2686
+ void next();
2687
+ };
2688
+ const res = f(ctx.req, ctx.res, expressNext);
2689
+ if (res && typeof res.then === "function") await res;
2690
+ return;
2691
+ }
2692
+ if (f.length === 2) {
2693
+ const res = f(ctx.req, ctx.res);
2694
+ if (res && typeof res.then === "function") await res;
2695
+ await next();
2696
+ return;
2697
+ }
2698
+ const out = fn(ctx);
2699
+ if (out && typeof out.then === "function") await out;
2700
+ await next();
2701
+ };
2702
+ }
2703
+ addRoute(method, path, handlers) {
2677
2704
  const { pattern, paramNames } = this.pathToRegex(path);
2678
- this.routes.push({ method, pattern, paramNames, handler });
2705
+ if (!handlers || handlers.length === 0) throw new Error("Route must include a handler");
2706
+ const rawMiddlewares = handlers.slice(0, handlers.length - 1);
2707
+ const rawLast = handlers[handlers.length - 1];
2708
+ const middlewares = rawMiddlewares.map((h) => this.toMiddleware(h));
2709
+ const last = (() => {
2710
+ const f = rawLast;
2711
+ if (typeof f !== "function") throw new Error("Route handler must be a function");
2712
+ if (f.length >= 2) {
2713
+ return async (ctx) => {
2714
+ if (f.length >= 3) {
2715
+ await new Promise((resolve2) => {
2716
+ try {
2717
+ f(ctx.req, ctx.res, () => resolve2());
2718
+ } catch (e) {
2719
+ resolve2();
2720
+ }
2721
+ });
2722
+ } else {
2723
+ const res = f(ctx.req, ctx.res);
2724
+ if (res && typeof res.then === "function") await res;
2725
+ }
2726
+ };
2727
+ }
2728
+ return f;
2729
+ })();
2730
+ this.routes.push({ method, pattern, paramNames, handler: last, middlewares });
2679
2731
  return this;
2680
2732
  }
2681
2733
  pathToRegex(path) {
@@ -2754,11 +2806,22 @@ var ServerRouter = class {
2754
2806
  }
2755
2807
  }
2756
2808
  const ctx = { req, res, params, query: this.parseQuery(url), body, headers: req.headers };
2809
+ const routeMiddlewares = route.middlewares || [];
2810
+ const chain = [
2811
+ ...this.middlewares,
2812
+ ...routeMiddlewares,
2813
+ async (c, n) => {
2814
+ await route.handler(c, n);
2815
+ }
2816
+ ];
2757
2817
  let i = 0;
2758
- const next = async () => i < this.middlewares.length && await this.middlewares[i++](ctx, next);
2818
+ const next = async () => {
2819
+ if (i >= chain.length) return;
2820
+ const mw = chain[i++];
2821
+ await mw(ctx, next);
2822
+ };
2759
2823
  try {
2760
2824
  await next();
2761
- await route.handler(ctx);
2762
2825
  } catch (e) {
2763
2826
  console.error("[ServerRouter] Route error:", e);
2764
2827
  !res.headersSent && (res.writeHead(500, { "Content-Type": "application/json" }), res.end(JSON.stringify({ error: "Internal Server Error", message: e instanceof Error ? e.message : "Unknown" })));
package/dist/server.mjs CHANGED
@@ -2636,20 +2636,72 @@ var ServerRouter = class {
2636
2636
  constructor() {
2637
2637
  this.routes = [];
2638
2638
  this.middlewares = [];
2639
- this.get = (path, handler) => this.addRoute("GET", path, handler);
2640
- this.post = (path, handler) => this.addRoute("POST", path, handler);
2641
- this.put = (path, handler) => this.addRoute("PUT", path, handler);
2642
- this.delete = (path, handler) => this.addRoute("DELETE", path, handler);
2643
- this.patch = (path, handler) => this.addRoute("PATCH", path, handler);
2644
- this.options = (path, handler) => this.addRoute("OPTIONS", path, handler);
2645
- }
2646
- use(middleware) {
2647
- this.middlewares.push(middleware);
2639
+ // Support per-route middleware: accept middleware(s) before the final handler
2640
+ this.get = (path, ...handlers) => this.addRoute("GET", path, handlers);
2641
+ this.post = (path, ...handlers) => this.addRoute("POST", path, handlers);
2642
+ this.put = (path, ...handlers) => this.addRoute("PUT", path, handlers);
2643
+ this.delete = (path, ...handlers) => this.addRoute("DELETE", path, handlers);
2644
+ this.patch = (path, ...handlers) => this.addRoute("PATCH", path, handlers);
2645
+ this.options = (path, ...handlers) => this.addRoute("OPTIONS", path, handlers);
2646
+ }
2647
+ // Accept both internal Middleware and Express-style `(req, res, next?)` functions
2648
+ use(mw) {
2649
+ this.middlewares.push(this.toMiddleware(mw));
2648
2650
  return this;
2649
2651
  }
2650
- addRoute(method, path, handler) {
2652
+ // Convert Express-like handler/middleware to internal Middleware
2653
+ toMiddleware(fn) {
2654
+ if (fn.length === 2 && fn.name !== "bound ") {
2655
+ }
2656
+ return async (ctx, next) => {
2657
+ const f = fn;
2658
+ if (f.length >= 3) {
2659
+ const expressNext = () => {
2660
+ void next();
2661
+ };
2662
+ const res = f(ctx.req, ctx.res, expressNext);
2663
+ if (res && typeof res.then === "function") await res;
2664
+ return;
2665
+ }
2666
+ if (f.length === 2) {
2667
+ const res = f(ctx.req, ctx.res);
2668
+ if (res && typeof res.then === "function") await res;
2669
+ await next();
2670
+ return;
2671
+ }
2672
+ const out = fn(ctx);
2673
+ if (out && typeof out.then === "function") await out;
2674
+ await next();
2675
+ };
2676
+ }
2677
+ addRoute(method, path, handlers) {
2651
2678
  const { pattern, paramNames } = this.pathToRegex(path);
2652
- this.routes.push({ method, pattern, paramNames, handler });
2679
+ if (!handlers || handlers.length === 0) throw new Error("Route must include a handler");
2680
+ const rawMiddlewares = handlers.slice(0, handlers.length - 1);
2681
+ const rawLast = handlers[handlers.length - 1];
2682
+ const middlewares = rawMiddlewares.map((h) => this.toMiddleware(h));
2683
+ const last = (() => {
2684
+ const f = rawLast;
2685
+ if (typeof f !== "function") throw new Error("Route handler must be a function");
2686
+ if (f.length >= 2) {
2687
+ return async (ctx) => {
2688
+ if (f.length >= 3) {
2689
+ await new Promise((resolve2) => {
2690
+ try {
2691
+ f(ctx.req, ctx.res, () => resolve2());
2692
+ } catch (e) {
2693
+ resolve2();
2694
+ }
2695
+ });
2696
+ } else {
2697
+ const res = f(ctx.req, ctx.res);
2698
+ if (res && typeof res.then === "function") await res;
2699
+ }
2700
+ };
2701
+ }
2702
+ return f;
2703
+ })();
2704
+ this.routes.push({ method, pattern, paramNames, handler: last, middlewares });
2653
2705
  return this;
2654
2706
  }
2655
2707
  pathToRegex(path) {
@@ -2728,11 +2780,22 @@ var ServerRouter = class {
2728
2780
  }
2729
2781
  }
2730
2782
  const ctx = { req, res, params, query: this.parseQuery(url), body, headers: req.headers };
2783
+ const routeMiddlewares = route.middlewares || [];
2784
+ const chain = [
2785
+ ...this.middlewares,
2786
+ ...routeMiddlewares,
2787
+ async (c, n) => {
2788
+ await route.handler(c, n);
2789
+ }
2790
+ ];
2731
2791
  let i = 0;
2732
- const next = async () => i < this.middlewares.length && await this.middlewares[i++](ctx, next);
2792
+ const next = async () => {
2793
+ if (i >= chain.length) return;
2794
+ const mw = chain[i++];
2795
+ await mw(ctx, next);
2796
+ };
2733
2797
  try {
2734
2798
  await next();
2735
- await route.handler(ctx);
2736
2799
  } catch (e) {
2737
2800
  console.error("[ServerRouter] Route error:", e);
2738
2801
  !res.headersSent && (res.writeHead(500, { "Content-Type": "application/json" }), res.end(JSON.stringify({ error: "Internal Server Error", message: e instanceof Error ? e.message : "Unknown" })));
package/dist/types.d.mts CHANGED
@@ -155,19 +155,21 @@ interface ServerRouteContext {
155
155
  query: Record<string, string>;
156
156
  body: any;
157
157
  headers: Record<string, string | string[] | undefined>;
158
+ user?: any;
158
159
  }
159
- type ServerRouteHandler = (ctx: ServerRouteContext) => void | Promise<void>;
160
+ type ServerRouteHandler = (ctx: ServerRouteContext, next?: () => Promise<void>) => void | Promise<void>;
160
161
  type Middleware = (ctx: ServerRouteContext, next: () => Promise<void>) => void | Promise<void>;
161
162
  declare class ServerRouter {
162
163
  private routes;
163
164
  private middlewares;
164
- use(middleware: Middleware): this;
165
- get: (path: string, handler: ServerRouteHandler) => this;
166
- post: (path: string, handler: ServerRouteHandler) => this;
167
- put: (path: string, handler: ServerRouteHandler) => this;
168
- delete: (path: string, handler: ServerRouteHandler) => this;
169
- patch: (path: string, handler: ServerRouteHandler) => this;
170
- options: (path: string, handler: ServerRouteHandler) => this;
165
+ use(mw: Middleware | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)): this;
166
+ private toMiddleware;
167
+ get: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
168
+ post: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
169
+ put: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
170
+ delete: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
171
+ patch: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
172
+ options: (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>) => this;
171
173
  private addRoute;
172
174
  private pathToRegex;
173
175
  private parseQuery;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "elit",
3
- "version": "3.1.1",
3
+ "version": "3.1.3",
4
4
  "description": "Optimized lightweight library for creating DOM elements with reactive state",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
package/src/server.ts CHANGED
@@ -28,9 +28,10 @@ export interface ServerRouteContext {
28
28
  query: Record<string, string>;
29
29
  body: any;
30
30
  headers: Record<string, string | string[] | undefined>;
31
+ user?: any;
31
32
  }
32
33
 
33
- export type ServerRouteHandler = (ctx: ServerRouteContext) => void | Promise<void>;
34
+ export type ServerRouteHandler = (ctx: ServerRouteContext, next?: () => Promise<void>) => void | Promise<void>;
34
35
  export type Middleware = (ctx: ServerRouteContext, next: () => Promise<void>) => void | Promise<void>;
35
36
 
36
37
  interface ServerRoute {
@@ -38,27 +39,102 @@ interface ServerRoute {
38
39
  pattern: RegExp;
39
40
  paramNames: string[];
40
41
  handler: ServerRouteHandler;
42
+ middlewares: Middleware[];
41
43
  }
42
44
 
43
45
  export class ServerRouter {
44
46
  private routes: ServerRoute[] = [];
45
47
  private middlewares: Middleware[] = [];
46
48
 
47
- use(middleware: Middleware): this {
48
- this.middlewares.push(middleware);
49
+ // Accept both internal Middleware and Express-style `(req, res, next?)` functions
50
+ use(mw: Middleware | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)): this {
51
+ this.middlewares.push(this.toMiddleware(mw as any));
49
52
  return this;
50
53
  }
51
54
 
52
- get = (path: string, handler: ServerRouteHandler): this => this.addRoute('GET', path, handler);
53
- post = (path: string, handler: ServerRouteHandler): this => this.addRoute('POST', path, handler);
54
- put = (path: string, handler: ServerRouteHandler): this => this.addRoute('PUT', path, handler);
55
- delete = (path: string, handler: ServerRouteHandler): this => this.addRoute('DELETE', path, handler);
56
- patch = (path: string, handler: ServerRouteHandler): this => this.addRoute('PATCH', path, handler);
57
- options = (path: string, handler: ServerRouteHandler): this => this.addRoute('OPTIONS', path, handler);
55
+ // Convert Express-like handler/middleware to internal Middleware
56
+ private toMiddleware(fn: Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)): Middleware {
57
+ // If it's already our Middleware, return as-is
58
+ if ((fn as Middleware).length === 2 && (fn as any).name !== 'bound ') {
59
+ // Cannot reliably detect, so always wrap to normalize behavior
60
+ }
61
+
62
+ return async (ctx: ServerRouteContext, next: () => Promise<void>) => {
63
+ const f: any = fn;
64
+
65
+ // Express-style with (req, res, next)
66
+ if (f.length >= 3) {
67
+ // Provide a next that triggers our next
68
+ const expressNext = () => {
69
+ // call our next but don't await here
70
+ void next();
71
+ };
72
+
73
+ const res = f(ctx.req, ctx.res, expressNext);
74
+ if (res && typeof res.then === 'function') await res;
75
+ // If express middleware didn't call next(), we simply return and stop the chain
76
+ return;
77
+ }
78
+
79
+ // Express-style with (req, res) - treat as middleware that continues after completion
80
+ if (f.length === 2) {
81
+ const res = f(ctx.req, ctx.res);
82
+ if (res && typeof res.then === 'function') await res;
83
+ await next();
84
+ return;
85
+ }
86
+
87
+ // Our internal handler style (ctx) => ... - call it and continue
88
+ const out = (fn as ServerRouteHandler)(ctx);
89
+ if (out && typeof out.then === 'function') await out;
90
+ await next();
91
+ };
92
+ }
93
+
94
+ // Support per-route middleware: accept middleware(s) before the final handler
95
+ get = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('GET', path, handlers as any);
96
+ post = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('POST', path, handlers as any);
97
+ put = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('PUT', path, handlers as any);
98
+ delete = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('DELETE', path, handlers as any);
99
+ patch = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('PATCH', path, handlers as any);
100
+ options = (path: string, ...handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this => this.addRoute('OPTIONS', path, handlers as any);
58
101
 
59
- private addRoute(method: HttpMethod, path: string, handler: ServerRouteHandler): this {
102
+ private addRoute(method: HttpMethod, path: string, handlers: Array<Middleware | ServerRouteHandler | ((req: IncomingMessage, res: ServerResponse, next?: () => void) => any)>): this {
60
103
  const { pattern, paramNames } = this.pathToRegex(path);
61
- this.routes.push({ method, pattern, paramNames, handler });
104
+ // Last item is the actual route handler, preceding items are middlewares
105
+ if (!handlers || handlers.length === 0) throw new Error('Route must include a handler');
106
+ const rawMiddlewares = handlers.slice(0, handlers.length - 1);
107
+ const rawLast = handlers[handlers.length - 1];
108
+
109
+ const middlewares = rawMiddlewares.map(h => this.toMiddleware(h as any));
110
+
111
+ // Normalize last handler: if it's express-like, wrap into ServerRouteHandler
112
+ const last = ((): ServerRouteHandler => {
113
+ const f: any = rawLast;
114
+ if (typeof f !== 'function') throw new Error('Route handler must be a function');
115
+
116
+ if (f.length >= 2) {
117
+ // Express-style final handler
118
+ return async (ctx: ServerRouteContext) => {
119
+ if (f.length >= 3) {
120
+ // expects next
121
+ await new Promise<void>((resolve) => {
122
+ try {
123
+ f(ctx.req, ctx.res, () => resolve());
124
+ } catch (e) { resolve(); }
125
+ });
126
+ } else {
127
+ const res = f(ctx.req, ctx.res);
128
+ if (res && typeof res.then === 'function') await res;
129
+ }
130
+ };
131
+ }
132
+
133
+ // Already a ServerRouteHandler (ctx)
134
+ return f as ServerRouteHandler;
135
+ })();
136
+
137
+ this.routes.push({ method, pattern, paramNames, handler: last, middlewares });
62
138
  return this;
63
139
  }
64
140
 
@@ -157,12 +233,25 @@ export class ServerRouter {
157
233
  }
158
234
 
159
235
  const ctx: ServerRouteContext = { req, res, params, query: this.parseQuery(url), body, headers: req.headers as any };
236
+
237
+ // Build middleware chain: global middlewares -> route middlewares -> final handler
238
+ // Pass `next` to the final handler so it can optionally call await next()
239
+ const routeMiddlewares = route.middlewares || [];
240
+ const chain: Middleware[] = [
241
+ ...this.middlewares,
242
+ ...routeMiddlewares,
243
+ async (c, n) => { await route.handler(c, n); }
244
+ ];
245
+
160
246
  let i = 0;
161
- const next = async () => i < this.middlewares.length && await this.middlewares[i++](ctx, next);
247
+ const next = async () => {
248
+ if (i >= chain.length) return;
249
+ const mw = chain[i++];
250
+ await mw(ctx, next);
251
+ };
162
252
 
163
253
  try {
164
254
  await next();
165
- await route.handler(ctx);
166
255
  }
167
256
  catch (e) {
168
257
  console.error('[ServerRouter] Route error:', e);