elysia 2.0.0-beta.2 → 2.0.0-beta.4
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/adapter/bun/index.d.ts +1 -1
- package/dist/adapter/bun/index.js +320 -56
- package/dist/adapter/bun/index.mjs +321 -57
- package/dist/adapter/utils.js +51 -30
- package/dist/adapter/utils.mjs +52 -31
- package/dist/adapter/web-standard/handler.js +5 -2
- package/dist/adapter/web-standard/handler.mjs +5 -2
- package/dist/base.d.ts +18 -7
- package/dist/base.js +213 -101
- package/dist/base.mjs +215 -103
- package/dist/compile/aot-capture.js +1 -1
- package/dist/compile/aot-capture.mjs +1 -1
- package/dist/compile/aot.d.ts +5 -4
- package/dist/compile/aot.js +17 -9
- package/dist/compile/aot.mjs +18 -9
- package/dist/compile/handler/descriptor.js +1 -1
- package/dist/compile/handler/descriptor.mjs +1 -1
- package/dist/compile/handler/frozen-validator.d.ts +4 -1
- package/dist/compile/handler/frozen-validator.js +8 -3
- package/dist/compile/handler/frozen-validator.mjs +5 -3
- package/dist/compile/handler/index.d.ts +2 -2
- package/dist/compile/handler/index.js +8 -6
- package/dist/compile/handler/index.mjs +8 -6
- package/dist/compile/handler/reconstruct.d.ts +1 -1
- package/dist/compile/handler/reconstruct.js +4 -3
- package/dist/compile/handler/reconstruct.mjs +4 -3
- package/dist/compile/handler/utils.js +2 -2
- package/dist/compile/handler/utils.mjs +3 -3
- package/dist/compile/jit-probe.d.ts +2 -2
- package/dist/context.d.ts +1 -1
- package/dist/context.js +8 -5
- package/dist/context.mjs +8 -5
- package/dist/cookie/config.d.ts +1 -0
- package/dist/cookie/config.js +3 -2
- package/dist/cookie/config.mjs +3 -2
- package/dist/cookie/cookie.d.ts +1 -0
- package/dist/cookie/cookie.js +6 -5
- package/dist/cookie/cookie.mjs +6 -5
- package/dist/cookie/crypto.d.ts +8 -7
- package/dist/cookie/crypto.js +38 -31
- package/dist/cookie/crypto.mjs +38 -32
- package/dist/cookie/error.js +1 -2
- package/dist/cookie/error.mjs +1 -2
- package/dist/cookie/lib.js +5 -1
- package/dist/cookie/lib.mjs +5 -1
- package/dist/cookie/serialize.js +1 -1
- package/dist/cookie/serialize.mjs +1 -1
- package/dist/cookie/types.d.ts +10 -0
- package/dist/cookie/utils.js +28 -14
- package/dist/cookie/utils.mjs +29 -15
- package/dist/handler/error.d.ts +23 -12
- package/dist/handler/error.js +24 -21
- package/dist/handler/error.mjs +20 -21
- package/dist/handler/fetch.js +6 -7
- package/dist/handler/fetch.mjs +7 -8
- package/dist/handler/utils.js +4 -2
- package/dist/handler/utils.mjs +5 -3
- package/dist/index.js +1 -8
- package/dist/package.js +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugin/aot/core.d.ts +33 -6
- package/dist/plugin/aot/core.js +120 -40
- package/dist/plugin/aot/core.mjs +121 -43
- package/dist/plugin/aot/esbuild.js +8 -2
- package/dist/plugin/aot/esbuild.mjs +9 -3
- package/dist/plugin/aot/hooks.d.ts +2 -1
- package/dist/plugin/aot/hooks.js +3 -3
- package/dist/plugin/aot/hooks.mjs +4 -4
- package/dist/plugin/aot/source.d.ts +4 -1
- package/dist/plugin/aot/source.js +21 -14
- package/dist/plugin/aot/source.mjs +21 -14
- package/dist/plugin/aot/worker.js +2 -2
- package/dist/plugin/aot/worker.mjs +2 -2
- package/dist/route-table.d.ts +3 -0
- package/dist/route-table.js +16 -11
- package/dist/route-table.mjs +16 -11
- package/dist/schema-snapshot.js +17 -22
- package/dist/schema-snapshot.mjs +17 -22
- package/dist/type/bridge-live.d.ts +1 -1
- package/dist/type/bridge-live.js +2 -2
- package/dist/type/bridge-live.mjs +2 -2
- package/dist/type/bridge.d.ts +1 -1
- package/dist/type/coerce-plan.js +3 -4
- package/dist/type/coerce-plan.mjs +1 -1
- package/dist/type/coerce.d.ts +1 -1
- package/dist/type/compat.d.ts +3 -0
- package/dist/type/compat.js +32 -14
- package/dist/type/compat.mjs +27 -8
- package/dist/type/constants.d.ts +1 -1
- package/dist/type/elysia/array-buffer.js +2 -3
- package/dist/type/elysia/array-buffer.mjs +1 -1
- package/dist/type/elysia/array-string.js +7 -4
- package/dist/type/elysia/array-string.mjs +9 -5
- package/dist/type/elysia/boolean-string.js +2 -3
- package/dist/type/elysia/boolean-string.mjs +1 -1
- package/dist/type/elysia/boolean.js +4 -3
- package/dist/type/elysia/boolean.mjs +4 -2
- package/dist/type/elysia/cookie.js +2 -1
- package/dist/type/elysia/cookie.mjs +2 -1
- package/dist/type/elysia/date.js +7 -7
- package/dist/type/elysia/date.mjs +3 -2
- package/dist/type/elysia/file-type.d.ts +9 -2
- package/dist/type/elysia/file-type.js +16 -1
- package/dist/type/elysia/file-type.mjs +16 -2
- package/dist/type/elysia/file.js +8 -4
- package/dist/type/elysia/file.mjs +8 -3
- package/dist/type/elysia/files.js +6 -4
- package/dist/type/elysia/files.mjs +5 -2
- package/dist/type/elysia/form.js +2 -3
- package/dist/type/elysia/form.mjs +3 -3
- package/dist/type/elysia/integer-string.js +4 -5
- package/dist/type/elysia/integer-string.mjs +3 -3
- package/dist/type/elysia/integer.js +4 -3
- package/dist/type/elysia/integer.mjs +4 -2
- package/dist/type/elysia/maybe-empty.js +3 -4
- package/dist/type/elysia/maybe-empty.mjs +1 -1
- package/dist/type/elysia/nullable.js +2 -3
- package/dist/type/elysia/nullable.mjs +1 -1
- package/dist/type/elysia/number.js +4 -3
- package/dist/type/elysia/number.mjs +4 -2
- package/dist/type/elysia/numeric-enum.js +2 -3
- package/dist/type/elysia/numeric-enum.mjs +1 -1
- package/dist/type/elysia/numeric.js +5 -5
- package/dist/type/elysia/numeric.mjs +3 -2
- package/dist/type/elysia/object-string.js +7 -4
- package/dist/type/elysia/object-string.mjs +9 -5
- package/dist/type/elysia/string.js +4 -3
- package/dist/type/elysia/string.mjs +4 -2
- package/dist/type/elysia/uint8-array.js +2 -3
- package/dist/type/elysia/uint8-array.mjs +1 -1
- package/dist/type/elysia/union-enum.js +2 -3
- package/dist/type/elysia/union-enum.mjs +1 -1
- package/dist/type/elysia/utils.js +2 -3
- package/dist/type/elysia/utils.mjs +1 -1
- package/dist/type/exports.js +10 -1
- package/dist/type/exports.mjs +7 -0
- package/dist/type/index.d.ts +9 -1
- package/dist/type/index.js +41 -13
- package/dist/type/index.mjs +44 -9
- package/dist/type/typebox-type-live.d.ts +9 -0
- package/dist/type/typebox-type-live.js +31 -0
- package/dist/type/typebox-type-live.mjs +16 -0
- package/dist/type/typebox-type.d.ts +24 -0
- package/dist/type/typebox-type.js +130 -0
- package/dist/type/typebox-type.mjs +66 -0
- package/dist/type/typebox-value-live.d.ts +9 -0
- package/dist/type/typebox-value-live.js +27 -0
- package/dist/type/typebox-value-live.mjs +11 -0
- package/dist/type/typebox-value.d.ts +30 -0
- package/dist/type/typebox-value.js +147 -0
- package/dist/type/typebox-value.mjs +62 -0
- package/dist/type/validator/custom-error.js +4 -5
- package/dist/type/validator/custom-error.mjs +3 -3
- package/dist/type/validator/default-precompute.js +4 -5
- package/dist/type/validator/default-precompute.mjs +1 -1
- package/dist/type/validator/index.d.ts +1 -1
- package/dist/type/validator/index.js +51 -42
- package/dist/type/validator/index.mjs +33 -23
- package/dist/type/validator/validator-cache.d.ts +1 -1
- package/dist/type/validator/validator-cache.js +27 -14
- package/dist/type/validator/validator-cache.mjs +27 -13
- package/dist/universal/constants.d.ts +2 -1
- package/dist/universal/constants.js +3 -1
- package/dist/universal/constants.mjs +2 -1
- package/dist/utils.d.ts +19 -1
- package/dist/utils.js +25 -3
- package/dist/utils.mjs +19 -3
- package/dist/validator/index.js +2 -1
- package/dist/validator/index.mjs +2 -1
- package/dist/ws/context.d.ts +8 -1
- package/dist/ws/context.js +65 -29
- package/dist/ws/context.mjs +64 -29
- package/dist/ws/route.js +176 -28
- package/dist/ws/route.mjs +179 -31
- package/package.json +5 -3
package/dist/cookie/crypto.d.ts
CHANGED
|
@@ -7,14 +7,15 @@ declare const signCookieSyncImpl: (val: string, secret: string) => string;
|
|
|
7
7
|
declare const keyCache: Map<string, Promise<CryptoKey>>;
|
|
8
8
|
declare function importSecretKey(secret: string): Promise<CryptoKey>;
|
|
9
9
|
declare function signCookieSubtle(val: string, secret: string): Promise<string>;
|
|
10
|
-
declare
|
|
11
|
-
declare function
|
|
12
|
-
declare function
|
|
13
|
-
declare function
|
|
14
|
-
declare function
|
|
15
|
-
declare function
|
|
10
|
+
declare const deriveSignKey: (secret: string, name: string) => string;
|
|
11
|
+
declare function signCookie(val: string, secret: string | null, name?: string): Promise<string>;
|
|
12
|
+
declare function signCookieSync(val: string, secret: string | null, name?: string): string;
|
|
13
|
+
declare function unsignCookie(input: string, secret: string | null, name?: string): Promise<string | false>;
|
|
14
|
+
declare function unsignCookieSync(input: string, secret: string | null, name?: string): string | false;
|
|
15
|
+
declare function unsignWithSecretsSync(name: string, value: unknown, secrets: string | null | (string | null)[] | undefined, legacy?: boolean): string;
|
|
16
|
+
declare function unsignWithSecrets(name: string, value: unknown, secrets: string | null | (string | null)[] | undefined, legacy?: boolean): Promise<string>;
|
|
16
17
|
declare const rawJsonValue: WeakMap<object, string>;
|
|
17
18
|
declare function maybeJsonDecode(value: unknown): any;
|
|
18
19
|
declare function resolvePendingCookie(entry: Record<string, any>, name: string): void;
|
|
19
20
|
//#endregion
|
|
20
|
-
export { hasSyncHmac, hmacProvider, importSecretKey, keyCache, maybeJsonDecode, rawJsonValue, resolvePendingCookie, signCookie, signCookieBun, signCookieNode, signCookieSubtle, signCookieSync, signCookieSyncImpl, unsignCookie, unsignCookieSync, unsignWithSecrets, unsignWithSecretsSync };
|
|
21
|
+
export { deriveSignKey, hasSyncHmac, hmacProvider, importSecretKey, keyCache, maybeJsonDecode, rawJsonValue, resolvePendingCookie, signCookie, signCookieBun, signCookieNode, signCookieSubtle, signCookieSync, signCookieSyncImpl, unsignCookie, unsignCookieSync, unsignWithSecrets, unsignWithSecretsSync };
|
package/dist/cookie/crypto.js
CHANGED
|
@@ -20,12 +20,11 @@ function nodeCrypto() {
|
|
|
20
20
|
}
|
|
21
21
|
return _nodeCrypto;
|
|
22
22
|
}
|
|
23
|
-
const HMAC_PROBE_DIGEST = "bzs6y9cVmkYub8fplSKaOuuqMqJlDwhMypFT/jSdCEk=";
|
|
24
23
|
const bunCryptoHasher = (() => {
|
|
25
24
|
const hasher = globalThis.Bun?.CryptoHasher;
|
|
26
25
|
if (typeof hasher !== "function") return void 0;
|
|
27
26
|
try {
|
|
28
|
-
return new hasher("sha256", "elysia").update("probe").digest("base64") ===
|
|
27
|
+
return new hasher("sha256", "elysia").update("probe").digest("base64") === "bzs6y9cVmkYub8fplSKaOuuqMqJlDwhMypFT/jSdCEk=" ? hasher : void 0;
|
|
29
28
|
} catch {
|
|
30
29
|
return;
|
|
31
30
|
}
|
|
@@ -62,19 +61,22 @@ async function signCookieSubtle(val, secret) {
|
|
|
62
61
|
const hmacBuffer = await crypto.subtle.sign("HMAC", await importSecretKey(secret), encoder.encode(val));
|
|
63
62
|
return `${val}.${btoa(String.fromCharCode(...new Uint8Array(hmacBuffer))).replace(removeTrailingEquals, "")}`;
|
|
64
63
|
}
|
|
65
|
-
|
|
64
|
+
const deriveSignKey = (secret, name) => `${name.length}\0${name}${secret}`;
|
|
65
|
+
async function signCookie(val, secret, name) {
|
|
66
66
|
val = coerceValue(val);
|
|
67
|
-
if (secret
|
|
67
|
+
if (!secret?.trim()) throw new TypeError("Secret key must be provided");
|
|
68
|
+
if (name !== void 0) secret = deriveSignKey(secret, name);
|
|
68
69
|
if (hasSyncHmac) return signCookieSyncImpl(val, secret);
|
|
69
70
|
return signCookieSubtle(val, secret);
|
|
70
71
|
}
|
|
71
|
-
function signCookieSync(val, secret) {
|
|
72
|
+
function signCookieSync(val, secret, name) {
|
|
72
73
|
val = coerceValue(val);
|
|
73
|
-
if (secret
|
|
74
|
+
if (!secret?.trim()) throw new TypeError("Secret key must be provided");
|
|
74
75
|
if (!hasSyncHmac) throw new Error("signCookieSync called without a sync HMAC available");
|
|
76
|
+
if (name !== void 0) secret = deriveSignKey(secret, name);
|
|
75
77
|
return signCookieSyncImpl(val, secret);
|
|
76
78
|
}
|
|
77
|
-
async function unsignCookie(input, secret) {
|
|
79
|
+
async function unsignCookie(input, secret, name) {
|
|
78
80
|
if (typeof input !== "string") throw new TypeError("Signed cookie string must be provided.");
|
|
79
81
|
const dot = input.lastIndexOf(".");
|
|
80
82
|
if (dot === -1) {
|
|
@@ -82,10 +84,10 @@ async function unsignCookie(input, secret) {
|
|
|
82
84
|
return false;
|
|
83
85
|
}
|
|
84
86
|
const tentativeValue = input.slice(0, dot);
|
|
85
|
-
if (secret
|
|
86
|
-
return require_utils.constantTimeEqual(await signCookie(tentativeValue, secret), input) ? tentativeValue : false;
|
|
87
|
+
if (!secret?.trim()) return false;
|
|
88
|
+
return require_utils.constantTimeEqual(await signCookie(tentativeValue, secret, name), input) ? tentativeValue : false;
|
|
87
89
|
}
|
|
88
|
-
function unsignCookieSync(input, secret) {
|
|
90
|
+
function unsignCookieSync(input, secret, name) {
|
|
89
91
|
if (typeof input !== "string") throw new TypeError("Signed cookie string must be provided.");
|
|
90
92
|
const dot = input.lastIndexOf(".");
|
|
91
93
|
if (dot === -1) {
|
|
@@ -93,32 +95,36 @@ function unsignCookieSync(input, secret) {
|
|
|
93
95
|
return false;
|
|
94
96
|
}
|
|
95
97
|
const tentativeValue = input.slice(0, dot);
|
|
96
|
-
if (secret
|
|
97
|
-
return require_utils.constantTimeEqual(signCookieSync(tentativeValue, secret), input) ? tentativeValue : false;
|
|
98
|
+
if (!secret?.trim()) return false;
|
|
99
|
+
return require_utils.constantTimeEqual(signCookieSync(tentativeValue, secret, name), input) ? tentativeValue : false;
|
|
98
100
|
}
|
|
99
|
-
function unsignWithSecretsSync(name, value, secrets) {
|
|
101
|
+
function unsignWithSecretsSync(name, value, secrets, legacy) {
|
|
100
102
|
if (typeof value !== "string") throw require_cookie_error.InvalidCookie.signature(name);
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
for (let pass = 0; pass < 2; pass++) {
|
|
104
|
+
const bound = pass === 0 ? name : void 0;
|
|
105
|
+
if (typeof secrets === "string") {
|
|
106
|
+
const temp = unsignCookieSync(value, secrets, bound);
|
|
107
|
+
if (temp !== false) return temp;
|
|
108
|
+
} else if (Array.isArray(secrets)) for (let i = 0; i < secrets.length; i++) {
|
|
109
|
+
const temp = unsignCookieSync(value, secrets[i], bound);
|
|
110
|
+
if (temp !== false) return temp;
|
|
111
|
+
}
|
|
112
|
+
if (!legacy) break;
|
|
109
113
|
}
|
|
110
114
|
throw require_cookie_error.InvalidCookie.signature(name);
|
|
111
115
|
}
|
|
112
|
-
async function unsignWithSecrets(name, value, secrets) {
|
|
116
|
+
async function unsignWithSecrets(name, value, secrets, legacy) {
|
|
113
117
|
if (typeof value !== "string") throw require_cookie_error.InvalidCookie.signature(name);
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
for (let pass = 0; pass < 2; pass++) {
|
|
119
|
+
const bound = pass === 0 ? name : void 0;
|
|
120
|
+
if (typeof secrets === "string") {
|
|
121
|
+
const temp = await unsignCookie(value, secrets, bound);
|
|
122
|
+
if (temp !== false) return temp;
|
|
123
|
+
} else if (Array.isArray(secrets)) for (let i = 0; i < secrets.length; i++) {
|
|
124
|
+
const temp = await unsignCookie(value, secrets[i], bound);
|
|
125
|
+
if (temp !== false) return temp;
|
|
126
|
+
}
|
|
127
|
+
if (!legacy) break;
|
|
122
128
|
}
|
|
123
129
|
throw require_cookie_error.InvalidCookie.signature(name);
|
|
124
130
|
}
|
|
@@ -139,7 +145,7 @@ function resolvePendingCookie(entry, name) {
|
|
|
139
145
|
const value = entry.value;
|
|
140
146
|
if (typeof value !== "string") throw require_cookie_error.InvalidCookie.signature(name);
|
|
141
147
|
if (!hasSyncHmac) throw new Error(`resolvePendingCookie called without sync HMAC. Unreachable under correct lane gating (cookie: "${name}")`);
|
|
142
|
-
const resolvedValue = maybeJsonDecode(unsignWithSecretsSync(name, value, entry["~unsign"]));
|
|
148
|
+
const resolvedValue = maybeJsonDecode(unsignWithSecretsSync(name, value, entry["~unsign"], !entry["~strict"]));
|
|
143
149
|
entry.value = resolvedValue;
|
|
144
150
|
if (resolvedValue !== null && typeof resolvedValue === "object") {
|
|
145
151
|
const raw = rawJsonValue.get(resolvedValue);
|
|
@@ -149,6 +155,7 @@ function resolvePendingCookie(entry, name) {
|
|
|
149
155
|
}
|
|
150
156
|
|
|
151
157
|
//#endregion
|
|
158
|
+
exports.deriveSignKey = deriveSignKey;
|
|
152
159
|
exports.hasSyncHmac = hasSyncHmac;
|
|
153
160
|
exports.hmacProvider = hmacProvider;
|
|
154
161
|
exports.importSecretKey = importSecretKey;
|
package/dist/cookie/crypto.mjs
CHANGED
|
@@ -19,12 +19,11 @@ function nodeCrypto() {
|
|
|
19
19
|
}
|
|
20
20
|
return _nodeCrypto;
|
|
21
21
|
}
|
|
22
|
-
const HMAC_PROBE_DIGEST = "bzs6y9cVmkYub8fplSKaOuuqMqJlDwhMypFT/jSdCEk=";
|
|
23
22
|
const bunCryptoHasher = (() => {
|
|
24
23
|
const hasher = globalThis.Bun?.CryptoHasher;
|
|
25
24
|
if (typeof hasher !== "function") return void 0;
|
|
26
25
|
try {
|
|
27
|
-
return new hasher("sha256", "elysia").update("probe").digest("base64") ===
|
|
26
|
+
return new hasher("sha256", "elysia").update("probe").digest("base64") === "bzs6y9cVmkYub8fplSKaOuuqMqJlDwhMypFT/jSdCEk=" ? hasher : void 0;
|
|
28
27
|
} catch {
|
|
29
28
|
return;
|
|
30
29
|
}
|
|
@@ -61,19 +60,22 @@ async function signCookieSubtle(val, secret) {
|
|
|
61
60
|
const hmacBuffer = await crypto.subtle.sign("HMAC", await importSecretKey(secret), encoder.encode(val));
|
|
62
61
|
return `${val}.${btoa(String.fromCharCode(...new Uint8Array(hmacBuffer))).replace(removeTrailingEquals, "")}`;
|
|
63
62
|
}
|
|
64
|
-
|
|
63
|
+
const deriveSignKey = (secret, name) => `${name.length}\0${name}${secret}`;
|
|
64
|
+
async function signCookie(val, secret, name) {
|
|
65
65
|
val = coerceValue(val);
|
|
66
|
-
if (secret
|
|
66
|
+
if (!secret?.trim()) throw new TypeError("Secret key must be provided");
|
|
67
|
+
if (name !== void 0) secret = deriveSignKey(secret, name);
|
|
67
68
|
if (hasSyncHmac) return signCookieSyncImpl(val, secret);
|
|
68
69
|
return signCookieSubtle(val, secret);
|
|
69
70
|
}
|
|
70
|
-
function signCookieSync(val, secret) {
|
|
71
|
+
function signCookieSync(val, secret, name) {
|
|
71
72
|
val = coerceValue(val);
|
|
72
|
-
if (secret
|
|
73
|
+
if (!secret?.trim()) throw new TypeError("Secret key must be provided");
|
|
73
74
|
if (!hasSyncHmac) throw new Error("signCookieSync called without a sync HMAC available");
|
|
75
|
+
if (name !== void 0) secret = deriveSignKey(secret, name);
|
|
74
76
|
return signCookieSyncImpl(val, secret);
|
|
75
77
|
}
|
|
76
|
-
async function unsignCookie(input, secret) {
|
|
78
|
+
async function unsignCookie(input, secret, name) {
|
|
77
79
|
if (typeof input !== "string") throw new TypeError("Signed cookie string must be provided.");
|
|
78
80
|
const dot = input.lastIndexOf(".");
|
|
79
81
|
if (dot === -1) {
|
|
@@ -81,10 +83,10 @@ async function unsignCookie(input, secret) {
|
|
|
81
83
|
return false;
|
|
82
84
|
}
|
|
83
85
|
const tentativeValue = input.slice(0, dot);
|
|
84
|
-
if (secret
|
|
85
|
-
return constantTimeEqual(await signCookie(tentativeValue, secret), input) ? tentativeValue : false;
|
|
86
|
+
if (!secret?.trim()) return false;
|
|
87
|
+
return constantTimeEqual(await signCookie(tentativeValue, secret, name), input) ? tentativeValue : false;
|
|
86
88
|
}
|
|
87
|
-
function unsignCookieSync(input, secret) {
|
|
89
|
+
function unsignCookieSync(input, secret, name) {
|
|
88
90
|
if (typeof input !== "string") throw new TypeError("Signed cookie string must be provided.");
|
|
89
91
|
const dot = input.lastIndexOf(".");
|
|
90
92
|
if (dot === -1) {
|
|
@@ -92,32 +94,36 @@ function unsignCookieSync(input, secret) {
|
|
|
92
94
|
return false;
|
|
93
95
|
}
|
|
94
96
|
const tentativeValue = input.slice(0, dot);
|
|
95
|
-
if (secret
|
|
96
|
-
return constantTimeEqual(signCookieSync(tentativeValue, secret), input) ? tentativeValue : false;
|
|
97
|
+
if (!secret?.trim()) return false;
|
|
98
|
+
return constantTimeEqual(signCookieSync(tentativeValue, secret, name), input) ? tentativeValue : false;
|
|
97
99
|
}
|
|
98
|
-
function unsignWithSecretsSync(name, value, secrets) {
|
|
100
|
+
function unsignWithSecretsSync(name, value, secrets, legacy) {
|
|
99
101
|
if (typeof value !== "string") throw InvalidCookie.signature(name);
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
for (let pass = 0; pass < 2; pass++) {
|
|
103
|
+
const bound = pass === 0 ? name : void 0;
|
|
104
|
+
if (typeof secrets === "string") {
|
|
105
|
+
const temp = unsignCookieSync(value, secrets, bound);
|
|
106
|
+
if (temp !== false) return temp;
|
|
107
|
+
} else if (Array.isArray(secrets)) for (let i = 0; i < secrets.length; i++) {
|
|
108
|
+
const temp = unsignCookieSync(value, secrets[i], bound);
|
|
109
|
+
if (temp !== false) return temp;
|
|
110
|
+
}
|
|
111
|
+
if (!legacy) break;
|
|
108
112
|
}
|
|
109
113
|
throw InvalidCookie.signature(name);
|
|
110
114
|
}
|
|
111
|
-
async function unsignWithSecrets(name, value, secrets) {
|
|
115
|
+
async function unsignWithSecrets(name, value, secrets, legacy) {
|
|
112
116
|
if (typeof value !== "string") throw InvalidCookie.signature(name);
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
if (
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
for (let pass = 0; pass < 2; pass++) {
|
|
118
|
+
const bound = pass === 0 ? name : void 0;
|
|
119
|
+
if (typeof secrets === "string") {
|
|
120
|
+
const temp = await unsignCookie(value, secrets, bound);
|
|
121
|
+
if (temp !== false) return temp;
|
|
122
|
+
} else if (Array.isArray(secrets)) for (let i = 0; i < secrets.length; i++) {
|
|
123
|
+
const temp = await unsignCookie(value, secrets[i], bound);
|
|
124
|
+
if (temp !== false) return temp;
|
|
125
|
+
}
|
|
126
|
+
if (!legacy) break;
|
|
121
127
|
}
|
|
122
128
|
throw InvalidCookie.signature(name);
|
|
123
129
|
}
|
|
@@ -138,7 +144,7 @@ function resolvePendingCookie(entry, name) {
|
|
|
138
144
|
const value = entry.value;
|
|
139
145
|
if (typeof value !== "string") throw InvalidCookie.signature(name);
|
|
140
146
|
if (!hasSyncHmac) throw new Error(`resolvePendingCookie called without sync HMAC. Unreachable under correct lane gating (cookie: "${name}")`);
|
|
141
|
-
const resolvedValue = maybeJsonDecode(unsignWithSecretsSync(name, value, entry["~unsign"]));
|
|
147
|
+
const resolvedValue = maybeJsonDecode(unsignWithSecretsSync(name, value, entry["~unsign"], !entry["~strict"]));
|
|
142
148
|
entry.value = resolvedValue;
|
|
143
149
|
if (resolvedValue !== null && typeof resolvedValue === "object") {
|
|
144
150
|
const raw = rawJsonValue.get(resolvedValue);
|
|
@@ -148,4 +154,4 @@ function resolvePendingCookie(entry, name) {
|
|
|
148
154
|
}
|
|
149
155
|
|
|
150
156
|
//#endregion
|
|
151
|
-
export { hasSyncHmac, hmacProvider, importSecretKey, keyCache, maybeJsonDecode, rawJsonValue, resolvePendingCookie, signCookie, signCookieBun, signCookieNode, signCookieSubtle, signCookieSync, signCookieSyncImpl, unsignCookie, unsignCookieSync, unsignWithSecrets, unsignWithSecretsSync };
|
|
157
|
+
export { deriveSignKey, hasSyncHmac, hmacProvider, importSecretKey, keyCache, maybeJsonDecode, rawJsonValue, resolvePendingCookie, signCookie, signCookieBun, signCookieNode, signCookieSubtle, signCookieSync, signCookieSyncImpl, unsignCookie, unsignCookieSync, unsignWithSecrets, unsignWithSecretsSync };
|
package/dist/cookie/error.js
CHANGED
|
@@ -16,8 +16,7 @@ var InvalidCookie = class InvalidCookie extends require_error.ElysiaError {
|
|
|
16
16
|
return new InvalidCookie(key, `"${key}" has invalid cookie signature`);
|
|
17
17
|
}
|
|
18
18
|
static secret(key) {
|
|
19
|
-
|
|
20
|
-
return new InvalidCookie(void 0, `Cookie is signed but no secret is provided`, 500);
|
|
19
|
+
return new InvalidCookie(key, `${key ? `Cookie "${key}"` : "A cookie"} is signed but \`cookie.secrets\` is missing or empty. Set it to a non-empty string: an empty secret signs with a zero-length key, which anyone can forge.`, 500);
|
|
21
20
|
}
|
|
22
21
|
};
|
|
23
22
|
|
package/dist/cookie/error.mjs
CHANGED
|
@@ -15,8 +15,7 @@ var InvalidCookie = class InvalidCookie extends ElysiaError {
|
|
|
15
15
|
return new InvalidCookie(key, `"${key}" has invalid cookie signature`);
|
|
16
16
|
}
|
|
17
17
|
static secret(key) {
|
|
18
|
-
|
|
19
|
-
return new InvalidCookie(void 0, `Cookie is signed but no secret is provided`, 500);
|
|
18
|
+
return new InvalidCookie(key, `${key ? `Cookie "${key}"` : "A cookie"} is signed but \`cookie.secrets\` is missing or empty. Set it to a non-empty string: an empty secret signs with a zero-length key, which anyone can forge.`, 500);
|
|
20
19
|
}
|
|
21
20
|
};
|
|
22
21
|
|
package/dist/cookie/lib.js
CHANGED
|
@@ -40,7 +40,11 @@ function serialize(name, value = "", options) {
|
|
|
40
40
|
if (value) value = encodeURIComponent(value);
|
|
41
41
|
let str = `${name}=${value}`;
|
|
42
42
|
const maxAge = options.maxAge;
|
|
43
|
-
if (maxAge !== void 0)
|
|
43
|
+
if (maxAge !== void 0) {
|
|
44
|
+
const age = Math.floor(maxAge);
|
|
45
|
+
if (!Number.isFinite(age)) throw new require_cookie_error.InvalidCookie(`Invalid cookie Max-Age ${JSON.stringify(maxAge)}.`);
|
|
46
|
+
str += "; Max-Age=" + age;
|
|
47
|
+
}
|
|
44
48
|
const domain = options.domain;
|
|
45
49
|
if (domain) {
|
|
46
50
|
if (COOKIE_ATTR_INVALID.test(domain)) throw new require_cookie_error.InvalidCookie(`Invalid cookie Domain ${JSON.stringify(domain)}.`);
|
package/dist/cookie/lib.mjs
CHANGED
|
@@ -39,7 +39,11 @@ function serialize(name, value = "", options) {
|
|
|
39
39
|
if (value) value = encodeURIComponent(value);
|
|
40
40
|
let str = `${name}=${value}`;
|
|
41
41
|
const maxAge = options.maxAge;
|
|
42
|
-
if (maxAge !== void 0)
|
|
42
|
+
if (maxAge !== void 0) {
|
|
43
|
+
const age = Math.floor(maxAge);
|
|
44
|
+
if (!Number.isFinite(age)) throw new InvalidCookie(`Invalid cookie Max-Age ${JSON.stringify(maxAge)}.`);
|
|
45
|
+
str += "; Max-Age=" + age;
|
|
46
|
+
}
|
|
43
47
|
const domain = options.domain;
|
|
44
48
|
if (domain) {
|
|
45
49
|
if (COOKIE_ATTR_INVALID.test(domain)) throw new InvalidCookie(`Invalid cookie Domain ${JSON.stringify(domain)}.`);
|
package/dist/cookie/serialize.js
CHANGED
|
@@ -7,7 +7,7 @@ function serializeCookie(cookies) {
|
|
|
7
7
|
if (!cookies || !require_utils.isNotEmpty(cookies)) return;
|
|
8
8
|
let set;
|
|
9
9
|
let isArray = false;
|
|
10
|
-
for (const key
|
|
10
|
+
for (const key of Object.keys(cookies)) {
|
|
11
11
|
if (!key) continue;
|
|
12
12
|
const property = cookies[key];
|
|
13
13
|
if (!property) continue;
|
|
@@ -6,7 +6,7 @@ function serializeCookie(cookies) {
|
|
|
6
6
|
if (!cookies || !isNotEmpty(cookies)) return;
|
|
7
7
|
let set;
|
|
8
8
|
let isArray = false;
|
|
9
|
-
for (const key
|
|
9
|
+
for (const key of Object.keys(cookies)) {
|
|
10
10
|
if (!key) continue;
|
|
11
11
|
const property = cookies[key];
|
|
12
12
|
if (!property) continue;
|
package/dist/cookie/types.d.ts
CHANGED
|
@@ -108,6 +108,16 @@ interface CookieOptions {
|
|
|
108
108
|
* `null` in the array makes Elysia accept an unsigned cookie (intended only for a one-way unsigned→signed migration)
|
|
109
109
|
*/
|
|
110
110
|
secrets?: string | null | (string | null)[];
|
|
111
|
+
/**
|
|
112
|
+
* Only use secret for signing cookie instead of secret + seperator + name
|
|
113
|
+
*
|
|
114
|
+
* Set to `false` once every signed cookie in circulation has been re-issued
|
|
115
|
+
*
|
|
116
|
+
* Applies to the app and route level
|
|
117
|
+
*
|
|
118
|
+
* @default true
|
|
119
|
+
*/
|
|
120
|
+
legacySignature?: boolean;
|
|
111
121
|
}
|
|
112
122
|
//#endregion
|
|
113
123
|
export { BaseCookie, CookieOptions };
|
package/dist/cookie/utils.js
CHANGED
|
@@ -69,7 +69,7 @@ async function parseCookieRaw(cookieString, config) {
|
|
|
69
69
|
if (v === void 0) continue;
|
|
70
70
|
let value = (0, deuri.default)(v) ?? v;
|
|
71
71
|
const signCheck = require_cookie_config.resolveSignSecrets(name, config);
|
|
72
|
-
if (signCheck !== void 0) value = await require_cookie_crypto.unsignWithSecrets(name, value, signCheck);
|
|
72
|
+
if (signCheck !== void 0) value = await require_cookie_crypto.unsignWithSecrets(name, value, signCheck, config.legacySignature);
|
|
73
73
|
out[name] = require_cookie_crypto.maybeJsonDecode(value);
|
|
74
74
|
}
|
|
75
75
|
return out;
|
|
@@ -85,7 +85,7 @@ function parseCookieRawSigned(cookieString, config) {
|
|
|
85
85
|
if (v === void 0) continue;
|
|
86
86
|
let value = (0, deuri.default)(v) ?? v;
|
|
87
87
|
const signCheck = require_cookie_config.resolveSignSecrets(name, config);
|
|
88
|
-
if (signCheck !== void 0) value = require_cookie_crypto.unsignWithSecretsSync(name, value, signCheck);
|
|
88
|
+
if (signCheck !== void 0) value = require_cookie_crypto.unsignWithSecretsSync(name, value, signCheck, config.legacySignature);
|
|
89
89
|
out[name] = require_cookie_crypto.maybeJsonDecode(value);
|
|
90
90
|
}
|
|
91
91
|
return out;
|
|
@@ -101,7 +101,10 @@ function buildCookieJar(set, raw, config, lazySign, deferDecode) {
|
|
|
101
101
|
if (entry.expires instanceof Date) entry.expires = new Date(entry.expires.getTime());
|
|
102
102
|
if (lazySign && typeof entry.value === "string") {
|
|
103
103
|
const secrets = require_cookie_config.resolveSignSecrets(name, config);
|
|
104
|
-
if (secrets !== void 0)
|
|
104
|
+
if (secrets !== void 0) {
|
|
105
|
+
entry["~unsign"] = secrets;
|
|
106
|
+
if (!config.legacySignature) entry["~strict"] = 1;
|
|
107
|
+
}
|
|
105
108
|
} else {
|
|
106
109
|
const value = entry.value;
|
|
107
110
|
if (value !== null && typeof value === "object") {
|
|
@@ -114,16 +117,27 @@ function buildCookieJar(set, raw, config, lazySign, deferDecode) {
|
|
|
114
117
|
return entry;
|
|
115
118
|
}
|
|
116
119
|
const cache = require_utils.nullObject();
|
|
120
|
+
function settle(key) {
|
|
121
|
+
if (!(key in store)) return;
|
|
122
|
+
const entry = materializeEntry(key);
|
|
123
|
+
if ("~unsign" in entry) require_cookie_crypto.resolvePendingCookie(entry, key);
|
|
124
|
+
}
|
|
117
125
|
return new Proxy(store, {
|
|
118
126
|
get(_, key) {
|
|
119
127
|
return cache[key] ??= new require_cookie_cookie.Cookie(key, set, key in store ? materializeEntry(key) : Object.assign(require_utils.nullObject(), config.defaults, config.fields[key]?.defaults));
|
|
120
128
|
},
|
|
129
|
+
has(target, key) {
|
|
130
|
+
if (typeof key === "string") settle(key);
|
|
131
|
+
return Reflect.has(target, key);
|
|
132
|
+
},
|
|
133
|
+
ownKeys(target) {
|
|
134
|
+
const keys = Reflect.ownKeys(target);
|
|
135
|
+
for (let i = 0; i < keys.length; i++) settle(keys[i]);
|
|
136
|
+
return keys;
|
|
137
|
+
},
|
|
121
138
|
getOwnPropertyDescriptor(target, key) {
|
|
122
|
-
if (typeof key === "string"
|
|
123
|
-
|
|
124
|
-
const entry = descriptor?.value;
|
|
125
|
-
if (entry && typeof entry === "object" && "~unsign" in entry) require_cookie_crypto.resolvePendingCookie(entry, String(key));
|
|
126
|
-
return descriptor;
|
|
139
|
+
if (typeof key === "string") settle(key);
|
|
140
|
+
return Reflect.getOwnPropertyDescriptor(target, key);
|
|
127
141
|
}
|
|
128
142
|
});
|
|
129
143
|
}
|
|
@@ -142,11 +156,11 @@ function collectSignPending(cookies, config) {
|
|
|
142
156
|
if (property["~raw"] === value) continue;
|
|
143
157
|
} else if (typeof value !== "string") value = value + "";
|
|
144
158
|
const secret = Array.isArray(r.secrets) ? r.secrets[0] ?? null : r.secrets;
|
|
145
|
-
if (secret
|
|
159
|
+
if (!secret?.trim()) throw new TypeError(`Cookie field "${key}" is signed but no \`secrets\` is provided.`);
|
|
146
160
|
(pending ??= []).push([
|
|
147
161
|
property,
|
|
148
162
|
value,
|
|
149
|
-
secret
|
|
163
|
+
require_cookie_crypto.deriveSignKey(secret, key)
|
|
150
164
|
]);
|
|
151
165
|
}
|
|
152
166
|
return pending;
|
|
@@ -156,8 +170,8 @@ function signCookieValues(cookies, config) {
|
|
|
156
170
|
if (!pending) return;
|
|
157
171
|
if (require_cookie_crypto.hasSyncHmac) {
|
|
158
172
|
for (let i = 0; i < pending.length; i++) {
|
|
159
|
-
const [property, value,
|
|
160
|
-
property.value = require_cookie_crypto.signCookieSyncImpl(value,
|
|
173
|
+
const [property, value, key] = pending[i];
|
|
174
|
+
property.value = require_cookie_crypto.signCookieSyncImpl(value, key);
|
|
161
175
|
}
|
|
162
176
|
return;
|
|
163
177
|
}
|
|
@@ -165,8 +179,8 @@ function signCookieValues(cookies, config) {
|
|
|
165
179
|
}
|
|
166
180
|
async function signPending(pending) {
|
|
167
181
|
for (let i = 0; i < pending.length; i++) {
|
|
168
|
-
const [property, value,
|
|
169
|
-
property.value = await require_cookie_crypto.signCookie(value,
|
|
182
|
+
const [property, value, key] = pending[i];
|
|
183
|
+
property.value = await require_cookie_crypto.signCookie(value, key);
|
|
170
184
|
}
|
|
171
185
|
}
|
|
172
186
|
|
package/dist/cookie/utils.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { dangerousKeys } from "../constants.mjs";
|
|
2
2
|
import { nullObject } from "../utils.mjs";
|
|
3
3
|
import { parse } from "./lib.mjs";
|
|
4
|
-
import { hasSyncHmac, maybeJsonDecode, rawJsonValue, resolvePendingCookie, signCookie, signCookieSyncImpl, unsignWithSecrets, unsignWithSecretsSync } from "./crypto.mjs";
|
|
4
|
+
import { deriveSignKey, hasSyncHmac, maybeJsonDecode, rawJsonValue, resolvePendingCookie, signCookie, signCookieSyncImpl, unsignWithSecrets, unsignWithSecretsSync } from "./crypto.mjs";
|
|
5
5
|
import { Cookie } from "./cookie.mjs";
|
|
6
6
|
import { compileCookieConfig, isCookieSigned, resolveSignSecrets } from "./config.mjs";
|
|
7
7
|
import decodeComponent from "deuri";
|
|
@@ -66,7 +66,7 @@ async function parseCookieRaw(cookieString, config) {
|
|
|
66
66
|
if (v === void 0) continue;
|
|
67
67
|
let value = decodeComponent(v) ?? v;
|
|
68
68
|
const signCheck = resolveSignSecrets(name, config);
|
|
69
|
-
if (signCheck !== void 0) value = await unsignWithSecrets(name, value, signCheck);
|
|
69
|
+
if (signCheck !== void 0) value = await unsignWithSecrets(name, value, signCheck, config.legacySignature);
|
|
70
70
|
out[name] = maybeJsonDecode(value);
|
|
71
71
|
}
|
|
72
72
|
return out;
|
|
@@ -82,7 +82,7 @@ function parseCookieRawSigned(cookieString, config) {
|
|
|
82
82
|
if (v === void 0) continue;
|
|
83
83
|
let value = decodeComponent(v) ?? v;
|
|
84
84
|
const signCheck = resolveSignSecrets(name, config);
|
|
85
|
-
if (signCheck !== void 0) value = unsignWithSecretsSync(name, value, signCheck);
|
|
85
|
+
if (signCheck !== void 0) value = unsignWithSecretsSync(name, value, signCheck, config.legacySignature);
|
|
86
86
|
out[name] = maybeJsonDecode(value);
|
|
87
87
|
}
|
|
88
88
|
return out;
|
|
@@ -98,7 +98,10 @@ function buildCookieJar(set, raw, config, lazySign, deferDecode) {
|
|
|
98
98
|
if (entry.expires instanceof Date) entry.expires = new Date(entry.expires.getTime());
|
|
99
99
|
if (lazySign && typeof entry.value === "string") {
|
|
100
100
|
const secrets = resolveSignSecrets(name, config);
|
|
101
|
-
if (secrets !== void 0)
|
|
101
|
+
if (secrets !== void 0) {
|
|
102
|
+
entry["~unsign"] = secrets;
|
|
103
|
+
if (!config.legacySignature) entry["~strict"] = 1;
|
|
104
|
+
}
|
|
102
105
|
} else {
|
|
103
106
|
const value = entry.value;
|
|
104
107
|
if (value !== null && typeof value === "object") {
|
|
@@ -111,16 +114,27 @@ function buildCookieJar(set, raw, config, lazySign, deferDecode) {
|
|
|
111
114
|
return entry;
|
|
112
115
|
}
|
|
113
116
|
const cache = nullObject();
|
|
117
|
+
function settle(key) {
|
|
118
|
+
if (!(key in store)) return;
|
|
119
|
+
const entry = materializeEntry(key);
|
|
120
|
+
if ("~unsign" in entry) resolvePendingCookie(entry, key);
|
|
121
|
+
}
|
|
114
122
|
return new Proxy(store, {
|
|
115
123
|
get(_, key) {
|
|
116
124
|
return cache[key] ??= new Cookie(key, set, key in store ? materializeEntry(key) : Object.assign(nullObject(), config.defaults, config.fields[key]?.defaults));
|
|
117
125
|
},
|
|
126
|
+
has(target, key) {
|
|
127
|
+
if (typeof key === "string") settle(key);
|
|
128
|
+
return Reflect.has(target, key);
|
|
129
|
+
},
|
|
130
|
+
ownKeys(target) {
|
|
131
|
+
const keys = Reflect.ownKeys(target);
|
|
132
|
+
for (let i = 0; i < keys.length; i++) settle(keys[i]);
|
|
133
|
+
return keys;
|
|
134
|
+
},
|
|
118
135
|
getOwnPropertyDescriptor(target, key) {
|
|
119
|
-
if (typeof key === "string"
|
|
120
|
-
|
|
121
|
-
const entry = descriptor?.value;
|
|
122
|
-
if (entry && typeof entry === "object" && "~unsign" in entry) resolvePendingCookie(entry, String(key));
|
|
123
|
-
return descriptor;
|
|
136
|
+
if (typeof key === "string") settle(key);
|
|
137
|
+
return Reflect.getOwnPropertyDescriptor(target, key);
|
|
124
138
|
}
|
|
125
139
|
});
|
|
126
140
|
}
|
|
@@ -139,11 +153,11 @@ function collectSignPending(cookies, config) {
|
|
|
139
153
|
if (property["~raw"] === value) continue;
|
|
140
154
|
} else if (typeof value !== "string") value = value + "";
|
|
141
155
|
const secret = Array.isArray(r.secrets) ? r.secrets[0] ?? null : r.secrets;
|
|
142
|
-
if (secret
|
|
156
|
+
if (!secret?.trim()) throw new TypeError(`Cookie field "${key}" is signed but no \`secrets\` is provided.`);
|
|
143
157
|
(pending ??= []).push([
|
|
144
158
|
property,
|
|
145
159
|
value,
|
|
146
|
-
secret
|
|
160
|
+
deriveSignKey(secret, key)
|
|
147
161
|
]);
|
|
148
162
|
}
|
|
149
163
|
return pending;
|
|
@@ -153,8 +167,8 @@ function signCookieValues(cookies, config) {
|
|
|
153
167
|
if (!pending) return;
|
|
154
168
|
if (hasSyncHmac) {
|
|
155
169
|
for (let i = 0; i < pending.length; i++) {
|
|
156
|
-
const [property, value,
|
|
157
|
-
property.value = signCookieSyncImpl(value,
|
|
170
|
+
const [property, value, key] = pending[i];
|
|
171
|
+
property.value = signCookieSyncImpl(value, key);
|
|
158
172
|
}
|
|
159
173
|
return;
|
|
160
174
|
}
|
|
@@ -162,8 +176,8 @@ function signCookieValues(cookies, config) {
|
|
|
162
176
|
}
|
|
163
177
|
async function signPending(pending) {
|
|
164
178
|
for (let i = 0; i < pending.length; i++) {
|
|
165
|
-
const [property, value,
|
|
166
|
-
property.value = await signCookie(value,
|
|
179
|
+
const [property, value, key] = pending[i];
|
|
180
|
+
property.value = await signCookie(value, key);
|
|
167
181
|
}
|
|
168
182
|
}
|
|
169
183
|
|
package/dist/handler/error.d.ts
CHANGED
|
@@ -2,17 +2,7 @@ import { AppHook } from "../types.js";
|
|
|
2
2
|
import { Context } from "../context.js";
|
|
3
3
|
|
|
4
4
|
//#region src/handler/error.d.ts
|
|
5
|
-
|
|
6
|
-
* Adopt the intercepted error's `type` into a problem the hook produced
|
|
7
|
-
* without one.
|
|
8
|
-
*
|
|
9
|
-
* `'about:blank'` is RFC 9457's "unspecified" default, so it's the only value
|
|
10
|
-
* worth replacing — an explicit type the handler set always wins.
|
|
11
|
-
*
|
|
12
|
-
* The result is copied rather than mutated: `.error(Class, value)` wraps a
|
|
13
|
-
* non-function into `() => value`, so the very same `ElysiaStatus` is replayed
|
|
14
|
-
* on every request and an in-place write would leak across requests
|
|
15
|
-
*/
|
|
5
|
+
declare const claimsProblemType: (error: any) => boolean;
|
|
16
6
|
declare function adoptErrorType(result: any, error: any): any;
|
|
17
7
|
/**
|
|
18
8
|
* Response served once every error hook has declined the error.
|
|
@@ -21,6 +11,27 @@ declare function adoptErrorType(result: any, error: any): any;
|
|
|
21
11
|
* which must land on *this* function rather than re-implementing it
|
|
22
12
|
*/
|
|
23
13
|
declare function fallbackResponse(context: Context, error: any, mapResponse: (response: unknown, set: Context['set'], context?: Context) => unknown, defaultError?: Response): unknown;
|
|
14
|
+
/**
|
|
15
|
+
* Numeric form of an annotated status, which may be written as a name.
|
|
16
|
+
* A numeric string keeps coercing so the production mask below can't be
|
|
17
|
+
* slipped past with `'502'`
|
|
18
|
+
*/
|
|
19
|
+
declare const resolveStatus: (status: unknown) => unknown;
|
|
20
|
+
/**
|
|
21
|
+
* Body served by an error that carries a status but no usable body:
|
|
22
|
+
* its declared `response`, otherwise its message
|
|
23
|
+
*/
|
|
24
|
+
declare function statusFallbackBody(error: any, status: unknown): any;
|
|
25
|
+
/**
|
|
26
|
+
* Read one annotation knob.
|
|
27
|
+
*
|
|
28
|
+
* Both knobs are canonically methods, so they're evaluated per serve and may
|
|
29
|
+
* be `async`. Running a stranger's function is side-effect surface (it may
|
|
30
|
+
* consume a stream or do IO), so it takes the same problem claim the shaping
|
|
31
|
+
* does — an unclaimed duck error never invokes one. A *value* annotation stays
|
|
32
|
+
* inert data and keeps duck-participating as it always has
|
|
33
|
+
*/
|
|
34
|
+
declare const readAnnotation: (self: any, key: "value" | "detail", claimsProblem: boolean) => any;
|
|
24
35
|
declare function createErrorHandler(onErrors: AppHook['error'] | undefined, mapResponse: (response: unknown, set: Context['set'], ...any: unknown[]) => unknown, defaultError?: Response, allowUnsafe?: boolean): (context: Context, error: Error) => unknown;
|
|
25
36
|
//#endregion
|
|
26
|
-
export { adoptErrorType, createErrorHandler, fallbackResponse };
|
|
37
|
+
export { adoptErrorType, claimsProblemType, createErrorHandler, fallbackResponse, readAnnotation, resolveStatus, statusFallbackBody };
|