elysia 2.0.0-beta.21 → 2.0.0-beta.23
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/_virtual/_rolldown/runtime.mjs +1 -0
- package/dist/adapter/bun/index.d.ts +6 -8
- package/dist/adapter/bun/index.js +6 -8
- package/dist/adapter/bun/index.mjs +7 -8
- package/dist/adapter/constants.mjs +1 -0
- package/dist/adapter/default-headers.mjs +1 -0
- package/dist/adapter/index.mjs +1 -0
- package/dist/adapter/origin.mjs +1 -0
- package/dist/adapter/response-ownership.mjs +1 -0
- package/dist/adapter/skip-clone.mjs +1 -0
- package/dist/adapter/types.mjs +1 -0
- package/dist/adapter/utils.d.ts +5 -8
- package/dist/adapter/utils.js +24 -18
- package/dist/adapter/utils.mjs +25 -18
- package/dist/adapter/web-standard/handler.mjs +2 -1
- package/dist/adapter/web-standard/index.mjs +1 -0
- package/dist/adapter/web-standard/utils.mjs +1 -0
- package/dist/base.d.ts +118 -69
- package/dist/base.js +214 -194
- package/dist/base.mjs +221 -200
- package/dist/compile/aot-capture.js +2 -2
- package/dist/compile/aot-capture.mjs +4 -3
- package/dist/compile/aot-emit.js +7 -8
- package/dist/compile/aot-emit.mjs +8 -8
- package/dist/compile/aot-reconstruct.mjs +3 -2
- package/dist/compile/aot.d.ts +3 -3
- package/dist/compile/aot.js +5 -5
- package/dist/compile/aot.mjs +6 -5
- package/dist/compile/handler/descriptor.d.ts +2 -5
- package/dist/compile/handler/descriptor.js +12 -17
- package/dist/compile/handler/descriptor.mjs +16 -21
- package/dist/compile/handler/frozen-validator.d.ts +2 -2
- package/dist/compile/handler/frozen-validator.js +3 -3
- package/dist/compile/handler/frozen-validator.mjs +4 -3
- package/dist/compile/handler/index.d.ts +3 -1
- package/dist/compile/handler/index.js +78 -118
- package/dist/compile/handler/index.mjs +84 -125
- package/dist/compile/handler/jit.d.ts +12 -12
- package/dist/compile/handler/jit.js +60 -43
- package/dist/compile/handler/jit.mjs +63 -47
- package/dist/compile/handler/params.d.ts +5 -1
- package/dist/compile/handler/params.js +14 -5
- package/dist/compile/handler/params.mjs +16 -7
- package/dist/compile/handler/reconstruct.d.ts +2 -2
- package/dist/compile/handler/reconstruct.js +2 -2
- package/dist/compile/handler/reconstruct.mjs +3 -2
- package/dist/compile/handler/static-clone-resolver.mjs +1 -0
- package/dist/compile/handler/utils.d.ts +13 -7
- package/dist/compile/handler/utils.js +75 -52
- package/dist/compile/handler/utils.mjs +77 -54
- package/dist/compile/jit-probe.mjs +1 -0
- package/dist/compile/lexer.js +4 -4
- package/dist/compile/lexer.mjs +5 -4
- package/dist/compile/utils.d.ts +2 -1
- package/dist/compile/utils.js +8 -3
- package/dist/compile/utils.mjs +8 -3
- package/dist/compiled.mjs +1 -0
- package/dist/constants.mjs +1 -0
- package/dist/context.d.ts +1 -1
- package/dist/context.js +1 -0
- package/dist/context.mjs +3 -1
- package/dist/cookie/config.d.ts +2 -2
- package/dist/cookie/config.js +21 -26
- package/dist/cookie/config.mjs +22 -26
- package/dist/cookie/cookie.mjs +1 -0
- package/dist/cookie/crypto.mjs +1 -0
- package/dist/cookie/error.mjs +1 -0
- package/dist/cookie/lib.mjs +1 -0
- package/dist/cookie/serialize.mjs +1 -0
- package/dist/cookie/types.mjs +1 -0
- package/dist/cookie/utils.d.ts +1 -1
- package/dist/cookie/utils.js +64 -45
- package/dist/cookie/utils.mjs +66 -46
- package/dist/error.d.ts +10 -6
- package/dist/error.js +22 -6
- package/dist/error.mjs +25 -9
- package/dist/generation.mjs +1 -0
- package/dist/handler/error.d.ts +12 -15
- package/dist/handler/error.js +43 -40
- package/dist/handler/error.mjs +45 -41
- package/dist/handler/fetch.js +59 -21
- package/dist/handler/fetch.mjs +61 -22
- package/dist/handler/utils.d.ts +16 -3
- package/dist/handler/utils.js +14 -13
- package/dist/handler/utils.mjs +16 -15
- package/dist/index.d.ts +9 -9
- package/dist/index.js +1 -0
- package/dist/index.mjs +3 -2
- package/dist/memory.mjs +1 -0
- package/dist/package.js +1 -1
- package/dist/package.mjs +2 -1
- package/dist/parse-query.js +76 -76
- package/dist/parse-query.mjs +77 -76
- package/dist/plugin/aot/bun.mjs +1 -0
- package/dist/plugin/aot/core.d.ts +1 -1
- package/dist/plugin/aot/core.js +7 -4
- package/dist/plugin/aot/core.mjs +8 -5
- package/dist/plugin/aot/esbuild.mjs +1 -0
- package/dist/plugin/aot/rspack-loader.mjs +1 -0
- package/dist/plugin/aot/rspack.mjs +1 -0
- package/dist/plugin/aot/treeshake.mjs +1 -0
- package/dist/plugin/aot/unplugin.mjs +4 -3
- package/dist/plugin/aot/vite.mjs +1 -0
- package/dist/plugin/aot/worker.mjs +1 -0
- package/dist/plugin/auto-head.mjs +1 -0
- package/dist/plugin/trace.mjs +1 -0
- package/dist/plugin/websocket.mjs +1 -0
- package/dist/route-table.mjs +1 -0
- package/dist/schema-snapshot.js +28 -3
- package/dist/schema-snapshot.mjs +29 -3
- package/dist/sucrose.d.ts +2 -2
- package/dist/sucrose.js +11 -11
- package/dist/sucrose.mjs +12 -11
- package/dist/trace.js +8 -10
- package/dist/trace.mjs +10 -11
- package/dist/type/bridge-live.d.ts +1 -1
- package/dist/type/bridge-live.mjs +1 -0
- package/dist/type/bridge.d.ts +1 -1
- package/dist/type/bridge.mjs +1 -0
- package/dist/type/coerce-plan.mjs +1 -0
- package/dist/type/coerce.d.ts +1 -1
- package/dist/type/coerce.mjs +1 -0
- package/dist/type/compat.mjs +1 -0
- package/dist/type/constants.d.ts +1 -1
- package/dist/type/constants.mjs +1 -0
- package/dist/type/elysia/accelerate.mjs +1 -0
- package/dist/type/elysia/array-buffer.d.ts +3 -2
- package/dist/type/elysia/array-buffer.js +5 -5
- package/dist/type/elysia/array-buffer.mjs +6 -5
- package/dist/type/elysia/array-string.mjs +1 -0
- package/dist/type/elysia/array.mjs +1 -0
- package/dist/type/elysia/boolean-string.mjs +1 -0
- package/dist/type/elysia/boolean.mjs +1 -0
- package/dist/type/elysia/cookie.mjs +1 -0
- package/dist/type/elysia/date.mjs +1 -0
- package/dist/type/elysia/file-type.mjs +1 -0
- package/dist/type/elysia/file.mjs +1 -0
- package/dist/type/elysia/files.mjs +1 -0
- package/dist/type/elysia/form.mjs +1 -0
- package/dist/type/elysia/integer-string.mjs +1 -0
- package/dist/type/elysia/integer.mjs +1 -0
- package/dist/type/elysia/intersect.mjs +1 -0
- package/dist/type/elysia/json-string.mjs +1 -0
- package/dist/type/elysia/keep-config.js +8 -8
- package/dist/type/elysia/keep-config.mjs +9 -8
- package/dist/type/elysia/maybe-empty.mjs +1 -0
- package/dist/type/elysia/no-validate.mjs +1 -0
- package/dist/type/elysia/nullable.mjs +1 -0
- package/dist/type/elysia/number.mjs +1 -0
- package/dist/type/elysia/numeric-enum.d.ts +4 -2
- package/dist/type/elysia/numeric-enum.mjs +1 -0
- package/dist/type/elysia/numeric.mjs +1 -0
- package/dist/type/elysia/object-string.mjs +1 -0
- package/dist/type/elysia/object.mjs +1 -0
- package/dist/type/elysia/optional.mjs +1 -0
- package/dist/type/elysia/problem.mjs +1 -0
- package/dist/type/elysia/string.mjs +1 -0
- package/dist/type/elysia/uint8-array.d.ts +2 -1
- package/dist/type/elysia/uint8-array.js +2 -2
- package/dist/type/elysia/uint8-array.mjs +3 -2
- package/dist/type/elysia/union-enum.mjs +1 -0
- package/dist/type/elysia/union.mjs +1 -0
- package/dist/type/elysia/utils.js +3 -3
- package/dist/type/elysia/utils.mjs +4 -3
- package/dist/type/exports.mjs +1 -0
- package/dist/type/index.mjs +2 -1
- package/dist/type/shared.mjs +1 -0
- package/dist/type/sync-require.mjs +1 -0
- package/dist/type/typebox-system-lite.mjs +1 -0
- package/dist/type/typebox-system-require.mjs +1 -0
- package/dist/type/typebox-type-live.mjs +1 -0
- package/dist/type/typebox-value-live.mjs +1 -0
- package/dist/type/typebox-value-ops.mjs +1 -0
- package/dist/type/typebox-value.mjs +1 -0
- package/dist/type/types.d.ts +1 -1
- package/dist/type/types.mjs +1 -0
- package/dist/type/utils.mjs +1 -0
- package/dist/type/validator/clean-safe.mjs +1 -0
- package/dist/type/validator/custom-error.js +41 -33
- package/dist/type/validator/custom-error.mjs +42 -33
- package/dist/type/validator/default-precompute.d.ts +2 -2
- package/dist/type/validator/default-precompute.js +10 -11
- package/dist/type/validator/default-precompute.mjs +13 -13
- package/dist/type/validator/exact-mirror.mjs +1 -0
- package/dist/type/validator/frozen-check.js +7 -7
- package/dist/type/validator/frozen-check.mjs +8 -7
- package/dist/type/validator/index.d.ts +2 -2
- package/dist/type/validator/index.js +4 -8
- package/dist/type/validator/index.mjs +5 -8
- package/dist/type/validator/string-codec-aot.d.ts +1 -1
- package/dist/type/validator/string-codec-aot.mjs +1 -0
- package/dist/type/validator/validator-cache.js +18 -18
- package/dist/type/validator/validator-cache.mjs +19 -18
- package/dist/types.d.ts +108 -70
- package/dist/types.mjs +1 -0
- package/dist/universal/constants.mjs +1 -0
- package/dist/universal/file.mjs +1 -0
- package/dist/universal/index.mjs +1 -0
- package/dist/universal/is-production.mjs +1 -0
- package/dist/universal/server.mjs +1 -0
- package/dist/utils.d.ts +49 -31
- package/dist/utils.js +221 -109
- package/dist/utils.mjs +215 -106
- package/dist/validator/index.d.ts +3 -3
- package/dist/validator/index.js +4 -4
- package/dist/validator/index.mjs +5 -4
- package/dist/validator/route.d.ts +2 -2
- package/dist/validator/route.mjs +1 -0
- package/dist/ws/context.js +1 -1
- package/dist/ws/context.mjs +2 -1
- package/dist/ws/index.mjs +1 -0
- package/dist/ws/parser.mjs +1 -0
- package/dist/ws/route.js +34 -25
- package/dist/ws/route.mjs +40 -30
- package/dist/ws/types.d.ts +2 -3
- package/dist/ws/types.mjs +1 -0
- package/package.json +2 -2
package/dist/cookie/utils.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
// @bun
|
|
1
2
|
import { nullObject } from "../utils.mjs";
|
|
2
3
|
import { InvalidCookie } from "./error.mjs";
|
|
3
4
|
import { parse } from "./lib.mjs";
|
|
4
5
|
import { deriveSignKey, hasSyncHmac, maybeJsonDecode, rawJsonValue, resolvePendingCookie, signCookie, signCookieSyncImpl, unsignWithSecrets, unsignWithSecretsSync } from "./crypto.mjs";
|
|
5
6
|
import { Cookie } from "./cookie.mjs";
|
|
6
|
-
import {
|
|
7
|
+
import { acceptsLegacySignature, isCookieSigned, resolveSignSecrets } from "./config.mjs";
|
|
7
8
|
import decodeComponent from "deuri";
|
|
8
9
|
|
|
9
10
|
//#region src/cookie/utils.ts
|
|
@@ -40,13 +41,13 @@ function parseCookieRawLazy(cookieString, config) {
|
|
|
40
41
|
return out;
|
|
41
42
|
}
|
|
42
43
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
44
|
+
* Stands in for a signed cookie that failed verification on a lane that can't
|
|
45
|
+
* verify on access (async HMAC, AOT); the jar rejects its first read.
|
|
46
|
+
* String key so a second Elysia copy agrees; null-prototype, which
|
|
47
|
+
* `JSON.parse` never yields, so no client-sent value (unsigned, or accepted by a
|
|
48
|
+
* `null` rotation secret) can forge it
|
|
48
49
|
*/
|
|
49
|
-
const
|
|
50
|
+
const invalidSignatureMarker = () => {
|
|
50
51
|
const marker = nullObject();
|
|
51
52
|
marker["~invalid"] = 1;
|
|
52
53
|
return marker;
|
|
@@ -63,10 +64,10 @@ async function parseCookieRaw(cookieString, config, lazy) {
|
|
|
63
64
|
let value = decodeComponent(v) ?? v;
|
|
64
65
|
const signCheck = resolveSignSecrets(name, config);
|
|
65
66
|
if (signCheck !== void 0) try {
|
|
66
|
-
value = await unsignWithSecrets(name, value, signCheck,
|
|
67
|
+
value = await unsignWithSecrets(name, value, signCheck, acceptsLegacySignature(name, config));
|
|
67
68
|
} catch (error) {
|
|
68
69
|
if (!lazy || !(error instanceof InvalidCookie)) throw error;
|
|
69
|
-
out[name] =
|
|
70
|
+
out[name] = invalidSignatureMarker();
|
|
70
71
|
continue;
|
|
71
72
|
}
|
|
72
73
|
out[name] = maybeJsonDecode(value);
|
|
@@ -84,31 +85,38 @@ function parseCookieRawSigned(cookieString, config, lazy) {
|
|
|
84
85
|
let value = decodeComponent(v) ?? v;
|
|
85
86
|
const signCheck = resolveSignSecrets(name, config);
|
|
86
87
|
if (signCheck !== void 0) try {
|
|
87
|
-
value = unsignWithSecretsSync(name, value, signCheck,
|
|
88
|
+
value = unsignWithSecretsSync(name, value, signCheck, acceptsLegacySignature(name, config));
|
|
88
89
|
} catch (error) {
|
|
89
90
|
if (!lazy || !(error instanceof InvalidCookie)) throw error;
|
|
90
|
-
out[name] =
|
|
91
|
+
out[name] = invalidSignatureMarker();
|
|
91
92
|
continue;
|
|
92
93
|
}
|
|
93
94
|
out[name] = maybeJsonDecode(value);
|
|
94
95
|
}
|
|
95
96
|
return out;
|
|
96
97
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
var CookieJarHandler = class {
|
|
99
|
+
constructor(setRef, config, lazySign, deferDecode) {
|
|
100
|
+
this.setRef = setRef;
|
|
101
|
+
this.config = config;
|
|
102
|
+
this.lazySign = lazySign;
|
|
103
|
+
this.deferDecode = deferDecode;
|
|
104
|
+
this.materialized = void 0;
|
|
105
|
+
this.cache = void 0;
|
|
106
|
+
}
|
|
107
|
+
materialize(store, name) {
|
|
108
|
+
if (this.materialized?.[name]) return store[name];
|
|
109
|
+
const config = this.config;
|
|
102
110
|
const rawValue = store[name];
|
|
103
111
|
const fieldDefaults = config.fields[name]?.defaults;
|
|
104
|
-
const entry = Object.assign(nullObject(), config.defaults, fieldDefaults, { value: deferDecode ? maybeJsonDecode(decodeComponent(rawValue) ?? rawValue) : rawValue });
|
|
112
|
+
const entry = Object.assign(nullObject(), config.defaults, fieldDefaults, { value: this.deferDecode ? maybeJsonDecode(decodeComponent(rawValue) ?? rawValue) : rawValue });
|
|
105
113
|
if (entry.expires instanceof Date) entry.expires = new Date(entry.expires.getTime());
|
|
106
114
|
if (rawValue?.["~invalid"] === 1 && Object.getPrototypeOf(rawValue) === null) entry["~unsign"] = 1;
|
|
107
|
-
else if (lazySign && typeof entry.value === "string") {
|
|
115
|
+
else if (this.lazySign && typeof entry.value === "string") {
|
|
108
116
|
const secrets = resolveSignSecrets(name, config);
|
|
109
117
|
if (secrets !== void 0) {
|
|
110
118
|
entry["~unsign"] = secrets;
|
|
111
|
-
if (!
|
|
119
|
+
if (!acceptsLegacySignature(name, config)) entry["~strict"] = 1;
|
|
112
120
|
}
|
|
113
121
|
} else {
|
|
114
122
|
const value = entry.value;
|
|
@@ -118,33 +126,33 @@ function buildCookieJar(set, raw, config, lazySign, deferDecode) {
|
|
|
118
126
|
}
|
|
119
127
|
}
|
|
120
128
|
store[name] = entry;
|
|
121
|
-
materialized[name] = 1;
|
|
129
|
+
(this.materialized ??= nullObject())[name] = 1;
|
|
122
130
|
return entry;
|
|
123
131
|
}
|
|
124
|
-
|
|
125
|
-
function settle(key) {
|
|
132
|
+
settle(store, key) {
|
|
126
133
|
if (!(key in store)) return;
|
|
127
|
-
const entry =
|
|
134
|
+
const entry = this.materialize(store, key);
|
|
128
135
|
if ("~unsign" in entry) resolvePendingCookie(entry, key);
|
|
129
136
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
ownKeys(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
137
|
+
get(store, key) {
|
|
138
|
+
return (this.cache ??= nullObject())[key] ??= new Cookie(key, this.setRef, key in store ? this.materialize(store, key) : Object.assign(nullObject(), this.config.defaults, this.config.fields[key]?.defaults));
|
|
139
|
+
}
|
|
140
|
+
has(store, key) {
|
|
141
|
+
if (typeof key === "string") this.settle(store, key);
|
|
142
|
+
return Reflect.has(store, key);
|
|
143
|
+
}
|
|
144
|
+
ownKeys(store) {
|
|
145
|
+
const keys = Reflect.ownKeys(store);
|
|
146
|
+
for (let i = 0; i < keys.length; i++) this.settle(store, keys[i]);
|
|
147
|
+
return keys;
|
|
148
|
+
}
|
|
149
|
+
getOwnPropertyDescriptor(store, key) {
|
|
150
|
+
if (typeof key === "string") this.settle(store, key);
|
|
151
|
+
return Reflect.getOwnPropertyDescriptor(store, key);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
function buildCookieJar(set, raw, config, lazySign, deferDecode) {
|
|
155
|
+
return new Proxy(raw, new CookieJarHandler(set, config, lazySign, deferDecode));
|
|
148
156
|
}
|
|
149
157
|
function collectSignPending(cookies, config) {
|
|
150
158
|
if (!cookies || !config.hasSign) return;
|
|
@@ -171,12 +179,24 @@ function collectSignPending(cookies, config) {
|
|
|
171
179
|
}
|
|
172
180
|
return pending;
|
|
173
181
|
}
|
|
174
|
-
function dropSigned(cookies, config) {
|
|
175
|
-
|
|
182
|
+
function dropSigned(cookies, config, set) {
|
|
183
|
+
if (set) Object.defineProperty(set, "~signFailed", {
|
|
184
|
+
value: true,
|
|
185
|
+
configurable: true
|
|
186
|
+
});
|
|
187
|
+
const signed = (name) => config.fields[name]?.sign || config.globalSign === true || config.globalSignSet?.has(name);
|
|
188
|
+
let kept = false;
|
|
189
|
+
for (const name in cookies) if (signed(name) && !Reflect.deleteProperty(cookies, name)) kept = true;
|
|
190
|
+
if (kept && set?.cookie === cookies) {
|
|
191
|
+
const copy = nullObject();
|
|
192
|
+
for (const name in cookies) if (!signed(name)) copy[name] = cookies[name];
|
|
193
|
+
set.cookie = copy;
|
|
194
|
+
}
|
|
176
195
|
}
|
|
177
|
-
function signCookieValues(cookies, config) {
|
|
196
|
+
function signCookieValues(cookies, config, set) {
|
|
178
197
|
let pending;
|
|
179
198
|
try {
|
|
199
|
+
if (set?.["~signFailed"]) throw new TypeError("A signed cookie of this request failed to sign");
|
|
180
200
|
pending = collectSignPending(cookies, config);
|
|
181
201
|
if (!pending) return;
|
|
182
202
|
if (hasSyncHmac) {
|
|
@@ -187,11 +207,11 @@ function signCookieValues(cookies, config) {
|
|
|
187
207
|
return;
|
|
188
208
|
}
|
|
189
209
|
} catch (error) {
|
|
190
|
-
dropSigned(cookies, config);
|
|
210
|
+
dropSigned(cookies, config, set);
|
|
191
211
|
throw error;
|
|
192
212
|
}
|
|
193
213
|
return signPending(pending).catch((error) => {
|
|
194
|
-
dropSigned(cookies, config);
|
|
214
|
+
dropSigned(cookies, config, set);
|
|
195
215
|
throw error;
|
|
196
216
|
});
|
|
197
217
|
}
|
package/dist/error.d.ts
CHANGED
|
@@ -181,6 +181,8 @@ type ProblemResponseBody<Status extends number, P> = Omit<{
|
|
|
181
181
|
}, keyof P> & Omit<P, 'status'> & {
|
|
182
182
|
status: Status;
|
|
183
183
|
};
|
|
184
|
+
/** Title of a status, as `problemBody` fills it */
|
|
185
|
+
declare const titleOf: (status: number) => string;
|
|
184
186
|
declare function problemBody(p: Problem): Record<string, unknown> & {
|
|
185
187
|
status: number;
|
|
186
188
|
};
|
|
@@ -234,9 +236,9 @@ type TaggedHTTPError<Type extends string, Annotation = {}> = {
|
|
|
234
236
|
* the instance to a response on its own, no `.error(Class, handler)` needed
|
|
235
237
|
*
|
|
236
238
|
* Everything an owned `HTTPError` serves is an RFC 9457 problem document:
|
|
237
|
-
* `type` is the problem type carried on the wire,
|
|
238
|
-
*
|
|
239
|
-
*
|
|
239
|
+
* `type` is the problem type carried on the wire, and the body (or the error
|
|
240
|
+
* message, when there is none) becomes `detail`, an object nested verbatim
|
|
241
|
+
* and never merged into the envelope
|
|
240
242
|
*
|
|
241
243
|
* - `detail()` - the common case. Whatever it returns becomes the `detail`
|
|
242
244
|
* member of the problem document, verbatim, objects included. The envelope
|
|
@@ -303,8 +305,10 @@ declare abstract class HTTPError<const in out T extends string = string> extends
|
|
|
303
305
|
readonly code?: string;
|
|
304
306
|
/**
|
|
305
307
|
* Absolute base for the RFC 9457 `type` URI, applied to every class made
|
|
306
|
-
* by {@link HTTPError.id} and to
|
|
307
|
-
*
|
|
308
|
+
* by {@link HTTPError.id} and to the built-in `ElysiaError`s (`NotFound`,
|
|
309
|
+
* `ParseError`, `InvalidCookie`, `InternalServerError`) both derive `type`
|
|
310
|
+
* from the same slug. Request validation is the exception, it keeps
|
|
311
|
+
* `type: 'validation'` unprefixed
|
|
308
312
|
*
|
|
309
313
|
* @example
|
|
310
314
|
* ```ts
|
|
@@ -375,4 +379,4 @@ declare abstract class HTTPError<const in out T extends string = string> extends
|
|
|
375
379
|
}>;
|
|
376
380
|
}
|
|
377
381
|
//#endregion
|
|
378
|
-
export { ElysiaError, ElysiaStatus, HTTPError, InternalServerError, MAX_ERRORS, NotFound, NumericStatus, PROBLEM_JSON, ParseError, Problem, ProblemResponseBody, SelectiveProblem, SelectiveStatus, StatusResponse, TaggedHTTPError, ValidationError, ValidationErrorResponse, elysiaErrorProblem, internalServerErrorBody, internalServerErrorBodyString, internalServerErrorResponse, isProduction, problem, problemBody, problemResponse, problemTypeOf, status, subValueAt, validationDetail };
|
|
382
|
+
export { ElysiaError, ElysiaStatus, HTTPError, InternalServerError, MAX_ERRORS, NotFound, NumericStatus, PROBLEM_JSON, ParseError, Problem, ProblemResponseBody, SelectiveProblem, SelectiveStatus, StatusResponse, TaggedHTTPError, ValidationError, ValidationErrorResponse, elysiaErrorProblem, internalServerErrorBody, internalServerErrorBodyString, internalServerErrorResponse, isProduction, problem, problemBody, problemResponse, problemTypeOf, status, subValueAt, titleOf, validationDetail };
|
package/dist/error.js
CHANGED
|
@@ -304,7 +304,14 @@ var ValidationError = class extends ElysiaError {
|
|
|
304
304
|
resolved = this.#thunk() ?? [];
|
|
305
305
|
if (resolved.length > 64) resolved = resolved.slice(0, 64);
|
|
306
306
|
resolved = scopeIssues(resolved);
|
|
307
|
-
|
|
307
|
+
let sub = walkSubSchema(this.schema, resolved[0]?.instancePath);
|
|
308
|
+
const missing = resolved[0]?.keyword === "required" && sub?.properties ? resolved[0].params?.requiredProperties : void 0;
|
|
309
|
+
if (Array.isArray(missing)) {
|
|
310
|
+
for (const key of missing) if (sub.properties[key]?.error !== void 0) {
|
|
311
|
+
sub = sub.properties[key];
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
308
315
|
if (sub?.error !== void 0) custom = typeof sub.error === "function" ? sub.error(production && !allowUnsafe ? {
|
|
309
316
|
type: "validation",
|
|
310
317
|
on: type,
|
|
@@ -333,8 +340,9 @@ var ValidationError = class extends ElysiaError {
|
|
|
333
340
|
if (!this.errors) return [];
|
|
334
341
|
return this.#collapseCoercionErrors(this.errors.filter(Boolean)).map((e) => {
|
|
335
342
|
if (!e) return e;
|
|
343
|
+
const raw = e.path ?? e.instancePath;
|
|
336
344
|
const issue = {
|
|
337
|
-
path: Array.isArray(
|
|
345
|
+
path: Array.isArray(raw) && raw.length ? raw.map(segmentString).join(".") : typeof raw === "string" && raw ? raw.replace(/^\//, "").replace(/\//g, ".") : "root",
|
|
338
346
|
message: e.message ?? "",
|
|
339
347
|
schemaPath: e.schemaPath,
|
|
340
348
|
params: e.params
|
|
@@ -492,12 +500,19 @@ var ElysiaStatus = class {
|
|
|
492
500
|
const response = res ?? (code in require_constants.StatusMapBack ? require_constants.StatusMapBack[code] : code);
|
|
493
501
|
this.status = require_constants.StatusMap[code] ?? code;
|
|
494
502
|
if (!emptyHttpStatus.has(this.status)) this.response = response;
|
|
503
|
+
else if (headers) {
|
|
504
|
+
const kept = {};
|
|
505
|
+
for (const key of Object.keys(headers)) if (key.toLowerCase() !== "content-type") kept[key] = headers[key];
|
|
506
|
+
headers = kept;
|
|
507
|
+
}
|
|
495
508
|
this.headers = headers;
|
|
496
509
|
}
|
|
497
510
|
};
|
|
498
511
|
Object.defineProperty(ElysiaStatus, "name", { value: "ElysiaStatus" });
|
|
499
512
|
const status = (code, response) => new ElysiaStatus(code, response);
|
|
500
513
|
const PROBLEM_JSON = "application/problem+json";
|
|
514
|
+
/** Title of a status, as `problemBody` fills it */
|
|
515
|
+
const titleOf = (status) => require_constants.StatusMapBack[status] ?? "Error";
|
|
501
516
|
function problemBody(p) {
|
|
502
517
|
const status = typeof p.status === "string" ? require_constants.StatusMap[p.status] ?? 500 : p.status ?? 500;
|
|
503
518
|
const body = {
|
|
@@ -505,7 +520,7 @@ function problemBody(p) {
|
|
|
505
520
|
...p,
|
|
506
521
|
status
|
|
507
522
|
};
|
|
508
|
-
|
|
523
|
+
body.title ??= titleOf(status);
|
|
509
524
|
return body;
|
|
510
525
|
}
|
|
511
526
|
function problemResponse(p, headers) {
|
|
@@ -571,9 +586,9 @@ function problem(statusOrDetail, detail) {
|
|
|
571
586
|
* the instance to a response on its own, no `.error(Class, handler)` needed
|
|
572
587
|
*
|
|
573
588
|
* Everything an owned `HTTPError` serves is an RFC 9457 problem document:
|
|
574
|
-
* `type` is the problem type carried on the wire,
|
|
575
|
-
*
|
|
576
|
-
*
|
|
589
|
+
* `type` is the problem type carried on the wire, and the body (or the error
|
|
590
|
+
* message, when there is none) becomes `detail`, an object nested verbatim
|
|
591
|
+
* and never merged into the envelope
|
|
577
592
|
*
|
|
578
593
|
* - `detail()` - the common case. Whatever it returns becomes the `detail`
|
|
579
594
|
* member of the problem document, verbatim, objects included. The envelope
|
|
@@ -662,4 +677,5 @@ exports.problemResponse = problemResponse;
|
|
|
662
677
|
exports.problemTypeOf = problemTypeOf;
|
|
663
678
|
exports.status = status;
|
|
664
679
|
exports.subValueAt = subValueAt;
|
|
680
|
+
exports.titleOf = titleOf;
|
|
665
681
|
exports.validationDetail = validationDetail;
|
package/dist/error.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @bun
|
|
1
2
|
import { StatusMap, StatusMapBack } from "./constants.mjs";
|
|
2
3
|
import { Create } from "./type/bridge.mjs";
|
|
3
4
|
import { isProduction } from "./universal/is-production.mjs";
|
|
@@ -48,7 +49,7 @@ function problemTypeOf(code) {
|
|
|
48
49
|
}
|
|
49
50
|
/**
|
|
50
51
|
* Problem members an `ElysiaError` serves. `title` is left to `problemBody`,
|
|
51
|
-
* which derives it from the status
|
|
52
|
+
* which derives it from the status \u2014 so `response` is only worth serving as
|
|
52
53
|
* `detail` when it says something the title doesn't
|
|
53
54
|
*/
|
|
54
55
|
function elysiaErrorProblem(error) {
|
|
@@ -303,7 +304,14 @@ var ValidationError = class extends ElysiaError {
|
|
|
303
304
|
resolved = this.#thunk() ?? [];
|
|
304
305
|
if (resolved.length > 64) resolved = resolved.slice(0, 64);
|
|
305
306
|
resolved = scopeIssues(resolved);
|
|
306
|
-
|
|
307
|
+
let sub = walkSubSchema(this.schema, resolved[0]?.instancePath);
|
|
308
|
+
const missing = resolved[0]?.keyword === "required" && sub?.properties ? resolved[0].params?.requiredProperties : void 0;
|
|
309
|
+
if (Array.isArray(missing)) {
|
|
310
|
+
for (const key of missing) if (sub.properties[key]?.error !== void 0) {
|
|
311
|
+
sub = sub.properties[key];
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
307
315
|
if (sub?.error !== void 0) custom = typeof sub.error === "function" ? sub.error(production && !allowUnsafe ? {
|
|
308
316
|
type: "validation",
|
|
309
317
|
on: type,
|
|
@@ -332,8 +340,9 @@ var ValidationError = class extends ElysiaError {
|
|
|
332
340
|
if (!this.errors) return [];
|
|
333
341
|
return this.#collapseCoercionErrors(this.errors.filter(Boolean)).map((e) => {
|
|
334
342
|
if (!e) return e;
|
|
343
|
+
const raw = e.path ?? e.instancePath;
|
|
335
344
|
const issue = {
|
|
336
|
-
path: Array.isArray(
|
|
345
|
+
path: Array.isArray(raw) && raw.length ? raw.map(segmentString).join(".") : typeof raw === "string" && raw ? raw.replace(/^\//, "").replace(/\//g, ".") : "root",
|
|
337
346
|
message: e.message ?? "",
|
|
338
347
|
schemaPath: e.schemaPath,
|
|
339
348
|
params: e.params
|
|
@@ -491,12 +500,19 @@ var ElysiaStatus = class {
|
|
|
491
500
|
const response = res ?? (code in StatusMapBack ? StatusMapBack[code] : code);
|
|
492
501
|
this.status = StatusMap[code] ?? code;
|
|
493
502
|
if (!emptyHttpStatus.has(this.status)) this.response = response;
|
|
503
|
+
else if (headers) {
|
|
504
|
+
const kept = {};
|
|
505
|
+
for (const key of Object.keys(headers)) if (key.toLowerCase() !== "content-type") kept[key] = headers[key];
|
|
506
|
+
headers = kept;
|
|
507
|
+
}
|
|
494
508
|
this.headers = headers;
|
|
495
509
|
}
|
|
496
510
|
};
|
|
497
511
|
Object.defineProperty(ElysiaStatus, "name", { value: "ElysiaStatus" });
|
|
498
512
|
const status = (code, response) => new ElysiaStatus(code, response);
|
|
499
513
|
const PROBLEM_JSON = "application/problem+json";
|
|
514
|
+
/** Title of a status, as `problemBody` fills it */
|
|
515
|
+
const titleOf = (status) => StatusMapBack[status] ?? "Error";
|
|
500
516
|
function problemBody(p) {
|
|
501
517
|
const status = typeof p.status === "string" ? StatusMap[p.status] ?? 500 : p.status ?? 500;
|
|
502
518
|
const body = {
|
|
@@ -504,7 +520,7 @@ function problemBody(p) {
|
|
|
504
520
|
...p,
|
|
505
521
|
status
|
|
506
522
|
};
|
|
507
|
-
|
|
523
|
+
body.title ??= titleOf(status);
|
|
508
524
|
return body;
|
|
509
525
|
}
|
|
510
526
|
function problemResponse(p, headers) {
|
|
@@ -570,9 +586,9 @@ function problem(statusOrDetail, detail) {
|
|
|
570
586
|
* the instance to a response on its own, no `.error(Class, handler)` needed
|
|
571
587
|
*
|
|
572
588
|
* Everything an owned `HTTPError` serves is an RFC 9457 problem document:
|
|
573
|
-
* `type` is the problem type carried on the wire,
|
|
574
|
-
*
|
|
575
|
-
*
|
|
589
|
+
* `type` is the problem type carried on the wire, and the body (or the error
|
|
590
|
+
* message, when there is none) becomes `detail`, an object nested verbatim
|
|
591
|
+
* and never merged into the envelope
|
|
576
592
|
*
|
|
577
593
|
* - `detail()` - the common case. Whatever it returns becomes the `detail`
|
|
578
594
|
* member of the problem document, verbatim, objects included. The envelope
|
|
@@ -594,7 +610,7 @@ function problem(statusOrDetail, detail) {
|
|
|
594
610
|
* return { balance: 0, currency: 'usd' }
|
|
595
611
|
* }
|
|
596
612
|
* }
|
|
597
|
-
* //
|
|
613
|
+
* // \u2192 { type: 'OUT_OF_CREDIT', title: 'Payment Required', status: 402,
|
|
598
614
|
* // detail: { balance: 0, currency: 'usd' } }
|
|
599
615
|
*
|
|
600
616
|
* class Overdrawn extends HTTPError<'OVERDRAWN'> {
|
|
@@ -641,4 +657,4 @@ var HTTPError = class HTTPError extends Error {
|
|
|
641
657
|
};
|
|
642
658
|
|
|
643
659
|
//#endregion
|
|
644
|
-
export { ElysiaError, ElysiaStatus, HTTPError, InternalServerError, MAX_ERRORS, NotFound, PROBLEM_JSON, ParseError, ValidationError, elysiaErrorProblem, internalServerErrorBody, internalServerErrorBodyString, internalServerErrorResponse, isProduction, problem, problemBody, problemResponse, problemTypeOf, status, subValueAt, validationDetail };
|
|
660
|
+
export { ElysiaError, ElysiaStatus, HTTPError, InternalServerError, MAX_ERRORS, NotFound, PROBLEM_JSON, ParseError, ValidationError, elysiaErrorProblem, internalServerErrorBody, internalServerErrorBodyString, internalServerErrorResponse, isProduction, problem, problemBody, problemResponse, problemTypeOf, status, subValueAt, titleOf, validationDetail };
|
package/dist/generation.mjs
CHANGED
package/dist/handler/error.d.ts
CHANGED
|
@@ -2,7 +2,12 @@ import { Context } from "../context.js";
|
|
|
2
2
|
import { AppHook } from "../types.js";
|
|
3
3
|
|
|
4
4
|
//#region src/handler/error.d.ts
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Whether an error claims a problem type, judged on `type` as the caller
|
|
7
|
+
* read it once: a getter read again could answer anything else, `undefined`
|
|
8
|
+
* included
|
|
9
|
+
*/
|
|
10
|
+
declare const claimsProblemType: (error: any, type: unknown) => boolean;
|
|
6
11
|
declare function adoptErrorType(result: any, error: any): any;
|
|
7
12
|
/**
|
|
8
13
|
* Response served once every error hook has declined the error.
|
|
@@ -11,25 +16,17 @@ declare function adoptErrorType(result: any, error: any): any;
|
|
|
11
16
|
* which must land on *this* function rather than re-implementing it
|
|
12
17
|
*/
|
|
13
18
|
declare function fallbackResponse(context: Context, error: any, mapResponse: (response: unknown, set: Context['set'], context?: Context) => unknown): 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
19
|
declare const resolveStatus: (status: unknown) => unknown;
|
|
20
20
|
/**
|
|
21
21
|
* Body served by an error that carries a status but no usable body:
|
|
22
|
-
* its declared `response`, otherwise its message
|
|
22
|
+
* its declared `response`, otherwise its message, or `mask` in its place
|
|
23
|
+
* on a production 5xx
|
|
23
24
|
*/
|
|
24
|
-
declare function statusFallbackBody(error: any, status: unknown): any;
|
|
25
|
+
declare function statusFallbackBody(error: any, status: unknown, mask?: string): any;
|
|
25
26
|
/**
|
|
26
|
-
* Read one annotation knob.
|
|
27
|
-
*
|
|
28
|
-
*
|
|
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
|
|
27
|
+
* Read one annotation knob, a method (may be `async`) or a plain value.
|
|
28
|
+
* A method may have side effects, so only an error claiming a problem type
|
|
29
|
+
* gets it invoked; a plain value is read from any error
|
|
33
30
|
*/
|
|
34
31
|
declare const readAnnotation: (self: any, key: "value" | "detail", claimsProblem: boolean) => any;
|
|
35
32
|
declare function createErrorHandler(onErrors: AppHook['error'] | undefined, mapResponse: (response: unknown, set: Context['set'], ...any: unknown[]) => unknown, allowUnsafe?: boolean): (context: Context, error: Error, sign?: ((set: Context["set"]) => unknown) | undefined) => unknown;
|
package/dist/handler/error.js
CHANGED
|
@@ -31,14 +31,21 @@ function parseQuery(context) {
|
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
const isPristineNotFound = (context, error) => error instanceof require_error.NotFound && error.response === "Not Found" && !context.set.cookie && !require_utils.isNotEmpty(context.set.headers);
|
|
34
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Whether an error claims a problem type, judged on `type` as the caller
|
|
36
|
+
* read it once: a getter read again could answer anything else, `undefined`
|
|
37
|
+
* included
|
|
38
|
+
*/
|
|
39
|
+
const claimsProblemType = (error, type) => typeof type === "string" ? !(error instanceof require_error.ValidationError) && error.constructor?.name !== "ValidationError" : error instanceof require_error.HTTPError;
|
|
35
40
|
function adoptErrorType(result, error) {
|
|
36
41
|
const body = result?.response;
|
|
37
|
-
|
|
42
|
+
const type = error?.type;
|
|
43
|
+
if (typeof type !== "string" || !claimsProblemType(error, type) || body?.type !== "about:blank" || result.headers?.["content-type"] !== "application/problem+json") return result;
|
|
44
|
+
const code = error.code;
|
|
38
45
|
return new require_error.ElysiaStatus(result.status, {
|
|
39
46
|
...body,
|
|
40
|
-
type
|
|
41
|
-
...typeof
|
|
47
|
+
type,
|
|
48
|
+
...typeof code === "string" ? { code } : {}
|
|
42
49
|
}, result.headers);
|
|
43
50
|
}
|
|
44
51
|
/**
|
|
@@ -55,38 +62,35 @@ function fallbackResponse(context, error, mapResponse) {
|
|
|
55
62
|
} catch {}
|
|
56
63
|
return fallbackErrorResponse(context, error, mapResponse);
|
|
57
64
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Numeric form of an annotated status, which may be written as a name.
|
|
60
|
-
* A numeric string keeps coercing so the production mask below can't be
|
|
61
|
-
* slipped past with `'502'`
|
|
62
|
-
*/
|
|
63
65
|
const resolveStatus = (status) => typeof status === "string" ? require_constants.StatusMap[status] ?? +status : status;
|
|
64
66
|
/**
|
|
65
67
|
* Body served by an error that carries a status but no usable body:
|
|
66
|
-
* its declared `response`, otherwise its message
|
|
68
|
+
* its declared `response`, otherwise its message, or `mask` in its place
|
|
69
|
+
* on a production 5xx
|
|
67
70
|
*/
|
|
68
|
-
function statusFallbackBody(error, status) {
|
|
71
|
+
function statusFallbackBody(error, status, mask = "Internal Server Error") {
|
|
69
72
|
const masked = require_universal_is_production.isProduction() && status >= 500;
|
|
70
73
|
const declared = error.response;
|
|
71
|
-
return declared !== void 0 && !(masked && typeof declared === "object") ? declared : masked ?
|
|
74
|
+
return declared !== void 0 && !(masked && typeof declared === "object") ? declared : masked ? mask : error.message ?? "";
|
|
72
75
|
}
|
|
73
76
|
/**
|
|
74
77
|
* RFC 9457 problem document carrying `detail` verbatim, mirroring `problem()`.
|
|
78
|
+
* `type` comes in as the value the claim was checked on, and `code` is read
|
|
79
|
+
* once, so a getter can't put anything but a string on the wire
|
|
75
80
|
*/
|
|
76
|
-
const problemOf = (self, detail, status, claimsProblem) =>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
const problemOf = (self, type, detail, status, claimsProblem) => {
|
|
82
|
+
const code = claimsProblem ? self.code : void 0;
|
|
83
|
+
return new require_error.ElysiaStatus(status, require_error.problemBody({
|
|
84
|
+
type: typeof type === "string" ? type : "about:blank",
|
|
85
|
+
...typeof code === "string" ? { code } : {},
|
|
86
|
+
detail,
|
|
87
|
+
status
|
|
88
|
+
}), { "content-type": require_error.PROBLEM_JSON });
|
|
89
|
+
};
|
|
82
90
|
/**
|
|
83
|
-
* Read one annotation knob.
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* be `async`. Running a stranger's function is side-effect surface (it may
|
|
87
|
-
* consume a stream or do IO), so it takes the same problem claim the shaping
|
|
88
|
-
* does — an unclaimed duck error never invokes one. A *value* annotation stays
|
|
89
|
-
* inert data and keeps duck-participating as it always has
|
|
91
|
+
* Read one annotation knob, a method (may be `async`) or a plain value.
|
|
92
|
+
* A method may have side effects, so only an error claiming a problem type
|
|
93
|
+
* gets it invoked; a plain value is read from any error
|
|
90
94
|
*/
|
|
91
95
|
const readAnnotation = (self, key, claimsProblem) => {
|
|
92
96
|
const annotation = self[key];
|
|
@@ -98,7 +102,8 @@ function fallbackErrorResponse(context, error, mapResponse) {
|
|
|
98
102
|
const self = error ?? {};
|
|
99
103
|
const status = resolveStatus(self.status);
|
|
100
104
|
const owned = error instanceof require_error.HTTPError;
|
|
101
|
-
const
|
|
105
|
+
const type = self.type;
|
|
106
|
+
const claimsProblem = claimsProblemType(error, type);
|
|
102
107
|
const served = typeof status === "number" ? status : resolveStatus(context.set.status);
|
|
103
108
|
const failed = (cause) => {
|
|
104
109
|
context.set.status = 500;
|
|
@@ -109,32 +114,29 @@ function fallbackErrorResponse(context, error, mapResponse) {
|
|
|
109
114
|
}
|
|
110
115
|
const legacy = () => {
|
|
111
116
|
if (error?.status) return mapResponse(statusFallbackBody(error, status), context.set, context);
|
|
112
|
-
if (error?.message != null)
|
|
113
|
-
if (context.set.status === void 0 || context.set.status === 200) context.set.status = 500;
|
|
114
|
-
return mapResponse(require_error.internalServerErrorResponse(error), context.set, context);
|
|
115
|
-
}
|
|
117
|
+
if (error?.message != null && (context.set.status === void 0 || context.set.status === 200)) context.set.status = 500;
|
|
116
118
|
return mapResponse(require_error.internalServerErrorResponse(error), context.set, context);
|
|
117
119
|
};
|
|
118
120
|
const serveMessage = () => {
|
|
119
121
|
if (!claimsProblem) return legacy();
|
|
120
122
|
mergeHeaders();
|
|
121
|
-
return mapResponse(problemOf(self, statusFallbackBody(error, served), served, claimsProblem), context.set, context);
|
|
123
|
+
return mapResponse(problemOf(self, type, statusFallbackBody(error, served, require_error.titleOf(served)), served, claimsProblem), context.set, context);
|
|
122
124
|
};
|
|
123
|
-
const
|
|
125
|
+
const serveAnnotation = (key) => {
|
|
124
126
|
let annotation;
|
|
125
127
|
try {
|
|
126
128
|
annotation = readAnnotation(self, key, claimsProblem);
|
|
127
129
|
} catch (cause) {
|
|
128
130
|
return failed(cause);
|
|
129
131
|
}
|
|
130
|
-
if (annotation === void 0) return key === "value" ?
|
|
132
|
+
if (annotation === void 0) return key === "value" ? serveAnnotation("detail") : serveMessage();
|
|
131
133
|
if (annotation instanceof Promise) return annotation.then((resolved) => {
|
|
132
|
-
if (resolved === void 0) return key === "value" ?
|
|
134
|
+
if (resolved === void 0) return key === "value" ? serveAnnotation("detail") : serveMessage();
|
|
133
135
|
mergeHeaders();
|
|
134
|
-
return mapResponse(key === "value" ? resolved : problemOf(self, resolved, served, claimsProblem), context.set, context);
|
|
136
|
+
return mapResponse(key === "value" ? resolved : problemOf(self, type, resolved, served, claimsProblem), context.set, context);
|
|
135
137
|
}, failed);
|
|
136
138
|
mergeHeaders();
|
|
137
|
-
return mapResponse(key === "value" ? annotation : problemOf(self, annotation, served, claimsProblem), context.set, context);
|
|
139
|
+
return mapResponse(key === "value" ? annotation : problemOf(self, type, annotation, served, claimsProblem), context.set, context);
|
|
138
140
|
};
|
|
139
141
|
if (error instanceof require_error.ValidationError) return mapResponse(error.type === "response" ? require_error.internalServerErrorResponse(void 0) : new require_error.ElysiaStatus(422, require_error.problemBody({
|
|
140
142
|
type: "validation",
|
|
@@ -142,7 +144,8 @@ function fallbackErrorResponse(context, error, mapResponse) {
|
|
|
142
144
|
title: "Validation Error",
|
|
143
145
|
status: 422
|
|
144
146
|
}), { "content-type": require_error.PROBLEM_JSON }), context.set, context);
|
|
145
|
-
if (owned || error instanceof Error && typeof status === "number" && status >= 100 && !(require_universal_is_production.isProduction() && status >= 500)) return
|
|
147
|
+
if (owned || error instanceof Error && typeof status === "number" && status >= 100 && !(require_universal_is_production.isProduction() && status >= 500)) return serveAnnotation("value");
|
|
148
|
+
if (claimsProblem && error instanceof Error && typeof status === "number" && status >= 500) return mapResponse(problemOf(self, type, require_error.titleOf(status), status, false), context.set, context);
|
|
146
149
|
return legacy();
|
|
147
150
|
}
|
|
148
151
|
function applyErrorStatus(context, error) {
|
|
@@ -166,7 +169,7 @@ function createErrorHandler(onErrors, mapResponse, allowUnsafe = false) {
|
|
|
166
169
|
else if (context.set.status === void 0 || context.set.status === 200) context.set.status = 500;
|
|
167
170
|
return mapWith(sign)(adoptErrorType(result, error), context.set, context);
|
|
168
171
|
};
|
|
169
|
-
const
|
|
172
|
+
const serveUnhandled = (context, error, sign) => isPristineNotFound(context, error) ? require_handler_utils.getNotFound() : fallbackResponse(context, error, mapWith(sign));
|
|
170
173
|
if (require_handler_utils.hasAsync(onErrors)) return async (context, error, sign) => {
|
|
171
174
|
require_adapter_utils.materializeSetHeaders(context.set);
|
|
172
175
|
enter(context, error);
|
|
@@ -175,7 +178,7 @@ function createErrorHandler(onErrors, mapResponse, allowUnsafe = false) {
|
|
|
175
178
|
if (typeof result?.then === "function") result = await result;
|
|
176
179
|
if (result !== void 0) return respond(context, error, result, sign);
|
|
177
180
|
}
|
|
178
|
-
return
|
|
181
|
+
return serveUnhandled(context, error, sign);
|
|
179
182
|
};
|
|
180
183
|
return (context, error, sign) => {
|
|
181
184
|
require_adapter_utils.materializeSetHeaders(context.set);
|
|
@@ -184,7 +187,7 @@ function createErrorHandler(onErrors, mapResponse, allowUnsafe = false) {
|
|
|
184
187
|
const result = onErrors[i](context);
|
|
185
188
|
if (result !== void 0) return respond(context, error, result, sign);
|
|
186
189
|
}
|
|
187
|
-
return
|
|
190
|
+
return serveUnhandled(context, error, sign);
|
|
188
191
|
};
|
|
189
192
|
}
|
|
190
193
|
|