h3 0.7.15 → 0.7.18
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/index.cjs +161 -536
- package/dist/index.d.ts +57 -250
- package/dist/index.mjs +159 -477
- package/package.json +20 -21
package/dist/index.cjs
CHANGED
|
@@ -2,229 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const cookieEs = require('cookie-es');
|
|
9
|
-
|
|
10
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
|
|
11
|
-
|
|
12
|
-
const destr__default = /*#__PURE__*/_interopDefaultLegacy(destr);
|
|
13
|
-
|
|
14
|
-
function getQuery(event) {
|
|
15
|
-
return ufo.getQuery(event.req.url || "");
|
|
16
|
-
}
|
|
17
|
-
const useQuery = getQuery;
|
|
18
|
-
function getRouterParams(event) {
|
|
19
|
-
return event.context.params || {};
|
|
20
|
-
}
|
|
21
|
-
function getRouterParam(event, name) {
|
|
22
|
-
const params = getRouterParams(event);
|
|
23
|
-
return params[name];
|
|
24
|
-
}
|
|
25
|
-
function getMethod(event, defaultMethod = "GET") {
|
|
26
|
-
return (event.req.method || defaultMethod).toUpperCase();
|
|
27
|
-
}
|
|
28
|
-
const useMethod = getMethod;
|
|
29
|
-
function isMethod(event, expected, allowHead) {
|
|
30
|
-
const method = getMethod(event);
|
|
31
|
-
if (allowHead && method === "HEAD") {
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
if (typeof expected === "string") {
|
|
35
|
-
if (method === expected) {
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
} else if (expected.includes(method)) {
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
function assertMethod(event, expected, allowHead) {
|
|
44
|
-
if (!isMethod(event, expected, allowHead)) {
|
|
45
|
-
throw createError({
|
|
46
|
-
statusCode: 405,
|
|
47
|
-
statusMessage: "HTTP method is not allowed."
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
function getRequestHeaders(event) {
|
|
52
|
-
return event.req.headers;
|
|
53
|
-
}
|
|
54
|
-
const getHeaders = getRequestHeaders;
|
|
55
|
-
function getRequestHeader(event, name) {
|
|
56
|
-
const headers = getRequestHeaders(event);
|
|
57
|
-
const value = headers[name.toLowerCase()];
|
|
58
|
-
return value;
|
|
59
|
-
}
|
|
60
|
-
const getHeader = getRequestHeader;
|
|
61
|
-
|
|
62
|
-
const RawBodySymbol = Symbol("h3RawBody");
|
|
63
|
-
const ParsedBodySymbol = Symbol("h3RawBody");
|
|
64
|
-
const PayloadMethods = ["PATCH", "POST", "PUT", "DELETE"];
|
|
65
|
-
function readRawBody(event, encoding = "utf-8") {
|
|
66
|
-
assertMethod(event, PayloadMethods);
|
|
67
|
-
if (RawBodySymbol in event.req) {
|
|
68
|
-
const promise2 = Promise.resolve(event.req[RawBodySymbol]);
|
|
69
|
-
return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
|
|
70
|
-
}
|
|
71
|
-
if ("body" in event.req) {
|
|
72
|
-
return Promise.resolve(event.req.body);
|
|
73
|
-
}
|
|
74
|
-
const promise = event.req[RawBodySymbol] = new Promise((resolve, reject) => {
|
|
75
|
-
const bodyData = [];
|
|
76
|
-
event.req.on("error", (err) => {
|
|
77
|
-
reject(err);
|
|
78
|
-
}).on("data", (chunk) => {
|
|
79
|
-
bodyData.push(chunk);
|
|
80
|
-
}).on("end", () => {
|
|
81
|
-
resolve(Buffer.concat(bodyData));
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
return encoding ? promise.then((buff) => buff.toString(encoding)) : promise;
|
|
85
|
-
}
|
|
86
|
-
const useRawBody = readRawBody;
|
|
87
|
-
async function readBody(event) {
|
|
88
|
-
if (ParsedBodySymbol in event.req) {
|
|
89
|
-
return event.req[ParsedBodySymbol];
|
|
90
|
-
}
|
|
91
|
-
const body = await readRawBody(event);
|
|
92
|
-
if (event.req.headers["content-type"] === "application/x-www-form-urlencoded") {
|
|
93
|
-
const parsedForm = Object.fromEntries(new URLSearchParams(body));
|
|
94
|
-
return parsedForm;
|
|
95
|
-
}
|
|
96
|
-
const json = destr__default(body);
|
|
97
|
-
event.req[ParsedBodySymbol] = json;
|
|
98
|
-
return json;
|
|
99
|
-
}
|
|
100
|
-
const useBody = readBody;
|
|
101
|
-
|
|
102
|
-
function handleCacheHeaders(event, opts) {
|
|
103
|
-
const cacheControls = ["public"].concat(opts.cacheControls || []);
|
|
104
|
-
let cacheMatched = false;
|
|
105
|
-
if (opts.maxAge !== void 0) {
|
|
106
|
-
cacheControls.push(`max-age=${+opts.maxAge}`, `s-maxage=${+opts.maxAge}`);
|
|
107
|
-
}
|
|
108
|
-
if (opts.modifiedTime) {
|
|
109
|
-
const modifiedTime = new Date(opts.modifiedTime);
|
|
110
|
-
const ifModifiedSince = event.req.headers["if-modified-since"];
|
|
111
|
-
event.res.setHeader("Last-Modified", modifiedTime.toUTCString());
|
|
112
|
-
if (ifModifiedSince) {
|
|
113
|
-
if (new Date(ifModifiedSince) >= opts.modifiedTime) {
|
|
114
|
-
cacheMatched = true;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
if (opts.etag) {
|
|
119
|
-
event.res.setHeader("Etag", opts.etag);
|
|
120
|
-
const ifNonMatch = event.req.headers["if-none-match"];
|
|
121
|
-
if (ifNonMatch === opts.etag) {
|
|
122
|
-
cacheMatched = true;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
event.res.setHeader("Cache-Control", cacheControls.join(", "));
|
|
126
|
-
if (cacheMatched) {
|
|
127
|
-
event.res.statusCode = 304;
|
|
128
|
-
event.res.end("");
|
|
129
|
-
return true;
|
|
130
|
-
}
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const MIMES = {
|
|
135
|
-
html: "text/html",
|
|
136
|
-
json: "application/json"
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
const defer = typeof setImmediate !== "undefined" ? setImmediate : (fn) => fn();
|
|
140
|
-
function send(event, data, type) {
|
|
141
|
-
if (type) {
|
|
142
|
-
defaultContentType(event, type);
|
|
143
|
-
}
|
|
144
|
-
return new Promise((resolve) => {
|
|
145
|
-
defer(() => {
|
|
146
|
-
event.res.end(data);
|
|
147
|
-
resolve(void 0);
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
function defaultContentType(event, type) {
|
|
152
|
-
if (type && !event.res.getHeader("Content-Type")) {
|
|
153
|
-
event.res.setHeader("Content-Type", type);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
function sendRedirect(event, location, code = 302) {
|
|
157
|
-
event.res.statusCode = code;
|
|
158
|
-
event.res.setHeader("Location", location);
|
|
159
|
-
const html = `<!DOCTYPE html>
|
|
160
|
-
<html>
|
|
161
|
-
<head><meta http-equiv="refresh" content="0; url=${encodeURI(location)}"></head>
|
|
162
|
-
<body>Redirecting to <a href=${JSON.stringify(location)}>${encodeURI(location)}</a></body>
|
|
163
|
-
</html>`;
|
|
164
|
-
return send(event, html, MIMES.html);
|
|
165
|
-
}
|
|
166
|
-
function getResponseHeaders(event) {
|
|
167
|
-
return event.res.getHeaders();
|
|
168
|
-
}
|
|
169
|
-
function getResponseHeader(event, name) {
|
|
170
|
-
return event.res.getHeader(name);
|
|
171
|
-
}
|
|
172
|
-
function setResponseHeaders(event, headers) {
|
|
173
|
-
Object.entries(headers).forEach(([name, value]) => event.res.setHeader(name, value));
|
|
174
|
-
}
|
|
175
|
-
const setHeaders = setResponseHeaders;
|
|
176
|
-
function setResponseHeader(event, name, value) {
|
|
177
|
-
event.res.setHeader(name, value);
|
|
178
|
-
}
|
|
179
|
-
const setHeader = setResponseHeader;
|
|
180
|
-
function appendResponseHeaders(event, headers) {
|
|
181
|
-
Object.entries(headers).forEach(([name, value]) => appendResponseHeader(event, name, value));
|
|
182
|
-
}
|
|
183
|
-
const appendHeaders = appendResponseHeaders;
|
|
184
|
-
function appendResponseHeader(event, name, value) {
|
|
185
|
-
let current = event.res.getHeader(name);
|
|
186
|
-
if (!current) {
|
|
187
|
-
event.res.setHeader(name, value);
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
if (!Array.isArray(current)) {
|
|
191
|
-
current = [current.toString()];
|
|
192
|
-
}
|
|
193
|
-
event.res.setHeader(name, current.concat(value));
|
|
194
|
-
}
|
|
195
|
-
const appendHeader = appendResponseHeader;
|
|
196
|
-
function isStream(data) {
|
|
197
|
-
return data && typeof data === "object" && typeof data.pipe === "function" && typeof data.on === "function";
|
|
198
|
-
}
|
|
199
|
-
function sendStream(event, data) {
|
|
200
|
-
return new Promise((resolve, reject) => {
|
|
201
|
-
data.pipe(event.res);
|
|
202
|
-
data.on("end", () => resolve(void 0));
|
|
203
|
-
data.on("error", (error) => reject(createError(error)));
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
function parseCookies(event) {
|
|
208
|
-
return cookieEs.parse(event.req.headers.cookie || "");
|
|
209
|
-
}
|
|
210
|
-
const useCookies = parseCookies;
|
|
211
|
-
function getCookie(event, name) {
|
|
212
|
-
return parseCookies(event)[name];
|
|
213
|
-
}
|
|
214
|
-
const useCookie = getCookie;
|
|
215
|
-
function setCookie(event, name, value, serializeOptions) {
|
|
216
|
-
const cookieStr = cookieEs.serialize(name, value, {
|
|
217
|
-
path: "/",
|
|
218
|
-
...serializeOptions
|
|
219
|
-
});
|
|
220
|
-
appendHeader(event, "Set-Cookie", cookieStr);
|
|
221
|
-
}
|
|
222
|
-
function deleteCookie(event, name, serializeOptions) {
|
|
223
|
-
setCookie(event, name, "", {
|
|
224
|
-
...serializeOptions,
|
|
225
|
-
maxAge: 0
|
|
226
|
-
});
|
|
227
|
-
}
|
|
5
|
+
require('destr');
|
|
6
|
+
require('ufo');
|
|
7
|
+
require('cookie-es');
|
|
228
8
|
|
|
229
9
|
class H3Error extends Error {
|
|
230
10
|
constructor() {
|
|
@@ -273,41 +53,142 @@ function createError(input) {
|
|
|
273
53
|
}
|
|
274
54
|
return err;
|
|
275
55
|
}
|
|
276
|
-
function
|
|
277
|
-
|
|
278
|
-
|
|
56
|
+
function isError(input) {
|
|
57
|
+
return input?.constructor?.__h3_error__ === true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const MIMES = {
|
|
61
|
+
html: "text/html",
|
|
62
|
+
json: "application/json"
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
typeof setImmediate !== "undefined" ? setImmediate : (fn) => fn();
|
|
66
|
+
|
|
67
|
+
class H3Headers {
|
|
68
|
+
constructor(init) {
|
|
69
|
+
if (!init) {
|
|
70
|
+
this._headers = {};
|
|
71
|
+
} else if (Array.isArray(init)) {
|
|
72
|
+
this._headers = Object.fromEntries(init.map(([key, value]) => [key.toLowerCase(), value]));
|
|
73
|
+
} else if (init && "append" in init) {
|
|
74
|
+
this._headers = Object.fromEntries([...init.entries()]);
|
|
75
|
+
} else {
|
|
76
|
+
this._headers = Object.fromEntries(Object.entries(init).map(([key, value]) => [key.toLowerCase(), value]));
|
|
77
|
+
}
|
|
279
78
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
|
|
79
|
+
append(name, value) {
|
|
80
|
+
const _name = name.toLowerCase();
|
|
81
|
+
this.set(_name, [this.get(_name), value].filter(Boolean).join(", "));
|
|
82
|
+
}
|
|
83
|
+
delete(name) {
|
|
84
|
+
delete this._headers[name.toLowerCase()];
|
|
85
|
+
}
|
|
86
|
+
get(name) {
|
|
87
|
+
return this._headers[name.toLowerCase()];
|
|
88
|
+
}
|
|
89
|
+
has(name) {
|
|
90
|
+
return name.toLowerCase() in this._headers;
|
|
91
|
+
}
|
|
92
|
+
set(name, value) {
|
|
93
|
+
this._headers[name.toLowerCase()] = String(value);
|
|
289
94
|
}
|
|
290
|
-
|
|
291
|
-
|
|
95
|
+
forEach(callbackfn) {
|
|
96
|
+
Object.entries(this._headers).forEach(([key, value]) => callbackfn(value, key, this));
|
|
292
97
|
}
|
|
293
|
-
event.res.statusCode = h3Error.statusCode;
|
|
294
|
-
event.res.statusMessage = h3Error.statusMessage;
|
|
295
|
-
event.res.setHeader("Content-Type", MIMES.json);
|
|
296
|
-
event.res.end(JSON.stringify(responseBody, null, 2));
|
|
297
98
|
}
|
|
298
|
-
|
|
299
|
-
|
|
99
|
+
|
|
100
|
+
class H3Response {
|
|
101
|
+
constructor(body = null, init = {}) {
|
|
102
|
+
this.body = null;
|
|
103
|
+
this.type = "default";
|
|
104
|
+
this.bodyUsed = false;
|
|
105
|
+
this.headers = new H3Headers(init.headers);
|
|
106
|
+
this.status = init.status ?? 200;
|
|
107
|
+
this.statusText = init.statusText || "";
|
|
108
|
+
this.redirected = !!init.status && [301, 302, 307, 308].includes(init.status);
|
|
109
|
+
this._body = body;
|
|
110
|
+
this.url = "";
|
|
111
|
+
this.ok = this.status < 300 && this.status > 199;
|
|
112
|
+
}
|
|
113
|
+
clone() {
|
|
114
|
+
return new H3Response(this.body, {
|
|
115
|
+
headers: this.headers,
|
|
116
|
+
status: this.status,
|
|
117
|
+
statusText: this.statusText
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
arrayBuffer() {
|
|
121
|
+
return Promise.resolve(this._body);
|
|
122
|
+
}
|
|
123
|
+
blob() {
|
|
124
|
+
return Promise.resolve(this._body);
|
|
125
|
+
}
|
|
126
|
+
formData() {
|
|
127
|
+
return Promise.resolve(this._body);
|
|
128
|
+
}
|
|
129
|
+
json() {
|
|
130
|
+
return Promise.resolve(this._body);
|
|
131
|
+
}
|
|
132
|
+
text() {
|
|
133
|
+
return Promise.resolve(this._body);
|
|
134
|
+
}
|
|
300
135
|
}
|
|
301
136
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
137
|
+
class H3Event {
|
|
138
|
+
constructor(req, res) {
|
|
139
|
+
this["__is_event__"] = true;
|
|
140
|
+
this.context = {};
|
|
141
|
+
this.req = req;
|
|
142
|
+
this.res = res;
|
|
143
|
+
this.event = this;
|
|
144
|
+
req.event = this;
|
|
145
|
+
req.context = this.context;
|
|
146
|
+
req.req = req;
|
|
147
|
+
req.res = res;
|
|
148
|
+
res.event = this;
|
|
149
|
+
res.res = res;
|
|
150
|
+
res.req = res.req || {};
|
|
151
|
+
res.req.res = res;
|
|
152
|
+
res.req.req = req;
|
|
153
|
+
}
|
|
154
|
+
respondWith(r) {
|
|
155
|
+
Promise.resolve(r).then((_response) => {
|
|
156
|
+
if (this.res.writableEnded) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const response = _response instanceof H3Response ? _response : new H3Response(_response);
|
|
160
|
+
response.headers.forEach((value, key) => {
|
|
161
|
+
this.res.setHeader(key, value);
|
|
162
|
+
});
|
|
163
|
+
if (response.status) {
|
|
164
|
+
this.res.statusCode = response.status;
|
|
165
|
+
}
|
|
166
|
+
if (response.statusText) {
|
|
167
|
+
this.res.statusMessage = response.statusText;
|
|
168
|
+
}
|
|
169
|
+
if (response.redirected) {
|
|
170
|
+
this.res.setHeader("Location", response.url);
|
|
171
|
+
}
|
|
172
|
+
if (!response._body) {
|
|
173
|
+
return this.res.end();
|
|
174
|
+
}
|
|
175
|
+
if (typeof response._body === "string" || "buffer" in response._body || "byteLength" in response._body) {
|
|
176
|
+
return this.res.end(response._body);
|
|
177
|
+
}
|
|
178
|
+
if (!response.headers.has("content-type")) {
|
|
179
|
+
response.headers.set("content-type", MIMES.json);
|
|
180
|
+
}
|
|
181
|
+
this.res.end(JSON.stringify(response._body));
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function isEvent(input) {
|
|
186
|
+
return "__is_event__" in input;
|
|
187
|
+
}
|
|
188
|
+
function createEvent(req, res) {
|
|
189
|
+
return new H3Event(req, res);
|
|
309
190
|
}
|
|
310
|
-
|
|
191
|
+
|
|
311
192
|
function callHandler(handler, req, res) {
|
|
312
193
|
const isMiddleware = handler.length > 2;
|
|
313
194
|
return new Promise((resolve, reject) => {
|
|
@@ -331,36 +212,38 @@ function callHandler(handler, req, res) {
|
|
|
331
212
|
}
|
|
332
213
|
});
|
|
333
214
|
}
|
|
334
|
-
function defineLazyHandler(handler, promisify) {
|
|
335
|
-
let _promise;
|
|
336
|
-
const resolve = () => {
|
|
337
|
-
if (!_promise) {
|
|
338
|
-
_promise = Promise.resolve(handler()).then((r) => promisify ? promisifyHandler(r.default || r) : r.default || r);
|
|
339
|
-
}
|
|
340
|
-
return _promise;
|
|
341
|
-
};
|
|
342
|
-
return function(req, res) {
|
|
343
|
-
return resolve().then((h) => h(req, res));
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
const lazyHandle = defineLazyHandler;
|
|
347
|
-
function useBase(base, handler) {
|
|
348
|
-
base = ufo.withoutTrailingSlash(base);
|
|
349
|
-
if (!base) {
|
|
350
|
-
return handler;
|
|
351
|
-
}
|
|
352
|
-
return function(req, res) {
|
|
353
|
-
req.originalUrl = req.originalUrl || req.url || "/";
|
|
354
|
-
req.url = ufo.withoutBase(req.url || "/", base);
|
|
355
|
-
return handler(req, res);
|
|
356
|
-
};
|
|
357
|
-
}
|
|
358
215
|
|
|
359
216
|
function defineEventHandler(handler) {
|
|
360
217
|
handler.__is_handler__ = true;
|
|
361
218
|
return handler;
|
|
362
219
|
}
|
|
363
220
|
const eventHandler = defineEventHandler;
|
|
221
|
+
function isEventHandler(input) {
|
|
222
|
+
return "__is_handler__" in input;
|
|
223
|
+
}
|
|
224
|
+
function toEventHandler(handler) {
|
|
225
|
+
if (isEventHandler(handler)) {
|
|
226
|
+
return handler;
|
|
227
|
+
}
|
|
228
|
+
if (typeof handler !== "function") {
|
|
229
|
+
throw new TypeError("Invalid handler. It should be a function:", handler);
|
|
230
|
+
}
|
|
231
|
+
return eventHandler((event) => {
|
|
232
|
+
return callHandler(handler, event.req, event.res);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
function dynamicEventHandler(initial) {
|
|
236
|
+
let current = initial;
|
|
237
|
+
const wrapper = eventHandler((event) => {
|
|
238
|
+
if (current) {
|
|
239
|
+
return current(event);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
wrapper.set = (handler) => {
|
|
243
|
+
current = handler;
|
|
244
|
+
};
|
|
245
|
+
return wrapper;
|
|
246
|
+
}
|
|
364
247
|
function defineLazyEventHandler(factory) {
|
|
365
248
|
let _promise;
|
|
366
249
|
let _resolved;
|
|
@@ -388,274 +271,16 @@ function defineLazyEventHandler(factory) {
|
|
|
388
271
|
});
|
|
389
272
|
}
|
|
390
273
|
const lazyEventHandler = defineLazyEventHandler;
|
|
391
|
-
function dynamicEventHandler(initial) {
|
|
392
|
-
let current = initial;
|
|
393
|
-
const wrapper = eventHandler((event) => {
|
|
394
|
-
if (current) {
|
|
395
|
-
return current(event);
|
|
396
|
-
}
|
|
397
|
-
});
|
|
398
|
-
wrapper.set = (handler) => {
|
|
399
|
-
current = handler;
|
|
400
|
-
};
|
|
401
|
-
return wrapper;
|
|
402
|
-
}
|
|
403
|
-
function isEventHandler(input) {
|
|
404
|
-
return "__is_handler__" in input;
|
|
405
|
-
}
|
|
406
|
-
function toEventHandler(handler) {
|
|
407
|
-
if (isEventHandler(handler)) {
|
|
408
|
-
return handler;
|
|
409
|
-
}
|
|
410
|
-
if (typeof handler !== "function") {
|
|
411
|
-
throw new TypeError("Invalid handler. It should be a function:", handler);
|
|
412
|
-
}
|
|
413
|
-
return eventHandler((event) => {
|
|
414
|
-
return callHandler(handler, event.req, event.res);
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
function createEvent(req, res) {
|
|
418
|
-
const event = {
|
|
419
|
-
__is_event__: true,
|
|
420
|
-
req,
|
|
421
|
-
res,
|
|
422
|
-
context: {}
|
|
423
|
-
};
|
|
424
|
-
event.event = event;
|
|
425
|
-
req.event = event;
|
|
426
|
-
req.context = event.context;
|
|
427
|
-
req.req = req;
|
|
428
|
-
req.res = res;
|
|
429
|
-
res.event = event;
|
|
430
|
-
res.res = res;
|
|
431
|
-
res.req = res.req || {};
|
|
432
|
-
res.req.res = res;
|
|
433
|
-
res.req.req = req;
|
|
434
|
-
return event;
|
|
435
|
-
}
|
|
436
|
-
function isEvent(input) {
|
|
437
|
-
return "__is_event__" in input;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
function createApp(options = {}) {
|
|
441
|
-
const stack = [];
|
|
442
|
-
const handler = createAppEventHandler(stack, options);
|
|
443
|
-
const nodeHandler = async function(req, res) {
|
|
444
|
-
const event = createEvent(req, res);
|
|
445
|
-
try {
|
|
446
|
-
await handler(event);
|
|
447
|
-
} catch (_error) {
|
|
448
|
-
const error = createError(_error);
|
|
449
|
-
if (!isError(_error)) {
|
|
450
|
-
error.unhandled = true;
|
|
451
|
-
}
|
|
452
|
-
if (options.onError) {
|
|
453
|
-
await options.onError(error, event);
|
|
454
|
-
} else {
|
|
455
|
-
if (error.unhandled || error.fatal) {
|
|
456
|
-
console.error("[h3]", error.fatal ? "[fatal]" : "[unhandled]", error);
|
|
457
|
-
}
|
|
458
|
-
await sendError(event, error, !!options.debug);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
};
|
|
462
|
-
const app = nodeHandler;
|
|
463
|
-
app.nodeHandler = nodeHandler;
|
|
464
|
-
app.stack = stack;
|
|
465
|
-
app.handler = handler;
|
|
466
|
-
app.use = (arg1, arg2, arg3) => use(app, arg1, arg2, arg3);
|
|
467
|
-
return app;
|
|
468
|
-
}
|
|
469
|
-
function use(app, arg1, arg2, arg3) {
|
|
470
|
-
if (Array.isArray(arg1)) {
|
|
471
|
-
arg1.forEach((i) => use(app, i, arg2, arg3));
|
|
472
|
-
} else if (Array.isArray(arg2)) {
|
|
473
|
-
arg2.forEach((i) => use(app, arg1, i, arg3));
|
|
474
|
-
} else if (typeof arg1 === "string") {
|
|
475
|
-
app.stack.push(normalizeLayer({ ...arg3, route: arg1, handler: arg2 }));
|
|
476
|
-
} else if (typeof arg1 === "function") {
|
|
477
|
-
app.stack.push(normalizeLayer({ ...arg2, route: "/", handler: arg1 }));
|
|
478
|
-
} else {
|
|
479
|
-
app.stack.push(normalizeLayer({ ...arg1 }));
|
|
480
|
-
}
|
|
481
|
-
return app;
|
|
482
|
-
}
|
|
483
|
-
function createAppEventHandler(stack, options) {
|
|
484
|
-
const spacing = options.debug ? 2 : void 0;
|
|
485
|
-
return eventHandler(async (event) => {
|
|
486
|
-
event.req.originalUrl = event.req.originalUrl || event.req.url || "/";
|
|
487
|
-
const reqUrl = event.req.url || "/";
|
|
488
|
-
for (const layer of stack) {
|
|
489
|
-
if (layer.route.length > 1) {
|
|
490
|
-
if (!reqUrl.startsWith(layer.route)) {
|
|
491
|
-
continue;
|
|
492
|
-
}
|
|
493
|
-
event.req.url = reqUrl.slice(layer.route.length) || "/";
|
|
494
|
-
} else {
|
|
495
|
-
event.req.url = reqUrl;
|
|
496
|
-
}
|
|
497
|
-
if (layer.match && !layer.match(event.req.url, event)) {
|
|
498
|
-
continue;
|
|
499
|
-
}
|
|
500
|
-
const val = await layer.handler(event);
|
|
501
|
-
if (event.res.writableEnded) {
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
|
-
const type = typeof val;
|
|
505
|
-
if (type === "string") {
|
|
506
|
-
return send(event, val, MIMES.html);
|
|
507
|
-
} else if (isStream(val)) {
|
|
508
|
-
return sendStream(event, val);
|
|
509
|
-
} else if (val === null) {
|
|
510
|
-
event.res.statusCode = 204;
|
|
511
|
-
return send(event);
|
|
512
|
-
} else if (type === "object" || type === "boolean" || type === "number") {
|
|
513
|
-
if (val.buffer) {
|
|
514
|
-
return send(event, val);
|
|
515
|
-
} else if (val instanceof Error) {
|
|
516
|
-
throw createError(val);
|
|
517
|
-
} else {
|
|
518
|
-
return send(event, JSON.stringify(val, null, spacing), MIMES.json);
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
if (!event.res.writableEnded) {
|
|
523
|
-
throw createError({ statusCode: 404, statusMessage: "Not Found" });
|
|
524
|
-
}
|
|
525
|
-
});
|
|
526
|
-
}
|
|
527
|
-
function normalizeLayer(input) {
|
|
528
|
-
let handler = input.handler || input.handle;
|
|
529
|
-
if (handler.handler) {
|
|
530
|
-
handler = handler.handler;
|
|
531
|
-
}
|
|
532
|
-
if (input.lazy) {
|
|
533
|
-
handler = lazyEventHandler(handler);
|
|
534
|
-
} else if (!isEventHandler(handler)) {
|
|
535
|
-
handler = toEventHandler(handler);
|
|
536
|
-
}
|
|
537
|
-
return {
|
|
538
|
-
route: ufo.withoutTrailingSlash(input.route),
|
|
539
|
-
match: input.match,
|
|
540
|
-
handler
|
|
541
|
-
};
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
const RouterMethods = ["connect", "delete", "get", "head", "options", "post", "put", "trace"];
|
|
545
|
-
function createRouter() {
|
|
546
|
-
const _router = radix3.createRouter({});
|
|
547
|
-
const routes = {};
|
|
548
|
-
const router = {};
|
|
549
|
-
const addRoute = (path, handler, method) => {
|
|
550
|
-
let route = routes[path];
|
|
551
|
-
if (!route) {
|
|
552
|
-
routes[path] = route = { handlers: {} };
|
|
553
|
-
_router.insert(path, route);
|
|
554
|
-
}
|
|
555
|
-
if (Array.isArray(method)) {
|
|
556
|
-
method.forEach((m) => addRoute(path, handler, m));
|
|
557
|
-
} else {
|
|
558
|
-
route.handlers[method] = toEventHandler(handler);
|
|
559
|
-
}
|
|
560
|
-
return router;
|
|
561
|
-
};
|
|
562
|
-
router.use = router.add = (path, handler, method) => addRoute(path, handler, method || "all");
|
|
563
|
-
for (const method of RouterMethods) {
|
|
564
|
-
router[method] = (path, handle) => router.add(path, handle, method);
|
|
565
|
-
}
|
|
566
|
-
router.handler = eventHandler((event) => {
|
|
567
|
-
let path = event.req.url || "/";
|
|
568
|
-
const queryUrlIndex = path.lastIndexOf("?");
|
|
569
|
-
if (queryUrlIndex > -1) {
|
|
570
|
-
path = path.substring(0, queryUrlIndex);
|
|
571
|
-
}
|
|
572
|
-
const matched = _router.lookup(path);
|
|
573
|
-
if (!matched) {
|
|
574
|
-
throw createError({
|
|
575
|
-
statusCode: 404,
|
|
576
|
-
name: "Not Found",
|
|
577
|
-
statusMessage: `Cannot find any route matching ${event.req.url || "/"}.`
|
|
578
|
-
});
|
|
579
|
-
}
|
|
580
|
-
const method = (event.req.method || "get").toLowerCase();
|
|
581
|
-
const handler = matched.handlers[method] || matched.handlers.all;
|
|
582
|
-
if (!handler) {
|
|
583
|
-
throw createError({
|
|
584
|
-
statusCode: 405,
|
|
585
|
-
name: "Method Not Allowed",
|
|
586
|
-
statusMessage: `Method ${method} is not allowed on this route.`
|
|
587
|
-
});
|
|
588
|
-
}
|
|
589
|
-
const params = matched.params || {};
|
|
590
|
-
event.event.context.params = params;
|
|
591
|
-
event.req.context.params = params;
|
|
592
|
-
return handler(event);
|
|
593
|
-
});
|
|
594
|
-
return router;
|
|
595
|
-
}
|
|
596
274
|
|
|
597
|
-
exports.
|
|
598
|
-
exports.
|
|
599
|
-
exports.
|
|
600
|
-
exports.appendHeaders = appendHeaders;
|
|
601
|
-
exports.appendResponseHeader = appendResponseHeader;
|
|
602
|
-
exports.appendResponseHeaders = appendResponseHeaders;
|
|
603
|
-
exports.assertMethod = assertMethod;
|
|
604
|
-
exports.callHandler = callHandler;
|
|
605
|
-
exports.createApp = createApp;
|
|
606
|
-
exports.createAppEventHandler = createAppEventHandler;
|
|
607
|
-
exports.createError = createError;
|
|
275
|
+
exports.H3Event = H3Event;
|
|
276
|
+
exports.H3Headers = H3Headers;
|
|
277
|
+
exports.H3Response = H3Response;
|
|
608
278
|
exports.createEvent = createEvent;
|
|
609
|
-
exports.createRouter = createRouter;
|
|
610
|
-
exports.defaultContentType = defaultContentType;
|
|
611
279
|
exports.defineEventHandler = defineEventHandler;
|
|
612
|
-
exports.defineHandle = defineHandle;
|
|
613
|
-
exports.defineHandler = defineHandler;
|
|
614
280
|
exports.defineLazyEventHandler = defineLazyEventHandler;
|
|
615
|
-
exports.defineLazyHandler = defineLazyHandler;
|
|
616
|
-
exports.defineMiddleware = defineMiddleware;
|
|
617
|
-
exports.deleteCookie = deleteCookie;
|
|
618
281
|
exports.dynamicEventHandler = dynamicEventHandler;
|
|
619
282
|
exports.eventHandler = eventHandler;
|
|
620
|
-
exports.getCookie = getCookie;
|
|
621
|
-
exports.getHeader = getHeader;
|
|
622
|
-
exports.getHeaders = getHeaders;
|
|
623
|
-
exports.getMethod = getMethod;
|
|
624
|
-
exports.getQuery = getQuery;
|
|
625
|
-
exports.getRequestHeader = getRequestHeader;
|
|
626
|
-
exports.getRequestHeaders = getRequestHeaders;
|
|
627
|
-
exports.getResponseHeader = getResponseHeader;
|
|
628
|
-
exports.getResponseHeaders = getResponseHeaders;
|
|
629
|
-
exports.getRouterParam = getRouterParam;
|
|
630
|
-
exports.getRouterParams = getRouterParams;
|
|
631
|
-
exports.handleCacheHeaders = handleCacheHeaders;
|
|
632
|
-
exports.isError = isError;
|
|
633
283
|
exports.isEvent = isEvent;
|
|
634
284
|
exports.isEventHandler = isEventHandler;
|
|
635
|
-
exports.isMethod = isMethod;
|
|
636
|
-
exports.isStream = isStream;
|
|
637
285
|
exports.lazyEventHandler = lazyEventHandler;
|
|
638
|
-
exports.lazyHandle = lazyHandle;
|
|
639
|
-
exports.parseCookies = parseCookies;
|
|
640
|
-
exports.promisifyHandle = promisifyHandle;
|
|
641
|
-
exports.promisifyHandler = promisifyHandler;
|
|
642
|
-
exports.readBody = readBody;
|
|
643
|
-
exports.readRawBody = readRawBody;
|
|
644
|
-
exports.send = send;
|
|
645
|
-
exports.sendError = sendError;
|
|
646
|
-
exports.sendRedirect = sendRedirect;
|
|
647
|
-
exports.sendStream = sendStream;
|
|
648
|
-
exports.setCookie = setCookie;
|
|
649
|
-
exports.setHeader = setHeader;
|
|
650
|
-
exports.setHeaders = setHeaders;
|
|
651
|
-
exports.setResponseHeader = setResponseHeader;
|
|
652
|
-
exports.setResponseHeaders = setResponseHeaders;
|
|
653
286
|
exports.toEventHandler = toEventHandler;
|
|
654
|
-
exports.use = use;
|
|
655
|
-
exports.useBase = useBase;
|
|
656
|
-
exports.useBody = useBody;
|
|
657
|
-
exports.useCookie = useCookie;
|
|
658
|
-
exports.useCookies = useCookies;
|
|
659
|
-
exports.useMethod = useMethod;
|
|
660
|
-
exports.useQuery = useQuery;
|
|
661
|
-
exports.useRawBody = useRawBody;
|