@heliosjs/middlewares 10.0.5 → 10.0.8

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/pipe.d.ts CHANGED
@@ -1,31 +1,32 @@
1
1
  import { type Pipe } from '@heliosjs/core/types';
2
2
  /**
3
- * Decorator to register a data transformation pipe.
3
+ * Registers a transformation pipe on a controller class or a single route method.
4
+ * Pipes run after guards and before middlewares; each supplied function replaces
5
+ * the matching part of the request with its return value, so the handler and its
6
+ * `@Body()` / `@QueryParam()` decorators see the transformed data.
4
7
  *
5
- * Pipes are used to transform incoming request data before it reaches
6
- * the route handler. They can be applied at the controller level and
7
- * modify parts of the request such as body, query, params, or headers.
8
+ * Use pipes for normalization and coercion (trim, lowercase, `Number(...)`,
9
+ * defaults). For schema validation prefer a DTO on the param decorator or
10
+ * `@Sanitize`.
8
11
  *
9
- * @param config - Configuration object containing transformation functions
10
- * for different parts of the request.
12
+ * @param pipe - An object with any of these keys, each a
13
+ * `(value, request) => value` transformer:
14
+ * - `body` — `(body, req) => body`. Why: reshape or clean the parsed body.
15
+ * - `query` — `(query, req) => query`, where query is
16
+ * `Record<string, string | string[]>`. Why: coerce query strings to the
17
+ * types the handler expects.
18
+ * - `params` — `(params, req) => params`, `Record<string, string>`. Why:
19
+ * normalize path segments (case, padding).
20
+ * - `headers` — `(headers, req) => headers`. Why: canonicalize header values.
21
+ * Omitted keys leave that part untouched.
11
22
  *
12
- * @returns A class decorator that attaches pipe metadata to the target.
23
+ * @returns A class or method decorator.
13
24
  *
14
25
  * @example
15
26
  * @Pipe({
16
- * body: (body) => ({ ...body, name: body.name.trim() }),
17
- * query: (query) => ({ ...query, page: Number(query.page) }),
27
+ * body: (body) => ({ ...body, name: body.name?.trim() }),
28
+ * query: (query) => ({ ...query, page: Number(query.page ?? 1) }),
18
29
  * })
19
30
  * class MyController {}
20
- *
21
- * @remarks
22
- * Each function in the pipe receives raw data and must return the transformed value.
23
- * Pipes are executed before controller methods and can be used for:
24
- * - data normalization
25
- * - type casting
26
- * - sanitization
27
- *
28
- * Metadata is stored under the CONTROLLER_CONFIGURATION key and later used
29
- * by the framework during request processing.
30
31
  */
31
- export declare function Pipe(pipe: Pipe): (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) => void;
32
+ export declare function Pipe(pipe: Pipe): (target: any, propertyKey?: string, _descriptor?: PropertyDescriptor) => void;
package/dist/pipe.js CHANGED
@@ -3,38 +3,39 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Pipe = Pipe;
4
4
  const utils_1 = require("@heliosjs/core/utils");
