@daloyjs/core 1.0.0-beta.6 → 1.0.0-beta.7

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.
Files changed (99) hide show
  1. package/README.md +2 -2
  2. package/dist/adapters/bun.d.ts +13 -1
  3. package/dist/adapters/bun.js +8 -1
  4. package/dist/adapters/cloudflare.d.ts +7 -1
  5. package/dist/adapters/cloudflare.js +6 -1
  6. package/dist/adapters/deno.d.ts +11 -1
  7. package/dist/adapters/deno.js +8 -1
  8. package/dist/adapters/fastly.d.ts +12 -2
  9. package/dist/adapters/fastly.js +12 -2
  10. package/dist/adapters/lambda.d.ts +37 -1
  11. package/dist/adapters/lambda.js +6 -1
  12. package/dist/adapters/node.d.ts +12 -1
  13. package/dist/adapters/node.js +7 -1
  14. package/dist/adapters/vercel.d.ts +13 -1
  15. package/dist/adapters/vercel.js +12 -1
  16. package/dist/app.d.ts +67 -17
  17. package/dist/app.js +97 -31
  18. package/dist/banner.d.ts +6 -0
  19. package/dist/banner.js +6 -0
  20. package/dist/cli.d.ts +35 -0
  21. package/dist/cli.js +23 -1
  22. package/dist/combine.d.ts +8 -0
  23. package/dist/combine.js +8 -0
  24. package/dist/compression.d.ts +3 -0
  25. package/dist/compression.js +3 -0
  26. package/dist/config.d.ts +4 -0
  27. package/dist/config.js +4 -0
  28. package/dist/conn-info.d.ts +35 -2
  29. package/dist/conn-info.js +35 -2
  30. package/dist/contract.d.ts +2 -0
  31. package/dist/contract.js +2 -0
  32. package/dist/cookie.d.ts +12 -0
  33. package/dist/cookie.js +12 -0
  34. package/dist/dependency.d.ts +4 -0
  35. package/dist/dependency.js +3 -0
  36. package/dist/discriminator.d.ts +13 -0
  37. package/dist/discriminator.js +23 -1
  38. package/dist/docs.d.ts +78 -0
  39. package/dist/docs.js +21 -0
  40. package/dist/errors.d.ts +16 -0
  41. package/dist/errors.js +14 -0
  42. package/dist/etag.d.ts +2 -0
  43. package/dist/etag.js +2 -0
  44. package/dist/fetch-guard.d.ts +7 -0
  45. package/dist/fetch-guard.js +7 -0
  46. package/dist/fetch-resilience.d.ts +4 -0
  47. package/dist/fetch-resilience.js +4 -0
  48. package/dist/http-signatures.d.ts +32 -0
  49. package/dist/http-signatures.js +30 -0
  50. package/dist/index.d.ts +1 -1
  51. package/dist/ip-restriction.d.ts +40 -3
  52. package/dist/ip-restriction.js +35 -3
  53. package/dist/jwk.d.ts +12 -1
  54. package/dist/jwk.js +6 -0
  55. package/dist/jwt.d.ts +14 -0
  56. package/dist/jwt.js +10 -0
  57. package/dist/load-shedding.d.ts +3 -0
  58. package/dist/load-shedding.js +3 -0
  59. package/dist/logger.d.ts +13 -0
  60. package/dist/logger.js +3 -0
  61. package/dist/mcp.d.ts +152 -10
  62. package/dist/mcp.js +223 -19
  63. package/dist/middleware.d.ts +68 -0
  64. package/dist/middleware.js +17 -0
  65. package/dist/mtls.d.ts +19 -2
  66. package/dist/mtls.js +12 -2
  67. package/dist/multipart.d.ts +42 -5
  68. package/dist/multipart.js +41 -5
  69. package/dist/openapi.d.ts +15 -9
  70. package/dist/openapi.js +6 -9
  71. package/dist/rate-limit-redis.d.ts +21 -2
  72. package/dist/rate-limit-redis.js +17 -2
  73. package/dist/safe-redirect.d.ts +6 -0
  74. package/dist/safe-redirect.js +6 -0
  75. package/dist/sbom.cdx.json +9 -9
  76. package/dist/sbom.spdx.json +5 -5
  77. package/dist/scheduler.d.ts +4 -0
  78. package/dist/schema.d.ts +25 -0
  79. package/dist/security-schemes.d.ts +50 -0
  80. package/dist/security-schemes.js +6 -0
  81. package/dist/security.d.ts +33 -0
  82. package/dist/security.js +28 -10
  83. package/dist/session.d.ts +34 -5
  84. package/dist/session.js +31 -5
  85. package/dist/streaming.d.ts +19 -0
  86. package/dist/streaming.js +16 -0
  87. package/dist/subdomains.d.ts +4 -0
  88. package/dist/subdomains.js +4 -0
  89. package/dist/time-claims.d.ts +22 -2
  90. package/dist/time-claims.js +6 -0
  91. package/dist/tracing.d.ts +12 -0
  92. package/dist/tracing.js +6 -0
  93. package/dist/types.d.ts +70 -1
  94. package/dist/waf.js +21 -1
  95. package/dist/webhook-delivery.d.ts +6 -0
  96. package/dist/webhook-delivery.js +5 -0
  97. package/dist/websocket.d.ts +137 -4
  98. package/dist/websocket.js +105 -4
  99. package/package.json +1 -1
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "bomFormat": "CycloneDX",
3
3
  "specVersion": "1.5",
