@web-ts-toolkit/express-json-router 0.43.0 → 0.45.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/README.md CHANGED
@@ -9,6 +9,8 @@ pnpm add @web-ts-toolkit/express-json-router express
9
9
  pnpm add -D @types/express
10
10
  ```
11
11
 
12
+ `express` and `@types/express` are already regular dependencies of this package; the install line above is for the consumer app that mounts the router.
13
+
12
14
  ## Highlights
13
15
 
14
16
  - return plain values from route handlers
@@ -89,6 +91,7 @@ These behave as defaults for future `new JsonRouter(...)` instances.
89
91
  - Updating a static property affects routers created after that change.
90
92
  - Existing routers keep the response-handler instance they were constructed with.
91
93
  - `JsonRouter.defaultHandler` returns a newly configured handler each time it is read.
94
+ - Mutating a handler retrieved via `JsonRouter.defaultHandler` does not reconfigure existing routers or future defaults.
92
95
  - For fully isolated behavior, pass an explicit handler instance as the third constructor argument.
93
96
 
94
97
  ```ts
@@ -107,6 +110,80 @@ handler.errorMessageProvider = () => 'custom-error';
107
110
  const routerUsingCustomHandler = new JsonRouter('/admin', undefined, handler);
108
111
  ```
109
112
 
113
+ ## Native Middleware And Error Boundaries
114
+
115
+ Thrown or rejected JSON callbacks are JSON-formatted by the router's response
116
+ handler and never reach application error middleware. Explicit `next(error)`
117
+ instead delegates to native Express error middleware, which owns the response:
118
+
119
+ ```ts
120
+ import express from 'express';
121
+ import JsonRouter from '@web-ts-toolkit/express-json-router';
122
+
123
+ const app = express();
124
+ const router = new JsonRouter('/api');
125
+
126
+ router.get('/throw', () => {
127
+ throw new Error('formatted as a JSON 500 by the router');
128
+ });
129
+
130
+ router.get(
131
+ '/guarded',
132
+ (req, res, next) => {
133
+ next(new Error('owned by the app final handler'));
134
+ return { unreachable: true };
135
+ },
136
+ () => ({ unreachable: true }),
137
+ );
138
+
139
+ app.use(router.original);
140
+ app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {
141
+ res.status(500).json({ ownedBy: 'app-final-handler', message: err.message });
142
+ });
143
+ ```
144
+
145
+ `use` and `param` delegate directly to the underlying native router:
146
+
147
+ - Callbacks are native Express middleware: sync/async failures reach
148
+ application error middleware and guarded JSON handlers do not run.
149
+ - Malformed `express.json()` input mounted before the router likewise reaches
150
+ application error middleware; `JsonRouter` does not sanitize upstream
151
+ body-parser failures.
152
+ - `basePath` is not prepended to `use`/`param` arguments; pass an explicit
153
+ mount path for scoped middleware. Broadly mounted `use` middleware runs
154
+ before JSON routes on the same underlying router in mount order.
155
+ - Both methods return the native router (`router.original`), not the
156
+ `JsonRouter`, so `.use(...).get(...)` is native registration. Write separate
157
+ `router.get(...)` statements for JSON routes. Native registrations never
158
+ appear in `getEndpoints()`.
159
+
160
+ ```ts
161
+ import express from 'express';
162
+ import JsonRouter from '@web-ts-toolkit/express-json-router';
163
+
164
+ const authMiddleware: express.RequestHandler = (req, res, next) => next();
165
+ const router = new JsonRouter('/api', authMiddleware);
166
+
167
+ router.param('userId', (req, res, next, id) => next());
168
+
169
+ router.get('/health', () => ({ ok: true }));
170
+ router.get('/users/:id', () => ({ ok: true }));
171
+
172
+ router.getEndpoints();
173
+ // [{ method: 'GET', path: '/api/health' }, { method: 'GET', path: '/api/users/:id' }]
174
+ ```
175
+
176
+ ## Route Builder Contract
177
+
178
+ `router.route(path)` is independent-registration sugar: each builder call equals
179
+ a direct `router.METHOD(path, ...)` call with its own native route,
180
+ response-handler wrapper (including constructor-middleware copies), and
181
+ `getEndpoints()` entry. It is not native `express.Router().route(path)`
182
+ grouping: an `.all()` guard calling `next('route')` does not skip a later
183
+ builder registration, HEAD requests fall back to the separately registered GET
184
+ handler, and constructor middleware re-runs for each chained registration
185
+ crossed by `next()`.
186
+
110
187
  ## Documentation
111
188
 
112
189
  Full package documentation lives in `website/docs/packages/express-json-router.md`.
package/index.d.mts CHANGED
@@ -71,16 +71,16 @@ declare class JsonRouterBase {
71
71
  IMUsed: typeof IMUsed;
72
72
  };
73
73
  static readonly HttpResponse: {
74
- ok: (data: unknown) => OK<unknown>;
75
- created: (data: unknown) => Created<unknown>;
76
- accepted: (data: unknown) => Accepted<unknown>;
77
- nonAuthoritativeInfo: (data: unknown) => NonAuthoritativeInfo<unknown>;
74
+ ok: <T>(data: T) => OK<T>;
75
+ created: <T>(data: T) => Created<T>;
76
+ accepted: <T>(data: T) => Accepted<T>;
77
+ nonAuthoritativeInfo: <T>(data: T) => NonAuthoritativeInfo<T>;
78
78
  noContent: () => NoContent;
79
- resetContent: (data: unknown) => ResetContent<unknown>;
80
- partialContent: (data: unknown) => PartialContent<unknown>;
81
- multiStatus: (data: unknown) => MultiStatus<unknown>;
82
- alreadyReported: (data: unknown) => AlreadyReported<unknown>;
83
- imUsed: (data: unknown) => IMUsed<unknown>;
79
+ resetContent: <T>(data: T) => ResetContent<T>;
80
+ partialContent: <T>(data: T) => PartialContent<T>;
81
+ multiStatus: <T>(data: T) => MultiStatus<T>;
82
+ alreadyReported: <T>(data: T) => AlreadyReported<T>;
83
+ imUsed: <T>(data: T) => IMUsed<T>;
84
84
  badRequest: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.BadRequestError;
85
85
  unauthorized: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.UnauthorizedError;
86
86
  forbidden: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.ForbiddenError;
@@ -108,7 +108,7 @@ declare class JsonRouterBase {
108
108
  tooManyRequests: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.TooManyRequestsError;
109
109
  requestHeaderFieldsTooLarge: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.RequestHeaderFieldsTooLargeError;
110
110
  unavailableForLegalReasons: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.UnavailableForLegalReasonsError;
111
- json: (data: unknown) => OK<unknown>;
111
+ json: <T>(data: T) => OK<T>;
112
112
  csv: (dataset?: unknown, options?: _web_ts_toolkit_express_response_handler_responses_csv.CsvResponseOptions | undefined) => _web_ts_toolkit_express_response_handler.CSVResponse;
113
113
  };
114
114
  static readonly ErrorFormats: {
@@ -142,15 +142,54 @@ declare class JsonRouterBase {
142
142
  get middlewares(): JsonRouterCallback[];
143
143
  /** Underlying Express router to mount with `app.use(router.original)`. */
144
144
  get original(): ExpressRouter;
145
+ /**
146
+ * Native `param` delegation to the underlying Express router.
147
+ *
148
+ * Boundary: `param` callbacks are native Express callbacks, not JSON-wrapped
149
+ * registrations. Thrown/rejected `param` failures reach application error
150
+ * middleware; they are not JSON-formatted by this router's response handler.
151
+ * Returns the underlying native router (`router.original`), not this
152
+ * `JsonRouter`, so chaining continues with native Express registration.
153
+ * Nothing registered here appears in `getEndpoints()`.
154
+ */
145
155
  param(...args: Parameters<ExpressRouter['param']>): ReturnType<ExpressRouter['param']>;
156
+ /**
157
+ * Native `use` delegation to the underlying Express router.
158
+ *
159
+ * Boundary: `use` callbacks are native Express middleware, not JSON-wrapped
160
+ * registrations. Thrown/rejected `use` failures and explicit `next(error)`
161
+ * reach application error middleware; they are not JSON-formatted by this
162
+ * router's response handler. `basePath` is not prepended here, so pass an
163
+ * explicit mount path for scoped middleware. Native middleware mounted
164
+ * without a path runs before JSON routes on the same underlying router in
165
+ * mount order. Returns the underlying native router (`router.original`),
166
+ * not this `JsonRouter`, so `.use(...).get(...)` continues with native
167
+ * Express registration. Use separate `router.get(...)` statements for JSON
168
+ * routes. Nothing registered here appears in `getEndpoints()`.
169
+ *
170
+ * @example
171
+ * const router = new JsonRouter('/api');
172
+ * router.use('/', authMiddleware);
173
+ * router.get('/health', () => ({ ok: true }));
174
+ */
146
175
  use(...args: Parameters<ExpressRouter['use']>): ReturnType<ExpressRouter['use']>;
147
176
  /**
148
177
  * Starts a fluent route builder for one path.
178
+ *
179
+ * Retained contract (independent-registration sugar): each builder method
180
+ * call is exactly equivalent to a direct `router.METHOD(path, ...)` call.
181
+ * Every call creates a separate native route with its own response-handler
182
+ * wrapper (including constructor-middleware copies) and its own
183
+ * `getEndpoints()` entry in call order. This is not native
184
+ * `express.Router().route(path)` grouping, so `next('route')` from an
185
+ * `.all()` guard cannot skip a later builder registration, HEAD requests
186
+ * fall back to the separately registered GET handler, and constructor
187
+ * middleware re-runs for each chained registration crossed by `next()`.
149
188
  * Registered handlers still pass through this router's response handler.
150
189
  */
151
190
  route(path: string): JsonRouteBuilder;
152
191
  private addEndpoint;
153
- /** Returns a defensive copy of registered endpoint method/path metadata. */
192
+ /** Returns a defensive copy of registered JSON endpoint method/path metadata. Native `use`/`param`/router registrations are not recorded. */
154
193
  getEndpoints(): JsonRouterEndpoint[];
155
194
  private normalizePath;
156
195
  }
package/index.d.ts CHANGED
@@ -71,16 +71,16 @@ declare class JsonRouterBase {
71
71
  IMUsed: typeof IMUsed;
72
72
  };
73
73
  static readonly HttpResponse: {
74
- ok: (data: unknown) => OK<unknown>;
75
- created: (data: unknown) => Created<unknown>;
76
- accepted: (data: unknown) => Accepted<unknown>;
77
- nonAuthoritativeInfo: (data: unknown) => NonAuthoritativeInfo<unknown>;
74
+ ok: <T>(data: T) => OK<T>;
75
+ created: <T>(data: T) => Created<T>;
76
+ accepted: <T>(data: T) => Accepted<T>;
77
+ nonAuthoritativeInfo: <T>(data: T) => NonAuthoritativeInfo<T>;
78
78
  noContent: () => NoContent;
79
- resetContent: (data: unknown) => ResetContent<unknown>;
80
- partialContent: (data: unknown) => PartialContent<unknown>;
81
- multiStatus: (data: unknown) => MultiStatus<unknown>;
82
- alreadyReported: (data: unknown) => AlreadyReported<unknown>;
83
- imUsed: (data: unknown) => IMUsed<unknown>;
79
+ resetContent: <T>(data: T) => ResetContent<T>;
80
+ partialContent: <T>(data: T) => PartialContent<T>;
81
+ multiStatus: <T>(data: T) => MultiStatus<T>;
82
+ alreadyReported: <T>(data: T) => AlreadyReported<T>;
83
+ imUsed: <T>(data: T) => IMUsed<T>;
84
84
  badRequest: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.BadRequestError;
85
85
  unauthorized: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.UnauthorizedError;
86
86
  forbidden: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.ForbiddenError;
@@ -108,7 +108,7 @@ declare class JsonRouterBase {
108
108
  tooManyRequests: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.TooManyRequestsError;
109
109
  requestHeaderFieldsTooLarge: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.RequestHeaderFieldsTooLargeError;
110
110
  unavailableForLegalReasons: (message?: string | undefined, options?: clientErrors.HttpErrorOptions | undefined) => clientErrors.UnavailableForLegalReasonsError;
111
- json: (data: unknown) => OK<unknown>;
111
+ json: <T>(data: T) => OK<T>;
112
112
  csv: (dataset?: unknown, options?: _web_ts_toolkit_express_response_handler_responses_csv.CsvResponseOptions | undefined) => _web_ts_toolkit_express_response_handler.CSVResponse;
113
113
  };
114
114
  static readonly ErrorFormats: {
@@ -142,15 +142,54 @@ declare class JsonRouterBase {
142
142
  get middlewares(): JsonRouterCallback[];
143
143
  /** Underlying Express router to mount with `app.use(router.original)`. */
144
144
  get original(): ExpressRouter;
145
+ /**
146
+ * Native `param` delegation to the underlying Express router.
147
+ *
148
+ * Boundary: `param` callbacks are native Express callbacks, not JSON-wrapped
149
+ * registrations. Thrown/rejected `param` failures reach application error
150
+ * middleware; they are not JSON-formatted by this router's response handler.
151
+ * Returns the underlying native router (`router.original`), not this
152
+ * `JsonRouter`, so chaining continues with native Express registration.
153
+ * Nothing registered here appears in `getEndpoints()`.
154
+ */
145
155
  param(...args: Parameters<ExpressRouter['param']>): ReturnType<ExpressRouter['param']>;
156
+ /**
157
+ * Native `use` delegation to the underlying Express router.
158
+ *
159
+ * Boundary: `use` callbacks are native Express middleware, not JSON-wrapped
160
+ * registrations. Thrown/rejected `use` failures and explicit `next(error)`
161
+ * reach application error middleware; they are not JSON-formatted by this
162
+ * router's response handler. `basePath` is not prepended here, so pass an
163
+ * explicit mount path for scoped middleware. Native middleware mounted
164
+ * without a path runs before JSON routes on the same underlying router in
165
+ * mount order. Returns the underlying native router (`router.original`),
166
+ * not this `JsonRouter`, so `.use(...).get(...)` continues with native
167
+ * Express registration. Use separate `router.get(...)` statements for JSON
168
+ * routes. Nothing registered here appears in `getEndpoints()`.
169
+ *
170
+ * @example
171
+ * const router = new JsonRouter('/api');
172
+ * router.use('/', authMiddleware);
173
+ * router.get('/health', () => ({ ok: true }));
174
+ */
146
175
  use(...args: Parameters<ExpressRouter['use']>): ReturnType<ExpressRouter['use']>;
147
176
  /**
148
177
  * Starts a fluent route builder for one path.
178
+ *
179
+ * Retained contract (independent-registration sugar): each builder method
180
+ * call is exactly equivalent to a direct `router.METHOD(path, ...)` call.
181
+ * Every call creates a separate native route with its own response-handler
182
+ * wrapper (including constructor-middleware copies) and its own
183
+ * `getEndpoints()` entry in call order. This is not native
184
+ * `express.Router().route(path)` grouping, so `next('route')` from an
185
+ * `.all()` guard cannot skip a later builder registration, HEAD requests
186
+ * fall back to the separately registered GET handler, and constructor
187
+ * middleware re-runs for each chained registration crossed by `next()`.
149
188
  * Registered handlers still pass through this router's response handler.
150
189
  */
151
190
  route(path: string): JsonRouteBuilder;
152
191
  private addEndpoint;
153
- /** Returns a defensive copy of registered endpoint method/path metadata. */
192
+ /** Returns a defensive copy of registered JSON endpoint method/path metadata. Native `use`/`param`/router registrations are not recorded. */
154
193
  getEndpoints(): JsonRouterEndpoint[];
155
194
  private normalizePath;
156
195
  }
package/index.js CHANGED
@@ -257,14 +257,53 @@ var JsonRouterBase = class _JsonRouterBase {
257
257
  get original() {
258
258
  return this._router;
259
259
  }
260
+ /**
261
+ * Native `param` delegation to the underlying Express router.
262
+ *
263
+ * Boundary: `param` callbacks are native Express callbacks, not JSON-wrapped
264
+ * registrations. Thrown/rejected `param` failures reach application error
265
+ * middleware; they are not JSON-formatted by this router's response handler.
266
+ * Returns the underlying native router (`router.original`), not this
267
+ * `JsonRouter`, so chaining continues with native Express registration.
268
+ * Nothing registered here appears in `getEndpoints()`.
269
+ */
260
270
  param(...args) {
261
271
  return this._router.param(...args);
262
272
  }
273
+ /**
274
+ * Native `use` delegation to the underlying Express router.
275
+ *
276
+ * Boundary: `use` callbacks are native Express middleware, not JSON-wrapped
277
+ * registrations. Thrown/rejected `use` failures and explicit `next(error)`
278
+ * reach application error middleware; they are not JSON-formatted by this
279
+ * router's response handler. `basePath` is not prepended here, so pass an
280
+ * explicit mount path for scoped middleware. Native middleware mounted
281
+ * without a path runs before JSON routes on the same underlying router in
282
+ * mount order. Returns the underlying native router (`router.original`),
283
+ * not this `JsonRouter`, so `.use(...).get(...)` continues with native
284
+ * Express registration. Use separate `router.get(...)` statements for JSON
285
+ * routes. Nothing registered here appears in `getEndpoints()`.
286
+ *
287
+ * @example
288
+ * const router = new JsonRouter('/api');
289
+ * router.use('/', authMiddleware);
290
+ * router.get('/health', () => ({ ok: true }));
291
+ */
263
292
  use(...args) {
264
293
  return this._router.use(...args);
265
294
  }
266
295
  /**
267
296
  * Starts a fluent route builder for one path.
297
+ *
298
+ * Retained contract (independent-registration sugar): each builder method
299
+ * call is exactly equivalent to a direct `router.METHOD(path, ...)` call.
300
+ * Every call creates a separate native route with its own response-handler
301
+ * wrapper (including constructor-middleware copies) and its own
302
+ * `getEndpoints()` entry in call order. This is not native
303
+ * `express.Router().route(path)` grouping, so `next('route')` from an
304
+ * `.all()` guard cannot skip a later builder registration, HEAD requests
305
+ * fall back to the separately registered GET handler, and constructor
306
+ * middleware re-runs for each chained registration crossed by `next()`.
268
307
  * Registered handlers still pass through this router's response handler.
269
308
  */
270
309
  route(path) {
@@ -289,7 +328,7 @@ var JsonRouterBase = class _JsonRouterBase {
289
328
  path: this.normalizePath(path)
290
329
  });
291
330
  }
292
- /** Returns a defensive copy of registered endpoint method/path metadata. */
331
+ /** Returns a defensive copy of registered JSON endpoint method/path metadata. Native `use`/`param`/router registrations are not recorded. */
293
332
  getEndpoints() {
294
333
  return this._endpoints.map((endpoint) => ({ ...endpoint }));
295
334
  }
package/index.mjs CHANGED
@@ -237,14 +237,53 @@ var JsonRouterBase = class _JsonRouterBase {
237
237
  get original() {
238
238
  return this._router;
239
239
  }
240
+ /**
241
+ * Native `param` delegation to the underlying Express router.
242
+ *
243
+ * Boundary: `param` callbacks are native Express callbacks, not JSON-wrapped
244
+ * registrations. Thrown/rejected `param` failures reach application error
245
+ * middleware; they are not JSON-formatted by this router's response handler.
246
+ * Returns the underlying native router (`router.original`), not this
247
+ * `JsonRouter`, so chaining continues with native Express registration.
248
+ * Nothing registered here appears in `getEndpoints()`.
249
+ */
240
250
  param(...args) {
241
251
  return this._router.param(...args);
242
252
  }
253
+ /**
254
+ * Native `use` delegation to the underlying Express router.
255
+ *
256
+ * Boundary: `use` callbacks are native Express middleware, not JSON-wrapped
257
+ * registrations. Thrown/rejected `use` failures and explicit `next(error)`
258
+ * reach application error middleware; they are not JSON-formatted by this
259
+ * router's response handler. `basePath` is not prepended here, so pass an
260
+ * explicit mount path for scoped middleware. Native middleware mounted
261
+ * without a path runs before JSON routes on the same underlying router in
262
+ * mount order. Returns the underlying native router (`router.original`),
263
+ * not this `JsonRouter`, so `.use(...).get(...)` continues with native
264
+ * Express registration. Use separate `router.get(...)` statements for JSON
265
+ * routes. Nothing registered here appears in `getEndpoints()`.
266
+ *
267
+ * @example
268
+ * const router = new JsonRouter('/api');
269
+ * router.use('/', authMiddleware);
270
+ * router.get('/health', () => ({ ok: true }));
271
+ */
243
272
  use(...args) {
244
273
  return this._router.use(...args);
245
274
  }
246
275
  /**
247
276
  * Starts a fluent route builder for one path.
277
+ *
278
+ * Retained contract (independent-registration sugar): each builder method
279
+ * call is exactly equivalent to a direct `router.METHOD(path, ...)` call.
280
+ * Every call creates a separate native route with its own response-handler
281
+ * wrapper (including constructor-middleware copies) and its own
282
+ * `getEndpoints()` entry in call order. This is not native
283
+ * `express.Router().route(path)` grouping, so `next('route')` from an
284
+ * `.all()` guard cannot skip a later builder registration, HEAD requests
285
+ * fall back to the separately registered GET handler, and constructor
286
+ * middleware re-runs for each chained registration crossed by `next()`.
248
287
  * Registered handlers still pass through this router's response handler.
249
288
  */
250
289
  route(path) {
@@ -269,7 +308,7 @@ var JsonRouterBase = class _JsonRouterBase {
269
308
  path: this.normalizePath(path)
270
309
  });
271
310
  }
272
- /** Returns a defensive copy of registered endpoint method/path metadata. */
311
+ /** Returns a defensive copy of registered JSON endpoint method/path metadata. Native `use`/`param`/router registrations are not recorded. */
273
312
  getEndpoints() {
274
313
  return this._endpoints.map((endpoint) => ({ ...endpoint }));
275
314
  }
package/llms.txt CHANGED
@@ -59,7 +59,10 @@ router.get('/users/:id', readUser);
59
59
  - constructor middleware and `getEndpoints()` results are snapshots; mutating caller arrays or returned arrays does not change future route registration or endpoint metadata
60
60
  - route-local Express error middleware with four arguments is rejected; mount error middleware with `router.use(...)`
61
61
  - static defaults (`errorMessageProvider`, `preJson`, `postJson`, `preError`, `postError`) affect routers created after the change; existing routers keep their constructed response handler
62
- - `JsonRouter.defaultHandler` returns a newly configured handler each time it is read; pass an explicit handler as the third constructor argument for isolated behavior
62
+ - `JsonRouter.defaultHandler` returns a newly configured handler each time it is read; mutating a retrieved handler does not reconfigure existing routers or future defaults; pass an explicit handler as the third constructor argument for isolated behavior
63
+ - `router.route(path)` is independent-registration sugar (one native route, wrapper, and `getEndpoints()` entry per builder call), not native `express.Router().route(path)` grouping: `next('route')` does not skip later builder calls, HEAD falls back to GET, constructor middleware re-runs per chained registration crossed by `next()`
64
+ - thrown/rejected JSON callbacks are JSON-formatted and never reach app error middleware; explicit `next(error)` delegates to native Express error middleware, which owns the response
65
+ - `router.use(...)`/`router.param(...)` delegate to the native router (`router.original`): native callbacks, `basePath` not prepended, nothing recorded in `getEndpoints()`; write separate `router.get(...)` statements for JSON routes
63
66
  - Express is a direct runtime dependency because this package constructs `express.Router()` instances; `@types/express` is installed as a dependency for strict TypeScript consumers
64
67
 
65
68
  ## Pointers
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@web-ts-toolkit/express-json-router",
3
3
  "description": "Express router wrapper for return-value JSON responses",
4
4
  "homepage": "https://web-ts-toolkit.pages.dev/docs/packages/express-json-router",
5
- "version": "0.43.0",
5
+ "version": "0.45.0",
6
6
  "sideEffects": false,
7
7
  "keywords": [
8
8
  "express",
@@ -30,9 +30,9 @@
30
30
  "node": ">=22"
31
31
  },
32
32
  "dependencies": {
33
- "@web-ts-toolkit/express-response-handler": "0.43.0",
34
- "@web-ts-toolkit/http-errors": "0.43.0",
35
- "@web-ts-toolkit/utils": "0.43.0",
33
+ "@web-ts-toolkit/express-response-handler": "0.45.0",
34
+ "@web-ts-toolkit/http-errors": "0.45.0",
35
+ "@web-ts-toolkit/utils": "0.45.0",
36
36
  "@types/express": "^5.0.6",
37
37
  "express": "^5.2.1"
38
38
  },