5
5
  /**
6
- * Decorator to register a data transformation pipe.
6
+ * Registers a transformation pipe on a controller class or a single route method.
7
+ * Pipes run after guards and before middlewares; each supplied function replaces
8
+ * the matching part of the request with its return value, so the handler and its
9
+ * `@Body()` / `@QueryParam()` decorators see the transformed data.
7
10
  *
8
- * Pipes are used to transform incoming request data before it reaches
9
- * the route handler. They can be applied at the controller level and
10
- * modify parts of the request such as body, query, params, or headers.
11
+ * Use pipes for normalization and coercion (trim, lowercase, `Number(...)`,
12
+ * defaults). For schema validation prefer a DTO on the param decorator or
13
+ * `@Sanitize`.
11
14
  *
12
- * @param config - Configuration object containing transformation functions
13
- * for different parts of the request.
15
+ * @param pipe - An object with any of these keys, each a
16
+ * `(value, request) => value` transformer:
17
+ * - `body` — `(body, req) => body`. Why: reshape or clean the parsed body.
18
+ * - `query` — `(query, req) => query`, where query is
19
+ * `Record<string, string | string[]>`. Why: coerce query strings to the
20
+ * types the handler expects.
21
+ * - `params` — `(params, req) => params`, `Record<string, string>`. Why:
22
+ * normalize path segments (case, padding).
23
+ * - `headers` — `(headers, req) => headers`. Why: canonicalize header values.
24
+ * Omitted keys leave that part untouched.
14
25
  *
15
- * @returns A class decorator that attaches pipe metadata to the target.
26
+ * @returns A class or method decorator.
16
27
  *
17
28
  * @example
18
29
  * @Pipe({
19
- * body: (body) => ({ ...body, name: body.name.trim() }),
20
- * query: (query) => ({ ...query, page: Number(query.page) }),
30
+ * body: (body) => ({ ...body, name: body.name?.trim() }),
31
+ * query: (query) => ({ ...query, page: Number(query.page ?? 1) }),
21
32
  * })
22
33
  * class MyController {}
23
- *
24
- * @remarks
25
- * Each function in the pipe receives raw data and must return the transformed value.
26
- * Pipes are executed before controller methods and can be used for:
27
- * - data normalization
28
- * - type casting
29
- * - sanitization
30
- *
31
- * Metadata is stored under the CONTROLLER_CONFIGURATION key and later used
32
- * by the framework during request processing.
33
34
  */
