@daloyjs/core 1.0.0-beta.6 → 1.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/adapters/bun.d.ts +13 -1
- package/dist/adapters/bun.js +8 -1
- package/dist/adapters/cloudflare.d.ts +7 -1
- package/dist/adapters/cloudflare.js +6 -1
- package/dist/adapters/deno.d.ts +11 -1
- package/dist/adapters/deno.js +8 -1
- package/dist/adapters/fastly.d.ts +12 -2
- package/dist/adapters/fastly.js +12 -2
- package/dist/adapters/lambda.d.ts +37 -1
- package/dist/adapters/lambda.js +6 -1
- package/dist/adapters/node.d.ts +12 -1
- package/dist/adapters/node.js +223 -12
- package/dist/adapters/vercel.d.ts +13 -1
- package/dist/adapters/vercel.js +12 -1
- package/dist/app.d.ts +78 -17
- package/dist/app.js +444 -86
- package/dist/banner.d.ts +6 -0
- package/dist/banner.js +6 -0
- package/dist/cli.d.ts +35 -0
- package/dist/cli.js +23 -1
- package/dist/combine.d.ts +8 -0
- package/dist/combine.js +8 -0
- package/dist/compression.d.ts +3 -0
- package/dist/compression.js +3 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.js +4 -0
- package/dist/conn-info.d.ts +35 -2
- package/dist/conn-info.js +35 -2
- package/dist/contract.d.ts +2 -0
- package/dist/contract.js +2 -0
- package/dist/cookie.d.ts +12 -0
- package/dist/cookie.js +12 -0
- package/dist/dependency.d.ts +4 -0
- package/dist/dependency.js +3 -0
- package/dist/discriminator.d.ts +13 -0
- package/dist/discriminator.js +23 -1
- package/dist/docs.d.ts +78 -0
- package/dist/docs.js +21 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.js +14 -0
- package/dist/etag.d.ts +2 -0
- package/dist/etag.js +2 -0
- package/dist/fetch-guard.d.ts +7 -0
- package/dist/fetch-guard.js +7 -0
- package/dist/fetch-resilience.d.ts +4 -0
- package/dist/fetch-resilience.js +4 -0
- package/dist/http-signatures.d.ts +32 -0
- package/dist/http-signatures.js +30 -0
- package/dist/index.d.ts +1 -1
- package/dist/ip-restriction.d.ts +40 -3
- package/dist/ip-restriction.js +35 -3
- package/dist/jwk.d.ts +12 -1
- package/dist/jwk.js +6 -0
- package/dist/jwt.d.ts +14 -0
- package/dist/jwt.js +10 -0
- package/dist/load-shedding.d.ts +3 -0
- package/dist/load-shedding.js +3 -0
- package/dist/logger.d.ts +13 -0
- package/dist/logger.js +3 -0
- package/dist/mcp.d.ts +152 -10
- package/dist/mcp.js +223 -19
- package/dist/middleware.d.ts +68 -0
- package/dist/middleware.js +17 -0
- package/dist/mtls.d.ts +19 -2
- package/dist/mtls.js +12 -2
- package/dist/multipart.d.ts +42 -5
- package/dist/multipart.js +41 -5
- package/dist/openapi.d.ts +15 -9
- package/dist/openapi.js +6 -9
- package/dist/rate-limit-redis.d.ts +21 -2
- package/dist/rate-limit-redis.js +17 -2
- package/dist/safe-redirect.d.ts +6 -0
- package/dist/safe-redirect.js +6 -0
- package/dist/sbom.cdx.json +9 -9
- package/dist/sbom.spdx.json +5 -5
- package/dist/scheduler.d.ts +4 -0
- package/dist/schema.d.ts +25 -0
- package/dist/security-schemes.d.ts +50 -0
- package/dist/security-schemes.js +6 -0
- package/dist/security.d.ts +33 -0
- package/dist/security.js +28 -10
- package/dist/session.d.ts +34 -5
- package/dist/session.js +31 -5
- package/dist/streaming.d.ts +19 -0
- package/dist/streaming.js +16 -0
- package/dist/subdomains.d.ts +4 -0
- package/dist/subdomains.js +4 -0
- package/dist/time-claims.d.ts +22 -2
- package/dist/time-claims.js +6 -0
- package/dist/tracing.d.ts +12 -0
- package/dist/tracing.js +6 -0
- package/dist/types.d.ts +70 -1
- package/dist/waf.js +21 -1
- package/dist/webhook-delivery.d.ts +6 -0
- package/dist/webhook-delivery.js +5 -0
- package/dist/websocket.d.ts +137 -4
- package/dist/websocket.js +105 -4
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export { validate, isStandardSchema } from "./schema.js";
|
|
|
20
20
|
export { diffOpenAPI, hasBreakingChanges } from "./openapi-diff.js";
|
|
21
21
|
export type { ChangeSeverity, OpenAPIChange, OpenAPIDiffResult } from "./openapi-diff.js";
|
|
22
22
|
export { MCP_DEFAULT_MAX_BODY_BYTES, MCP_PROTOCOL_VERSION, MCP_PROTOCOL_VERSIONS, McpToolError, createMcpHandler, mcpRoutes, } from "./mcp.js";
|
|
23
|
-
export type { McpContent, McpEmbeddedResourceContent, McpHandler, McpHandlerOptions, McpImageContent, McpJsonObject, McpJsonRpcId, McpJsonSchema, McpJsonValue, McpPrompt, McpPromptArgument, McpPromptDefinition, McpPromptMessage, McpPromptResult, McpRequestContext, McpResource, McpResourceContents, McpResourceDefinition, McpServerInfo, McpTextContent, McpTool, McpToolHandler, McpToolResult, } from "./mcp.js";
|
|
23
|
+
export type { McpContent, McpEmbeddedResourceContent, McpHandler, McpHandlerOptions, McpIcon, McpImageContent, McpJsonObject, McpJsonRpcId, McpJsonSchema, McpJsonValue, McpPrompt, McpPromptArgument, McpPromptDefinition, McpPromptMessage, McpPromptResult, McpRequestContext, McpResource, McpResourceContents, McpResourceDefinition, McpResourceTemplate, McpResourceTemplateDefinition, McpServerInfo, McpTextContent, McpTool, McpToolAnnotations, McpToolHandler, McpToolResult, } from "./mcp.js";
|
|
24
24
|
export { readBodyLimited, safeJsonParse, isForbiddenObjectKey, sanitizeHeaderName, sanitizeHeaderValue, timingSafeEqual, randomId, assertNoDuplicateSingletonHeaders, assertNoReservedInternalHeaders, assertHeaderCountWithinLimit, DEFAULT_MAX_HEADER_COUNT, RESERVED_INBOUND_HEADER_PREFIXES, SMUGGLING_SINGLETON_HEADERS, verifyWebhookSignature, signWebhookPayload, WEBHOOK_DEFAULT_TOLERANCE_SECONDS, assertStrongSecret, MIN_PROD_SECRET_BYTES, WEAK_SECRET_STRINGS, sanitizeFilename, assertSafeRelativePath, hasMongoOperatorKeys, assertNoMongoOperators, } from "./security.js";
|
|
25
25
|
export type { WebhookHmacAlgorithm } from "./security.js";
|
|
26
26
|
export { requestId, secureHeaders, SECURE_HEADERS_MARKER, cors, CORS_HOOK_MARKER, CORS_ORIGIN_ALLOW_MARKER, CORS_WILDCARD_ORIGIN_MARKER, rateLimit, loginThrottle, timing, bearerAuth, basicAuth, csrf, CSRF_HOOK_MARKER, fetchMetadata, requireScopes, REQUIRE_SCOPES_AGGREGATE_KEY, REQUIRE_SCOPES_HOOK_MARKER, _resetSharedRateLimitStoresForTests, } from "./middleware.js";
|
package/dist/ip-restriction.d.ts
CHANGED
|
@@ -53,13 +53,18 @@ export interface IpRestrictionOptions {
|
|
|
53
53
|
}
|
|
54
54
|
/** @internal Parsed IP address (shared with `fetchGuard()`). */
|
|
55
55
|
export interface ParsedIp {
|
|
56
|
+
/** Big-endian address bytes: 4 bytes for IPv4, 16 for IPv6. */
|
|
56
57
|
bytes: Uint8Array;
|
|
58
|
+
/** Address family: `4` for IPv4, `6` for IPv6. */
|
|
57
59
|
family: 4 | 6;
|
|
58
60
|
}
|
|
59
61
|
/** @internal Compiled CIDR matcher (shared with `fetchGuard()`). */
|
|
60
62
|
export interface IpMatcher {
|
|
63
|
+
/** Address family the matcher applies to: `4` or `6`. */
|
|
61
64
|
family: 4 | 6;
|
|
65
|
+
/** CIDR prefix length in bits (0-32 for IPv4, 0-128 for IPv6). */
|
|
62
66
|
prefix: number;
|
|
67
|
+
/** Network address bytes with all host bits masked to zero. */
|
|
63
68
|
bytes: Uint8Array;
|
|
64
69
|
}
|
|
65
70
|
/**
|
|
@@ -80,12 +85,44 @@ export interface IpMatcher {
|
|
|
80
85
|
* On reject the middleware throws a {@link ForbiddenError}, which Daloy
|
|
81
86
|
* renders as RFC 9457 `application/problem+json`.
|
|
82
87
|
*
|
|
88
|
+
* @param opts Allow/deny lists plus IP-resolution options; see
|
|
89
|
+
* {@link IpRestrictionOptions}. Deny matches always win over allow.
|
|
90
|
+
* @returns A {@link Hooks} object whose `beforeHandle` enforces the lists,
|
|
91
|
+
* failing closed (403) when the client IP cannot be resolved or parsed.
|
|
92
|
+
* @throws Error at setup time when neither `allow` nor `deny` is provided,
|
|
93
|
+
* or when a pattern is not a valid IP/CIDR.
|
|
83
94
|
* @since 0.19.0
|
|
84
95
|
*/
|
|
85
96
|
export declare function ipRestriction(opts: IpRestrictionOptions): Hooks;
|
|
86
|
-
/**
|
|
97
|
+
/**
|
|
98
|
+
* Test whether a parsed IP falls inside a compiled CIDR matcher, comparing
|
|
99
|
+
* only the matcher's prefix bits. IPv4-mapped IPv6 addresses
|
|
100
|
+
* (`::ffff:a.b.c.d`) are normalized so they match IPv4 matchers.
|
|
101
|
+
*
|
|
102
|
+
* @param ip Parsed client address from {@link parseIp}.
|
|
103
|
+
* @param m Compiled matcher from {@link compileCidrMatcher}.
|
|
104
|
+
* @returns `true` when the address is within the matcher's range.
|
|
105
|
+
* @internal
|
|
106
|
+
*/
|
|
87
107
|
export declare function matchesMatcher(ip: ParsedIp, m: IpMatcher): boolean;
|
|
88
|
-
/**
|
|
108
|
+
/**
|
|
109
|
+
* Compile an IP or CIDR pattern (e.g. `"10.0.0.0/8"`, `"::1"`) into an
|
|
110
|
+
* {@link IpMatcher}. A bare address gets a full-length prefix (/32 or /128);
|
|
111
|
+
* host bits beyond the prefix are masked to zero.
|
|
112
|
+
*
|
|
113
|
+
* @param input IPv4/IPv6 address, optionally with a `/prefix` suffix.
|
|
114
|
+
* @returns The compiled matcher used by {@link matchesMatcher}.
|
|
115
|
+
* @throws Error when the address or CIDR prefix is invalid.
|
|
116
|
+
* @internal
|
|
117
|
+
*/
|
|
89
118
|
export declare function compileCidrMatcher(input: string): IpMatcher;
|
|
90
|
-
/**
|
|
119
|
+
/**
|
|
120
|
+
* Parse an IPv4 or IPv6 address string into raw bytes. Supports IPv6 `::`
|
|
121
|
+
* compression and IPv4-mapped tails (`::ffff:1.2.3.4`).
|
|
122
|
+
*
|
|
123
|
+
* @param input Address string; surrounding whitespace is trimmed.
|
|
124
|
+
* @returns The parsed address, or `undefined` when the input is not a valid
|
|
125
|
+
* IP (callers treat unparseable addresses as a rejection, failing closed).
|
|
126
|
+
* @internal
|
|
127
|
+
*/
|
|
91
128
|
export declare function parseIp(input: string): ParsedIp | undefined;
|
package/dist/ip-restriction.js
CHANGED
|
@@ -26,6 +26,12 @@ import { ForbiddenError } from "./errors.js";
|
|
|
26
26
|
* On reject the middleware throws a {@link ForbiddenError}, which Daloy
|
|
27
27
|
* renders as RFC 9457 `application/problem+json`.
|
|
28
28
|
*
|
|
29
|
+
* @param opts Allow/deny lists plus IP-resolution options; see
|
|
30
|
+
* {@link IpRestrictionOptions}. Deny matches always win over allow.
|
|
31
|
+
* @returns A {@link Hooks} object whose `beforeHandle` enforces the lists,
|
|
32
|
+
* failing closed (403) when the client IP cannot be resolved or parsed.
|
|
33
|
+
* @throws Error at setup time when neither `allow` nor `deny` is provided,
|
|
34
|
+
* or when a pattern is not a valid IP/CIDR.
|
|
29
35
|
* @since 0.19.0
|
|
30
36
|
*/
|
|
31
37
|
export function ipRestriction(opts) {
|
|
@@ -64,7 +70,16 @@ function forwardedIpResolver(ctx) {
|
|
|
64
70
|
return forwarded.split(",")[0]?.trim();
|
|
65
71
|
return headers.get("x-real-ip") ?? undefined;
|
|
66
72
|
}
|
|
67
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* Test whether a parsed IP falls inside a compiled CIDR matcher, comparing
|
|
75
|
+
* only the matcher's prefix bits. IPv4-mapped IPv6 addresses
|
|
76
|
+
* (`::ffff:a.b.c.d`) are normalized so they match IPv4 matchers.
|
|
77
|
+
*
|
|
78
|
+
* @param ip Parsed client address from {@link parseIp}.
|
|
79
|
+
* @param m Compiled matcher from {@link compileCidrMatcher}.
|
|
80
|
+
* @returns `true` when the address is within the matcher's range.
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
68
83
|
export function matchesMatcher(ip, m) {
|
|
69
84
|
const candidate = normalizeFamily(ip, m.family);
|
|
70
85
|
if (!candidate)
|
|
@@ -83,7 +98,16 @@ export function matchesMatcher(ip, m) {
|
|
|
83
98
|
const mask = 0xff << (8 - remaining);
|
|
84
99
|
return ((candidate[fullBytes] ^ expected[fullBytes]) & mask) === 0;
|
|
85
100
|
}
|
|
86
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* Compile an IP or CIDR pattern (e.g. `"10.0.0.0/8"`, `"::1"`) into an
|
|
103
|
+
* {@link IpMatcher}. A bare address gets a full-length prefix (/32 or /128);
|
|
104
|
+
* host bits beyond the prefix are masked to zero.
|
|
105
|
+
*
|
|
106
|
+
* @param input IPv4/IPv6 address, optionally with a `/prefix` suffix.
|
|
107
|
+
* @returns The compiled matcher used by {@link matchesMatcher}.
|
|
108
|
+
* @throws Error when the address or CIDR prefix is invalid.
|
|
109
|
+
* @internal
|
|
110
|
+
*/
|
|
87
111
|
export function compileCidrMatcher(input) {
|
|
88
112
|
let addr = input;
|
|
89
113
|
let prefixStr;
|
|
@@ -135,7 +159,15 @@ function applyPrefixMask(bytes, prefix) {
|
|
|
135
159
|
}
|
|
136
160
|
return out;
|
|
137
161
|
}
|
|
138
|
-
/**
|
|
162
|
+
/**
|
|
163
|
+
* Parse an IPv4 or IPv6 address string into raw bytes. Supports IPv6 `::`
|
|
164
|
+
* compression and IPv4-mapped tails (`::ffff:1.2.3.4`).
|
|
165
|
+
*
|
|
166
|
+
* @param input Address string; surrounding whitespace is trimmed.
|
|
167
|
+
* @returns The parsed address, or `undefined` when the input is not a valid
|
|
168
|
+
* IP (callers treat unparseable addresses as a rejection, failing closed).
|
|
169
|
+
* @internal
|
|
170
|
+
*/
|
|
139
171
|
export function parseIp(input) {
|
|
140
172
|
const trimmed = input.trim();
|
|
141
173
|
if (trimmed.includes(":"))
|
package/dist/jwk.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { BaseContext, Hooks } from "./types.js";
|
|
|
4
4
|
export type JwkAlgorithm = Exclude<JwtAlgorithm, "HS256" | "HS384" | "HS512">;
|
|
5
5
|
/** Minimal JWKS document shape (RFC 7517 §5). */
|
|
6
6
|
export interface JwkSet {
|
|
7
|
+
/** Public JWKs; each entry should carry a `kid` so tokens can select their key. */
|
|
7
8
|
keys: JsonWebKey[];
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
@@ -13,7 +14,11 @@ export interface JwkSet {
|
|
|
13
14
|
export type JwkSource = JwkSet | string | (() => JwkSet | Promise<JwkSet>);
|
|
14
15
|
/** Per-request payload-revalidation hook. */
|
|
15
16
|
export type JwkVerifyHook = (payload: Record<string, unknown>, ctx: BaseContext<any, any>) => boolean | void | Promise<boolean | void>;
|
|
16
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Options for {@link jwk}: the JWKS source and asymmetric algorithm allowlist
|
|
19
|
+
* are required; issuer / audience / clock-skew checks, JWKS fetch caching,
|
|
20
|
+
* and a per-request revalidation hook are opt-in.
|
|
21
|
+
*/
|
|
17
22
|
export interface JwkOptions {
|
|
18
23
|
/** JWKS source (object, URL, or resolver). */
|
|
19
24
|
jwks: JwkSource;
|
|
@@ -91,6 +96,12 @@ export interface JwkOptions {
|
|
|
91
96
|
* });
|
|
92
97
|
* ```
|
|
93
98
|
*
|
|
99
|
+
* @param opts - JWKS source, algorithm allowlist, and claim checks; see
|
|
100
|
+
* {@link JwkOptions}.
|
|
101
|
+
* @returns A {@link Hooks} object to pass to `app.use()` or a route's `hooks`;
|
|
102
|
+
* failed auth yields a `401` problem+json with `WWW-Authenticate`.
|
|
103
|
+
* @throws {Error} at construction for missing options, an empty or
|
|
104
|
+
* symmetric-containing allowlist, invalid TTLs, or a malformed realm.
|
|
94
105
|
* @since 0.22.0
|
|
95
106
|
*/
|
|
96
107
|
export declare function jwk(opts: JwkOptions): Hooks;
|
package/dist/jwk.js
CHANGED
|
@@ -161,6 +161,12 @@ function makeJwksLoader(source, fetchImpl, ttlSeconds, maxStaleSeconds) {
|
|
|
161
161
|
* });
|
|
162
162
|
* ```
|
|
163
163
|
*
|
|
164
|
+
* @param opts - JWKS source, algorithm allowlist, and claim checks; see
|
|
165
|
+
* {@link JwkOptions}.
|
|
166
|
+
* @returns A {@link Hooks} object to pass to `app.use()` or a route's `hooks`;
|
|
167
|
+
* failed auth yields a `401` problem+json with `WWW-Authenticate`.
|
|
168
|
+
* @throws {Error} at construction for missing options, an empty or
|
|
169
|
+
* symmetric-containing allowlist, invalid TTLs, or a malformed realm.
|
|
164
170
|
* @since 0.22.0
|
|
165
171
|
*/
|
|
166
172
|
export function jwk(opts) {
|
package/dist/jwt.d.ts
CHANGED
|
@@ -23,19 +23,24 @@ export type JwtAlgorithm = "HS256" | "HS384" | "HS512" | "RS256" | "RS384" | "RS
|
|
|
23
23
|
export declare const DEFAULT_JWT_MAX_LIFETIME_SECONDS: number;
|
|
24
24
|
/** Structured error thrown by every JWT helper. */
|
|
25
25
|
export declare class JwtError extends Error {
|
|
26
|
+
/** Stable machine-readable error code (e.g. `"alg_none_refused"`, `"weak_hs_secret"`). */
|
|
26
27
|
readonly code: string;
|
|
27
28
|
constructor(code: string, message: string);
|
|
28
29
|
}
|
|
29
30
|
/** Result of a successful verify. */
|
|
30
31
|
export interface JwtVerified {
|
|
32
|
+
/** Decoded JOSE header (`alg`, `kid`, `typ`, ...). */
|
|
31
33
|
readonly header: Record<string, unknown>;
|
|
34
|
+
/** Decoded claims payload after signature and time-claim checks passed. */
|
|
32
35
|
readonly payload: Record<string, unknown>;
|
|
33
36
|
}
|
|
34
37
|
/** Key material accepted by the signer/verifier. */
|
|
35
38
|
export type JwtKeyMaterial = CryptoKey | Uint8Array | JsonWebKey;
|
|
36
39
|
/** Options for {@link createJwtSigner}. */
|
|
37
40
|
export interface JwtSignerOptions {
|
|
41
|
+
/** Signing algorithm. `"none"` is always refused. */
|
|
38
42
|
alg: JwtAlgorithm;
|
|
43
|
+
/** Signing key. HS* secrets shorter than 32 bytes and RSA keys under 2048 bits are refused. */
|
|
39
44
|
key: JwtKeyMaterial;
|
|
40
45
|
/**
|
|
41
46
|
* Maximum allowed `exp - iat` window in seconds. Required: refuse-at-
|
|
@@ -98,6 +103,10 @@ export interface JwtVerifierOptions {
|
|
|
98
103
|
* `acknowledgeNoExp: true` was set at construction outside production) and
|
|
99
104
|
* refuses payloads whose `exp - (iat | now)` exceeds `maxLifetimeSeconds`.
|
|
100
105
|
*
|
|
106
|
+
* @param opts - Algorithm, key, and lifetime policy; see {@link JwtSignerOptions}.
|
|
107
|
+
* @returns An object whose `sign(payload)` resolves to the compact JWS string.
|
|
108
|
+
* @throws {JwtError} for `alg: "none"`, unknown algorithms, weak keys, a
|
|
109
|
+
* missing/invalid `maxLifetimeSeconds`, or `acknowledgeNoExp` in production.
|
|
101
110
|
* @since 0.21.0
|
|
102
111
|
*/
|
|
103
112
|
export declare function createJwtSigner(opts: JwtSignerOptions): {
|
|
@@ -110,6 +119,11 @@ export declare function createJwtSigner(opts: JwtSignerOptions): {
|
|
|
110
119
|
* refuses-at-construction when a symmetric algorithm (`HS*`) is mixed with
|
|
111
120
|
* a JWK / JWKS-shaped key source (the documented confused-deputy attack).
|
|
112
121
|
*
|
|
122
|
+
* @param opts - Allowlist, key source, and claim checks; see {@link JwtVerifierOptions}.
|
|
123
|
+
* @returns An object whose `verify(token)` resolves to the decoded
|
|
124
|
+
* {@link JwtVerified} or rejects with {@link JwtError}.
|
|
125
|
+
* @throws {JwtError} at construction for an empty/invalid allowlist, `"none"`
|
|
126
|
+
* in the allowlist, weak HS* secrets, or HS* mixed with a JWK source.
|
|
113
127
|
* @since 0.21.0
|
|
114
128
|
*/
|
|
115
129
|
export declare function createJwtVerifier(opts: JwtVerifierOptions): {
|
package/dist/jwt.js
CHANGED
|
@@ -60,6 +60,7 @@ const MIN_RSA_KEY_BITS = 2048;
|
|
|
60
60
|
export const DEFAULT_JWT_MAX_LIFETIME_SECONDS = 30 * 24 * 60 * 60;
|
|
61
61
|
/** Structured error thrown by every JWT helper. */
|
|
62
62
|
export class JwtError extends Error {
|
|
63
|
+
/** Stable machine-readable error code (e.g. `"alg_none_refused"`, `"weak_hs_secret"`). */
|
|
63
64
|
code;
|
|
64
65
|
constructor(code, message) {
|
|
65
66
|
super(`[${code}] ${message}`);
|
|
@@ -228,6 +229,10 @@ function buildSignAlgorithm(alg) {
|
|
|
228
229
|
* `acknowledgeNoExp: true` was set at construction outside production) and
|
|
229
230
|
* refuses payloads whose `exp - (iat | now)` exceeds `maxLifetimeSeconds`.
|
|
230
231
|
*
|
|
232
|
+
* @param opts - Algorithm, key, and lifetime policy; see {@link JwtSignerOptions}.
|
|
233
|
+
* @returns An object whose `sign(payload)` resolves to the compact JWS string.
|
|
234
|
+
* @throws {JwtError} for `alg: "none"`, unknown algorithms, weak keys, a
|
|
235
|
+
* missing/invalid `maxLifetimeSeconds`, or `acknowledgeNoExp` in production.
|
|
231
236
|
* @since 0.21.0
|
|
232
237
|
*/
|
|
233
238
|
export function createJwtSigner(opts) {
|
|
@@ -326,6 +331,11 @@ function normalizeStringSet(value) {
|
|
|
326
331
|
* refuses-at-construction when a symmetric algorithm (`HS*`) is mixed with
|
|
327
332
|
* a JWK / JWKS-shaped key source (the documented confused-deputy attack).
|
|
328
333
|
*
|
|
334
|
+
* @param opts - Allowlist, key source, and claim checks; see {@link JwtVerifierOptions}.
|
|
335
|
+
* @returns An object whose `verify(token)` resolves to the decoded
|
|
336
|
+
* {@link JwtVerified} or rejects with {@link JwtError}.
|
|
337
|
+
* @throws {JwtError} at construction for an empty/invalid allowlist, `"none"`
|
|
338
|
+
* in the allowlist, weak HS* secrets, or HS* mixed with a JWK source.
|
|
329
339
|
* @since 0.21.0
|
|
330
340
|
*/
|
|
331
341
|
export function createJwtVerifier(opts) {
|
package/dist/load-shedding.d.ts
CHANGED
|
@@ -65,6 +65,9 @@ export interface LoadSheddingSnapshot {
|
|
|
65
65
|
* retryAfterSeconds: 5,
|
|
66
66
|
* }));
|
|
67
67
|
* ```
|
|
68
|
+
*
|
|
69
|
+
* @param opts - Pressure thresholds (event-loop delay default 1000 ms, ELU default 0.98, optional heap/RSS byte caps), sampling interval, `Retry-After` seconds, and an optional custom `healthCheck`.
|
|
70
|
+
* @returns A {@link Hooks} bundle that sheds requests with `503` + `Retry-After` while pressure thresholds are exceeded.
|
|
68
71
|
*/
|
|
69
72
|
export declare function loadShedding(opts?: LoadSheddingOptions): Hooks;
|
|
70
73
|
/**
|
package/dist/load-shedding.js
CHANGED
|
@@ -37,6 +37,9 @@ async function tryLoadPerfHooks() {
|
|
|
37
37
|
* retryAfterSeconds: 5,
|
|
38
38
|
* }));
|
|
39
39
|
* ```
|
|
40
|
+
*
|
|
41
|
+
* @param opts - Pressure thresholds (event-loop delay default 1000 ms, ELU default 0.98, optional heap/RSS byte caps), sampling interval, `Retry-After` seconds, and an optional custom `healthCheck`.
|
|
42
|
+
* @returns A {@link Hooks} bundle that sheds requests with `503` + `Retry-After` while pressure thresholds are exceeded.
|
|
40
43
|
*/
|
|
41
44
|
export function loadShedding(opts = {}) {
|
|
42
45
|
const maxDelay = opts.maxEventLoopDelayMs ?? 1000;
|
package/dist/logger.d.ts
CHANGED
|
@@ -10,13 +10,21 @@ export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
|
|
|
10
10
|
* thin adapter; the default implementation is {@link createLogger}.
|
|
11
11
|
*/
|
|
12
12
|
export interface Logger {
|
|
13
|
+
/** Minimum level emitted; records below this level are dropped. */
|
|
13
14
|
level: LogLevel;
|
|
15
|
+
/** Log at `trace` level. Pass a fields object plus optional message, or a message string. */
|
|
14
16
|
trace(obj: object | string, msg?: string): void;
|
|
17
|
+
/** Log at `debug` level. Pass a fields object plus optional message, or a message string. */
|
|
15
18
|
debug(obj: object | string, msg?: string): void;
|
|
19
|
+
/** Log at `info` level. Pass a fields object plus optional message, or a message string. */
|
|
16
20
|
info(obj: object | string, msg?: string): void;
|
|
21
|
+
/** Log at `warn` level. Pass a fields object plus optional message, or a message string. */
|
|
17
22
|
warn(obj: object | string, msg?: string): void;
|
|
23
|
+
/** Log at `error` level. Pass a fields object plus optional message, or a message string. */
|
|
18
24
|
error(obj: object | string, msg?: string): void;
|
|
25
|
+
/** Log at `fatal` level. Pass a fields object plus optional message, or a message string. */
|
|
19
26
|
fatal(obj: object | string, msg?: string): void;
|
|
27
|
+
/** Return a derived logger whose records always include `bindings` merged into each record. */
|
|
20
28
|
child(bindings: Record<string, unknown>): Logger;
|
|
21
29
|
}
|
|
22
30
|
/**
|
|
@@ -63,7 +71,9 @@ export interface LoggerRedactionOptions {
|
|
|
63
71
|
export declare const DEFAULT_REDACT_KEYS: readonly string[];
|
|
64
72
|
/** Options for {@link createLogger}. */
|
|
65
73
|
export interface ConsoleLoggerOptions {
|
|
74
|
+
/** Minimum level to emit. Defaults to `"info"`. */
|
|
66
75
|
level?: LogLevel;
|
|
76
|
+
/** Fields merged into every record emitted by this logger and its children. */
|
|
67
77
|
bindings?: Record<string, unknown>;
|
|
68
78
|
/** Where to write. Defaults to process.stdout.write or console.log. */
|
|
69
79
|
write?: (line: string) => void;
|
|
@@ -89,6 +99,9 @@ interface ResolvedRedaction {
|
|
|
89
99
|
* `cfg.redactJwt` is on) with `cfg.censor`. Exported for direct use by
|
|
90
100
|
* custom logger implementations that want the same defaults.
|
|
91
101
|
*
|
|
102
|
+
* @param record - Log record to redact. Mutated in place (cycle-safe, depth-capped).
|
|
103
|
+
* @param cfg - Resolved redaction settings (key set, censor, JWT/credential toggles, max depth).
|
|
104
|
+
* @returns The same `record` object, for chaining.
|
|
92
105
|
* @since 0.15.0
|
|
93
106
|
*/
|
|
94
107
|
export declare function redactRecord(record: Record<string, unknown>, cfg: ResolvedRedaction): Record<string, unknown>;
|
package/dist/logger.js
CHANGED
|
@@ -123,6 +123,9 @@ function redactString(value, cfg) {
|
|
|
123
123
|
* `cfg.redactJwt` is on) with `cfg.censor`. Exported for direct use by
|
|
124
124
|
* custom logger implementations that want the same defaults.
|
|
125
125
|
*
|
|
126
|
+
* @param record - Log record to redact. Mutated in place (cycle-safe, depth-capped).
|
|
127
|
+
* @param cfg - Resolved redaction settings (key set, censor, JWT/credential toggles, max depth).
|
|
128
|
+
* @returns The same `record` object, for chaining.
|
|
126
129
|
* @since 0.15.0
|
|
127
130
|
*/
|
|
128
131
|
export function redactRecord(record, cfg) {
|
package/dist/mcp.d.ts
CHANGED
|
@@ -52,6 +52,22 @@ export type McpJsonSchema = McpJsonObject;
|
|
|
52
52
|
* @since 1.0.0
|
|
53
53
|
*/
|
|
54
54
|
export type McpJsonRpcId = string | number | null;
|
|
55
|
+
/**
|
|
56
|
+
* Icon metadata clients may render next to a server, tool, resource, or
|
|
57
|
+
* prompt (MCP 2025-11-25, SEP-973).
|
|
58
|
+
*
|
|
59
|
+
* @since 1.0.0
|
|
60
|
+
*/
|
|
61
|
+
export interface McpIcon {
|
|
62
|
+
/** Icon URL. Prefer `https:` or `data:` URIs that clients can fetch safely. */
|
|
63
|
+
src: string;
|
|
64
|
+
/** Optional icon media type, e.g. `"image/png"`. */
|
|
65
|
+
mimeType?: string;
|
|
66
|
+
/** Optional pixel sizes the icon is available in, e.g. `["48x48"]`. */
|
|
67
|
+
sizes?: string[];
|
|
68
|
+
/** Optional theme the icon is designed for. */
|
|
69
|
+
theme?: "light" | "dark";
|
|
70
|
+
}
|
|
55
71
|
/**
|
|
56
72
|
* Identity block returned from the MCP `initialize` handshake.
|
|
57
73
|
*
|
|
@@ -64,6 +80,12 @@ export interface McpServerInfo {
|
|
|
64
80
|
title?: string;
|
|
65
81
|
/** Server version surfaced to clients for debugging and compatibility. */
|
|
66
82
|
version: string;
|
|
83
|
+
/** Optional human-readable server description (MCP 2025-11-25). */
|
|
84
|
+
description?: string;
|
|
85
|
+
/** Optional homepage URL for this server (MCP 2025-11-25). */
|
|
86
|
+
websiteUrl?: string;
|
|
87
|
+
/** Optional icons clients may display for this server (MCP 2025-11-25). */
|
|
88
|
+
icons?: McpIcon[];
|
|
67
89
|
}
|
|
68
90
|
/**
|
|
69
91
|
* Per-request context passed to tool, resource, and prompt handlers.
|
|
@@ -74,9 +96,10 @@ export interface McpRequestContext {
|
|
|
74
96
|
/** The original HTTP request received by the DaloyJS route. */
|
|
75
97
|
request: Request;
|
|
76
98
|
/**
|
|
77
|
-
* Protocol version selected for this call.
|
|
78
|
-
*
|
|
79
|
-
*
|
|
99
|
+
* Protocol version selected for this call. `initialize` negotiates it from
|
|
100
|
+
* `params.protocolVersion`; other calls take the `MCP-Protocol-Version`
|
|
101
|
+
* header, falling back to `2025-03-26` (the spec's assumption for
|
|
102
|
+
* headerless requests) when supported, otherwise the preferred version.
|
|
80
103
|
*/
|
|
81
104
|
protocolVersion: string;
|
|
82
105
|
/** JSON-RPC id for request/response correlation. */
|
|
@@ -90,7 +113,9 @@ export interface McpRequestContext {
|
|
|
90
113
|
* @since 1.0.0
|
|
91
114
|
*/
|
|
92
115
|
export interface McpTextContent {
|
|
116
|
+
/** Discriminator literal identifying this block as text. */
|
|
93
117
|
type: "text";
|
|
118
|
+
/** The plain-text payload of the block. */
|
|
94
119
|
text: string;
|
|
95
120
|
}
|
|
96
121
|
/**
|
|
@@ -102,8 +127,11 @@ export interface McpTextContent {
|
|
|
102
127
|
* @since 1.0.0
|
|
103
128
|
*/
|
|
104
129
|
export interface McpImageContent {
|
|
130
|
+
/** Discriminator literal identifying this block as an image. */
|
|
105
131
|
type: "image";
|
|
132
|
+
/** Base64-encoded image bytes. */
|
|
106
133
|
data: string;
|
|
134
|
+
/** Image media type, e.g. `"image/png"`. */
|
|
107
135
|
mimeType: string;
|
|
108
136
|
}
|
|
109
137
|
/**
|
|
@@ -112,7 +140,9 @@ export interface McpImageContent {
|
|
|
112
140
|
* @since 1.0.0
|
|
113
141
|
*/
|
|
114
142
|
export interface McpEmbeddedResourceContent {
|
|
143
|
+
/** Discriminator literal identifying this block as an embedded resource. */
|
|
115
144
|
type: "resource";
|
|
145
|
+
/** The embedded resource contents (uri plus text or base64 blob). */
|
|
116
146
|
resource: McpResourceContents;
|
|
117
147
|
}
|
|
118
148
|
/**
|
|
@@ -131,13 +161,36 @@ export type McpContent = McpTextContent | McpImageContent | McpEmbeddedResourceC
|
|
|
131
161
|
* @since 1.0.0
|
|
132
162
|
*/
|
|
133
163
|
export interface McpToolResult {
|
|
134
|
-
/**
|
|
135
|
-
|
|
164
|
+
/**
|
|
165
|
+
* Human or model-readable content blocks returned to the MCP client. When
|
|
166
|
+
* omitted, {@link createMcpHandler} backfills a text block serializing
|
|
167
|
+
* `structuredContent` so pre-2025-06-18 clients still receive output.
|
|
168
|
+
*/
|
|
169
|
+
content?: McpContent[];
|
|
136
170
|
/** Optional structured payload for clients that can consume typed output. */
|
|
137
171
|
structuredContent?: McpJsonObject;
|
|
138
172
|
/** Set to `true` for domain/tool errors the model may recover from. */
|
|
139
173
|
isError?: boolean;
|
|
140
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Behavioral hints a tool can advertise to MCP clients. Hints are untrusted
|
|
177
|
+
* metadata for UX decisions (confirmation prompts, badges); clients must not
|
|
178
|
+
* rely on them for security decisions.
|
|
179
|
+
*
|
|
180
|
+
* @since 1.0.0
|
|
181
|
+
*/
|
|
182
|
+
export interface McpToolAnnotations {
|
|
183
|
+
/** Human-readable title for the tool. */
|
|
184
|
+
title?: string;
|
|
185
|
+
/** Hint that the tool does not modify its environment. */
|
|
186
|
+
readOnlyHint?: boolean;
|
|
187
|
+
/** Hint that the tool may perform destructive updates. */
|
|
188
|
+
destructiveHint?: boolean;
|
|
189
|
+
/** Hint that repeated calls with the same arguments have no extra effect. */
|
|
190
|
+
idempotentHint?: boolean;
|
|
191
|
+
/** Hint that the tool interacts with external entities. */
|
|
192
|
+
openWorldHint?: boolean;
|
|
193
|
+
}
|
|
141
194
|
/**
|
|
142
195
|
* Handler for a single MCP tool.
|
|
143
196
|
*
|
|
@@ -172,6 +225,16 @@ export interface McpTool<TArgs extends Record<string, unknown> = Record<string,
|
|
|
172
225
|
description: string;
|
|
173
226
|
/** JSON Schema for `params.arguments`. */
|
|
174
227
|
inputSchema: McpJsonSchema;
|
|
228
|
+
/**
|
|
229
|
+
* Optional JSON Schema describing `structuredContent` in tool results
|
|
230
|
+
* (MCP 2025-06-18). When set, handlers should return `structuredContent`
|
|
231
|
+
* matching it.
|
|
232
|
+
*/
|
|
233
|
+
outputSchema?: McpJsonSchema;
|
|
234
|
+
/** Optional behavioral hints for clients. */
|
|
235
|
+
annotations?: McpToolAnnotations;
|
|
236
|
+
/** Optional icons clients may display for this tool (MCP 2025-11-25). */
|
|
237
|
+
icons?: McpIcon[];
|
|
175
238
|
/** Execute the tool with untrusted JSON arguments. */
|
|
176
239
|
handler: McpToolHandler<TArgs>;
|
|
177
240
|
}
|
|
@@ -191,6 +254,8 @@ export interface McpResource {
|
|
|
191
254
|
description?: string;
|
|
192
255
|
/** MIME type returned by `resources/read`, such as `"application/json"`. */
|
|
193
256
|
mimeType?: string;
|
|
257
|
+
/** Optional icons clients may display for this resource (MCP 2025-11-25). */
|
|
258
|
+
icons?: McpIcon[];
|
|
194
259
|
}
|
|
195
260
|
/**
|
|
196
261
|
* Resource payload returned from `resources/read`.
|
|
@@ -228,6 +293,51 @@ export interface McpResourceDefinition extends McpResource {
|
|
|
228
293
|
*/
|
|
229
294
|
read: (ctx: McpRequestContext) => McpResourceContents | McpResourceContents[] | Promise<McpResourceContents | McpResourceContents[]>;
|
|
230
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* Resource template metadata returned from `resources/templates/list`.
|
|
298
|
+
*
|
|
299
|
+
* @since 1.0.0
|
|
300
|
+
*/
|
|
301
|
+
export interface McpResourceTemplate {
|
|
302
|
+
/**
|
|
303
|
+
* URI template for this resource family, e.g. `"daloy://records/{id}"`.
|
|
304
|
+
* DaloyJS supports simple `{name}` variables (RFC 6570 level 1); each
|
|
305
|
+
* variable matches one URI segment (no `/`).
|
|
306
|
+
*/
|
|
307
|
+
uriTemplate: string;
|
|
308
|
+
/** Stable template name. */
|
|
309
|
+
name: string;
|
|
310
|
+
/** Optional human-readable title. */
|
|
311
|
+
title?: string;
|
|
312
|
+
/** Optional description shown by clients. */
|
|
313
|
+
description?: string;
|
|
314
|
+
/** MIME type of resources produced by this template. */
|
|
315
|
+
mimeType?: string;
|
|
316
|
+
/** Optional icons clients may display for this template (MCP 2025-11-25). */
|
|
317
|
+
icons?: McpIcon[];
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Definition of a parameterized MCP resource template.
|
|
321
|
+
*
|
|
322
|
+
* Templates answer `resources/read` for URIs that match `uriTemplate` but are
|
|
323
|
+
* not listed as concrete resources. Template variables arrive as raw URI
|
|
324
|
+
* segment strings; validate them before touching databases or files.
|
|
325
|
+
*
|
|
326
|
+
* @since 1.0.0
|
|
327
|
+
*/
|
|
328
|
+
export interface McpResourceTemplateDefinition extends McpResourceTemplate {
|
|
329
|
+
/**
|
|
330
|
+
* Read a resource instantiated from this template for `resources/read`.
|
|
331
|
+
*
|
|
332
|
+
* @param uri - The full resource URI requested by the client.
|
|
333
|
+
* @param variables - Template variable values extracted from `uri`.
|
|
334
|
+
* @param ctx - Request metadata and the original HTTP request.
|
|
335
|
+
* @returns One or more content entries for this resource.
|
|
336
|
+
* @throws {McpToolError} for caller-correctable failures such as an unknown
|
|
337
|
+
* record id; these become JSON-RPC invalid-params errors.
|
|
338
|
+
*/
|
|
339
|
+
read: (uri: string, variables: Record<string, string>, ctx: McpRequestContext) => McpResourceContents | McpResourceContents[] | Promise<McpResourceContents | McpResourceContents[]>;
|
|
340
|
+
}
|
|
231
341
|
/**
|
|
232
342
|
* Argument metadata for an MCP prompt.
|
|
233
343
|
*
|
|
@@ -253,8 +363,14 @@ export interface McpPrompt {
|
|
|
253
363
|
title?: string;
|
|
254
364
|
/** Optional prompt description. */
|
|
255
365
|
description?: string;
|
|
256
|
-
/**
|
|
366
|
+
/**
|
|
367
|
+
* Prompt arguments clients may supply to `prompts/get`. Arguments marked
|
|
368
|
+
* `required: true` are enforced by {@link createMcpHandler}: a `prompts/get`
|
|
369
|
+
* call missing one fails with a JSON-RPC invalid-params error.
|
|
370
|
+
*/
|
|
257
371
|
arguments?: McpPromptArgument[];
|
|
372
|
+
/** Optional icons clients may display for this prompt (MCP 2025-11-25). */
|
|
373
|
+
icons?: McpIcon[];
|
|
258
374
|
}
|
|
259
375
|
/**
|
|
260
376
|
* Message returned from `prompts/get`.
|
|
@@ -326,8 +442,25 @@ export interface McpHandlerOptions {
|
|
|
326
442
|
tools?: readonly McpTool[];
|
|
327
443
|
/** Readable resources exposed through `resources/list` and `resources/read`. */
|
|
328
444
|
resources?: readonly McpResourceDefinition[];
|
|
445
|
+
/**
|
|
446
|
+
* Parameterized resource templates exposed through
|
|
447
|
+
* `resources/templates/list` and matched by `resources/read` when a URI is
|
|
448
|
+
* not a listed concrete resource.
|
|
449
|
+
*/
|
|
450
|
+
resourceTemplates?: readonly McpResourceTemplateDefinition[];
|
|
329
451
|
/** Reusable prompts exposed through `prompts/list` and `prompts/get`. */
|
|
330
452
|
prompts?: readonly McpPromptDefinition[];
|
|
453
|
+
/**
|
|
454
|
+
* Extra `Origin` header values allowed on MCP requests, e.g.
|
|
455
|
+
* `"https://app.example.com"` (or the literal `"null"` for opaque origins).
|
|
456
|
+
*
|
|
457
|
+
* The MCP Streamable HTTP spec requires servers to validate `Origin` to
|
|
458
|
+
* prevent DNS rebinding attacks. DaloyJS always allows requests without an
|
|
459
|
+
* `Origin` header (non-browser MCP clients), same-origin requests, and
|
|
460
|
+
* loopback origins (`localhost`, `*.localhost`, `127.0.0.1`, `[::1]`); every
|
|
461
|
+
* other origin is rejected with `403` unless listed here.
|
|
462
|
+
*/
|
|
463
|
+
allowedOrigins?: readonly string[];
|
|
331
464
|
/** Accepted MCP protocol versions. Defaults to {@link MCP_PROTOCOL_VERSIONS}. */
|
|
332
465
|
protocolVersions?: readonly string[];
|
|
333
466
|
/**
|
|
@@ -364,10 +497,16 @@ export type McpHandler = (request: Request) => Promise<Response>;
|
|
|
364
497
|
*
|
|
365
498
|
* The handler implements the server side of MCP over one HTTP endpoint:
|
|
366
499
|
* `initialize`, `ping`, `tools/list`, `tools/call`, `resources/list`,
|
|
367
|
-
* `resources/read`, `prompts/list`, and
|
|
368
|
-
* requests over `POST`, acknowledges
|
|
369
|
-
* `MCP-Protocol-Version` header,
|
|
370
|
-
*
|
|
500
|
+
* `resources/templates/list`, `resources/read`, `prompts/list`, and
|
|
501
|
+
* `prompts/get`. It accepts JSON-RPC requests over `POST`, acknowledges
|
|
502
|
+
* notifications with `202`, validates the `MCP-Protocol-Version` header,
|
|
503
|
+
* bounds request bodies, enforces required prompt arguments, and returns
|
|
504
|
+
* JSON-RPC errors for malformed input.
|
|
505
|
+
*
|
|
506
|
+
* Security: per the Streamable HTTP spec's DNS-rebinding guidance, every
|
|
507
|
+
* request bearing an `Origin` header is validated. Same-origin and loopback
|
|
508
|
+
* origins pass; anything else is rejected with `403` unless listed in
|
|
509
|
+
* {@link McpHandlerOptions.allowedOrigins}.
|
|
371
510
|
*
|
|
372
511
|
* It intentionally does not spawn stdio servers, manage OAuth metadata, keep
|
|
373
512
|
* durable sessions, or open server-initiated SSE streams. Use DaloyJS
|
|
@@ -378,6 +517,9 @@ export type McpHandler = (request: Request) => Promise<Response>;
|
|
|
378
517
|
* @param options - Server identity, capabilities, limits, and response headers.
|
|
379
518
|
* @returns A Fetch-compatible request handler suitable for {@link mcpRoutes}
|
|
380
519
|
* or for direct use in any web-standard runtime.
|
|
520
|
+
* @throws {TypeError} at construction for invalid serverInfo, protocol
|
|
521
|
+
* versions, body limits, duplicate names/URIs, malformed `allowedOrigins`
|
|
522
|
+
* entries, or unsupported URI template expressions.
|
|
381
523
|
*
|
|
382
524
|
* @example
|
|
383
525
|
* ```ts
|