285 lines
9.4 KiB
JavaScript
285 lines
9.4 KiB
JavaScript
import { c as NodeResponse, s as NullProtoObj, u as FastURL } from "./h3+rou3+srvx.mjs";
|
|
//#region node_modules/h3-v2/dist/h3-Bz4OPZv_.mjs
|
|
function decodePathname(pathname) {
|
|
return decodeURI(pathname.includes("%25") ? pathname.replace(/%25/g, "%2525") : pathname);
|
|
}
|
|
var kEventNS = "h3.internal.event.";
|
|
var kEventRes = /* @__PURE__ */ Symbol.for(`${kEventNS}res`);
|
|
var kEventResHeaders = /* @__PURE__ */ Symbol.for(`${kEventNS}res.headers`);
|
|
var kEventResErrHeaders = /* @__PURE__ */ Symbol.for(`${kEventNS}res.err.headers`);
|
|
var H3Event = class {
|
|
app;
|
|
req;
|
|
url;
|
|
context;
|
|
static __is_event__ = true;
|
|
constructor(req, context, app) {
|
|
this.context = context || req.context || new NullProtoObj();
|
|
this.req = req;
|
|
this.app = app;
|
|
const _url = req._url;
|
|
const url = _url && _url instanceof URL ? _url : new FastURL(req.url);
|
|
if (url.pathname.includes("%")) url.pathname = decodePathname(url.pathname);
|
|
this.url = url;
|
|
}
|
|
get res() {
|
|
return this[kEventRes] ||= new H3EventResponse();
|
|
}
|
|
get runtime() {
|
|
return this.req.runtime;
|
|
}
|
|
waitUntil(promise) {
|
|
this.req.waitUntil?.(promise);
|
|
}
|
|
toString() {
|
|
return `[${this.req.method}] ${this.req.url}`;
|
|
}
|
|
toJSON() {
|
|
return this.toString();
|
|
}
|
|
get node() {
|
|
return this.req.runtime?.node;
|
|
}
|
|
get headers() {
|
|
return this.req.headers;
|
|
}
|
|
get path() {
|
|
return this.url.pathname + this.url.search;
|
|
}
|
|
get method() {
|
|
return this.req.method;
|
|
}
|
|
};
|
|
var H3EventResponse = class {
|
|
status;
|
|
statusText;
|
|
get headers() {
|
|
return this[kEventResHeaders] ||= new Headers();
|
|
}
|
|
get errHeaders() {
|
|
return this[kEventResErrHeaders] ||= new Headers();
|
|
}
|
|
};
|
|
var DISALLOWED_STATUS_CHARS = /[^\u0009\u0020-\u007E]/g;
|
|
function sanitizeStatusMessage(statusMessage = "") {
|
|
return statusMessage.replace(DISALLOWED_STATUS_CHARS, "");
|
|
}
|
|
function sanitizeStatusCode(statusCode, defaultStatusCode = 200) {
|
|
if (!statusCode) return defaultStatusCode;
|
|
if (typeof statusCode === "string") statusCode = +statusCode;
|
|
if (statusCode < 100 || statusCode > 599) return defaultStatusCode;
|
|
return statusCode;
|
|
}
|
|
var HTTPError = class HTTPError extends Error {
|
|
get name() {
|
|
return "HTTPError";
|
|
}
|
|
status;
|
|
statusText;
|
|
headers;
|
|
cause;
|
|
data;
|
|
body;
|
|
unhandled;
|
|
static isError(input) {
|
|
return input instanceof Error && input?.name === "HTTPError";
|
|
}
|
|
static status(status, statusText, details) {
|
|
return new HTTPError({
|
|
...details,
|
|
statusText,
|
|
status
|
|
});
|
|
}
|
|
constructor(arg1, arg2) {
|
|
let messageInput;
|
|
let details;
|
|
if (typeof arg1 === "string") {
|
|
messageInput = arg1;
|
|
details = arg2;
|
|
} else details = arg1;
|
|
const status = sanitizeStatusCode(details?.status || details?.statusCode || (details?.cause)?.status || (details?.cause)?.statusCode, 500);
|
|
const statusText = sanitizeStatusMessage(details?.statusText || details?.statusMessage || (details?.cause)?.statusText || (details?.cause)?.statusMessage);
|
|
const message = messageInput || details?.message || (details?.cause)?.message || details?.statusText || details?.statusMessage || [
|
|
"HTTPError",
|
|
status,
|
|
statusText
|
|
].filter(Boolean).join(" ");
|
|
super(message, { cause: details });
|
|
this.cause = details;
|
|
this.status = status;
|
|
this.statusText = statusText || void 0;
|
|
const rawHeaders = details?.headers || (details?.cause)?.headers;
|
|
this.headers = rawHeaders ? new Headers(rawHeaders) : void 0;
|
|
this.unhandled = details?.unhandled ?? (details?.cause)?.unhandled ?? void 0;
|
|
this.data = details?.data;
|
|
this.body = details?.body;
|
|
}
|
|
get statusCode() {
|
|
return this.status;
|
|
}
|
|
get statusMessage() {
|
|
return this.statusText;
|
|
}
|
|
toJSON() {
|
|
const unhandled = this.unhandled;
|
|
return {
|
|
status: this.status,
|
|
statusText: this.statusText,
|
|
unhandled,
|
|
message: unhandled ? "HTTPError" : this.message,
|
|
data: unhandled ? void 0 : this.data,
|
|
...unhandled ? void 0 : this.body
|
|
};
|
|
}
|
|
};
|
|
function isJSONSerializable(value, _type) {
|
|
if (value === null || value === void 0) return true;
|
|
if (_type !== "object") return _type === "boolean" || _type === "number" || _type === "string";
|
|
if (typeof value.toJSON === "function") return true;
|
|
if (Array.isArray(value)) return true;
|
|
if (typeof value.pipe === "function" || typeof value.pipeTo === "function") return false;
|
|
if (value instanceof NullProtoObj) return true;
|
|
const proto = Object.getPrototypeOf(value);
|
|
return proto === Object.prototype || proto === null;
|
|
}
|
|
var kNotFound = /* @__PURE__ */ Symbol.for("h3.notFound");
|
|
var kHandled = /* @__PURE__ */ Symbol.for("h3.handled");
|
|
function toResponse(val, event, config = {}) {
|
|
if (typeof val?.then === "function") return (val.catch?.((error) => error) || Promise.resolve(val)).then((resolvedVal) => toResponse(resolvedVal, event, config));
|
|
const response = prepareResponse(val, event, config);
|
|
if (typeof response?.then === "function") return toResponse(response, event, config);
|
|
const { onResponse } = config;
|
|
return onResponse ? Promise.resolve(onResponse(response, event)).then(() => response) : response;
|
|
}
|
|
var HTTPResponse = class {
|
|
#headers;
|
|
#init;
|
|
body;
|
|
constructor(body, init) {
|
|
this.body = body;
|
|
this.#init = init;
|
|
}
|
|
get status() {
|
|
return this.#init?.status || 200;
|
|
}
|
|
get statusText() {
|
|
return this.#init?.statusText || "OK";
|
|
}
|
|
get headers() {
|
|
return this.#headers ||= new Headers(this.#init?.headers);
|
|
}
|
|
};
|
|
function prepareResponse(val, event, config, nested) {
|
|
if (val === kHandled) return new NodeResponse(null);
|
|
if (val === kNotFound) val = new HTTPError({
|
|
status: 404,
|
|
message: `Cannot find any route matching [${event.req.method}] ${event.url}`
|
|
});
|
|
if (val && val instanceof Error) {
|
|
const isHTTPError = HTTPError.isError(val);
|
|
const error = isHTTPError ? val : new HTTPError(val);
|
|
if (!isHTTPError) {
|
|
error.unhandled = true;
|
|
if (val?.stack) error.stack = val.stack;
|
|
}
|
|
if (error.unhandled && !config.silent) console.error(error);
|
|
const { onError } = config;
|
|
const errHeaders = event[kEventRes]?.[kEventResErrHeaders];
|
|
return onError && !nested ? Promise.resolve(onError(error, event)).catch((error) => error).then((newVal) => prepareResponse(newVal ?? val, event, config, true)) : errorResponse(error, config.debug, errHeaders);
|
|
}
|
|
const preparedRes = event[kEventRes];
|
|
const preparedHeaders = preparedRes?.[kEventResHeaders];
|
|
event[kEventRes] = void 0;
|
|
if (!(val instanceof Response)) {
|
|
const res = prepareResponseBody(val, event, config);
|
|
const status = res.status || preparedRes?.status;
|
|
return new NodeResponse(nullBody(event.req.method, status) ? null : res.body, {
|
|
status,
|
|
statusText: res.statusText || preparedRes?.statusText,
|
|
headers: res.headers && preparedHeaders ? mergeHeaders$1(res.headers, preparedHeaders) : res.headers || preparedHeaders
|
|
});
|
|
}
|
|
if (!preparedHeaders || nested || !val.ok) return val;
|
|
try {
|
|
mergeHeaders$1(val.headers, preparedHeaders, val.headers);
|
|
return val;
|
|
} catch {
|
|
return new NodeResponse(nullBody(event.req.method, val.status) ? null : val.body, {
|
|
status: val.status,
|
|
statusText: val.statusText,
|
|
headers: mergeHeaders$1(val.headers, preparedHeaders)
|
|
});
|
|
}
|
|
}
|
|
function mergeHeaders$1(base, overrides, target = new Headers(base)) {
|
|
for (const [name, value] of overrides) if (name === "set-cookie") target.append(name, value);
|
|
else target.set(name, value);
|
|
return target;
|
|
}
|
|
var frozen = (name) => (...args) => {
|
|
throw new Error(`Headers are frozen (${name} ${args.join(", ")})`);
|
|
};
|
|
var FrozenHeaders = class extends Headers {
|
|
set = frozen("set");
|
|
append = frozen("append");
|
|
delete = frozen("delete");
|
|
};
|
|
var emptyHeaders = /* @__PURE__ */ new FrozenHeaders({ "content-length": "0" });
|
|
var jsonHeaders = /* @__PURE__ */ new FrozenHeaders({ "content-type": "application/json;charset=UTF-8" });
|
|
function prepareResponseBody(val, event, config) {
|
|
if (val === null || val === void 0) return {
|
|
body: "",
|
|
headers: emptyHeaders
|
|
};
|
|
const valType = typeof val;
|
|
if (valType === "string") return { body: val };
|
|
if (val instanceof Uint8Array) {
|
|
event.res.headers.set("content-length", val.byteLength.toString());
|
|
return { body: val };
|
|
}
|
|
if (val instanceof HTTPResponse || val?.constructor?.name === "HTTPResponse") return val;
|
|
if (isJSONSerializable(val, valType)) return {
|
|
body: JSON.stringify(val, void 0, config.debug ? 2 : void 0),
|
|
headers: jsonHeaders
|
|
};
|
|
if (valType === "bigint") return {
|
|
body: val.toString(),
|
|
headers: jsonHeaders
|
|
};
|
|
if (val instanceof Blob) {
|
|
const headers = new Headers({
|
|
"content-type": val.type,
|
|
"content-length": val.size.toString()
|
|
});
|
|
let filename = val.name;
|
|
if (filename) {
|
|
filename = encodeURIComponent(filename);
|
|
headers.set("content-disposition", `filename="${filename}"; filename*=UTF-8''${filename}`);
|
|
}
|
|
return {
|
|
body: val.stream(),
|
|
headers
|
|
};
|
|
}
|
|
if (valType === "symbol") return { body: val.toString() };
|
|
if (valType === "function") return { body: `${val.name}()` };
|
|
return { body: val };
|
|
}
|
|
function nullBody(method, status) {
|
|
return method === "HEAD" || status === 100 || status === 101 || status === 102 || status === 204 || status === 205 || status === 304;
|
|
}
|
|
function errorResponse(error, debug, errHeaders) {
|
|
let headers = error.headers ? mergeHeaders$1(jsonHeaders, error.headers) : new Headers(jsonHeaders);
|
|
if (errHeaders) headers = mergeHeaders$1(headers, errHeaders);
|
|
return new NodeResponse(JSON.stringify({
|
|
...error.toJSON(),
|
|
stack: debug && error.stack ? error.stack.split("\n").map((l) => l.trim()) : void 0
|
|
}, void 0, debug ? 2 : void 0), {
|
|
status: error.status,
|
|
statusText: error.statusText,
|
|
headers
|
|
});
|
|
}
|
|
//#endregion
|
|
export { toResponse as n, H3Event as t };
|