34
35
  function Pipe(pipe) {
35
- return function (target, propertyKey, descriptor) {
36
+ return function (target, propertyKey, _descriptor) {
36
37
  const data = [{ pipe }];
37
- if (descriptor) {
38
+ if (propertyKey) {
38
39
  (0, utils_1.defineMiddlewaresMeta)(data, target, propertyKey);
39
40
  }
40
41
  else {
package/dist/pipe.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"pipe.js","sourceRoot":"","sources":["../src/pipe.ts"],"names":[],"mappings":";;AA+BA,oBAUC;AAxCD,gDAA6D;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,SAAgB,IAAI,CAAC,IAAU;IAC7B,OAAO,UAAU,MAAW,EAAE,WAAoB,EAAE,UAA+B;QACjF,MAAM,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAExB,IAAI,UAAU,EAAE,CAAC;YACf,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"pipe.js","sourceRoot":"","sources":["../src/pipe.ts"],"names":[],"mappings":";;AAgCA,oBAUC;AAzCD,gDAA6D;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,SAAgB,IAAI,CAAC,IAAU;IAC7B,OAAO,UAAU,MAAW,EAAE,WAAoB,EAAE,WAAgC;QAClF,MAAM,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAExB,IAAI,WAAW,EAAE,CAAC;YAChB,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
package/dist/roles.d.ts CHANGED
@@ -1,15 +1,25 @@
1
1
  import type { GuardFunction } from '@heliosjs/core/types';
2
+ /** Role match policy for `@Roles`: `'any'` (at least one required role) or `'all'` (every required role). */
2
3
  export type RoleMode = 'any' | 'all';
4
+ /** Trailing options object accepted by `@Roles`. */
3
5
  export interface RolesOptions {
6
+ /** Match policy. Default `'any'`. */
4
7
  mode?: RoleMode;
8
+ /** Denial message when the check fails. Default `'Insufficient role'`. */
5
9
  message?: string;
6
10
  }
7
11
  type RolesArg = string | string[];
12
+ /**
13
+ * @internal `true` when `userRoles` satisfies `required` under `mode` (`'all'`:
14
+ * every required role present; otherwise: at least one).
15
+ */
8
16
  export declare function matchRoles(required: string[], userRoles: string[], mode: RoleMode): boolean;
17
+ /** @internal Splits `@Roles(...)`'s variadic arguments into a flat role list plus the trailing options object, if any. */
9
18
  export declare function normalizeArgs(args: (RolesArg | RolesOptions)[]): {
10
19
  roles: string[];
11
20
  options: RolesOptions;
12
21
  };
22
+ /** @internal Builds the `GuardFunction` `@Roles` registers via `@Guard`, using the configured `RolesExtractor`. */
13
23
  export declare function createRolesGuard(required: string[], options: RolesOptions): GuardFunction;
14
24
  /**
15
25
  * Restrict a controller or route to users holding the required role(s).
@@ -26,5 +36,5 @@ export declare function createRolesGuard(required: string[], options: RolesOptio
26
36
  * @example
27
37
  * @Roles(['admin', 'editor'], { mode: 'all' }) // ALL
28
38
  */
29
- export declare function Roles(...args: (RolesArg | RolesOptions)[]): (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) => void;
39
+ export declare function Roles(...args: (RolesArg | RolesOptions)[]): (target: any, propertyKey?: string, _descriptor?: PropertyDescriptor) => void;
30
40
  export {};
package/dist/roles.js CHANGED
@@ -5,11 +5,16 @@ exports.normalizeArgs = normalizeArgs;
5
5
  exports.createRolesGuard = createRolesGuard;
6
6
  exports.Roles = Roles;
7
7
  const utils_1 = require("@heliosjs/core/utils");
8
+ /**
9
+ * @internal `true` when `userRoles` satisfies `required` under `mode` (`'all'`:
10
+ * every required role present; otherwise: at least one).
11
+ */
8
12
  function matchRoles(required, userRoles, mode) {
9
13
  return mode === 'all'
10
14
  ? required.every((role) => userRoles.includes(role))
11
15
  : required.some((role) => userRoles.includes(role));
12
16
  }
17
+ /** @internal Splits `@Roles(...)`'s variadic arguments into a flat role list plus the trailing options object, if any. */
13
18
  function normalizeArgs(args) {
14
19
  let options = {};
15
20
  let roleArgs = args;
@@ -28,6 +33,7 @@ function normalizeArgs(args) {
28
33
  });
29
34
  return { roles, options };
30
35
  }
36
+ /** @internal Builds the `GuardFunction` `@Roles` registers via `@Guard`, using the configured `RolesExtractor`. */
31
37
  function createRolesGuard(required, options) {
32
38
  const mode = options.mode ?? 'any';
33
39
  const message = options.message ?? 'Insufficient role';
@@ -59,9 +65,9 @@ function createRolesGuard(required, options) {
59
65
  function Roles(...args) {
60
66
  const { roles, options } = normalizeArgs(args);
61
67
  const guard = createRolesGuard(roles, options);
62
- return function (target, propertyKey, descriptor) {
68
+ return function (target, propertyKey, _descriptor) {
63
69
  const data = [{ guard }];
64
- if (descriptor) {
70
+ if (propertyKey) {
65
71
  (0, utils_1.defineMiddlewaresMeta)(data, target, propertyKey);
66
72
  }
67
73
  else {
package/dist/roles.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"roles.js","sourceRoot":"","sources":["../src/roles.ts"],"names":[],"mappings":";;AAYA,gCAQC;AAED,sCAsBC;AAED,4CAoBC;AAiBD,sBAaC;AA/FD,gDAAmG;AAWnG,SAAgB,UAAU,CACxB,QAAkB,EAClB,SAAmB,EACnB,IAAc;IAEd,OAAO,IAAI,KAAK,KAAK;QACnB,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,SAAgB,aAAa,CAC3B,IAAiC;IAEjC,IAAI,OAAO,GAAiB,EAAE,CAAC;IAC/B,IAAI,QAAQ,GAAG,IAAI,CAAC;IAEpB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACnC,MAAM,SAAS,GACb,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpE,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,GAAG,IAAoB,CAAC;QAC/B,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACrC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC;QACnC,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1C,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5B,CAAC;AAED,SAAgB,gBAAgB,CAC9B,QAAkB,EAClB,OAAqB;IAErB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC;IACnC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,mBAAmB,CAAC;IAEvD,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;QACnB,MAAM,SAAS,GAAG,IAAA,yBAAiB,GAAE,CAAC;QACtC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,yBAAiB,CACzB,4DAA4D,CAC7D,CAAC;QACJ,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAEtE,OAAO,UAAU,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAgB,KAAK,CAAC,GAAG,IAAiC;IACxD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAE/C,OAAO,UAAU,MAAW,EAAE,WAAoB,EAAE,UAA+B;QACjF,MAAM,IAAI,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAEzB,IAAI,UAAU,EAAE,CAAC;YACf,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"roles.js","sourceRoot":"","sources":["../src/roles.ts"],"names":[],"mappings":"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"}
@@ -1,40 +1,34 @@
1
1
  import type { SanitizerConfig } from '@heliosjs/core/types';
2
2
  /**
3
- * Decorator to apply sanitization configurations to a controller or method.
3
+ * Runs a Joi schema over one part of the request on a controller class or a
4
+ * single route method. Sanitizers run first in the pipeline (before guards), so
5
+ * every later stage sees the cleaned/validated data.
4
6
  *
5
- * This decorator accepts one or more sanitization configuration objects which define
6
- * how incoming request data should be sanitized before processing. It can be applied
7
- * at the class level to apply sanitization globally to all methods or at the method level
8
- * for fine-grained control.
7
+ * Depending on `action` a config either validates (throws on mismatch),
8
+ * sanitizes (coerces/strips and writes the result back onto the request), or
9
+ * both. The `SANITIZER` helper from `@heliosjs/core` provides ready-made Joi
10
+ * builders (`SANITIZER.string.email()`, `SANITIZER.xss()`, …).
9
11
  *
10
- * The sanitization configurations are stored as metadata on the target or method,
11
- * which can be retrieved by the framework to perform the actual sanitization during
12
- * request handling.
12
+ * @param config - One `SanitizerConfig`, or an array applied in order. Each has:
13
+ * - `schema` (**required**) a `Joi.Schema` to run.
14
+ * - `type` (**required**) — which request part to target, one of
15
+ * `'body'`, `'query'`, `'params'`, `'headers'`.
16
+ * - `action` — `'validate'` (reject on error), `'sanitize'` (transform in
17
+ * place), or `'both'`. Default `'both'`.
18
+ * - `options` — Joi `ValidationOptions` passed through.
19
+ * - `stripUnknown` — drop keys not in the schema.
20
+ * Why an array: apply different schemas to different request parts on the same
21
+ * route.
13
22
  *
14
- * @param {SanitizerConfig | SanitizerConfig[]} sanitizeConfig - A single or array of sanitization configuration objects.
15
- *
16
- * @returns {Function} A decorator function that applies the sanitization metadata.
17
- *
18
- * @example
19
- * // Apply sanitization to all methods in a controller
20
- * @Sanitize({ trim: true, escape: true })
21
- * class MyController {
22
- * // ...
23
- * }
23
+ * @returns A class or method decorator.
24
24
  *
25
25
  * @example
26
- * // Apply multiple sanitization rules to a specific method
27
- * @Sanitize([
28
- * { trim: true },
29
- * { escape: true }
30
- * ])
31
- * async myMethod() {
32
- * // ...
33
- * }
34
- *
35
- * @remarks
36
- * The metadata key used for storing the sanitization configurations is defined by `SANITIZE`.
37
- * This metadata is accessible via Reflect API and used internally by the framework
38
- * to apply sanitization logic.
26
+ * @Sanitize({
27
+ * type: 'body',
28
+ * action: 'both',
29
+ * schema: Joi.object({ email: SANITIZER.string.email(), bio: SANITIZER.xss() }),
30
+ * stripUnknown: true,
31
+ * })
32
+ * class ProfileController {}
39
33
  */
40
- export declare function Sanitize(config: SanitizerConfig | SanitizerConfig[]): (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) => void;
34
+ export declare function Sanitize(config: SanitizerConfig | SanitizerConfig[]): (target: any, propertyKey?: string, _descriptor?: PropertyDescriptor) => void;
package/dist/sanitize.js CHANGED
@@ -3,48 +3,42 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Sanitize = Sanitize;
4
4
  const utils_1 = require("@heliosjs/core/utils");
5
5
  /**
6
- * Decorator to apply sanitization configurations to a controller or method.
6
+ * Runs a Joi schema over one part of the request on a controller class or a
7
+ * single route method. Sanitizers run first in the pipeline (before guards), so
8
+ * every later stage sees the cleaned/validated data.
7
9
  *
8
- * This decorator accepts one or more sanitization configuration objects which define
9
- * how incoming request data should be sanitized before processing. It can be applied
10
- * at the class level to apply sanitization globally to all methods or at the method level
11
- * for fine-grained control.
10
+ * Depending on `action` a config either validates (throws on mismatch),
11
+ * sanitizes (coerces/strips and writes the result back onto the request), or
12
+ * both. The `SANITIZER` helper from `@heliosjs/core` provides ready-made Joi
13
+ * builders (`SANITIZER.string.email()`, `SANITIZER.xss()`, …).
12
14
  *
13
- * The sanitization configurations are stored as metadata on the target or method,
14
- * which can be retrieved by the framework to perform the actual sanitization during
15
- * request handling.
15
+ * @param config - One `SanitizerConfig`, or an array applied in order. Each has:
16
+ * - `schema` (**required**) a `Joi.Schema` to run.
17
+ * - `type` (**required**) — which request part to target, one of
18
+ * `'body'`, `'query'`, `'params'`, `'headers'`.
19
+ * - `action` — `'validate'` (reject on error), `'sanitize'` (transform in
20
+ * place), or `'both'`. Default `'both'`.
21
+ * - `options` — Joi `ValidationOptions` passed through.
22
+ * - `stripUnknown` — drop keys not in the schema.
23
+ * Why an array: apply different schemas to different request parts on the same
24
+ * route.
16
25
  *
17
- * @param {SanitizerConfig | SanitizerConfig[]} sanitizeConfig - A single or array of sanitization configuration objects.
18
- *
19
- * @returns {Function} A decorator function that applies the sanitization metadata.
20
- *
21
- * @example
22
- * // Apply sanitization to all methods in a controller
23
- * @Sanitize({ trim: true, escape: true })
24
- * class MyController {
25
- * // ...
26
- * }
26
+ * @returns A class or method decorator.
27
27
  *
28
28
  * @example
29
- * // Apply multiple sanitization rules to a specific method
30
- * @Sanitize([
31
- * { trim: true },
32
- * { escape: true }
33
- * ])
34
- * async myMethod() {
35
- * // ...
36
- * }
37
- *
38
- * @remarks
39
- * The metadata key used for storing the sanitization configurations is defined by `SANITIZE`.
40
- * This metadata is accessible via Reflect API and used internally by the framework
41
- * to apply sanitization logic.
29
+ * @Sanitize({
30
+ * type: 'body',
31
+ * action: 'both',
32
+ * schema: Joi.object({ email: SANITIZER.string.email(), bio: SANITIZER.xss() }),
33
+ * stripUnknown: true,
34
+ * })
35
+ * class ProfileController {}
42
36
  */
43
37
  function Sanitize(config) {
44
- return function (target, propertyKey, descriptor) {
38
+ return function (target, propertyKey, _descriptor) {
45
39
  const sanitizers = Array.isArray(config) ? config : [config];
46
40
  const data = sanitizers.map(sanitizer => ({ sanitizer }));
47
- if (descriptor) {
41
+ if (propertyKey) {
48
42
  (0, utils_1.defineMiddlewaresMeta)(data, target, propertyKey);
49
43
  }
50
44
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":";;AAwCA,4BAWC;AAlDD,gDAA6D;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,SAAgB,QAAQ,CAAC,MAA2C;IAClE,OAAO,UAAU,MAAW,EAAE,WAAoB,EAAE,UAA+B;QACjF,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QAE1D,IAAI,UAAU,EAAE,CAAC;YACf,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":";;AAkCA,4BAWC;AA5CD,gDAA6D;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,SAAgB,QAAQ,CAAC,MAA2C;IAClE,OAAO,UAAU,MAAW,EAAE,WAAoB,EAAE,WAAgC;QAClF,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QAE1D,IAAI,WAAW,EAAE,CAAC;YAChB,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
package/dist/status.d.ts CHANGED
@@ -1,35 +1,23 @@
1
1
  /**
2
- * Decorator to set the HTTP status code for the response.
2
+ * Sets the HTTP status code for successful responses from a controller class or a
3
+ * single route method. Method-level wins over class-level. Without it a
4
+ * successful handler responds `200` (or the code you set via `res.status`).
3
5
  *
4
- * This decorator can be applied at the method level to specify the HTTP status code
5
- * that should be returned when the method's response is sent. It can also be applied
6
- * at the class level to set a default status code for all methods within the class.
6
+ * This only affects the success path errors still carry the status of the
7
+ * thrown `HeliosError`, and an explicit `res.redirect()` keeps its own code.
7
8
  *
8
- * The status code is stored as metadata on the target or method, which can be retrieved
9
- * by the framework to set the HTTP response status accordingly.
9
+ * @param status - The HTTP status code to send, e.g. `201` for a create, `202`
10
+ * for an accepted async job, `204` for an empty body. Why: express REST
11
+ * semantics without touching the `Response` object.
10
12
  *
11
- * @param {number} status - The HTTP status code to set for the response.
12
- *
13
- * @returns {Function} A decorator function that applies the status code metadata.
13
+ * @returns A class or method decorator.
14
14
  *
15
15
  * @example
16
- * // Set status code 201 for a specific method
17
- * @Status(201)
18
- * async createResource() {
19
- * // ...
16
+ * class UserController {
17
+ * @Post('/')
18
+ * @Status(201)
19
+ * create(@Body() dto: CreateUserDto) {}
20
20
  * }
21
- *
22
- * @example
23
- * // Set default status code 204 for all methods in a controller
24
- * @Status(204)
25
- * class MyController {
26
- * // ...
27
- * }
28
- *
29
- * @remarks
30
- * The metadata key used for storing the status code is defined by `OK_METADATA_KEY`.
31
- * This metadata is accessible via Reflect API and used internally by the framework
32
- * to set the HTTP response status.
33
21
  */
34
22
  export declare function Status(status: number): (target: any, propertyKey?: string) => void;
35
23
  /**
package/dist/status.js CHANGED
@@ -4,43 +4,34 @@ exports.Ok204 = exports.Ok201 = exports.Ok200 = void 0;
4
4
  exports.Status = Status;
5
5
  const utils_1 = require("@heliosjs/core/utils");
6
6
  /**
7
- * Decorator to set the HTTP status code for the response.
7
+ * Sets the HTTP status code for successful responses from a controller class or a
8
+ * single route method. Method-level wins over class-level. Without it a
9
+ * successful handler responds `200` (or the code you set via `res.status`).
8
10
  *
9
- * This decorator can be applied at the method level to specify the HTTP status code
10
- * that should be returned when the method's response is sent. It can also be applied
11
- * at the class level to set a default status code for all methods within the class.
11
+ * This only affects the success path errors still carry the status of the
12
+ * thrown `HeliosError`, and an explicit `res.redirect()` keeps its own code.
12
13
  *
13
- * The status code is stored as metadata on the target or method, which can be retrieved
14
- * by the framework to set the HTTP response status accordingly.
14
+ * @param status - The HTTP status code to send, e.g. `201` for a create, `202`
15
+ * for an accepted async job, `204` for an empty body. Why: express REST
16
+ * semantics without touching the `Response` object.
15
17
  *
16
- * @param {number} status - The HTTP status code to set for the response.
17
- *
18
- * @returns {Function} A decorator function that applies the status code metadata.
19
- *
20
- * @example
21
- * // Set status code 201 for a specific method
22
- * @Status(201)
23
- * async createResource() {
24
- * // ...
25
- * }
18
+ * @returns A class or method decorator.
26
19
  *
27
20
  * @example
28
- * // Set default status code 204 for all methods in a controller
29
- * @Status(204)
30
- * class MyController {
31
- * // ...
21
+ * class UserController {
22
+ * @Post('/')
23
+ * @Status(201)
24
+ * create(@Body() dto: CreateUserDto) {}
32
25
  * }
33
- *
34
- * @remarks
35
- * The metadata key used for storing the status code is defined by `OK_METADATA_KEY`.
36
- * This metadata is accessible via Reflect API and used internally by the framework
37
- * to set the HTTP response status.
38
26
  */
39
27
  function Status(status) {
40
28
  return function (target, propertyKey) {
41
29
  if (propertyKey) {
42
30
  (0, utils_1.defineMiddlewaresMeta)([{ status }], target, propertyKey);
43
31
  }
32
+ else {
33
+ (0, utils_1.defineMiddlewaresMeta)([{ status }], target);
34
+ }
44
35
  };
45
36
  }
46
37
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":";;;AAkCA,wBAMC;AAxCD,gDAA6D;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,SAAgB,MAAM,CAAC,MAAc;IACnC,OAAO,UAAU,MAAW,EAAE,WAAoB;QAChD,IAAI,WAAW,EAAE,CAAC;YAChB,IAAA,6BAAqB,EAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACI,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAA1B,QAAA,KAAK,SAAqB;AAEvC;;;;;;;GAOG;AACI,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAA1B,QAAA,KAAK,SAAqB;AAEvC;;;;;;;;GAQG;AACI,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAA1B,QAAA,KAAK,SAAqB"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":";;;AAsBA,wBAQC;AA9BD,gDAA6D;AAC7D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAgB,MAAM,CAAC,MAAc;IACnC,OAAO,UAAU,MAAW,EAAE,WAAoB;QAChD,IAAI,WAAW,EAAE,CAAC;YAChB,IAAA,6BAAqB,EAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACN,IAAA,6BAAqB,EAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACI,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAA1B,QAAA,KAAK,SAAqB;AAEvC;;;;;;;GAOG;AACI,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAA1B,QAAA,KAAK,SAAqB;AAEvC;;;;;;;;GAQG;AACI,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAA1B,QAAA,KAAK,SAAqB"}
package/dist/use.d.ts CHANGED
@@ -1,46 +1,25 @@
1
1
  import type { MiddlewareCB } from '@heliosjs/core/types';
2
2
  /**
3
- * Decorator to register middleware(s) at the controller or method level.
3
+ * Registers one or more middlewares on a controller class or a single route
4
+ * method. Middlewares run before the handler, in declaration order, after guards
5
+ * and pipes in the request pipeline. Calling `next(err)` with an error aborts the
6
+ * request; not calling `next` still proceeds (the pipeline advances once the
7
+ * middleware resolves).
4
8
  *
5
- * Middlewares are functions executed before the route handler.
6
- * They can be used to:
7
- * - modify request/response
8
- * - perform logging
9
- * - handle authentication/authorization
10
- * - short-circuit request handling
9
+ * Applied to a class, the middleware covers every route in it (and its child
10
+ * controllers); applied to a method, only that route.
11
11
  *
12
- * @param middleware - A single middleware function or an array of middleware functions.
12
+ * @param middleware - A middleware callback `(req, res, next) => void | Promise<void>`,
13
+ * or an array of them applied in order. Why: attach auth, logging, request
14
+ * shaping, or short-circuit logic without hand-wiring it into each handler.
13
15
  *
14
- * @returns A decorator that attaches middleware metadata to the target
15
- * (either a class or a method).
16
+ * @returns A class or method decorator.
16
17
  *
17
18
  * @example
18
- * // Single middleware
19
- * @Use((req, res, next) => {
20
- * console.log('Request received');
21
- * next();
22
- * })
23
- * class MyController {}
24
- *
25
- * @example
26
- * // Multiple middlewares
27
- * @Use([
28
- * authMiddleware,
29
- * loggingMiddleware,
30
- * ])
31
- * class MyController {}
32
- *
33
- * @example
34
- * // Method-level middleware
19
+ * @Use([authMiddleware, loggingMiddleware])
35
20
  * class MyController {
36
- * @Use(authMiddleware)
21
+ * @Use(rateLimitMiddleware)
37
22
  * getData() {}
38
23
  * }
39
- *
40
- * @remarks
41
- * - Middlewares are executed in the order they are defined.
42
- * - Can be applied at both class and method levels.
43
- * - Metadata is stored using the MIDDLEWARES_CONFIG key and used
44
- * internally by the framework during request handling.
45
24
  */
46
- export declare function Use(middleware: MiddlewareCB | MiddlewareCB[]): (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) => any;
25
+ export declare function Use(middleware: MiddlewareCB | MiddlewareCB[]): (target: any, propertyKey?: string, _descriptor?: PropertyDescriptor) => any;
package/dist/use.js CHANGED
@@ -3,51 +3,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Use = Use;
4
4
  const utils_1 = require("@heliosjs/core/utils");
5
5
  /**
6
- * Decorator to register middleware(s) at the controller or method level.
6
+ * Registers one or more middlewares on a controller class or a single route
7
+ * method. Middlewares run before the handler, in declaration order, after guards
8
+ * and pipes in the request pipeline. Calling `next(err)` with an error aborts the
9
+ * request; not calling `next` still proceeds (the pipeline advances once the
10
+ * middleware resolves).
7
11
  *
8
- * Middlewares are functions executed before the route handler.
9
- * They can be used to:
10
- * - modify request/response
11
- * - perform logging
12
- * - handle authentication/authorization
13
- * - short-circuit request handling
12
+ * Applied to a class, the middleware covers every route in it (and its child
13
+ * controllers); applied to a method, only that route.
14
14
  *
15
- * @param middleware - A single middleware function or an array of middleware functions.
15
+ * @param middleware - A middleware callback `(req, res, next) => void | Promise<void>`,
16
+ * or an array of them applied in order. Why: attach auth, logging, request
17
+ * shaping, or short-circuit logic without hand-wiring it into each handler.
16
18
  *
17
- * @returns A decorator that attaches middleware metadata to the target
18
- * (either a class or a method).
19
+ * @returns A class or method decorator.
19
20
  *
20
21
  * @example
21
- * // Single middleware
22
- * @Use((req, res, next) => {
23
- * console.log('Request received');
24
- * next();
25
- * })
26
- * class MyController {}
27
- *
28
- * @example
29
- * // Multiple middlewares
30
- * @Use([
31
- * authMiddleware,
32
- * loggingMiddleware,
33
- * ])
34
- * class MyController {}
35
- *
36
- * @example
37
- * // Method-level middleware
22
+ * @Use([authMiddleware, loggingMiddleware])
38
23
  * class MyController {
39
- * @Use(authMiddleware)
24
+ * @Use(rateLimitMiddleware)
40
25
  * getData() {}
41
26
  * }
42
- *
43
- * @remarks
44
- * - Middlewares are executed in the order they are defined.
45
- * - Can be applied at both class and method levels.
46
- * - Metadata is stored using the MIDDLEWARES_CONFIG key and used
47
- * internally by the framework during request handling.
48
27
  */
49
28
  function Use(middleware) {
50
- return function (target, propertyKey, descriptor) {
29
+ return function (target, propertyKey, _descriptor) {
51
30
  const middlewares = Array.isArray(middleware) ? middleware : [middleware];
52
31
  const data = middlewares.map((middleware) => ({ middleware }));
53
32
  if (propertyKey) {
package/dist/use.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"use.js","sourceRoot":"","sources":["../src/use.ts"],"names":[],"mappings":";;AA+CA,kBAcC;AA5DD,gDAA6D;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,SAAgB,GAAG,CAAC,UAAyC;IAC3D,OAAO,UAAU,MAAW,EAAE,WAAoB,EAAE,UAA+B;QACjF,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAE1E,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;QAE/D,IAAI,WAAW,EAAE,CAAC;YAChB,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"use.js","sourceRoot":"","sources":["../src/use.ts"],"names":[],"mappings":";;AA0BA,kBAcC;AAvCD,gDAA6D;AAE7D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,SAAgB,GAAG,CAAC,UAAyC;IAC3D,OAAO,UAAU,MAAW,EAAE,WAAoB,EAAE,WAAgC;QAClF,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAE1E,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;QAE/D,IAAI,WAAW,EAAE,CAAC;YAChB,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,IAAA,6BAAqB,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heliosjs/middlewares",
3
- "version": "10.0.5",
3
+ "version": "10.0.8",
4
4
  "description": "Middlewares for @heliosjs",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -30,7 +30,7 @@
30
30
  "reflect-metadata": "^0.2.2"
31
31
  },
32
32
  "peerDependencies": {
33
- "@heliosjs/core": "^3.2.8",
33
+ "@heliosjs/core": "^3.2.11",
34
34
  "@types/node": ">=20.0.0",
35
35
  "reflect-metadata": "^0.2.2",
36
36
  "typescript": ">=5.0.0"