@fishka/express 0.9.15 → 0.9.17

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
@@ -12,7 +12,7 @@ npm install @fishka/express
12
12
 
13
13
  ```typescript
14
14
  import express from 'express';
15
- import { createRouteTable, param, toInt } from '@fishka/express';
15
+ import { createRouteTable, transform, toInt } from '@fishka/express';
16
16
  import { assertString } from '@fishka/assertions';
17
17
 
18
18
  const app = express();
@@ -21,13 +21,10 @@ app.use(express.json());
21
21
  const routes = createRouteTable(app);
22
22
 
23
23
  // GET /users/:id - with typed path params
24
- routes.get('users/:id', {
25
- $path: { id: param(toInt()) },
26
- run: async ctx => ({
27
- id: ctx.path.id, // number - typed from $path
28
- name: 'John',
29
- }),
30
- });
24
+ routes.get('users/:id', async ctx => ({
25
+ id: ctx.path('id', transform(toInt())), // number - validated inline
26
+ name: 'John',
27
+ }));
31
28
 
32
29
  // GET /users - list all users
33
30
  routes.get('users', async () => [
@@ -36,10 +33,10 @@ routes.get('users', async () => [
36
33
  ]);
37
34
 
38
35
  // POST /users - with body validation
39
- routes.post<{ name: string }, { id: number }>('users', {
40
- $body: { name: v => assertString(v, 'name required') },
41
- run: async ctx => ({ id: 1 }),
42
- });
36
+ routes.post('users', async ctx => ({
37
+ id: 1,
38
+ name: ctx.body({ name: v => assertString(v, 'name required') }).name
39
+ }));
43
40
 
44
41
  // DELETE /users/:id
45
42
  routes.delete('users/:id', async () => {});
@@ -49,29 +46,26 @@ app.listen(3000);
49
46
 
50
47
  ## URL Parameter Validation
51
48
 
52
- Use `param()` to validate and transform path/query parameters. All operators are composable:
49
+ Use `transform()` to validate and transform path/query parameters. All operators are composable:
53
50
 
54
51
  ```typescript
55
- import { param, toInt, minLength, matches, min, range, oneOf } from '@fishka/express';
56
-
57
- routes.get('users/:id', {
58
- $path: {
59
- id: param(toInt()), // string number
60
- },
61
- $query: {
62
- page: param(toInt(), min(1)), // number >= 1
63
- limit: param(toInt(), range(1, 100)), // number 1-100
64
- sort: param(oneOf('asc', 'desc')), // enum
65
- search: param(minLength(3)), // string min 3 chars
66
- },
67
- run: async ctx => ({
68
- id: ctx.path.id, // number
69
- page: ctx.query.page, // number
70
- sort: ctx.query.sort, // 'asc' | 'desc'
71
- }),
72
- });
52
+ import { transform, toInt, minLength, matches, min, range, oneOf } from '@fishka/express';
53
+
54
+ routes.get('users/:id', async ctx => ({
55
+ id: ctx.path('id', transform(toInt())), // string → number (required)
56
+ page: ctx.query('page', transform(toInt(), min(1))), // number >= 1, optional
57
+ limit: ctx.query('limit', transform(toInt(), range(1, 100))), // number 1-100, optional
58
+ sort: ctx.query('sort', transform(oneOf('asc', 'desc'))), // enum, optional
59
+ search: ctx.query('search', transform(minLength(3))), // string min 3 chars, optional
60
+ }));
73
61
  ```
74
62
 
63
+ ### Without Validators
64
+
65
+ - `ctx.path('name')` - returns string (throws 400 if missing)
66
+ - `ctx.query('name')` - returns string | undefined (returns undefined if missing/empty)
67
+ - Validators receive raw values (including undefined/null/empty) and can enforce requiredness
68
+
75
69
  ### Available Operators
76
70
 
77
71
  **Transformations (string → T):**
@@ -93,23 +87,23 @@ routes.get('users/:id', {
93
87
  - `range(min, max)` - value range
94
88
 
95
89
  **Generic:**
96
- - `check(fn, msg)` - custom validation
90
+ - `transform(...ops)` - chain of validators/transformers
91
+ - `assert(predicate, msg)` - custom validation with predicate
92
+ - `validator(fn)` - custom validator returning string|undefined
97
93
  - `map(fn)` - transform value
98
94
 
99
95
  ### Optional Parameters
100
96
 
101
- Use `optional()` to make parameters optional:
97
+ Query parameters are optional by default. Use `ctx.query()` without a validator to get optional string values:
102
98
 
103
99
  ```typescript