4
- "serialNumber": "urn:uuid:a88e3a69-b278-5771-a67e-40fb774e004e",
4
+ "serialNumber": "urn:uuid:b5480fcc-c870-525f-bf19-08a30ac9e3d6",
5
5
  "version": 1,
6
6
  "metadata": {
7
- "timestamp": "2026-07-01T22:47:12.881Z",
7
+ "timestamp": "2026-07-02T15:07:00.378Z",
8
8
  "tools": [
9
9
  {
10
10
  "vendor": "DaloyJS",
11
11
  "name": "daloy-generate-sbom",
12
- "version": "1.0.0-beta.6"
12
+ "version": "1.0.0-beta.7"
13
13
  }
14
14
  ],
15
15
  "authors": [
@@ -19,11 +19,11 @@
19
19
  ],
20
20
  "component": {
21
21
  "type": "library",
22
- "bom-ref": "pkg:npm/@daloyjs/core@1.0.0-beta.6",
22
+ "bom-ref": "pkg:npm/@daloyjs/core@1.0.0-beta.7",
23
23
  "name": "@daloyjs/core",
24
- "version": "1.0.0-beta.6",
24
+ "version": "1.0.0-beta.7",
25
25
  "description": "DaloyJS is a runtime-portable, contract-first TypeScript web framework with built-in OpenAPI (Hey API), typed client generation, large-scale maintainability, and security-first defaults. Hono-grade portability, Elysia-grade DX, FastAPI-grade docs, Fastify-grade ops — distributed via pnpm.",
26
- "purl": "pkg:npm/@daloyjs/core@1.0.0-beta.6",
26
+ "purl": "pkg:npm/@daloyjs/core@1.0.0-beta.7",
27
27
  "licenses": [
28
28
  {
29
29
  "license": {
@@ -46,9 +46,9 @@
46
46
  }
47
47
  ],
48
48
  "swid": {
49
- "tagId": "swidtag--daloyjs-core-1.0.0-beta.6",
49
+ "tagId": "swidtag--daloyjs-core-1.0.0-beta.7",
50
50
  "name": "@daloyjs/core",
51
- "version": "1.0.0-beta.6",
51
+ "version": "1.0.0-beta.7",
52
52
  "tagVersion": 0,
53
53
  "patch": false
54
54
  }
@@ -57,7 +57,7 @@
57
57
  "components": [],
58
58
  "dependencies": [
59
59
  {
60
- "ref": "pkg:npm/@daloyjs/core@1.0.0-beta.6",
60
+ "ref": "pkg:npm/@daloyjs/core@1.0.0-beta.7",
61
61
  "dependsOn": []
62
62
  }
63
63
  ]
@@ -2,10 +2,10 @@
2
2
  "spdxVersion": "SPDX-2.3",
3
3
  "dataLicense": "CC0-1.0",
4
4
  "SPDXID": "SPDXRef-DOCUMENT",
5
- "name": "@daloyjs/core-1.0.0-beta.6",
6
- "documentNamespace": "https://github.com/daloyjs/daloy/sbom/@daloyjs/core-1.0.0-beta.6-a88e3a69-b278-5771-a67e-40fb774e004e",
5
+ "name": "@daloyjs/core-1.0.0-beta.7",
6
+ "documentNamespace": "https://github.com/daloyjs/daloy/sbom/@daloyjs/core-1.0.0-beta.7-b5480fcc-c870-525f-bf19-08a30ac9e3d6",
7
7
  "creationInfo": {
8
- "created": "2026-07-01T22:47:12.881Z",
8
+ "created": "2026-07-02T15:07:00.378Z",
9
9
  "creators": [
10
10
  "Tool: daloy-generate-sbom",
11
11
  "Organization: DaloyJS"
@@ -16,7 +16,7 @@
16
16
  {
17
17
  "SPDXID": "SPDXRef-Package--daloyjs-core",
18
18
  "name": "@daloyjs/core",
19
- "versionInfo": "1.0.0-beta.6",
19
+ "versionInfo": "1.0.0-beta.7",
20
20
  "downloadLocation": "https://github.com/daloyjs/daloy",
21
21
  "filesAnalyzed": false,
22
22
  "licenseConcluded": "MIT",
@@ -27,7 +27,7 @@
27
27
  {
28
28
  "referenceCategory": "PACKAGE-MANAGER",
29
29
  "referenceType": "purl",
30
- "referenceLocator": "pkg:npm/@daloyjs/core@1.0.0-beta.6"
30
+ "referenceLocator": "pkg:npm/@daloyjs/core@1.0.0-beta.7"
31
31
  }
32
32
  ]
33
33
  }
@@ -57,9 +57,13 @@ export declare class CronParseError extends Error {
57
57
  * @since 0.37.0
58
58
  */
59
59
  export interface SchedulerLogger {
60
+ /** Log at debug level (task definitions as they are registered). */
60
61
  debug(obj: object | string, msg?: string): void;
62
+ /** Log at info level (scheduler started / stopped lifecycle events). */
61
63
  info(obj: object | string, msg?: string): void;
64
+ /** Log at warn level (overrun-skipped runs, stop grace-period timeouts). */
62
65
  warn(obj: object | string, msg?: string): void;
66
+ /** Log at error level (a task handler threw or rejected). */
63
67
  error(obj: object | string, msg?: string): void;
64
68
  }
65
69
  /**
package/dist/schema.d.ts CHANGED
@@ -7,35 +7,60 @@
7
7
  * `~standard`. No vendor lock-in.
8
8
  */
9
9
  export interface StandardSchemaV1<Input = unknown, Output = Input> {
10
+ /** The Standard Schema contract object every compatible validator exposes. */
10
11
  readonly "~standard": StandardSchemaV1.Props<Input, Output>;
11
12
  }
12
13
  export declare namespace StandardSchemaV1 {
14
+ /**
15
+ * The `~standard` contract exposed by a Standard Schema validator: spec
16
+ * version, vendor tag, and the vendor-neutral `validate` entry point.
17
+ */
13
18
  interface Props<Input = unknown, Output = Input> {
19
+ /** Spec version implemented by the validator. Always `1`. */
14
20
  readonly version: 1;
21
+ /** Name of the validator library (e.g. `"zod"`, `"valibot"`). */
15
22
  readonly vendor: string;
23
+ /** Validates a value; may be sync or async. Returns `{ value }` on success or `{ issues }` on failure. */
16
24
  readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
25
+ /** Type-only carrier for {@link InferInput}/{@link InferOutput}; never populated at runtime. */
17
26
  readonly types?: Types<Input, Output>;
18
27
  }
28
+ /** Outcome of {@link Props.validate}: a {@link SuccessResult} or a {@link FailureResult}. */
19
29
  type Result<Output> = SuccessResult<Output> | FailureResult;
30
+ /** Successful validation: the parsed/coerced output value and no issues. */
20
31
  interface SuccessResult<Output> {
32
+ /** The validated (and possibly transformed) output value. */
21
33
  readonly value: Output;
34
+ /** Always `undefined` on success; lets `result.issues` discriminate the union. */
22
35
  readonly issues?: undefined;
23
36
  }
37
+ /** Failed validation: one or more {@link Issue}s and no output value. */
24
38
  interface FailureResult {
39
+ /** The validation problems found; always non-empty on failure. */
25
40
  readonly issues: ReadonlyArray<Issue>;
26
41
  }
42
+ /** One validation problem reported by a validator. */
27
43
  interface Issue {
44
+ /** Human-readable description of the problem. */
28
45
  readonly message: string;
46
+ /** Location of the problem as a key path from the root; omitted for root-level issues. */
29
47
  readonly path?: ReadonlyArray<PropertyKey | PathSegment>;
30
48
  }
49
+ /** Object-wrapped path entry used by validators that attach extra metadata to path keys. */
31
50
  interface PathSegment {
51
+ /** The property key this segment addresses. */
32
52
  readonly key: PropertyKey;
33
53
  }
54
+ /** Type-level input/output carrier referenced by {@link Props.types}; runtime value is never read. */
34
55
  interface Types<Input, Output> {
56
+ /** The type accepted by the validator before parsing/coercion. */
35
57
  readonly input: Input;
58
+ /** The type produced by the validator after parsing/coercion. */
36
59
  readonly output: Output;
37
60
  }
61
+ /** Infers the input (pre-validation) type of a Standard Schema validator. */
38
62
  type InferInput<S extends StandardSchemaV1> = NonNullable<S["~standard"]["types"]>["input"];
63
+ /** Infers the output (post-validation) type of a Standard Schema validator. */
39
64
  type InferOutput<S extends StandardSchemaV1> = NonNullable<S["~standard"]["types"]>["output"];
40
65
  }
41
66
  /**
@@ -14,66 +14,92 @@ export type ApiKeyLocation = "header" | "query" | "cookie";
14
14
  export interface HttpBearerSchemeOptions {
15
15
  /** Hint about the bearer token format (e.g. "JWT"). */
16
16
  bearerFormat?: string;
17
+ /** Human-readable description shown in the generated docs (CommonMark). */
17
18
  description?: string;
18
19
  /** Require payload/body authentication for routes using this scheme. */
19
20
  requirePayloadAuth?: boolean;
20
21
  }
21
22
  /** Options for {@link httpBasicScheme}. */
22
23
  export interface HttpBasicSchemeOptions {
24
+ /** Human-readable description shown in the generated docs (CommonMark). */
23
25
  description?: string;
24
26
  /** Require payload/body authentication for routes using this scheme. */
25
27
  requirePayloadAuth?: boolean;
26
28
  }
27
29
  /** Options for {@link apiKeyScheme}. */
28
30
  export interface ApiKeySchemeOptions {
31
+ /** Where the key is presented: `"header"`, `"query"`, or `"cookie"`. */
29
32
  in: ApiKeyLocation;
33
+ /** Name of the header, query parameter, or cookie that carries the key. */
30
34
  name: string;
35
+ /** Human-readable description shown in the generated docs (CommonMark). */
31
36
  description?: string;
32
37
  /** Require payload/body authentication for routes using this scheme. */
33
38
  requirePayloadAuth?: boolean;
34
39
  }
35
40
  /** OAuth2 Implicit flow object (deprecated in OAuth 2.1 but still part of OpenAPI). */
36
41
  export interface OAuth2ImplicitFlow {
42
+ /** Authorization endpoint URL (OpenAPI `authorizationUrl`; must be TLS). */
37
43
  authorizationUrl: string;
44
+ /** Optional URL for obtaining refresh tokens. */
38
45
  refreshUrl?: string;
46
+ /** Map of scope name to short description. May be empty. */
39
47
  scopes: Record<string, string>;
40
48
  }
41
49
  /** OAuth2 Resource Owner Password Credentials flow object. */
42
50
  export interface OAuth2PasswordFlow {
51
+ /** Token endpoint URL (OpenAPI `tokenUrl`; must be TLS). */
43
52
  tokenUrl: string;
53
+ /** Optional URL for obtaining refresh tokens. */
44
54
  refreshUrl?: string;
55
+ /** Map of scope name to short description. May be empty. */
45
56
  scopes: Record<string, string>;
46
57
  }
47
58
  /** OAuth2 Client Credentials flow object. */
48
59
  export interface OAuth2ClientCredentialsFlow {
60
+ /** Token endpoint URL (OpenAPI `tokenUrl`; must be TLS). */
49
61
  tokenUrl: string;
62
+ /** Optional URL for obtaining refresh tokens. */
50
63
  refreshUrl?: string;
64
+ /** Map of scope name to short description. May be empty. */
51
65
  scopes: Record<string, string>;
52
66
  }
53
67
  /** OAuth2 Authorization Code flow object (the recommended interactive flow). */
54
68
  export interface OAuth2AuthorizationCodeFlow {
69
+ /** Authorization endpoint URL (OpenAPI `authorizationUrl`; must be TLS). */
55
70
  authorizationUrl: string;
71
+ /** Token endpoint URL (OpenAPI `tokenUrl`; must be TLS). */
56
72
  tokenUrl: string;
73
+ /** Optional URL for obtaining refresh tokens. */
57
74
  refreshUrl?: string;
75
+ /** Map of scope name to short description. May be empty. */
58
76
  scopes: Record<string, string>;
59
77
  }
60
78
  /** Container for all OAuth2 flows supported by a single scheme. At least one entry is required. */
61
79
  export interface OAuth2Flows {
80
+ /** Implicit flow (deprecated in OAuth 2.1; avoid for new APIs). */
62
81
  implicit?: OAuth2ImplicitFlow;
82
+ /** Resource Owner Password Credentials flow. */
63
83
  password?: OAuth2PasswordFlow;
84
+ /** Client Credentials flow (machine-to-machine). */
64
85
  clientCredentials?: OAuth2ClientCredentialsFlow;
86
+ /** Authorization Code flow (the recommended interactive flow). */
65
87
  authorizationCode?: OAuth2AuthorizationCodeFlow;
66
88
  }
67
89
  /** Options for {@link oauth2Scheme}. */
68
90
  export interface OAuth2SchemeOptions {
91
+ /** Supported OAuth2 flows. At least one entry is required. */
69
92
  flows: OAuth2Flows;
93
+ /** Human-readable description shown in the generated docs (CommonMark). */
70
94
  description?: string;
71
95
  /** Require payload/body authentication for routes using this scheme. */
72
96
  requirePayloadAuth?: boolean;
73
97
  }
74
98
  /** Options for {@link openIdConnectScheme}. */
75
99
  export interface OpenIdConnectSchemeOptions {
100
+ /** OpenID Connect Discovery URL (typically ends in `/.well-known/openid-configuration`). */
76
101
  openIdConnectUrl: string;
102
+ /** Human-readable description shown in the generated docs (CommonMark). */
77
103
  description?: string;
78
104
  /** Require payload/body authentication for routes using this scheme. */
79
105
  requirePayloadAuth?: boolean;
@@ -82,38 +108,56 @@ export interface OpenIdConnectSchemeOptions {
82
108
  export declare const REQUIRE_PAYLOAD_AUTH_EXTENSION: "x-daloy-require-payload-auth";
83
109
  /** Mixin shape for schemes that opt into payload authentication via {@link REQUIRE_PAYLOAD_AUTH_EXTENSION}. */
84
110
  export interface RequirePayloadAuthExtension {
111
+ /** Set to `true` when routes using this scheme must also pass payload (signed body) authentication. */
85
112
  readonly [REQUIRE_PAYLOAD_AUTH_EXTENSION]?: true;
86
113
  }
87
114
  /** OpenAPI HTTP Bearer security scheme returned by {@link httpBearerScheme}. */
88
115
  export interface HttpBearerScheme extends RequirePayloadAuthExtension {
116
+ /** OpenAPI security scheme `type` discriminant. Always `"http"`. */
89
117
  type: "http";
118
+ /** HTTP auth scheme name per RFC 9110. Always `"bearer"`. */
90
119
  scheme: "bearer";
120
+ /** Hint about the bearer token format (e.g. "JWT"). */
91
121
  bearerFormat?: string;
122
+ /** Human-readable description shown in the generated docs (CommonMark). */
92
123
  description?: string;
93
124
  }
94
125
  /** OpenAPI HTTP Basic security scheme returned by {@link httpBasicScheme}. */
95
126
  export interface HttpBasicScheme extends RequirePayloadAuthExtension {
127
+ /** OpenAPI security scheme `type` discriminant. Always `"http"`. */
96
128
  type: "http";
129
+ /** HTTP auth scheme name per RFC 9110. Always `"basic"`. */
97
130
  scheme: "basic";
131
+ /** Human-readable description shown in the generated docs (CommonMark). */
98
132
  description?: string;
99
133
  }
100
134
  /** OpenAPI API-key security scheme returned by {@link apiKeyScheme}. */
101
135
  export interface ApiKeyScheme extends RequirePayloadAuthExtension {
136
+ /** OpenAPI security scheme `type` discriminant. Always `"apiKey"`. */
102
137
  type: "apiKey";
138
+ /** Where the key is presented: `"header"`, `"query"`, or `"cookie"`. */
103
139
  in: ApiKeyLocation;
140
+ /** Name of the header, query parameter, or cookie that carries the key. */
104
141
  name: string;
142
+ /** Human-readable description shown in the generated docs (CommonMark). */
105
143
  description?: string;
106
144
  }
107
145
  /** OpenAPI OAuth2 security scheme returned by {@link oauth2Scheme}. */
108
146
  export interface OAuth2Scheme extends RequirePayloadAuthExtension {
147
+ /** OpenAPI security scheme `type` discriminant. Always `"oauth2"`. */
109
148
  type: "oauth2";
149
+ /** Supported OAuth2 flows (at least one entry). */
110
150
  flows: OAuth2Flows;
151
+ /** Human-readable description shown in the generated docs (CommonMark). */
111
152
  description?: string;
112
153
  }
113
154
  /** OpenAPI OpenID Connect security scheme returned by {@link openIdConnectScheme}. */
114
155
  export interface OpenIdConnectScheme extends RequirePayloadAuthExtension {
156
+ /** OpenAPI security scheme `type` discriminant. Always `"openIdConnect"`. */
115
157
  type: "openIdConnect";
158
+ /** OpenID Connect Discovery URL (typically ends in `/.well-known/openid-configuration`). */
116
159
  openIdConnectUrl: string;
160
+ /** Human-readable description shown in the generated docs (CommonMark). */
117
161
  description?: string;
118
162
  }
119
163
  /** Union of every concrete security scheme this module can build. */
@@ -122,12 +166,18 @@ export type SecurityScheme = HttpBearerScheme | HttpBasicScheme | ApiKeyScheme |
122
166
  * Returns `true` when `scheme` opts into payload (signed body) authentication
123
167
  * via either the legacy `requirePayloadAuth` flag or the canonical
124
168
  * {@link REQUIRE_PAYLOAD_AUTH_EXTENSION} OpenAPI extension.
169
+ *
170
+ * @param scheme - Candidate security scheme object (non-objects are tolerated).
171
+ * @returns `true` when payload auth is required; `false` otherwise.
125
172
  */
126
173
  export declare function securitySchemeRequiresPayloadAuth(scheme: unknown): boolean;
127
174
  /**
128
175
  * Normalize a builder output into a spec-compliant OpenAPI security scheme by
129
176
  * stripping the convenience `requirePayloadAuth` flag and emitting the
130
177
  * canonical {@link REQUIRE_PAYLOAD_AUTH_EXTENSION} extension instead.
178
+ *
179
+ * @param scheme - Candidate security scheme object (non-objects pass through untouched).
180
+ * @returns A copy without `requirePayloadAuth` (extension set when it was `true`), or the input itself when no normalization is needed.
131
181
  */
132
182
  export declare function toOpenAPISecurityScheme(scheme: unknown): unknown;
133
183
  /**
@@ -20,6 +20,9 @@ function markRequirePayloadAuth(scheme, options) {
20
20
  * Returns `true` when `scheme` opts into payload (signed body) authentication
21
21
  * via either the legacy `requirePayloadAuth` flag or the canonical
22
22
  * {@link REQUIRE_PAYLOAD_AUTH_EXTENSION} OpenAPI extension.
23
+ *
24
+ * @param scheme - Candidate security scheme object (non-objects are tolerated).
25
+ * @returns `true` when payload auth is required; `false` otherwise.
23
26
  */
24
27
  export function securitySchemeRequiresPayloadAuth(scheme) {
25
28
  if (!scheme || typeof scheme !== "object")
@@ -32,6 +35,9 @@ export function securitySchemeRequiresPayloadAuth(scheme) {
32
35
  * Normalize a builder output into a spec-compliant OpenAPI security scheme by
33
36
  * stripping the convenience `requirePayloadAuth` flag and emitting the
34
37
  * canonical {@link REQUIRE_PAYLOAD_AUTH_EXTENSION} extension instead.
38
+ *
39
+ * @param scheme - Candidate security scheme object (non-objects pass through untouched).
40
+ * @returns A copy without `requirePayloadAuth` (extension set when it was `true`), or the input itself when no normalization is needed.
35
41
  */
36
42
  export function toOpenAPISecurityScheme(scheme) {
37
43
  if (!scheme || typeof scheme !== "object")
@@ -105,6 +105,21 @@ export declare function sanitizeHeaderValue(value: string): string;
105
105
  * @since 0.1.0
106
106
  */
107
107
  export declare function timingSafeEqual(a: string, b: string): boolean;
108
+ /**
109
+ * Generate a cryptographically strong, URL-safe identifier (~22 chars).
110
+ *
111
+ * Uses Web Crypto's `crypto.randomUUID()` when available, falling back to
112
+ * 16 random bytes via `crypto.getRandomValues()`. The last-resort fallback
113
+ * (timestamp + `Math.random()`) only triggers in environments without
114
+ * WebCrypto, which is none of Node 20+/Bun/Deno/Cloudflare Workers/Vercel
115
+ * Edge.
116
+ *
117
+ * Suitable for request ids, session ids, and short-lived correlation tokens.
118
+ * Do not use for long-lived secrets unless you also sign or wrap them.
119
+ *
120
+ * @returns A random URL-safe id string.
121
+ * @since 0.1.0
122
+ */
108
123
  export declare function randomId(): string;
109
124
  /**
110
125
  * Header names that MUST appear at most once on a request per RFC 7230.
@@ -126,6 +141,7 @@ export declare const SMUGGLING_SINGLETON_HEADERS: readonly string[];
126
141
  * Throws {@link BadRequestError} so the framework returns a structured
127
142
  * `400 problem+json` instead of forwarding a smuggling-class request.
128
143
  *
144
+ * @param headers - Normalized request headers to inspect.
129
145
  * @since 0.15.0
130
146
  */
131
147
  export declare function assertNoDuplicateSingletonHeaders(headers: Headers): void;
@@ -163,6 +179,7 @@ export declare const RESERVED_INBOUND_HEADER_PREFIXES: readonly string[];
163
179
  * `400 problem+json` instead of routing a request that may be probing
164
180
  * for an internal-dispatch bypass.
165
181
  *
182
+ * @param headers - Normalized request headers to inspect (names arrive lowercased).
166
183
  * @since 0.36.0
167
184
  */
168
185
  export declare function assertNoReservedInternalHeaders(headers: Headers): void;
@@ -229,6 +246,8 @@ export declare const WEAK_SECRET_STRINGS: readonly string[];
229
246
  * The thrown `Error` includes the `scope` argument (e.g. `"session"`) so
230
247
  * the developer sees which subsystem rejected the secret.
231
248
  *
249
+ * @param secret - Candidate secret value to vet.
250
+ * @param scope - Subsystem name used to prefix the thrown error message.
232
251
  * @since 0.17.0
233
252
  */
234
253
  export declare function assertStrongSecret(secret: unknown, scope: string): void;
@@ -283,6 +302,11 @@ export declare const WEBHOOK_DEFAULT_TOLERANCE_SECONDS = 300;
283
302
  * });
284
303
  * ```
285
304
  *
305
+ * @param opts - Payload, expected signature, shared secret, and optional
306
+ * `algorithm` (defaults to `"sha256"`), `timestamp`, `toleranceSeconds`,
307
+ * and `now` clock for replay-window checks.
308
+ * @returns `true` only when the signature matches the HMAC of the (optionally
309
+ * timestamp-prefixed) payload and the timestamp is within tolerance.
286
310
  * @since 0.15.0
287
311
  */
288
312
  export declare function verifyWebhookSignature(opts: {
@@ -325,6 +349,11 @@ export declare function verifyWebhookSignature(opts: {
325
349
  * companion of {@link verifyWebhookSignature}; useful for tests, for
326
350
  * outbound webhook senders, and for diffing implementations.
327
351
  *
352
+ * @param opts - Payload, shared secret, optional `algorithm` (defaults to
353
+ * `"sha256"`), and optional `timestamp` to bind the signature to.
354
+ * @returns The hex-encoded HMAC digest.
355
+ * @throws TypeError on an unsupported algorithm or malformed timestamp;
356
+ * Error when WebCrypto is unavailable.
328
357
  * @since 0.15.0
329
358
  */
330
359
  export declare function signWebhookPayload(opts: {
@@ -415,6 +444,8 @@ export declare function assertSafeRelativePath(input: string): string;
415
444
  * Returns `true` on the first hit. Use before passing untrusted data
416
445
  * into a query object that may be interpreted as an operator expression.
417
446
  *
447
+ * @param value - Parsed, untrusted JSON value to scan recursively.
448
+ * @returns `true` when any nested key starts with `$`; `false` otherwise.
418
449
  * @since 0.35.0
419
450
  */
420
451
  export declare function hasMongoOperatorKeys(value: unknown): boolean;
@@ -424,6 +455,8 @@ export declare function hasMongoOperatorKeys(value: unknown): boolean;
424
455
  * threading it into a NoSQL driver — closes the
425
456
  * `{"password": {"$ne": null}}` authentication-bypass class of bug.
426
457
  *
458
+ * @param value - Parsed, untrusted JSON value to scan recursively.
459
+ * @throws BadRequestError when any nested key starts with `$`.
427
460
  * @since 0.35.0
428
461
  */
429
462
  export declare function assertNoMongoOperators(value: unknown): void;
package/dist/security.js CHANGED
@@ -197,6 +197,16 @@ export function timingSafeEqual(a, b) {
197
197
  }
198
198
  return mismatch === 0;
199
199
  }
200
+ // Cache the Web Crypto entry points at module load so randomId() doesn't pay
201
+ // for a `globalThis.crypto` + optional-chain property lookup per request.
202
+ // Falls back to the runtime lookup path if Web Crypto is patched/replaced
203
+ // after module load (test harnesses, custom runtimes) — the cache is only
204
+ // trusted when `globalThis.crypto` is still the same reference, otherwise
205
+ // the stubbed object would be silently bypassed.
206
+ const _webCrypto = globalThis.crypto;
207
+ const _randomUUID = _webCrypto && typeof _webCrypto.randomUUID === "function"
208
+ ? _webCrypto.randomUUID.bind(_webCrypto)
209
+ : undefined;
200
210
  /**
201
211
  * Generate a cryptographically strong, URL-safe identifier (~22 chars).
202
212
  *
@@ -212,16 +222,6 @@ export function timingSafeEqual(a, b) {
212
222
  * @returns A random URL-safe id string.
213
223
  * @since 0.1.0
214
224
  */
215
- // Cache the Web Crypto entry points at module load so randomId() doesn't pay
216
- // for a `globalThis.crypto` + optional-chain property lookup per request.
217
- // Falls back to the runtime lookup path if Web Crypto is patched/replaced
218
- // after module load (test harnesses, custom runtimes) — the cache is only
219
- // trusted when `globalThis.crypto` is still the same reference, otherwise
220
- // the stubbed object would be silently bypassed.
221
- const _webCrypto = globalThis.crypto;
222
- const _randomUUID = _webCrypto && typeof _webCrypto.randomUUID === "function"
223
- ? _webCrypto.randomUUID.bind(_webCrypto)
224
- : undefined;
225
225
  export function randomId() {
226
226
  const c = globalThis.crypto;
227
227
  if (c === _webCrypto && _randomUUID !== undefined)
@@ -260,6 +260,7 @@ export const SMUGGLING_SINGLETON_HEADERS = Object.freeze([
260
260
  * Throws {@link BadRequestError} so the framework returns a structured
261
261
  * `400 problem+json` instead of forwarding a smuggling-class request.
262
262
  *
263
+ * @param headers - Normalized request headers to inspect.
263
264
  * @since 0.15.0
264
265
  */
265
266
  export function assertNoDuplicateSingletonHeaders(headers) {
@@ -307,6 +308,7 @@ export const RESERVED_INBOUND_HEADER_PREFIXES = Object.freeze([
307
308
  * `400 problem+json` instead of routing a request that may be probing
308
309
  * for an internal-dispatch bypass.
309
310
  *
311
+ * @param headers - Normalized request headers to inspect (names arrive lowercased).
310
312
  * @since 0.36.0
311
313
  */
312
314
  export function assertNoReservedInternalHeaders(headers) {
@@ -426,6 +428,8 @@ const WEAK_SECRET_SET = new Set(WEAK_SECRET_STRINGS.map((s) => s.toLowerCase()))
426
428
  * The thrown `Error` includes the `scope` argument (e.g. `"session"`) so
427
429
  * the developer sees which subsystem rejected the secret.
428
430
  *
431
+ * @param secret - Candidate secret value to vet.
432
+ * @param scope - Subsystem name used to prefix the thrown error message.
429
433
  * @since 0.17.0
430
434
  */
431
435
  export function assertStrongSecret(secret, scope) {
@@ -603,6 +607,11 @@ function buildSignedPayloadBytes(payload, timestamp) {
603
607
  * });
604
608
  * ```
605
609
  *
610
+ * @param opts - Payload, expected signature, shared secret, and optional
611
+ * `algorithm` (defaults to `"sha256"`), `timestamp`, `toleranceSeconds`,
612
+ * and `now` clock for replay-window checks.
613
+ * @returns `true` only when the signature matches the HMAC of the (optionally
614
+ * timestamp-prefixed) payload and the timestamp is within tolerance.
606
615
  * @since 0.15.0
607
616
  */
608
617
  export async function verifyWebhookSignature(opts) {
@@ -648,6 +657,11 @@ export async function verifyWebhookSignature(opts) {
648
657
  * companion of {@link verifyWebhookSignature}; useful for tests, for
649
658
  * outbound webhook senders, and for diffing implementations.
650
659
  *
660
+ * @param opts - Payload, shared secret, optional `algorithm` (defaults to
661
+ * `"sha256"`), and optional `timestamp` to bind the signature to.
662
+ * @returns The hex-encoded HMAC digest.
663
+ * @throws TypeError on an unsupported algorithm or malformed timestamp;
664
+ * Error when WebCrypto is unavailable.
651
665
  * @since 0.15.0
652
666
  */
653
667
  export async function signWebhookPayload(opts) {
@@ -840,6 +854,8 @@ function walkForMongoOperators(value) {
840
854
  * Returns `true` on the first hit. Use before passing untrusted data
841
855
  * into a query object that may be interpreted as an operator expression.
842
856
  *
857
+ * @param value - Parsed, untrusted JSON value to scan recursively.
858
+ * @returns `true` when any nested key starts with `$`; `false` otherwise.
843
859
  * @since 0.35.0
844
860
  */
845
861
  export function hasMongoOperatorKeys(value) {
@@ -851,6 +867,8 @@ export function hasMongoOperatorKeys(value) {
851
867
  * threading it into a NoSQL driver — closes the
852
868
  * `{"password": {"$ne": null}}` authentication-bypass class of bug.
853
869
  *
870
+ * @param value - Parsed, untrusted JSON value to scan recursively.
871
+ * @throws BadRequestError when any nested key starts with `$`.
854
872
  * @since 0.35.0
855
873
  */
856
874
  export function assertNoMongoOperators(value) {
package/dist/session.d.ts CHANGED
@@ -49,8 +49,11 @@ export interface SessionRecord {
49
49
  * lazily delete expired records.
50
50
  */
51
51
  export interface SessionStore {
52
+ /** Load the record for a session id, or `null` when missing/expired. */
52
53
  get(sid: string): SessionRecord | null | Promise<SessionRecord | null>;
54
+ /** Persist (create or overwrite) the record for a session id. */
53
55
  set(sid: string, record: SessionRecord): void | Promise<void>;
56
+ /** Delete the record for a session id; a no-op when it does not exist. */
54
57
  destroy(sid: string): void | Promise<void>;
55
58
  /** Optional fast-path for rolling sessions; falls back to `set()` if omitted. */
56
59
  touch?(sid: string, expiresAt: number): void | Promise<void>;
@@ -128,9 +131,13 @@ export type SessionContext = {
128
131
  */
129
132
  export declare class MemorySessionStore implements SessionStore {
130
133
  private readonly map;
134
+ /** Load a record; expired records are deleted and reported as `null`. */
131
135
  get(sid: string): SessionRecord | null;
136
+ /** Store (or overwrite) a record for a session id. */
132
137
  set(sid: string, record: SessionRecord): void;
138
+ /** Remove the record for a session id, if present. */
133
139
  destroy(sid: string): void;
140
+ /** Extend an existing record's expiry (ms since epoch) without rewriting data. */
134
141
  touch(sid: string, expiresAt: number): void;
135
142
  /** Test helper. Remove every record. */
136
143
  clear(): void;
@@ -155,6 +162,14 @@ export declare class MemorySessionStore implements SessionStore {
155
162
  * const app = new App();
156
163
  * app.use(session({ secret: process.env.SESSION_SECRET! }));
157
164
  * ```
165
+ *
166
+ * @param opts Secrets, cookie attributes, store, TTL, and rolling behavior;
167
+ * see {@link SessionOptions}. Cookies default to `__Host-` prefixed,
168
+ * `HttpOnly`, `Secure`, `SameSite=Lax`.
169
+ * @returns A {@link Hooks} object that loads/verifies the session before the
170
+ * handler and persists mutations plus the `Set-Cookie` header afterwards.
171
+ * @throws Error at setup time on missing/short secrets, invalid cookie
172
+ * attribute combinations, or a non-positive `ttlSeconds`.
158
173
  */
159
174
  export declare function session(opts: SessionOptions): Hooks;
160
175
  /** Options for {@link rotateSession}. */
@@ -177,18 +192,32 @@ export interface RotateSessionOptions {
177
192
  * session key-rotation arrays: old cookies verify with any configured secret
178
193
  * and rotated cookies are re-signed with the first/current secret.
179
194
  *
195
+ * @param opts Which session keys (or computed value) to watch, and whether
196
+ * payload data survives rotation (`keepData`, default `true`); see
197
+ * {@link RotateSessionOptions}.
198
+ * @returns A {@link Hooks} object that snapshots the watched value before the
199
+ * handler and regenerates the session id when it changed afterwards
200
+ * (session-fixation defense).
180
201
  * @since 0.23.0
181
202
  */
182
203
  export declare function rotateSession(opts?: RotateSessionOptions): Hooks;
183
204
  /**
184
- * Sign an arbitrary string with HMAC-SHA256. Returns `${value}.${sig}` where
185
- * `sig` is URL-safe base64. Useful for building custom signed cookies or
186
- * tokens that do not need a session store.
205
+ * Sign an arbitrary string with HMAC-SHA256. Useful for building custom
206
+ * signed cookies or tokens that do not need a session store.
207
+ *
208
+ * @param value String to sign; must not contain `.` (the separator).
209
+ * @param secret HMAC key, at least 16 characters.
210
+ * @returns `${value}.${sig}` where `sig` is URL-safe base64.
211
+ * @throws Error when `value` contains `.` or the secret is too short.
187
212
  */
188
213
  export declare function signValue(value: string, secret: string): Promise<string>;
189
214
  /**
190
- * Verify a `signValue()`-produced string. Returns the original value when the
191
- * signature checks out, otherwise `null`. Constant-time on the signature.
215
+ * Verify a `signValue()`-produced string. Constant-time on the signature
216
+ * comparison.
217
+ *
218
+ * @param signed The `${value}.${sig}` string to verify.
219
+ * @param secret HMAC key(s); an array lets rotated old secrets still verify.
220
+ * @returns The original value when any secret's signature matches, else `null`.
192
221
  */
193
222
  export declare function verifySignedValue(signed: string, secret: string | string[]): Promise<string | null>;
194
223
  /** Type-augmentation helper: `interface AppState extends SessionState {}`. */