elysia 2.0.0-beta.1 → 2.0.0-beta.2
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/utils.d.ts +2 -2
- package/dist/adapter/web-standard/handler.js +11 -7
- package/dist/adapter/web-standard/handler.mjs +12 -8
- package/dist/base.d.ts +18 -3
- package/dist/base.js +31 -15
- package/dist/base.mjs +31 -15
- package/dist/compile/aot-capture.js +1 -1
- package/dist/compile/aot-capture.mjs +2 -2
- package/dist/compile/handler/descriptor.d.ts +1 -1
- package/dist/compile/handler/frozen-validator.d.ts +2 -1
- package/dist/compile/handler/frozen-validator.js +33 -3
- package/dist/compile/handler/frozen-validator.mjs +33 -4
- package/dist/compile/handler/index.d.ts +1 -1
- package/dist/compile/handler/jit.js +5 -8
- package/dist/compile/handler/jit.mjs +6 -9
- package/dist/compile/handler/params.js +3 -3
- package/dist/compile/handler/params.mjs +4 -4
- package/dist/compile/handler/utils.d.ts +1 -1
- package/dist/compile/handler/utils.js +5 -2
- package/dist/compile/handler/utils.mjs +5 -2
- package/dist/context.d.ts +2 -2
- package/dist/cookie/cookie.js +1 -0
- package/dist/cookie/cookie.mjs +1 -0
- package/dist/error.d.ts +139 -6
- package/dist/error.js +73 -0
- package/dist/error.mjs +73 -1
- package/dist/handler/error.d.ts +20 -1
- package/dist/handler/error.js +120 -8
- package/dist/handler/error.mjs +119 -9
- package/dist/handler/fetch.js +9 -5
- package/dist/handler/fetch.mjs +9 -5
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -0
- package/dist/index.mjs +2 -2
- package/dist/package.js +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugin/aot/core.d.ts +4 -3
- package/dist/plugin/aot/core.js +1 -1
- package/dist/plugin/aot/core.mjs +1 -1
- package/dist/route-table.d.ts +1 -1
- package/dist/sucrose.js +118 -16
- package/dist/sucrose.mjs +118 -16
- package/dist/type/bridge.d.ts +6 -6
- package/dist/type/coerce.js +9 -4
- package/dist/type/coerce.mjs +9 -4
- package/dist/type/elysia/array-string.js +29 -2
- package/dist/type/elysia/array-string.mjs +30 -3
- package/dist/type/elysia/file-type.js +11 -1
- package/dist/type/elysia/file-type.mjs +11 -1
- package/dist/type/elysia/form.js +2 -1
- package/dist/type/elysia/form.mjs +2 -1
- package/dist/type/elysia/object-string.js +26 -2
- package/dist/type/elysia/object-string.mjs +27 -3
- package/dist/type/validator/index.js +11 -13
- package/dist/type/validator/index.mjs +12 -14
- package/dist/types.d.ts +104 -18
- package/dist/universal/file.js +1 -0
- package/dist/universal/file.mjs +1 -0
- package/dist/universal/index.d.ts +1 -1
- package/dist/utils.d.ts +3 -5
- package/dist/utils.js +7 -9
- package/dist/utils.mjs +6 -10
- package/dist/ws/route.js +1 -1
- package/dist/ws/route.mjs +1 -1
- package/package.json +2 -2
package/dist/handler/error.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_constants = require('../constants.js');
|
|
2
3
|
const require_utils = require('../utils.js');
|
|
3
4
|
const require_universal_is_production = require('../universal/is-production.js');
|
|
4
5
|
const require_error = require('../error.js');
|
|
@@ -34,6 +35,31 @@ function parseQuery(context) {
|
|
|
34
35
|
});
|
|
35
36
|
}
|
|
36
37
|
const isPristineNotFound = (context, error) => error instanceof require_error.NotFound && error.response === "Not Found" && !context.set.cookie && !require_utils.isNotEmpty(context.set.headers);
|
|
38
|
+
/**
|
|
39
|
+
* Adopt the intercepted error's `type` into a problem the hook produced
|
|
40
|
+
* without one.
|
|
41
|
+
*
|
|
42
|
+
* `'about:blank'` is RFC 9457's "unspecified" default, so it's the only value
|
|
43
|
+
* worth replacing — an explicit type the handler set always wins.
|
|
44
|
+
*
|
|
45
|
+
* The result is copied rather than mutated: `.error(Class, value)` wraps a
|
|
46
|
+
* non-function into `() => value`, so the very same `ElysiaStatus` is replayed
|
|
47
|
+
* on every request and an in-place write would leak across requests
|
|
48
|
+
*/
|
|
49
|
+
function adoptErrorType(result, error) {
|
|
50
|
+
const body = result?.response;
|
|
51
|
+
if (typeof error?.type !== "string" || body?.type !== "about:blank" || result.headers?.["content-type"] !== "application/problem+json") return result;
|
|
52
|
+
return new require_error.ElysiaStatus(result.code, {
|
|
53
|
+
...body,
|
|
54
|
+
type: error.type
|
|
55
|
+
}, result.headers);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Response served once every error hook has declined the error.
|
|
59
|
+
*
|
|
60
|
+
* Exported for the JIT: a route with error hooks emits its own catch block,
|
|
61
|
+
* which must land on *this* function rather than re-implementing it
|
|
62
|
+
*/
|
|
37
63
|
function fallbackResponse(context, error, mapResponse, defaultError) {
|
|
38
64
|
if (typeof error?.toResponse === "function") try {
|
|
39
65
|
const r = error.toResponse();
|
|
@@ -42,14 +68,98 @@ function fallbackResponse(context, error, mapResponse, defaultError) {
|
|
|
42
68
|
} catch {}
|
|
43
69
|
return fallbackErrorResponse(context, error, mapResponse, defaultError);
|
|
44
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Numeric form of an annotated status, which may be written as a name.
|
|
73
|
+
* A numeric string keeps coercing so the production mask below can't be
|
|
74
|
+
* slipped past with `'502'`
|
|
75
|
+
*/
|
|
76
|
+
const resolveStatus = (status) => typeof status === "string" ? require_constants.StatusMap[status] ?? +status : status;
|
|
77
|
+
/**
|
|
78
|
+
* Body served by an error that carries a status but no usable body:
|
|
79
|
+
* its declared `response`, otherwise its message
|
|
80
|
+
*/
|
|
81
|
+
const statusFallbackBody = (error, status) => error.response !== void 0 ? error.response : require_universal_is_production.isProduction() && status >= 500 ? "Internal Server Error" : error.message ?? "";
|
|
82
|
+
/**
|
|
83
|
+
* RFC 9457 problem document carrying `detail` verbatim, mirroring `problem()`.
|
|
84
|
+
*
|
|
85
|
+
* `detail` is served exactly as annotated — objects included — it is never
|
|
86
|
+
* spread into the envelope. `problemBody` only defaults `type` when the key is
|
|
87
|
+
* *absent*, so an error without one has to supply `'about:blank'` itself
|
|
88
|
+
*/
|
|
89
|
+
const problemOf = (self, detail, status) => new require_error.ElysiaStatus(status, require_error.problemBody({
|
|
90
|
+
type: self.type ?? "about:blank",
|
|
91
|
+
detail,
|
|
92
|
+
status
|
|
93
|
+
}), { "content-type": require_error.PROBLEM_JSON });
|
|
94
|
+
/**
|
|
95
|
+
* Read one annotation knob.
|
|
96
|
+
*
|
|
97
|
+
* Both knobs are canonically methods, so they're evaluated per serve and may
|
|
98
|
+
* be `async`. Running a stranger's function is side-effect surface (it may
|
|
99
|
+
* consume a stream or do IO), so it takes the same problem claim the shaping
|
|
100
|
+
* does — an unclaimed duck error never invokes one. A *value* annotation stays
|
|
101
|
+
* inert data and keeps duck-participating as it always has
|
|
102
|
+
*/
|
|
103
|
+
const readAnnotation = (self, key, claimsProblem) => {
|
|
104
|
+
const annotation = self[key];
|
|
105
|
+
return typeof annotation === "function" ? claimsProblem ? annotation.call(self) : void 0 : annotation;
|
|
106
|
+
};
|
|
45
107
|
function fallbackErrorResponse(context, error, mapResponse, defaultError) {
|
|
46
108
|
if (error instanceof require_error.ElysiaStatus) return mapResponse(error, context.set, context);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
109
|
+
const self = error;
|
|
110
|
+
const status = resolveStatus(self.status);
|
|
111
|
+
const owned = error instanceof require_error.HTTPError;
|
|
112
|
+
const claimsProblem = owned || typeof self.type === "string";
|
|
113
|
+
const served = typeof status === "number" ? status : resolveStatus(context.set.status);
|
|
114
|
+
const failed = (cause) => {
|
|
115
|
+
context.set.status = 500;
|
|
116
|
+
return mapResponse(require_error.internalServerErrorResponse(cause), context.set, context);
|
|
117
|
+
};
|
|
118
|
+
const mergeHeaders = () => {
|
|
119
|
+
if (self.headers) Object.assign(require_adapter_utils.materializeSetHeaders(context.set), self.headers);
|
|
120
|
+
};
|
|
121
|
+
const legacy = () => {
|
|
122
|
+
if (error?.status) return mapResponse(statusFallbackBody(error, status), context.set, context);
|
|
123
|
+
if (error?.message != null) {
|
|
124
|
+
if (context.set.status === void 0 || context.set.status === 200) context.set.status = 500;
|
|
125
|
+
return mapResponse(require_error.internalServerErrorResponse(error), context.set, context);
|
|
126
|
+
}
|
|
127
|
+
return defaultError ? defaultError.clone() : require_error.internalServerErrorResponse(error);
|
|
128
|
+
};
|
|
129
|
+
const serveMessage = () => claimsProblem ? mapResponse(problemOf(self, statusFallbackBody(error, served), served), context.set, context) : legacy();
|
|
130
|
+
const serveDetail = () => {
|
|
131
|
+
let detail;
|
|
132
|
+
try {
|
|
133
|
+
detail = readAnnotation(self, "detail", claimsProblem);
|
|
134
|
+
} catch (cause) {
|
|
135
|
+
return failed(cause);
|
|
136
|
+
}
|
|
137
|
+
if (detail === void 0) return serveMessage();
|
|
138
|
+
if (detail instanceof Promise) return detail.then((resolved) => {
|
|
139
|
+
if (resolved === void 0) return serveMessage();
|
|
140
|
+
mergeHeaders();
|
|
141
|
+
return mapResponse(problemOf(self, resolved, served), context.set, context);
|
|
142
|
+
}, failed);
|
|
143
|
+
mergeHeaders();
|
|
144
|
+
return mapResponse(problemOf(self, detail, served), context.set, context);
|
|
145
|
+
};
|
|
146
|
+
if (owned || error instanceof Error && typeof status === "number" && status >= 100 && !(require_universal_is_production.isProduction() && status >= 500)) {
|
|
147
|
+
let value;
|
|
148
|
+
try {
|
|
149
|
+
value = readAnnotation(self, "value", claimsProblem);
|
|
150
|
+
} catch (cause) {
|
|
151
|
+
return failed(cause);
|
|
152
|
+
}
|
|
153
|
+
if (value === void 0) return serveDetail();
|
|
154
|
+
if (value instanceof Promise) return value.then((resolved) => {
|
|
155
|
+
if (resolved === void 0) return serveDetail();
|
|
156
|
+
mergeHeaders();
|
|
157
|
+
return mapResponse(resolved, context.set, context);
|
|
158
|
+
}, failed);
|
|
159
|
+
mergeHeaders();
|
|
160
|
+
return mapResponse(value, context.set, context);
|
|
51
161
|
}
|
|
52
|
-
return
|
|
162
|
+
return legacy();
|
|
53
163
|
}
|
|
54
164
|
function applyErrorStatus(context, error) {
|
|
55
165
|
if (error?.status) context.set.status = error.status;
|
|
@@ -76,7 +186,7 @@ function createErrorHandler(onErrors, mapResponse, defaultError, allowUnsafe = f
|
|
|
76
186
|
if (result !== void 0) {
|
|
77
187
|
if (result instanceof require_error.ElysiaStatus || result instanceof Response) context.set.status = result.status;
|
|
78
188
|
else if (context.set.status === void 0 || context.set.status === 200) context.set.status = 500;
|
|
79
|
-
return mapResponse(result, context.set, context);
|
|
189
|
+
return mapResponse(adoptErrorType(result, error), context.set, context);
|
|
80
190
|
}
|
|
81
191
|
}
|
|
82
192
|
if (isPristineNotFound(context, error)) return require_handler_utils.getNotFound();
|
|
@@ -93,7 +203,7 @@ function createErrorHandler(onErrors, mapResponse, defaultError, allowUnsafe = f
|
|
|
93
203
|
if (result !== void 0) {
|
|
94
204
|
if (result instanceof require_error.ElysiaStatus || result instanceof Response) context.set.status = result.status;
|
|
95
205
|
else if (context.set.status === void 0 || context.set.status === 200) context.set.status = 500;
|
|
96
|
-
return mapResponse(result, context.set, context);
|
|
206
|
+
return mapResponse(adoptErrorType(result, error), context.set, context);
|
|
97
207
|
}
|
|
98
208
|
}
|
|
99
209
|
if (isPristineNotFound(context, error)) return require_handler_utils.getNotFound();
|
|
@@ -102,4 +212,6 @@ function createErrorHandler(onErrors, mapResponse, defaultError, allowUnsafe = f
|
|
|
102
212
|
}
|
|
103
213
|
|
|
104
214
|
//#endregion
|
|
105
|
-
exports.
|
|
215
|
+
exports.adoptErrorType = adoptErrorType;
|
|
216
|
+
exports.createErrorHandler = createErrorHandler;
|
|
217
|
+
exports.fallbackResponse = fallbackResponse;
|
package/dist/handler/error.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { StatusMap } from "../constants.mjs";
|
|
1
2
|
import { isNotEmpty } from "../utils.mjs";
|
|
2
3
|
import { isProduction } from "../universal/is-production.mjs";
|
|
3
|
-
import { ElysiaStatus, NotFound, ValidationError, internalServerErrorResponse } from "../error.mjs";
|
|
4
|
+
import { ElysiaStatus, HTTPError, NotFound, PROBLEM_JSON, ValidationError, internalServerErrorResponse, problemBody } from "../error.mjs";
|
|
4
5
|
import { materializeSetHeaders } from "../adapter/utils.mjs";
|
|
5
6
|
import { parseQueryFromURL } from "../parse-query.mjs";
|
|
6
7
|
import { getAsyncIndexes, getNotFound } from "./utils.mjs";
|
|
@@ -33,6 +34,31 @@ function parseQuery(context) {
|
|
|
33
34
|
});
|
|
34
35
|
}
|
|
35
36
|
const isPristineNotFound = (context, error) => error instanceof NotFound && error.response === "Not Found" && !context.set.cookie && !isNotEmpty(context.set.headers);
|
|
37
|
+
/**
|
|
38
|
+
* Adopt the intercepted error's `type` into a problem the hook produced
|
|
39
|
+
* without one.
|
|
40
|
+
*
|
|
41
|
+
* `'about:blank'` is RFC 9457's "unspecified" default, so it's the only value
|
|
42
|
+
* worth replacing — an explicit type the handler set always wins.
|
|
43
|
+
*
|
|
44
|
+
* The result is copied rather than mutated: `.error(Class, value)` wraps a
|
|
45
|
+
* non-function into `() => value`, so the very same `ElysiaStatus` is replayed
|
|
46
|
+
* on every request and an in-place write would leak across requests
|
|
47
|
+
*/
|
|
48
|
+
function adoptErrorType(result, error) {
|
|
49
|
+
const body = result?.response;
|
|
50
|
+
if (typeof error?.type !== "string" || body?.type !== "about:blank" || result.headers?.["content-type"] !== "application/problem+json") return result;
|
|
51
|
+
return new ElysiaStatus(result.code, {
|
|
52
|
+
...body,
|
|
53
|
+
type: error.type
|
|
54
|
+
}, result.headers);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Response served once every error hook has declined the error.
|
|
58
|
+
*
|
|
59
|
+
* Exported for the JIT: a route with error hooks emits its own catch block,
|
|
60
|
+
* which must land on *this* function rather than re-implementing it
|
|
61
|
+
*/
|
|
36
62
|
function fallbackResponse(context, error, mapResponse, defaultError) {
|
|
37
63
|
if (typeof error?.toResponse === "function") try {
|
|
38
64
|
const r = error.toResponse();
|
|
@@ -41,14 +67,98 @@ function fallbackResponse(context, error, mapResponse, defaultError) {
|
|
|
41
67
|
} catch {}
|
|
42
68
|
return fallbackErrorResponse(context, error, mapResponse, defaultError);
|
|
43
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Numeric form of an annotated status, which may be written as a name.
|
|
72
|
+
* A numeric string keeps coercing so the production mask below can't be
|
|
73
|
+
* slipped past with `'502'`
|
|
74
|
+
*/
|
|
75
|
+
const resolveStatus = (status) => typeof status === "string" ? StatusMap[status] ?? +status : status;
|
|
76
|
+
/**
|
|
77
|
+
* Body served by an error that carries a status but no usable body:
|
|
78
|
+
* its declared `response`, otherwise its message
|
|
79
|
+
*/
|
|
80
|
+
const statusFallbackBody = (error, status) => error.response !== void 0 ? error.response : isProduction() && status >= 500 ? "Internal Server Error" : error.message ?? "";
|
|
81
|
+
/**
|
|
82
|
+
* RFC 9457 problem document carrying `detail` verbatim, mirroring `problem()`.
|
|
83
|
+
*
|
|
84
|
+
* `detail` is served exactly as annotated — objects included — it is never
|
|
85
|
+
* spread into the envelope. `problemBody` only defaults `type` when the key is
|
|
86
|
+
* *absent*, so an error without one has to supply `'about:blank'` itself
|
|
87
|
+
*/
|
|
88
|
+
const problemOf = (self, detail, status) => new ElysiaStatus(status, problemBody({
|
|
89
|
+
type: self.type ?? "about:blank",
|
|
90
|
+
detail,
|
|
91
|
+
status
|
|
92
|
+
}), { "content-type": PROBLEM_JSON });
|
|
93
|
+
/**
|
|
94
|
+
* Read one annotation knob.
|
|
95
|
+
*
|
|
96
|
+
* Both knobs are canonically methods, so they're evaluated per serve and may
|
|
97
|
+
* be `async`. Running a stranger's function is side-effect surface (it may
|
|
98
|
+
* consume a stream or do IO), so it takes the same problem claim the shaping
|
|
99
|
+
* does — an unclaimed duck error never invokes one. A *value* annotation stays
|
|
100
|
+
* inert data and keeps duck-participating as it always has
|
|
101
|
+
*/
|
|
102
|
+
const readAnnotation = (self, key, claimsProblem) => {
|
|
103
|
+
const annotation = self[key];
|
|
104
|
+
return typeof annotation === "function" ? claimsProblem ? annotation.call(self) : void 0 : annotation;
|
|
105
|
+
};
|
|
44
106
|
function fallbackErrorResponse(context, error, mapResponse, defaultError) {
|
|
45
107
|
if (error instanceof ElysiaStatus) return mapResponse(error, context.set, context);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
108
|
+
const self = error;
|
|
109
|
+
const status = resolveStatus(self.status);
|
|
110
|
+
const owned = error instanceof HTTPError;
|
|
111
|
+
const claimsProblem = owned || typeof self.type === "string";
|
|
112
|
+
const served = typeof status === "number" ? status : resolveStatus(context.set.status);
|
|
113
|
+
const failed = (cause) => {
|
|
114
|
+
context.set.status = 500;
|
|
115
|
+
return mapResponse(internalServerErrorResponse(cause), context.set, context);
|
|
116
|
+
};
|
|
117
|
+
const mergeHeaders = () => {
|
|
118
|
+
if (self.headers) Object.assign(materializeSetHeaders(context.set), self.headers);
|
|
119
|
+
};
|
|
120
|
+
const legacy = () => {
|
|
121
|
+
if (error?.status) return mapResponse(statusFallbackBody(error, status), context.set, context);
|
|
122
|
+
if (error?.message != null) {
|
|
123
|
+
if (context.set.status === void 0 || context.set.status === 200) context.set.status = 500;
|
|
124
|
+
return mapResponse(internalServerErrorResponse(error), context.set, context);
|
|
125
|
+
}
|
|
126
|
+
return defaultError ? defaultError.clone() : internalServerErrorResponse(error);
|
|
127
|
+
};
|
|
128
|
+
const serveMessage = () => claimsProblem ? mapResponse(problemOf(self, statusFallbackBody(error, served), served), context.set, context) : legacy();
|
|
129
|
+
const serveDetail = () => {
|
|
130
|
+
let detail;
|
|
131
|
+
try {
|
|
132
|
+
detail = readAnnotation(self, "detail", claimsProblem);
|
|
133
|
+
} catch (cause) {
|
|
134
|
+
return failed(cause);
|
|
135
|
+
}
|
|
136
|
+
if (detail === void 0) return serveMessage();
|
|
137
|
+
if (detail instanceof Promise) return detail.then((resolved) => {
|
|
138
|
+
if (resolved === void 0) return serveMessage();
|
|
139
|
+
mergeHeaders();
|
|
140
|
+
return mapResponse(problemOf(self, resolved, served), context.set, context);
|
|
141
|
+
}, failed);
|
|
142
|
+
mergeHeaders();
|
|
143
|
+
return mapResponse(problemOf(self, detail, served), context.set, context);
|
|
144
|
+
};
|
|
145
|
+
if (owned || error instanceof Error && typeof status === "number" && status >= 100 && !(isProduction() && status >= 500)) {
|
|
146
|
+
let value;
|
|
147
|
+
try {
|
|
148
|
+
value = readAnnotation(self, "value", claimsProblem);
|
|
149
|
+
} catch (cause) {
|
|
150
|
+
return failed(cause);
|
|
151
|
+
}
|
|
152
|
+
if (value === void 0) return serveDetail();
|
|
153
|
+
if (value instanceof Promise) return value.then((resolved) => {
|
|
154
|
+
if (resolved === void 0) return serveDetail();
|
|
155
|
+
mergeHeaders();
|
|
156
|
+
return mapResponse(resolved, context.set, context);
|
|
157
|
+
}, failed);
|
|
158
|
+
mergeHeaders();
|
|
159
|
+
return mapResponse(value, context.set, context);
|
|
50
160
|
}
|
|
51
|
-
return
|
|
161
|
+
return legacy();
|
|
52
162
|
}
|
|
53
163
|
function applyErrorStatus(context, error) {
|
|
54
164
|
if (error?.status) context.set.status = error.status;
|
|
@@ -75,7 +185,7 @@ function createErrorHandler(onErrors, mapResponse, defaultError, allowUnsafe = f
|
|
|
75
185
|
if (result !== void 0) {
|
|
76
186
|
if (result instanceof ElysiaStatus || result instanceof Response) context.set.status = result.status;
|
|
77
187
|
else if (context.set.status === void 0 || context.set.status === 200) context.set.status = 500;
|
|
78
|
-
return mapResponse(result, context.set, context);
|
|
188
|
+
return mapResponse(adoptErrorType(result, error), context.set, context);
|
|
79
189
|
}
|
|
80
190
|
}
|
|
81
191
|
if (isPristineNotFound(context, error)) return getNotFound();
|
|
@@ -92,7 +202,7 @@ function createErrorHandler(onErrors, mapResponse, defaultError, allowUnsafe = f
|
|
|
92
202
|
if (result !== void 0) {
|
|
93
203
|
if (result instanceof ElysiaStatus || result instanceof Response) context.set.status = result.status;
|
|
94
204
|
else if (context.set.status === void 0 || context.set.status === 200) context.set.status = 500;
|
|
95
|
-
return mapResponse(result, context.set, context);
|
|
205
|
+
return mapResponse(adoptErrorType(result, error), context.set, context);
|
|
96
206
|
}
|
|
97
207
|
}
|
|
98
208
|
if (isPristineNotFound(context, error)) return getNotFound();
|
|
@@ -101,4 +211,4 @@ function createErrorHandler(onErrors, mapResponse, defaultError, allowUnsafe = f
|
|
|
101
211
|
}
|
|
102
212
|
|
|
103
213
|
//#endregion
|
|
104
|
-
export { createErrorHandler };
|
|
214
|
+
export { adoptErrorType, createErrorHandler, fallbackResponse };
|
package/dist/handler/fetch.js
CHANGED
|
@@ -5,10 +5,10 @@ const require_universal_is_production = require('../universal/is-production.js')
|
|
|
5
5
|
const require_error = require('../error.js');
|
|
6
6
|
const require_adapter_utils = require('../adapter/utils.js');
|
|
7
7
|
const require_handler_utils = require('./utils.js');
|
|
8
|
+
const require_handler_error = require('./error.js');
|
|
8
9
|
const require_adapter_origin = require('../adapter/origin.js');
|
|
9
10
|
const require_adapter_constants = require('../adapter/constants.js');
|
|
10
11
|
const require_context = require('../context.js');
|
|
11
|
-
const require_handler_error = require('./error.js');
|
|
12
12
|
let deuri = require("deuri");
|
|
13
13
|
deuri = require_runtime.__toESM(deuri);
|
|
14
14
|
|
|
@@ -176,10 +176,14 @@ function createFetchHandler(app) {
|
|
|
176
176
|
} catch (e) {
|
|
177
177
|
console.error(e);
|
|
178
178
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
179
|
+
const deferred = context["~afterResponse"];
|
|
180
|
+
if (deferred) {
|
|
181
|
+
const total = deferred.length;
|
|
182
|
+
for (let i = 0; i < total; i++) try {
|
|
183
|
+
await deferred[i](context);
|
|
184
|
+
} catch (e) {
|
|
185
|
+
console.error(e);
|
|
186
|
+
}
|
|
183
187
|
}
|
|
184
188
|
if (traceAfterResponsePhase) {
|
|
185
189
|
let cache = context.trace;
|
package/dist/handler/fetch.mjs
CHANGED
|
@@ -3,10 +3,10 @@ import { isProduction } from "../universal/is-production.mjs";
|
|
|
3
3
|
import { NotFound, PROBLEM_JSON, internalServerErrorResponse } from "../error.mjs";
|
|
4
4
|
import { handleSet, materializeSetHeaders } from "../adapter/utils.mjs";
|
|
5
5
|
import { NOT_FOUND_BODY, emptyResponse, getAsyncIndexes, getNotFound } from "./utils.mjs";
|
|
6
|
+
import { createErrorHandler } from "./error.mjs";
|
|
6
7
|
import { origin } from "../adapter/origin.mjs";
|
|
7
8
|
import { defaultAdapter } from "../adapter/constants.mjs";
|
|
8
9
|
import { createContext } from "../context.mjs";
|
|
9
|
-
import { createErrorHandler } from "./error.mjs";
|
|
10
10
|
import decodeComponent from "deuri";
|
|
11
11
|
|
|
12
12
|
//#region src/handler/fetch.ts
|
|
@@ -173,10 +173,14 @@ function createFetchHandler(app) {
|
|
|
173
173
|
} catch (e) {
|
|
174
174
|
console.error(e);
|
|
175
175
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
176
|
+
const deferred = context["~afterResponse"];
|
|
177
|
+
if (deferred) {
|
|
178
|
+
const total = deferred.length;
|
|
179
|
+
for (let i = 0; i < total; i++) try {
|
|
180
|
+
await deferred[i](context);
|
|
181
|
+
} catch (e) {
|
|
182
|
+
console.error(e);
|
|
183
|
+
}
|
|
180
184
|
}
|
|
181
185
|
if (traceAfterResponsePhase) {
|
|
182
186
|
let cache = context.trace;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { BaseCookie, CookieOptions } from "./cookie/types.js";
|
|
2
2
|
import { Cookie } from "./cookie/cookie.js";
|
|
3
|
-
import { StatusMap, StatusMapBack } from "./constants.js";
|
|
4
|
-
import { ElysiaError, ElysiaStatus, InternalServerError, NotFound, ParseError, Problem, SelectiveStatus, ValidationError, problem, status, validationDetail } from "./error.js";
|
|
5
3
|
import { ElysiaFile, file } from "./universal/file.js";
|
|
4
|
+
import { StatusMap, StatusMapBack } from "./constants.js";
|
|
6
5
|
import { env } from "./universal/env.js";
|
|
7
6
|
import { Server } from "./universal/server.js";
|
|
8
|
-
import { HTTPHeaders, InputSchema, Macro, MacroToContext, MacroToProperty, RouteSchema, SSEPayload, UnwrapRoute, UnwrapSchema } from "./types.js";
|
|
9
7
|
import { bytes, form, prefix, redirect, sse } from "./utils.js";
|
|
8
|
+
import { HTTPHeaders, InputSchema, Macro, MacroToContext, MacroToProperty, RouteSchema, SSEPayload, UnwrapRoute, UnwrapSchema } from "./types.js";
|
|
9
|
+
import { ElysiaError, ElysiaStatus, HTTPError, InternalServerError, NotFound, ParseError, Problem, SelectiveStatus, TaggedHTTPError, ValidationError, problem, status, validationDetail } from "./error.js";
|
|
10
10
|
import { Context, ErrorContext, createBaseContext, createContext } from "./context.js";
|
|
11
11
|
import { InvalidCookie } from "./cookie/error.js";
|
|
12
12
|
import { AnySchema, BaseSchema, StandardJSONSchemaV1Like, StandardSchemaV1Like } from "./type/types.js";
|
|
@@ -20,4 +20,4 @@ import { TypeSystem, t } from "./type/index.js";
|
|
|
20
20
|
import { AotFingerprint, Capture, Compiled, CompilerSession, ProgramId } from "./compile/aot.js";
|
|
21
21
|
import { AnyElysia, Elysia } from "./base.js";
|
|
22
22
|
import { borrow } from "./adapter/response-ownership.js";
|
|
23
|
-
export { AnyElysia, type AnySchema, type AotFingerprint, type BaseCookie, type BaseSchema, Compiled, type CompilerSession, type Context, type Cookie, type CookieOptions, Elysia, Elysia as default, ElysiaError, ElysiaFile, ElysiaStatus, type ErrorContext, type FileTypeDetector, type HTTPHeaders, type InputSchema, InternalServerError, InvalidCookie, type Macro, type MacroToContext, type MacroToProperty, Capture as Manifest, MultiValidator, NotFound, ParseError, type Problem, type ProgramId, type RouteSchema, type SSEPayload, type SelectiveStatus, type Server, type StandardJSONSchemaV1Like, type StandardSchemaV1Like, StandardValidator, StatusMap, StatusMapBack, type TCookieField, type TCookieObject, type TFiles, TypeBoxValidator, TypeSystem, type UnwrapRoute, type UnwrapSchema, ValidationError, Validator, borrow, bytes, createBaseContext, createContext, env, file, fileType, form, prefix, problem, redirect, setFileTypeDetector, setupTypebox, sse, status, t, validationDetail };
|
|
23
|
+
export { AnyElysia, type AnySchema, type AotFingerprint, type BaseCookie, type BaseSchema, Compiled, type CompilerSession, type Context, type Cookie, type CookieOptions, Elysia, Elysia as default, ElysiaError, ElysiaFile, ElysiaStatus, type ErrorContext, type FileTypeDetector, HTTPError, type HTTPHeaders, type InputSchema, InternalServerError, InvalidCookie, type Macro, type MacroToContext, type MacroToProperty, Capture as Manifest, MultiValidator, NotFound, ParseError, type Problem, type ProgramId, type RouteSchema, type SSEPayload, type SelectiveStatus, type Server, type StandardJSONSchemaV1Like, type StandardSchemaV1Like, StandardValidator, StatusMap, StatusMapBack, type TCookieField, type TCookieObject, type TFiles, type TaggedHTTPError, TypeBoxValidator, TypeSystem, type UnwrapRoute, type UnwrapSchema, ValidationError, Validator, borrow, bytes, createBaseContext, createContext, env, file, fileType, form, prefix, problem, redirect, setFileTypeDetector, setupTypebox, sse, status, t, validationDetail };
|
package/dist/index.js
CHANGED
|
@@ -26,6 +26,7 @@ exports.Elysia = require_base.Elysia;
|
|
|
26
26
|
exports.ElysiaError = require_error.ElysiaError;
|
|
27
27
|
exports.ElysiaFile = require_universal_file.ElysiaFile;
|
|
28
28
|
exports.ElysiaStatus = require_error.ElysiaStatus;
|
|
29
|
+
exports.HTTPError = require_error.HTTPError;
|
|
29
30
|
exports.InternalServerError = require_error.InternalServerError;
|
|
30
31
|
exports.InvalidCookie = require_cookie_error.InvalidCookie;
|
|
31
32
|
exports.Manifest = require_compile_aot.Capture;
|
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { StatusMap, StatusMapBack } from "./constants.mjs";
|
|
|
2
2
|
import { ElysiaFile, file } from "./universal/file.mjs";
|
|
3
3
|
import { bytes, form, prefix, redirect, sse } from "./utils.mjs";
|
|
4
4
|
import { env } from "./universal/env.mjs";
|
|
5
|
-
import { ElysiaError, ElysiaStatus, InternalServerError, NotFound, ParseError, ValidationError, problem, status, validationDetail } from "./error.mjs";
|
|
5
|
+
import { ElysiaError, ElysiaStatus, HTTPError, InternalServerError, NotFound, ParseError, ValidationError, problem, status, validationDetail } from "./error.mjs";
|
|
6
6
|
import { InvalidCookie } from "./cookie/error.mjs";
|
|
7
7
|
import { borrow } from "./adapter/response-ownership.mjs";
|
|
8
8
|
import { Capture, Compiled } from "./compile/aot.mjs";
|
|
@@ -18,4 +18,4 @@ import { TypeSystem, t } from "./type/index.mjs";
|
|
|
18
18
|
var src_default = Elysia;
|
|
19
19
|
|
|
20
20
|
//#endregion
|
|
21
|
-
export { Compiled, Elysia, ElysiaError, ElysiaFile, ElysiaStatus, InternalServerError, InvalidCookie, Capture as Manifest, MultiValidator, NotFound, ParseError, StandardValidator, StatusMap, StatusMapBack, TypeBoxValidator, TypeSystem, ValidationError, Validator, borrow, bytes, createBaseContext, createContext, src_default as default, env, file, fileType, form, prefix, problem, redirect, setFileTypeDetector, setupTypebox, sse, status, t, validationDetail };
|
|
21
|
+
export { Compiled, Elysia, ElysiaError, ElysiaFile, ElysiaStatus, HTTPError, InternalServerError, InvalidCookie, Capture as Manifest, MultiValidator, NotFound, ParseError, StandardValidator, StatusMap, StatusMapBack, TypeBoxValidator, TypeSystem, ValidationError, Validator, borrow, bytes, createBaseContext, createContext, src_default as default, env, file, fileType, form, prefix, problem, redirect, setFileTypeDetector, setupTypebox, sse, status, t, validationDetail };
|
package/dist/package.js
CHANGED
package/dist/package.mjs
CHANGED
|
@@ -83,11 +83,12 @@ interface ElysiaAotOptions {
|
|
|
83
83
|
* a coercion/codec schema (its 422 error detail can only name the
|
|
84
84
|
* offending field coarsely, best-effort).
|
|
85
85
|
*
|
|
86
|
-
* -
|
|
87
|
-
*
|
|
86
|
+
* - unset (default): follow the `ELYSIA_AOT_VERBOSE` environment variable
|
|
87
|
+
* - `false`: collapse all affected routes into a single build-end
|
|
88
|
+
* summary line (none if no route is affected)
|
|
88
89
|
* - `true`: also print the per-route detail line as each one is found
|
|
89
90
|
*
|
|
90
|
-
* @default
|
|
91
|
+
* @default undefined
|
|
91
92
|
*/
|
|
92
93
|
verbose?: boolean;
|
|
93
94
|
}
|
package/dist/plugin/aot/core.js
CHANGED
|
@@ -384,7 +384,7 @@ async function generateCompiledArtifacts(file, options) {
|
|
|
384
384
|
process.env.ELYSIA_AOT_BUILD = "1";
|
|
385
385
|
const previousAotVerbose = process.env.ELYSIA_AOT_VERBOSE;
|
|
386
386
|
if (options?.verbose) process.env.ELYSIA_AOT_VERBOSE = "1";
|
|
387
|
-
else delete process.env.ELYSIA_AOT_VERBOSE;
|
|
387
|
+
else if (options?.verbose === false) delete process.env.ELYSIA_AOT_VERBOSE;
|
|
388
388
|
try {
|
|
389
389
|
const entry = resolveEntry(file);
|
|
390
390
|
const entryReal = realPath(entry);
|
package/dist/plugin/aot/core.mjs
CHANGED
|
@@ -382,7 +382,7 @@ async function generateCompiledArtifacts(file, options) {
|
|
|
382
382
|
process.env.ELYSIA_AOT_BUILD = "1";
|
|
383
383
|
const previousAotVerbose = process.env.ELYSIA_AOT_VERBOSE;
|
|
384
384
|
if (options?.verbose) process.env.ELYSIA_AOT_VERBOSE = "1";
|
|
385
|
-
else delete process.env.ELYSIA_AOT_VERBOSE;
|
|
385
|
+
else if (options?.verbose === false) delete process.env.ELYSIA_AOT_VERBOSE;
|
|
386
386
|
try {
|
|
387
387
|
const entry = resolveEntry(file);
|
|
388
388
|
const entryReal = realPath(entry);
|
package/dist/route-table.d.ts
CHANGED