@wild-framework/http 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,7 +2,8 @@ export { action } from "./action.js";
2
2
  export type { ActionHandler } from "./action.js";
3
3
  export { ForbiddenException, HttpException, NotFoundException, UnauthorizedException, ValidationException, } from "./errors.js";
4
4
  export { HttpProvider } from "./provider.js";
5
- export { Router } from "./router.js";
5
+ export { Router, type RegisteredRoute } from "./router.js";
6
6
  export { ExpressServer, createErrorHandler } from "./server.js";
7
+ export { requestIdMiddleware, requestLogger } from "./logging.js";
7
8
  export type { RouteHandler } from "./wrap.js";
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACH,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAChE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACH,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -3,4 +3,5 @@ export { ForbiddenException, HttpException, NotFoundException, UnauthorizedExcep
3
3
  export { HttpProvider } from "./provider.js";
4
4
  export { Router } from "./router.js";
5
5
  export { ExpressServer, createErrorHandler } from "./server.js";
6
+ export { requestIdMiddleware, requestLogger } from "./logging.js";
6
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EACH,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EACH,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAwB,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { RequestHandler } from "express";
2
+ import { Logger } from "@wild-framework/logging";
3
+ /**
4
+ * Assigns a request id (reusing `x-request-id` when present), echoes it on
5
+ * the response, and runs the rest of the request inside the request-context
6
+ * store — so every `Logger` call downstream automatically carries `requestId`.
7
+ */
8
+ export declare function requestIdMiddleware(): RequestHandler;
9
+ /**
10
+ * Logs each request on completion: method, path, status, duration, request id.
11
+ *
12
+ * `getLogger` resolves lazily so this middleware can be mounted before the
13
+ * logger binding exists (return `null` to skip logging).
14
+ */
15
+ export declare function requestLogger(getLogger: () => Logger | null): RequestHandler;
16
+ //# sourceMappingURL=logging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAmC,MAAM,SAAS,CAAC;AAE/E,OAAO,EAAE,MAAM,EAAsB,MAAM,yBAAyB,CAAC;AAErE;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,CASpD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,cAAc,CA4B5E"}
@@ -0,0 +1,50 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { Logger, withRequestContext } from "@wild-framework/logging";
3
+ /**
4
+ * Assigns a request id (reusing `x-request-id` when present), echoes it on
5
+ * the response, and runs the rest of the request inside the request-context
6
+ * store — so every `Logger` call downstream automatically carries `requestId`.
7
+ */
8
+ export function requestIdMiddleware() {
9
+ return (req, res, next) => {
10
+ const incoming = req.headers["x-request-id"];
11
+ const requestId = (Array.isArray(incoming) ? incoming[0] : incoming) ?? randomUUID();
12
+ res.setHeader("x-request-id", requestId);
13
+ withRequestContext({ requestId }, () => next());
14
+ };
15
+ }
16
+ /**
17
+ * Logs each request on completion: method, path, status, duration, request id.
18
+ *
19
+ * `getLogger` resolves lazily so this middleware can be mounted before the
20
+ * logger binding exists (return `null` to skip logging).
21
+ */
22
+ export function requestLogger(getLogger) {
23
+ let logger;
24
+ return (req, res, next) => {
25
+ logger ??= getLogger();
26
+ const start = process.hrtime.bigint();
27
+ res.on("finish", () => {
28
+ if (!logger)
29
+ return;
30
+ const durationMs = Number(process.hrtime.bigint() - start) / 1e6;
31
+ const statusCode = res.statusCode;
32
+ const message = `${req.method} ${req.originalUrl} ${statusCode}`;
33
+ const context = {
34
+ method: req.method,
35
+ path: req.originalUrl,
36
+ statusCode,
37
+ durationMs: Math.round(durationMs * 100) / 100,
38
+ requestId: req.headers["x-request-id"] ?? res.getHeader("x-request-id"),
39
+ };
40
+ if (statusCode >= 500)
41
+ logger.error(message, context);
42
+ else if (statusCode >= 400)
43
+ logger.warn(message, context);
44
+ else
45
+ logger.info(message, context);
46
+ });
47
+ next();
48
+ };
49
+ }
50
+ //# sourceMappingURL=logging.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAErE;;;;GAIG;AACH,MAAM,UAAU,mBAAmB;IAC/B,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QACvD,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,UAAU,EAAE,CAAC;QAErF,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;QAEzC,kBAAkB,CAAC,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC;AACN,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,SAA8B;IACxD,IAAI,MAAiC,CAAC;IAEtC,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QACvD,MAAM,KAAK,SAAS,EAAE,CAAC;QAEvB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACtC,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YAClB,IAAI,CAAC,MAAM;gBAAE,OAAO;YAEpB,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC;YACjE,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;YAClC,MAAM,OAAO,GAAG,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,WAAW,IAAI,UAAU,EAAE,CAAC;YACjE,MAAM,OAAO,GAAG;gBACZ,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE,GAAG,CAAC,WAAW;gBACrB,UAAU;gBACV,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG;gBAC9C,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC;aAC1E,CAAC;YAEF,IAAI,UAAU,IAAI,GAAG;gBAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;iBACjD,IAAI,UAAU,IAAI,GAAG;gBAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;;gBACrD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,IAAI,EAAE,CAAC;IACX,CAAC,CAAC;AACN,CAAC"}
@@ -3,12 +3,16 @@ import type { Provider, Application } from "@wild-framework/core";
3
3
  * Registers the HTTP layer with the application.
4
4
  *
5
5
  * - `register()`: creates Express app, Router, ExpressServer. Binds Router
6
- * into the container and calls `app.setServer()`.
6
+ * into the container and calls `app.setServer()`. Adds request-id +
7
+ * request-logger middleware (the logger is resolved lazily, so this works
8
+ * whether or not `@wild-framework/logging` is registered).
7
9
  * - `boot()`: registers the global error handler middleware on the Express app.
8
10
  */
9
11
  export declare class HttpProvider implements Provider {
10
12
  private expressApp;
13
+ private resolveLogger;
11
14
  register(app: Application): void;
12
15
  boot(_app: Application): void;
16
+ private tryResolveLogger;
13
17
  }
14
18
  //# sourceMappingURL=provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAMlE;;;;;;GAMG;AACH,qBAAa,YAAa,YAAW,QAAQ;IACzC,OAAO,CAAC,UAAU,CAAwB;IAE1C,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;IAkBhC,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;CAKhC"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAQlE;;;;;;;;GAQG;AACH,qBAAa,YAAa,YAAW,QAAQ;IACzC,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,aAAa,CAAsC;IAE3D,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;IA8BhC,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAM7B,OAAO,CAAC,gBAAgB;CAG3B"}
package/dist/provider.js CHANGED
@@ -1,20 +1,28 @@
1
1
  import { Container } from "@wild-framework/container";
2
2
  import express, {} from "express";
3
+ import { Logger } from "@wild-framework/logging";
3
4
  import { Router } from "./router.js";
4
5
  import { ExpressServer, createErrorHandler } from "./server.js";
6
+ import { requestIdMiddleware, requestLogger } from "./logging.js";
5
7
  /**
6
8
  * Registers the HTTP layer with the application.
7
9
  *
8
10
  * - `register()`: creates Express app, Router, ExpressServer. Binds Router
9
- * into the container and calls `app.setServer()`.
11
+ * into the container and calls `app.setServer()`. Adds request-id +
12
+ * request-logger middleware (the logger is resolved lazily, so this works
13
+ * whether or not `@wild-framework/logging` is registered).
10
14
  * - `boot()`: registers the global error handler middleware on the Express app.
11
15
  */
12
16
  export class HttpProvider {
13
17
  expressApp = null;
18
+ resolveLogger = null;
14
19
  register(app) {
15
20
  const container = app.resolve(Container);
16
21
  // Express app
17
22
  this.expressApp = express();
23
+ // Request id + request logging (logger resolved lazily on first request)
24
+ this.expressApp.use(requestIdMiddleware());
25
+ this.expressApp.use(requestLogger(() => this.tryResolveLogger()));
18
26
  // Router — bound into container so providers can add routes
19
27
  const router = new Router(container);
20
28
  container.singleton(Router, () => router);
@@ -23,11 +31,22 @@ export class HttpProvider {
23
31
  // Server — registered on app for app.listen()
24
32
  const server = new ExpressServer(this.expressApp);
25
33
  app.setServer(server);
34
+ this.resolveLogger = () => {
35
+ try {
36
+ return app.resolve(Logger);
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ };
26
42
  }
27
43
  boot(_app) {
28
44
  // Global error handler — must be the last middleware on the Express app.
29
45
  // Added during boot phase 2, after all routes have been registered.
30
- this.expressApp.use(createErrorHandler());
46
+ this.expressApp.use(createErrorHandler(this.tryResolveLogger() ?? undefined));
47
+ }
48
+ tryResolveLogger() {
49
+ return this.resolveLogger ? this.resolveLogger() : null;
31
50
  }
32
51
  }
33
52
  //# sourceMappingURL=provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,OAAO,EAAE,EAAgB,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEhE;;;;;;GAMG;AACH,MAAM,OAAO,YAAY;IACb,UAAU,GAAmB,IAAI,CAAC;IAE1C,QAAQ,CAAC,GAAgB;QACrB,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEzC,cAAc;QACd,IAAI,CAAC,UAAU,GAAG,OAAO,EAAE,CAAC;QAE5B,4DAA4D;QAC5D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;QACrC,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;QAE1C,0EAA0E;QAC1E,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAEhD,8CAA8C;QAC9C,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClD,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,CAAC,IAAiB;QAClB,yEAAyE;QACzE,oEAAoE;QACpE,IAAI,CAAC,UAAW,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC/C,CAAC;CACJ"}
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,OAAO,EAAE,EAAgB,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElE;;;;;;;;GAQG;AACH,MAAM,OAAO,YAAY;IACb,UAAU,GAAmB,IAAI,CAAC;IAClC,aAAa,GAAiC,IAAI,CAAC;IAE3D,QAAQ,CAAC,GAAgB;QACrB,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEzC,cAAc;QACd,IAAI,CAAC,UAAU,GAAG,OAAO,EAAE,CAAC;QAE5B,yEAAyE;QACzE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;QAElE,4DAA4D;QAC5D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;QACrC,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;QAE1C,0EAA0E;QAC1E,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAEhD,8CAA8C;QAC9C,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClD,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAEtB,IAAI,CAAC,aAAa,GAAG,GAAG,EAAE;YACtB,IAAI,CAAC;gBACD,OAAO,GAAG,CAAC,OAAO,CAAS,MAAM,CAAC,CAAC;YACvC,CAAC;YAAC,MAAM,CAAC;gBACL,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC,CAAC;IACN,CAAC;IAED,IAAI,CAAC,IAAiB;QAClB,yEAAyE;QACzE,oEAAoE;QACpE,IAAI,CAAC,UAAW,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,SAAS,CAAC,CAAC,CAAC;IACnF,CAAC;IAEO,gBAAgB;QACpB,OAAO,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,CAAC;CACJ"}
package/dist/router.d.ts CHANGED
@@ -1,6 +1,24 @@
1
1
  import { Router as ExpressRouter, type RequestHandler } from "express";
2
+ import type { ZodSchema } from "zod";
2
3
  import { Container } from "@wild-framework/container";
3
4
  import { type RouteHandler } from "./wrap.js";
5
+ import type { ActionHandler } from "./action.js";
6
+ /**
7
+ * A route registered on the Router, with enough metadata to generate
8
+ * OpenAPI docs.
9
+ */
10
+ export interface RegisteredRoute {
11
+ /** HTTP method (lowercase). */
12
+ method: "get" | "post" | "put" | "patch" | "delete";
13
+ /** Route path, e.g. "/users/:id". */
14
+ path: string;
15
+ /** Zod request-body schema, if the route used a validator class. */
16
+ validator?: ZodSchema;
17
+ /** Name of the validator class, if any (used to name the OpenAPI schema). */
18
+ validatorName?: string;
19
+ /** Controller action, if the route used `action(Controller, "method")`. */
20
+ action?: ActionHandler;
21
+ }
4
22
  /**
5
23
  * Wild Framework Router.
6
24
  *
@@ -13,6 +31,7 @@ import { type RouteHandler } from "./wrap.js";
13
31
  export declare class Router {
14
32
  private container;
15
33
  private expressRouter;
34
+ private registeredRoutes;
16
35
  constructor(container: Container);
17
36
  get(path: string, ...handlers: RouteHandler[]): void;
18
37
  post(path: string, ...handlers: RouteHandler[]): void;
@@ -23,8 +42,17 @@ export declare class Router {
23
42
  * Register global middleware on the router.
24
43
  */
25
44
  use(...handlers: RequestHandler[]): void;
45
+ /**
46
+ * All routes registered on this router, with validator/controller
47
+ * metadata. Used by `@wild-framework/openapi` to generate docs.
48
+ */
49
+ getRegisteredRoutes(): RegisteredRoute[];
26
50
  /** @internal — get the underlying Express router. */
27
51
  _getExpressRouter(): ExpressRouter;
52
+ /**
53
+ * Record a route's metadata for OpenAPI generation.
54
+ */
55
+ private track;
28
56
  private wrapAll;
29
57
  }
30
58
  //# sourceMappingURL=router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAE3D;;;;;;;;GAQG;AACH,qBAAa,MAAM;IAGH,OAAO,CAAC,SAAS;IAF7B,OAAO,CAAC,aAAa,CAAgB;gBAEjB,SAAS,EAAE,SAAS;IAQxC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAIpD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAIrD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAIpD,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAItD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAQvD;;OAEG;IACH,GAAG,CAAC,GAAG,QAAQ,EAAE,cAAc,EAAE,GAAG,IAAI;IAQxC,qDAAqD;IACrD,iBAAiB,IAAI,aAAa;IAIlC,OAAO,CAAC,OAAO;CAGlB"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,+BAA+B;IAC/B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpD,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED;;;;;;;;GAQG;AACH,qBAAa,MAAM;IAIH,OAAO,CAAC,SAAS;IAH7B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,gBAAgB,CAAyB;gBAE7B,SAAS,EAAE,SAAS;IAQxC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAKpD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAKrD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAKpD,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAKtD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IASvD;;OAEG;IACH,GAAG,CAAC,GAAG,QAAQ,EAAE,cAAc,EAAE,GAAG,IAAI;IAQxC;;;OAGG;IACH,mBAAmB,IAAI,eAAe,EAAE;IAQxC,qDAAqD;IACrD,iBAAiB,IAAI,aAAa;IAIlC;;OAEG;IACH,OAAO,CAAC,KAAK;IAuBb,OAAO,CAAC,OAAO;CAGlB"}
package/dist/router.js CHANGED
@@ -13,6 +13,7 @@ import { wrapHandler } from "./wrap.js";
13
13
  export class Router {
14
14
  container;
15
15
  expressRouter;
16
+ registeredRoutes = [];
16
17
  constructor(container) {
17
18
  this.container = container;
18
19
  this.expressRouter = ExpressRouter();
@@ -21,18 +22,23 @@ export class Router {
21
22
  // HTTP methods
22
23
  // -------------------------------------------------------------------
23
24
  get(path, ...handlers) {
25
+ this.track("get", path, handlers);
24
26
  this.expressRouter.get(path, ...this.wrapAll(handlers));
25
27
  }
26
28
  post(path, ...handlers) {
29
+ this.track("post", path, handlers);
27
30
  this.expressRouter.post(path, ...this.wrapAll(handlers));
28
31
  }
29
32
  put(path, ...handlers) {
33
+ this.track("put", path, handlers);
30
34
  this.expressRouter.put(path, ...this.wrapAll(handlers));
31
35
  }
32
36
  patch(path, ...handlers) {
37
+ this.track("patch", path, handlers);
33
38
  this.expressRouter.patch(path, ...this.wrapAll(handlers));
34
39
  }
35
40
  delete(path, ...handlers) {
41
+ this.track("delete", path, handlers);
36
42
  this.expressRouter.delete(path, ...this.wrapAll(handlers));
37
43
  }
38
44
  // -------------------------------------------------------------------
@@ -45,12 +51,41 @@ export class Router {
45
51
  this.expressRouter.use(...handlers);
46
52
  }
47
53
  // -------------------------------------------------------------------
54
+ // OpenAPI metadata
55
+ // -------------------------------------------------------------------
56
+ /**
57
+ * All routes registered on this router, with validator/controller
58
+ * metadata. Used by `@wild-framework/openapi` to generate docs.
59
+ */
60
+ getRegisteredRoutes() {
61
+ return [...this.registeredRoutes];
62
+ }
63
+ // -------------------------------------------------------------------
48
64
  // Internal
49
65
  // -------------------------------------------------------------------
50
66
  /** @internal — get the underlying Express router. */
51
67
  _getExpressRouter() {
52
68
  return this.expressRouter;
53
69
  }
70
+ /**
71
+ * Record a route's metadata for OpenAPI generation.
72
+ */
73
+ track(method, path, handlers) {
74
+ const entry = { method, path };
75
+ for (const h of handlers) {
76
+ // Validator class (has `static schema`)
77
+ if (typeof h === "function" && "schema" in h) {
78
+ entry.validator = h.schema;
79
+ entry.validatorName = h.name;
80
+ continue;
81
+ }
82
+ // Controller action
83
+ if (typeof h === "object" && h !== null && "controller" in h && "method" in h) {
84
+ entry.action = h;
85
+ }
86
+ }
87
+ this.registeredRoutes.push(entry);
88
+ }
54
89
  wrapAll(handlers) {
55
90
  return handlers.map((h) => wrapHandler(h, this.container));
56
91
  }
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,aAAa,EAAuB,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAqB,MAAM,WAAW,CAAC;AAE3D;;;;;;;;GAQG;AACH,MAAM,OAAO,MAAM;IAGK;IAFZ,aAAa,CAAgB;IAErC,YAAoB,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;QACpC,IAAI,CAAC,aAAa,GAAG,aAAa,EAAE,CAAC;IACzC,CAAC;IAED,sEAAsE;IACtE,eAAe;IACf,sEAAsE;IAEtE,GAAG,CAAC,IAAY,EAAE,GAAG,QAAwB;QACzC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,CAAC,IAAY,EAAE,GAAG,QAAwB;QAC1C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,GAAG,CAAC,IAAY,EAAE,GAAG,QAAwB;QACzC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,IAAY,EAAE,GAAG,QAAwB;QAC3C,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,GAAG,QAAwB;QAC5C,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,sEAAsE;IACtE,aAAa;IACb,sEAAsE;IAEtE;;OAEG;IACH,GAAG,CAAC,GAAG,QAA0B;QAC7B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,sEAAsE;IACtE,WAAW;IACX,sEAAsE;IAEtE,qDAAqD;IACrD,iBAAiB;QACb,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC;IAEO,OAAO,CAAC,QAAwB;QACpC,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAqB,CAAC;IACnF,CAAC;CACJ"}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Server as CoreServer } from "@wild-framework/core";
2
2
  import express, { type Express } from "express";
3
+ import type { Logger } from "@wild-framework/logging";
3
4
  /**
4
5
  * Express-backed implementation of core's `Server` interface.
5
6
  *
@@ -17,8 +18,13 @@ export declare class ExpressServer implements CoreServer {
17
18
  /**
18
19
  * Create a global error handler middleware for Express.
19
20
  *
20
- * Formats `HttpException` instances as structured JSON.
21
- * Unexpected errors return 500 with a generic message.
21
+ * Formats `HttpException` instances as structured JSON. Also recognizes
22
+ * any error carrying a numeric `statusCode` (e.g. `@wild-framework/auth` exceptions),
23
+ * keeping http decoupled from other packages.
24
+ *
25
+ * Unexpected errors return 500 with a generic message. When a `logger` is
26
+ * provided, unexpected errors are logged through it (carrying the request
27
+ * id from the request context) instead of `console.error`.
22
28
  */
23
- export declare function createErrorHandler(): express.ErrorRequestHandler;
29
+ export declare function createErrorHandler(logger?: Logger): express.ErrorRequestHandler;
24
30
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,OAAO,EAAE,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAIhD;;;;GAIG;AACH,qBAAa,aAAc,YAAW,UAAU;IAC5C,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,MAAM,CAA2B;gBAE7B,GAAG,EAAE,OAAO;IAIlB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAS/B,gBAAgB;IAChB,cAAc,IAAI,OAAO;CAG5B;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAAC,mBAAmB,CAehE"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,OAAO,EAAE,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAEhD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGtD;;;;GAIG;AACH,qBAAa,aAAc,YAAW,UAAU;IAC5C,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,MAAM,CAA2B;gBAE7B,GAAG,EAAE,OAAO;IAIlB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAS/B,gBAAgB;IAChB,cAAc,IAAI,OAAO;CAG5B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAwC/E"}
package/dist/server.js CHANGED
@@ -33,17 +33,40 @@ export class ExpressServer {
33
33
  /**
34
34
  * Create a global error handler middleware for Express.
35
35
  *
36
- * Formats `HttpException` instances as structured JSON.
37
- * Unexpected errors return 500 with a generic message.
36
+ * Formats `HttpException` instances as structured JSON. Also recognizes
37
+ * any error carrying a numeric `statusCode` (e.g. `@wild-framework/auth` exceptions),
38
+ * keeping http decoupled from other packages.
39
+ *
40
+ * Unexpected errors return 500 with a generic message. When a `logger` is
41
+ * provided, unexpected errors are logged through it (carrying the request
42
+ * id from the request context) instead of `console.error`.
38
43
  */
39
- export function createErrorHandler() {
40
- return (err, _req, res, _next) => {
44
+ export function createErrorHandler(logger) {
45
+ const logError = logger ?? {
46
+ error: (message, context) => {
47
+ console.error(message, context ?? "");
48
+ },
49
+ };
50
+ return (err, req, res, _next) => {
41
51
  if (err instanceof HttpException) {
42
52
  res.status(err.statusCode).json(err.toJSON());
43
53
  return;
44
54
  }
45
- // Unexpected error — log and return generic 500
46
- console.error("[wild/http] Unhandled error:", err);
55
+ // Structural fallback: any error exposing a statusCode (e.g. auth)
56
+ const status = err?.statusCode;
57
+ if (typeof status === "number" && status >= 400 && status < 600) {
58
+ const message = err instanceof Error ? err.message : "Error";
59
+ res.status(status).json({
60
+ error: "Error",
61
+ message,
62
+ statusCode: status,
63
+ });
64
+ return;
65
+ }
66
+ // Unexpected error — log (through the logger when available) and return generic 500
67
+ logError.error(`Unhandled error: ${req.method} ${req.originalUrl}`, {
68
+ error: err instanceof Error ? { name: err.name, message: err.message, stack: err.stack } : err,
69
+ });
47
70
  res.status(500).json({
48
71
  error: "Internal Server Error",
49
72
  message: "An unexpected error occurred.",
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,EAAE,EAAgB,MAAM,SAAS,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C;;;;GAIG;AACH,MAAM,OAAO,aAAa;IACd,GAAG,CAAU;IACb,MAAM,GAAsB,IAAI,CAAC;IAEzC,YAAY,GAAY;QACpB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACrB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,QAAQ;QACV,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACf,OAAO,OAAO,EAAE,CAAC;YACrB,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACP,CAAC;IAED,gBAAgB;IAChB,cAAc;QACV,OAAO,IAAI,CAAC,GAAG,CAAC;IACpB,CAAC;CACJ;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB;IAC9B,OAAO,CAAC,GAAY,EAAE,IAAqB,EAAE,GAAqB,EAAE,KAA2B,EAAE,EAAE;QAC/F,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YAC/B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YAC9C,OAAO;QACX,CAAC;QAED,gDAAgD;QAChD,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;QACnD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACjB,KAAK,EAAE,uBAAuB;YAC9B,OAAO,EAAE,+BAA+B;YACxC,UAAU,EAAE,GAAG;SAClB,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/wrap.d.ts CHANGED
@@ -2,8 +2,11 @@ import type { Request, Response, NextFunction } from "express";
2
2
  import type { ActionHandler } from "./action.js";
3
3
  /**
4
4
  * Express request handler type (after wrapping).
5
+ *
6
+ * Deliberately a loose function signature so user middleware written with
7
+ * Express 5 types (whose RequestHandler returns `unknown`) is assignable.
5
8
  */
6
- type ExpressHandler = (req: Request, res: Response, next: NextFunction) => void | Promise<void>;
9
+ type ExpressHandler = (req: Request, res: Response, next: NextFunction) => unknown;
7
10
  /**
8
11
  * Any value that can be used as a route handler — raw middleware,
9
12
  * ActionHandler, or a validator class (must have `static schema`).
@@ -1 +1 @@
1
- {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../src/wrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;GAEG;AACH,KAAK,cAAc,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhG;;;GAGG;AACH,MAAM,MAAM,YAAY,GAClB,cAAc,GACd,aAAa,GACb,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,CAAC;AAExC;;GAEG;AACH,UAAU,QAAQ;IACd,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,CAAC,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,GAAG,cAAc,CAatF"}
1
+ {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../src/wrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;GAKG;AACH,KAAK,cAAc,GAAG,CAClB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,KACjB,OAAO,CAAC;AAEb;;;GAGG;AACH,MAAM,MAAM,YAAY,GAClB,cAAc,GACd,aAAa,GACb,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,CAAC;AAExC;;GAEG;AACH,UAAU,QAAQ;IACd,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,CAAC,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,GAAG,cAAc,CAatF"}
package/dist/wrap.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"wrap.js","sourceRoot":"","sources":["../src/wrap.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAwBlD;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,OAAqB,EAAE,SAAmB;IAClE,yEAAyE;IACzE,IAAI,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,8CAA8C;IAC9C,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,OAAO,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC1C,CAAC;IAED,wBAAwB;IACxB,OAAO,OAAyB,CAAC;AACrC,CAAC;AAED,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,SAAS,gBAAgB,CAAC,CAAe;IACrC,OAAO,CACH,OAAO,CAAC,KAAK,UAAU;QACvB,QAAQ,IAAI,CAAC,CAChB,CAAC;AACN,CAAC;AAED,SAAS,eAAe,CAAC,CAAe;IACpC,OAAO,CACH,OAAO,CAAC,KAAK,QAAQ;QACrB,CAAC,KAAK,IAAI;QACV,YAAY,IAAI,CAAC;QACjB,QAAQ,IAAI,CAAC,CAChB,CAAC;AACN,CAAC;AAED,8EAA8E;AAC9E,WAAW;AACX,8EAA8E;AAE9E,SAAS,aAAa,CAClB,cAA6D;IAE7D,2CAA2C;IAC3C,MAAM,MAAM,GAAI,cAAmD,CAAC,MAAM,CAAC;IAE3E,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAE1C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,IAAI,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,CAAC;QAED,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACvB,IAAI,EAAE,CAAC;IACX,CAAC,CAAC;AACN,CAAC;AAED,SAAS,UAAU,CAAC,MAAqB,EAAE,SAAmB;IAC1D,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC5B,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAA6B,CAAC;YAClF,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAEvC,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CACX,WAAW,MAAM,CAAC,MAAM,8BAA8B,MAAM,CAAC,UAAU,CAAC,IAAI,IAAI,CACnF,CAAC;YACN,CAAC;YAED,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC;IACL,CAAC,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"wrap.js","sourceRoot":"","sources":["../src/wrap.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AA+BlD;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,OAAqB,EAAE,SAAmB;IAClE,yEAAyE;IACzE,IAAI,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,8CAA8C;IAC9C,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,OAAO,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC1C,CAAC;IAED,wBAAwB;IACxB,OAAO,OAAyB,CAAC;AACrC,CAAC;AAED,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,SAAS,gBAAgB,CAAC,CAAe;IACrC,OAAO,CACH,OAAO,CAAC,KAAK,UAAU;QACvB,QAAQ,IAAI,CAAC,CAChB,CAAC;AACN,CAAC;AAED,SAAS,eAAe,CAAC,CAAe;IACpC,OAAO,CACH,OAAO,CAAC,KAAK,QAAQ;QACrB,CAAC,KAAK,IAAI;QACV,YAAY,IAAI,CAAC;QACjB,QAAQ,IAAI,CAAC,CAChB,CAAC;AACN,CAAC;AAED,8EAA8E;AAC9E,WAAW;AACX,8EAA8E;AAE9E,SAAS,aAAa,CAClB,cAA6D;IAE7D,2CAA2C;IAC3C,MAAM,MAAM,GAAI,cAAmD,CAAC,MAAM,CAAC;IAE3E,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAE1C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,IAAI,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,CAAC;QAED,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACvB,IAAI,EAAE,CAAC;IACX,CAAC,CAAC;AACN,CAAC;AAED,SAAS,UAAU,CAAC,MAAqB,EAAE,SAAmB;IAC1D,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC5B,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAA6B,CAAC;YAClF,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAEvC,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CACX,WAAW,MAAM,CAAC,MAAM,8BAA8B,MAAM,CAAC,UAAU,CAAC,IAAI,IAAI,CACnF,CAAC;YACN,CAAC;YAED,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC;IACL,CAAC,CAAC;AACN,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wild-framework/http",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -32,8 +32,10 @@
32
32
  ],
33
33
  "dependencies": {
34
34
  "express": "^5.1.0",
35
- "@wild-framework/core": "0.1.0",
36
- "@wild-framework/container": "0.1.0"
35
+ "zod": "^3.24.0",
36
+ "@wild-framework/core": "0.2.0",
37
+ "@wild-framework/container": "0.2.0",
38
+ "@wild-framework/logging": "0.2.0"
37
39
  },
38
40
  "devDependencies": {
39
41
  "@types/express": "^5.0.0"