104
- import { optional, param, toInt } from '@fishka/express';
100
+ import { transform, toInt } from '@fishka/express';
105
101
 
106
- routes.get('users', {
107
- $query: {
108
- page: optional(param(toInt())), // number | undefined
109
- },
110
- run: async ctx => {
111
- const page = ctx.query.page ?? 1;
112
- },
102
+ routes.get('users', async ctx => {
103
+ const page = ctx.query('page', transform(toInt())) ?? 1; // number | undefined
104
+ const search = ctx.query('search'); // string | undefined
105
+
106
+ return { page, search };
113
107
  });
114
108
  ```
115
109
 
@@ -163,7 +157,7 @@ Full initialization with TLS context, validation, and error handling:
163
157
 
164
158
  ```typescript
165
159
  import express from 'express';
166
- import { createRouteTable, createTlsMiddleware, catchAllMiddleware, param, toInt } from '@fishka/express';
160
+ import { createRouteTable, createTlsMiddleware, catchAllMiddleware, transform, toInt } from '@fishka/express';
167
161
 
168
162
  const app = express();
169
163
 
@@ -178,10 +172,9 @@ const routes = createRouteTable(app);
178
172
 
179
173
  routes.get('health', async () => ({ status: 'UP' }));
180
174
 
181
- routes.get('users/:id', {
182
- $path: { id: param(toInt()) },
183
- run: async ctx => ({ id: ctx.path.id }),
184
- });
175
+ routes.get('users/:id', async ctx => ({
176
+ id: ctx.path('id', transform(toInt()))
177
+ }));
185
178
 
186
179
  // 4. Error handler - catches middleware/parsing errors
187
180
  app.use(catchAllMiddleware);
@@ -1,9 +1,9 @@
1
- /** Validator function that validates and returns typed value */
2
- export type TypeValidator<T> = (value: unknown) => T;
1
+ /** Validator function that validates and returns a typed value */
2
+ export type ParamValidator<T> = (value: unknown) => T;
3
3
  /** Map of param name to type validator */
4
- export type TypedValidatorMap = Record<string, TypeValidator<unknown>>;
4
+ export type ParamValidatorMap = Record<string, ParamValidator<unknown>>;
5
5
  /** Infer validated types from validator map */
6
- export type InferValidated<T extends TypedValidatorMap | undefined> = T extends TypedValidatorMap ? {
6
+ export type ValidatedParams<T extends ParamValidatorMap | undefined> = T extends ParamValidatorMap ? {
7
7
  [K in keyof T]: ReturnType<T[K]>;
8
8
  } : Record<string, never>;
9
9
  export declare class HttpError extends Error {
@@ -1 +1 @@
1
- {"version":3,"file":"api.types.js","sourceRoot":"","sources":["../../src/api.types.ts"],"names":[],"mappings":";;;AAyDA,gCAEC;AA2BD,4BAEC;AAxFD,mDAAkD;AAclD,MAAa,SAAU,SAAQ,KAAK;IAClC,YACkB,MAAc,EAC9B,OAAe,EACC,OAAiC;QAEjD,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,WAAM,GAAN,MAAM,CAAQ;QAEd,YAAO,GAAP,OAAO,CAA0B;QAGjD,qDAAqD;QACrD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC;CACF;AAVD,8BAUC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,SAAgB,UAAU,CAAC,KAAc,EAAE,MAAc,EAAE,OAAe;IACxE,IAAA,yBAAY,EAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAC5D,CAAC;AA0BD,gFAAgF;AAChF,SAAgB,QAAQ,CAAc,MAAS;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"api.types.js","sourceRoot":"","sources":["../../src/api.types.ts"],"names":[],"mappings":";;;AAwDA,gCAEC;AA2BD,4BAEC;AAvFD,mDAAkD;AAalD,MAAa,SAAU,SAAQ,KAAK;IAClC,YACkB,MAAc,EAC9B,OAAe,EACC,OAAiC;QAEjD,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,WAAM,GAAN,MAAM,CAAQ;QAEd,YAAO,GAAP,OAAO,CAA0B;QAGjD,qDAAqD;QACrD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC;CACF;AAVD,8BAUC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,SAAgB,UAAU,CAAC,KAAc,EAAE,MAAc,EAAE,OAAe;IACxE,IAAA,yBAAY,EAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAC5D,CAAC;AA0BD,gFAAgF;AAChF,SAAgB,QAAQ,CAAc,MAAS;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
@@ -1,4 +1,3 @@
1
- import { TypedValidatorMap } from './api.types';
2
1
  import { DeleteEndpoint, GetEndpoint, PatchEndpoint, PostEndpoint, PutEndpoint, RequestContext, ResponseOrValue } from './router';
3
2
  import { ExpressRouter } from './utils/express.utils';
4
3
  /**
@@ -8,19 +7,25 @@ import { ExpressRouter } from './utils/express.utils';
8
7
  export declare class RouteTable {
9
8
  private readonly app;
10
9
  constructor(app: ExpressRouter);
11
- /** Register GET endpoint with full type inference for path/query params. */
12
- get<Result, PathParams extends TypedValidatorMap = TypedValidatorMap, QueryParams extends TypedValidatorMap = TypedValidatorMap>(path: string, endpoint: GetEndpoint<Result, PathParams, QueryParams>): this;
13
- /** Register GET endpoint with function shorthand. */
10
+ /** Register a GET endpoint. */
11
+ get<Result>(path: string, endpoint: GetEndpoint<Result>): this;
12
+ /** Register a GET endpoint with function shorthand. */
14
13
  get<Result>(path: string, run: (ctx: RequestContext) => ResponseOrValue<Result> | Promise<ResponseOrValue<Result>>): this;
15
- /** Register POST endpoint with full type inference for path/query params. */
16
- post<Body, Result = void, PathParams extends TypedValidatorMap = TypedValidatorMap, QueryParams extends TypedValidatorMap = TypedValidatorMap>(path: string, endpoint: PostEndpoint<Body, Result, PathParams, QueryParams>): this;
17
- /** Register PATCH endpoint with full type inference for path/query params. */
18
- patch<Body, Result = void, PathParams extends TypedValidatorMap = TypedValidatorMap, QueryParams extends TypedValidatorMap = TypedValidatorMap>(path: string, endpoint: PatchEndpoint<Body, Result, PathParams, QueryParams>): this;
19
- /** Register PUT endpoint with full type inference for path/query params. */
20
- put<Body, Result = void, PathParams extends TypedValidatorMap = TypedValidatorMap, QueryParams extends TypedValidatorMap = TypedValidatorMap>(path: string, endpoint: PutEndpoint<Body, Result, PathParams, QueryParams>): this;
21
- /** Register DELETE endpoint with full endpoint object. */
22
- delete<PathParams extends TypedValidatorMap = TypedValidatorMap, QueryParams extends TypedValidatorMap = TypedValidatorMap>(path: string, endpoint: DeleteEndpoint<PathParams, QueryParams>): this;
23
- /** Register DELETE endpoint with function shorthand. */
14
+ /** Register a POST endpoint. */
15
+ post<Result = void>(path: string, endpoint: PostEndpoint<Result>): this;
16
+ /** Register a POST endpoint with function shorthand. */
17
+ post<Result = void>(path: string, run: (ctx: RequestContext) => ResponseOrValue<Result> | Promise<ResponseOrValue<Result>>): this;
18
+ /** Register a PATCH endpoint. */
19
+ patch<Result = void>(path: string, endpoint: PatchEndpoint<Result>): this;
20
+ /** Register a PATCH endpoint with function shorthand. */
21
+ patch<Result = void>(path: string, run: (ctx: RequestContext) => ResponseOrValue<Result> | Promise<ResponseOrValue<Result>>): this;
22
+ /** Register a PUT endpoint. */
23
+ put<Result = void>(path: string, endpoint: PutEndpoint<Result>): this;
24
+ /** Register a PUT endpoint with function shorthand. */
25
+ put<Result = void>(path: string, run: (ctx: RequestContext) => ResponseOrValue<Result> | Promise<ResponseOrValue<Result>>): this;
26
+ /** Register a DELETE endpoint with a full endpoint object. */
27
+ delete(path: string, endpoint: DeleteEndpoint): this;
28
+ /** Register a DELETE endpoint with function shorthand. */
24
29
  delete(path: string, run: (ctx: RequestContext) => void | Promise<void>): this;
25
30
  }
26
31
  /**
@@ -16,18 +16,18 @@ class RouteTable {
16
16
  (0, router_1.mountGet)(this.app, path, endpoint);
17
17
  return this;
18
18
  }
19
- /** Register POST endpoint with full type inference for path/query params. */
20
- post(path, endpoint) {
19
+ post(path, endpointOrRun) {
20
+ const endpoint = typeof endpointOrRun === 'function' ? { run: endpointOrRun } : endpointOrRun;
21
21
  (0, router_1.mountPost)(this.app, path, endpoint);
22
22
  return this;
23
23
  }
24
- /** Register PATCH endpoint with full type inference for path/query params. */
25
- patch(path, endpoint) {
24
+ patch(path, endpointOrRun) {
25
+ const endpoint = typeof endpointOrRun === 'function' ? { run: endpointOrRun } : endpointOrRun;
26
26
  (0, router_1.mountPatch)(this.app, path, endpoint);
27
27
  return this;
28
28
  }
29
- /** Register PUT endpoint with full type inference for path/query params. */
30
- put(path, endpoint) {
29
+ put(path, endpointOrRun) {
30
+ const endpoint = typeof endpointOrRun === 'function' ? { run: endpointOrRun } : endpointOrRun;
31
31
  (0, router_1.mountPut)(this.app, path, endpoint);
32
32
  return this;
33
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"route-table.js","sourceRoot":"","sources":["../../src/route-table.ts"],"names":[],"mappings":";;;AA6GA,4CAEC;AA9GD,qCAakB;AAGlB;;;GAGG;AACH,MAAa,UAAU;IACrB,YAA6B,GAAkB;QAAlB,QAAG,GAAH,GAAG,CAAe;IAAG,CAAC;IAYnD,GAAG,CAKD,IAAY,EACZ,aAEyF;QAEzF,MAAM,QAAQ,GAAG,OAAO,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QAC9F,IAAA,iBAAQ,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,QAAgC,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6EAA6E;IAC7E,IAAI,CAKF,IAAY,EAAE,QAA6D;QAC3E,IAAA,kBAAS,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,QAA4C,CAAC,CAAC;QACxE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8EAA8E;IAC9E,KAAK,CAKH,IAAY,EAAE,QAA8D;QAC5E,IAAA,mBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,QAA6C,CAAC,CAAC;QAC1E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4EAA4E;IAC5E,GAAG,CAKD,IAAY,EAAE,QAA4D;QAC1E,IAAA,iBAAQ,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,QAA2C,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC;IACd,CAAC;IAWD,MAAM,CAIJ,IAAY,EACZ,aAAwG;QAExG,MAAM,QAAQ,GAAG,OAAO,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QAC9F,IAAA,oBAAW,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,QAA0B,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAjFD,gCAiFC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,GAAkB;IACjD,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"route-table.js","sourceRoot":"","sources":["../../src/route-table.ts"],"names":[],"mappings":";;;AAwGA,4CAEC;AA1GD,qCAakB;AAGlB;;;GAGG;AACH,MAAa,UAAU;IACrB,YAA6B,GAAkB;QAAlB,QAAG,GAAH,GAAG,CAAe;IAAG,CAAC;IAQnD,GAAG,CACD,IAAY,EACZ,aAA0H;QAE1H,MAAM,QAAQ,GAAG,OAAO,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QAC9F,IAAA,iBAAQ,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,QAAgC,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAQD,IAAI,CACF,IAAY,EACZ,aAA2H;QAE3H,MAAM,QAAQ,GAAG,OAAO,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QAC9F,IAAA,kBAAS,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,QAAiC,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC;IAQD,KAAK,CACH,IAAY,EACZ,aAA4H;QAE5H,MAAM,QAAQ,GAAG,OAAO,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QAC9F,IAAA,mBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,QAAkC,CAAC,CAAC;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;IAQD,GAAG,CACD,IAAY,EACZ,aAA0H;QAE1H,MAAM,QAAQ,GAAG,OAAO,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QAC9F,IAAA,iBAAQ,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,QAAgC,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAQD,MAAM,CACJ,IAAY,EACZ,aAA+E;QAE/E,MAAM,QAAQ,GAAG,OAAO,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QAC9F,IAAA,oBAAW,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,QAA0B,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA7ED,gCA6EC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,GAAkB;IACjD,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC"}
@@ -1,5 +1,5 @@
1
- import { Assertion, ObjectAssertion } from '@fishka/assertions';
2
- import { ApiResponse, InferValidated, TypedValidatorMap } from './api.types';
1
+ import { Assertion } from '@fishka/assertions';
2
+ import { ApiResponse, ParamValidator } from './api.types';
3
3
  import { AuthUser } from './auth/auth.types';
4
4
  import { ExpressRequest, ExpressResponse, ExpressRouter } from './utils/express.utils';
5
5
  /** Express API allows handlers to return a response in the raw form. */
@@ -10,19 +10,36 @@ export type ResponseOrValue<ResponseEntity> = ApiResponse<ResponseEntity> | Resp
10
10
  */
11
11
  export type EndpointMiddleware<Context = RequestContext> = (run: () => Promise<unknown>, context: Context) => Promise<unknown>;
12
12
  /** Generic request context passed to all handlers. Database-agnostic and extensible. */
13
- export interface RequestContext<Body = void, PathParams extends TypedValidatorMap = TypedValidatorMap, QueryParams extends TypedValidatorMap = TypedValidatorMap> {
14
- /** Parsed and validated request body (for POST/PATCH/PUT handlers). */
15
- body: Body;
13
+ export interface RequestContext {
16
14
  /** Express Request object. */
17
15
  req: ExpressRequest;
18
16
  /** Express Response object. */
19
17
  res: ExpressResponse;
20
18
  /** Authenticated user (if any). Populated by auth middleware. */
21
19
  authUser?: AuthUser;
22
- /** Validated path parameters (typed from $path validators). */
23
- path: InferValidated<PathParams>;
24
- /** Validated query parameters (typed from $query validators). */
25
- query: InferValidated<QueryParams>;
20
+ /**
21
+ * Get and validate a path parameter.
22
+ * @param name - Name of the path parameter
23
+ * @param validator - Optional validator. If not provided, returns the raw string value.
24
+ * @returns Validated value of type T (or string if no validator)
25
+ * @throws {HttpError} 400 Bad Request if validation fails
26
+ */
27
+ path<T = string>(name: string, validator?: ParamValidator<T>): T;
28
+ /**
29
+ * Get and validate a query parameter.
30
+ * @param name - Name of the query parameter
31
+ * @param validator - Optional validator. If not provided, returns the raw string value or undefined.
32
+ * @returns Validated value of type T, or undefined if parameter is not present
33
+ * @throws {HttpError} 400 Bad Request if validation fails
34
+ */
35
+ query<T = string>(name: string, validator?: ParamValidator<T>): T | undefined;
36
+ /**
37
+ * Get and validate the request body.
38
+ * @param validator - Validator function or object assertion
39
+ * @returns Validated body of type T
40
+ * @throws {HttpError} 400 Bad Request if validation fails
41
+ */
42
+ body<T>(validator: Assertion<T>): T;
26
43
  /**
27
44
  * Generic state storage for middleware to attach data.
28
45
  * Allows middleware to pass information to handlers and other middleware.
@@ -30,31 +47,24 @@ export interface RequestContext<Body = void, PathParams extends TypedValidatorMa
30
47
  state: Map<string, unknown>;
31
48
  }
32
49
  /** Base interface with common endpoint properties. */
33
- export interface EndpointBase<PathParams extends TypedValidatorMap = TypedValidatorMap, QueryParams extends TypedValidatorMap = TypedValidatorMap, Body = void, Result = unknown> {
34
- /** Path parameter validators (typed). */
35
- $path?: PathParams;
36
- /** Query parameter validators (typed). */
37
- $query?: QueryParams;
50
+ export interface EndpointBase<Result = unknown> {
38
51
  /** Optional middleware to execute before the handler. */
39
52
  middlewares?: Array<EndpointMiddleware>;
40
53
  /** Handler function. Can be sync or async. */
41
- run: (ctx: RequestContext<Body, PathParams, QueryParams>) => ResponseOrValue<Result> | Promise<ResponseOrValue<Result>>;
54
+ run: (ctx: RequestContext) => ResponseOrValue<Result> | Promise<ResponseOrValue<Result>>;
42
55
  }
43
56
  /** Descriptor for GET list routes. */
44
- export type GetListEndpoint<ResultElementType, PathParams extends TypedValidatorMap = TypedValidatorMap, QueryParams extends TypedValidatorMap = TypedValidatorMap> = EndpointBase<PathParams, QueryParams, void, Array<ResultElementType>>;
57
+ export type GetListEndpoint<ResultElementType> = EndpointBase<Array<ResultElementType>>;
45
58
  /** Descriptor for GET routes. */
46
- export type GetEndpoint<Result, PathParams extends TypedValidatorMap = TypedValidatorMap, QueryParams extends TypedValidatorMap = TypedValidatorMap> = EndpointBase<PathParams, QueryParams, void, Result>;
59
+ export type GetEndpoint<Result> = EndpointBase<Result>;
47
60
  /** Descriptor for POST routes. */
48
- export interface PostEndpoint<Body, Result = void, PathParams extends TypedValidatorMap = TypedValidatorMap, QueryParams extends TypedValidatorMap = TypedValidatorMap> extends EndpointBase<PathParams, QueryParams, Body, Result> {
49
- /** Request body validator. */
50
- $body: Body extends object ? ObjectAssertion<Body> : Assertion<Body>;
51
- }
61
+ export type PostEndpoint<Result = void> = EndpointBase<Result>;
52
62
  /** Same as POST. Used for full object updates. */
53
- export type PutEndpoint<Body, Result = void, PathParams extends TypedValidatorMap = TypedValidatorMap, QueryParams extends TypedValidatorMap = TypedValidatorMap> = PostEndpoint<Body, Result, PathParams, QueryParams>;
63
+ export type PutEndpoint<Result = void> = EndpointBase<Result>;
54
64
  /** Same as PUT. While PUT is used for the whole object update, PATCH is used for a partial update. */
55
- export type PatchEndpoint<Body, Result = void, PathParams extends TypedValidatorMap = TypedValidatorMap, QueryParams extends TypedValidatorMap = TypedValidatorMap> = PutEndpoint<Body, Result, PathParams, QueryParams>;
65
+ export type PatchEndpoint<Result = void> = EndpointBase<Result>;
56
66
  /** Descriptor for DELETE routes. */
57
- export type DeleteEndpoint<PathParams extends TypedValidatorMap = TypedValidatorMap, QueryParams extends TypedValidatorMap = TypedValidatorMap> = EndpointBase<PathParams, QueryParams, void, void>;
67
+ export type DeleteEndpoint = EndpointBase<void>;
58
68
  /** Union type for all route registration info objects. */
59
69
  export type RouteRegistrationInfo = ({
60
70
  method: 'get';
@@ -77,11 +87,11 @@ export type RouteRegistrationInfo = ({
77
87
  /** Registers a GET route. */
78
88
  export declare const mountGet: (app: ExpressRouter, path: string, endpoint: GetEndpoint<unknown> | GetListEndpoint<unknown>) => void;
79
89
  /** Registers a POST route. */
80
- export declare const mountPost: <Body, Result>(app: ExpressRouter, path: string, endpoint: PostEndpoint<Body, Result>) => void;
90
+ export declare const mountPost: <Result>(app: ExpressRouter, path: string, endpoint: PostEndpoint<Result>) => void;
81
91
  /** Registers a PATCH route. */
82
- export declare const mountPatch: <Body, Result>(app: ExpressRouter, path: string, endpoint: PatchEndpoint<Body, Result>) => void;
92
+ export declare const mountPatch: <Result>(app: ExpressRouter, path: string, endpoint: PatchEndpoint<Result>) => void;
83
93
  /** Registers a PUT route. */
84
- export declare const mountPut: <Body, Result>(app: ExpressRouter, path: string, endpoint: PutEndpoint<Body, Result>) => void;
94
+ export declare const mountPut: <Result>(app: ExpressRouter, path: string, endpoint: PutEndpoint<Result>) => void;
85
95
  /** Registers a DELETE route. */
86
96
  export declare const mountDelete: (app: ExpressRouter, path: string, endpoint: DeleteEndpoint) => void;
87
97
  /** Mounts a route with the given method, endpoint, and path. */
@@ -42,9 +42,94 @@ const error_handling_1 = require("./error-handling");
42
42
  const http_status_codes_1 = require("./http-status-codes");
43
43
  const thread_local_storage_1 = require("./thread-local/thread-local-storage");
44
44
  const conversion_utils_1 = require("./utils/conversion.utils");
45
- // ============================================================================
46
- // Internal implementation details
47
- // ============================================================================
45
+ /** Implementation of RequestContext with caching for validated parameters. */
46
+ class RequestContextImpl {
47
+ constructor(
48
+ /** Express request object. */
49
+ req,
50
+ /** Express response object. */
51
+ res,
52
+ /** Authenticated user (if any). */
53
+ authUser,
54
+ /** Request-scoped state storage. */
55
+ state = new Map()) {
56
+ this.req = req;
57
+ this.res = res;
58
+ this.authUser = authUser;
59
+ this.state = state;
60
+ }
61
+ /**
62
+ * Validates a parameter with optional validator and caching.
63
+ * @param name Parameter name.
64
+ * @param rawValue Raw parameter value from request.
65
+ * @param validator Optional validator function.
66
+ * @param cache Cache map for this parameter type.
67
+ * @param isRequired Whether parameter is required (path=true, query=false).
68
+ * @returns Validated value or undefined for optional missing parameters.
69
+ */
70
+ validateParam(name, rawValue, validator, isRequired) {
71
+ try {
72
+ let result;
73
+ if (validator) {
74
+ // Pass value to validator even if it's undefined/null/empty
75
+ result = validator(rawValue);
76
+ }
77
+ else {
78
+ // Without validator
79
+ if (rawValue === undefined || rawValue === null || rawValue === '') {
80
+ if (isRequired) {
81
+ (0, api_types_1.assertHttp)(false, http_status_codes_1.HTTP_BAD_REQUEST, `Missing required parameter: ${name}`);
82
+ }
83
+ return undefined;
84
+ }
85
+ result = rawValue;
86
+ }
87
+ return result;
88
+ }
89
+ catch (error) {
90
+ if (error instanceof api_types_1.HttpError)
91
+ throw error;
92
+ throw new api_types_1.HttpError(http_status_codes_1.HTTP_BAD_REQUEST, (0, assertions_1.getMessageFromError)(error));
93
+ }
94
+ }
95
+ path(name, validator) {
96
+ const rawValue = this.req.params[name];
97
+ const result = this.validateParam(name, rawValue, validator, true);
98
+ (0, api_types_1.assertHttp)(result !== undefined, http_status_codes_1.HTTP_BAD_REQUEST, `Missing required path parameter: ${name}`);
99
+ return result;
100
+ }
101
+ query(name, validator) {
102
+ const parsedUrl = url.parse(this.req.url, true);
103
+ const rawValue = parsedUrl.query[name];
104
+ const value = Array.isArray(rawValue) ? rawValue[0] : rawValue;
105
+ return this.validateParam(name, value, validator, false);
106
+ }
107
+ body(validator) {
108
+ const apiRequest = this.req.body;
109
+ try {
110
+ // Handle validation based on whether the validator is an object or function
111
+ if (typeof validator === 'function') {
112
+ // It's a ValueAssertion (function) - call it directly
113
+ validator(apiRequest);
114
+ }
115
+ else {
116
+ // It's an ObjectAssertion - use validateObject
117
+ const objectValidator = validator;
118
+ const isEmptyValidator = Object.keys(objectValidator).length === 0;
119
+ const errorMessage = (0, assertions_1.validateObject)(apiRequest, objectValidator, `${http_status_codes_1.HTTP_BAD_REQUEST}: request body`, {
120
+ failOnUnknownFields: !isEmptyValidator,
121
+ });
122
+ (0, api_types_1.assertHttp)(!errorMessage, http_status_codes_1.HTTP_BAD_REQUEST, errorMessage || 'Request body validation failed');
123
+ }
124
+ return apiRequest;
125
+ }
126
+ catch (error) {
127
+ if (error instanceof api_types_1.HttpError)
128
+ throw error;
129
+ throw new api_types_1.HttpError(http_status_codes_1.HTTP_BAD_REQUEST, (0, assertions_1.getMessageFromError)(error));
130
+ }
131
+ }
132
+ }
48
133
  /** Registers a GET route. */
49
134
  const mountGet = (app, path, endpoint) => mount(app, { method: 'get', endpoint, path });
50
135
  exports.mountGet = mountGet;
@@ -96,48 +181,12 @@ function createRouteHandler(method, endpoint) {
96
181
  res.send(response);
97
182
  };
98
183
  }
99
- /**
100
- * @Internal
101
- * Validates and builds typed path/query parameters using $path and $query validators.
102
- */
103
- function buildValidatedParams(req, $path, $query) {
104
- const pathResult = {};
105
- const queryResult = {};
106
- try {
107
- // Validate path params
108
- if ($path) {
109
- for (const [key, validator] of Object.entries($path)) {
110
- const value = req.params[key];
111
- pathResult[key] = validator(value);
112
- }
113
- }
114
- // Validate query params
115
- if ($query) {
116
- const parsedUrl = url.parse(req.url, true);
117
- for (const [key, validator] of Object.entries($query)) {
118
- const rawValue = parsedUrl.query[key];
119
- const value = Array.isArray(rawValue) ? rawValue[0] : rawValue;
120
- queryResult[key] = validator(value);
121
- }
122
- }
123
- }
124
- catch (error) {
125
- if (error instanceof api_types_1.HttpError)
126
- throw error;
127
- throw new api_types_1.HttpError(http_status_codes_1.HTTP_BAD_REQUEST, (0, assertions_1.getMessageFromError)(error));
128
- }
129
- return {
130
- path: pathResult,
131
- query: queryResult,
132
- };
133
- }
134
184
  /**
135
185
  * @Internal
136
186
  * Runs GET handler with optional middleware.
137
187
  */
138
188
  async function executeGetEndpoint(route, req, res) {
139
- const validated = buildValidatedParams(req, route.$path, route.$query);
140
- const requestContext = newRequestContext(undefined, req, res, validated.path, validated.query);
189
+ const requestContext = new RequestContextImpl(req, res);
141
190
  return await executeWithMiddleware(() => route.run(requestContext), route.middlewares || [], requestContext);
142
191
  }
143
192
  /**
@@ -145,8 +194,7 @@ async function executeGetEndpoint(route, req, res) {
145
194
  * Runs DELETE handler with optional middleware.
146
195
  */
147
196
  async function executeDeleteEndpoint(route, req, res) {
148
- const validated = buildValidatedParams(req, route.$path, route.$query);
149
- const requestContext = newRequestContext(undefined, req, res, validated.path, validated.query);
197
+ const requestContext = new RequestContextImpl(req, res);
150
198
  await executeWithMiddleware(() => route.run(requestContext), route.middlewares || [], requestContext);
151
199
  return undefined;
152
200
  }
@@ -155,32 +203,8 @@ async function executeDeleteEndpoint(route, req, res) {
155
203
  * Runs POST/PUT/PATCH handler with optional middleware.
156
204
  */
157
205
  async function executeBodyEndpoint(route, req, res) {
158
- const validator = route.$body;
159
- const apiRequest = req.body;
160
- try {
161
- // Handle validation based on whether the validator is an object or function
162
- if (typeof validator === 'function') {
163
- // It's a ValueAssertion (function) - call it directly
164
- validator(apiRequest);
165
- }
166
- else {
167
- // It's an ObjectAssertion - use validateObject
168
- const objectValidator = validator;
169
- const isEmptyValidator = Object.keys(objectValidator).length === 0;
170
- const errorMessage = (0, assertions_1.validateObject)(apiRequest, objectValidator, `${http_status_codes_1.HTTP_BAD_REQUEST}: request body`, {
171
- failOnUnknownFields: !isEmptyValidator,
172
- });
173
- (0, api_types_1.assertHttp)(!errorMessage, http_status_codes_1.HTTP_BAD_REQUEST, errorMessage || 'Request body validation failed');
174
- }
175
- }
176
- catch (error) {
177
- if (error instanceof api_types_1.HttpError)
178
- throw error;
179
- throw new api_types_1.HttpError(http_status_codes_1.HTTP_BAD_REQUEST, (0, assertions_1.getMessageFromError)(error));
180
- }
181
- const validated = buildValidatedParams(req, route.$path, route.$query);
182
- const requestContext = newRequestContext(apiRequest, req, res, validated.path, validated.query);
183
- return await executeWithMiddleware(() => route.run(requestContext), (route.middlewares || []), requestContext);
206
+ const requestContext = new RequestContextImpl(req, res);
207
+ return await executeWithMiddleware(() => route.run(requestContext), route.middlewares || [], requestContext);
184
208
  }
185
209
  /**
186
210
  * @Internal
@@ -197,18 +221,4 @@ async function executeWithMiddleware(run, middlewares, context) {
197
221
  };
198
222
  return await current(0);
199
223
  }
200
- /**
201
- * @Internal
202
- * Creates a new RequestContext instance.
203
- */
204
- function newRequestContext(requestBody, req, res, validatedPath, validatedQuery) {
205
- return {
206
- body: requestBody,
207
- req,
208
- res,
209
- path: validatedPath,
210
- query: validatedQuery,
211
- state: new Map(),
212
- };
213
- }
214
224
  //# sourceMappingURL=router.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/router.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/router.ts"],"names":[],"mappings":"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"}