ruins
Version:
> [!IMPORTANT] > This is in beta. Not everything is ironed out and some modules might misbehave
1,511 lines (1,489 loc) • 147 kB
JavaScript
import process from 'node:process';globalThis._importMeta_=globalThis._importMeta_||{url:"file:///_entry.js",env:process.env};import http, { Server as Server$1 } from 'node:http';
import https, { Server } from 'node:https';
import { EventEmitter } from 'node:events';
import { Buffer as Buffer$1 } from 'node:buffer';
import { promises, existsSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { resolve as resolve$1, dirname as dirname$1, join } from 'node:path';
import { createHash } from 'node:crypto';
const suspectProtoRx = /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/;
const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
const JsonSigRx = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
function jsonParseTransform(key, value) {
if (key === "__proto__" || key === "constructor" && value && typeof value === "object" && "prototype" in value) {
warnKeyDropped(key);
return;
}
return value;
}
function warnKeyDropped(key) {
console.warn(`[destr] Dropping "${key}" key to prevent prototype pollution.`);
}
function destr(value, options = {}) {
if (typeof value !== "string") {
return value;
}
const _value = value.trim();
if (
// eslint-disable-next-line unicorn/prefer-at
value[0] === '"' && value.endsWith('"') && !value.includes("\\")
) {
return _value.slice(1, -1);
}
if (_value.length <= 9) {
const _lval = _value.toLowerCase();
if (_lval === "true") {
return true;
}
if (_lval === "false") {
return false;
}
if (_lval === "undefined") {
return void 0;
}
if (_lval === "null") {
return null;
}
if (_lval === "nan") {
return Number.NaN;
}
if (_lval === "infinity") {
return Number.POSITIVE_INFINITY;
}
if (_lval === "-infinity") {
return Number.NEGATIVE_INFINITY;
}
}
if (!JsonSigRx.test(value)) {
if (options.strict) {
throw new SyntaxError("[destr] Invalid JSON");
}
return value;
}
try {
if (suspectProtoRx.test(value) || suspectConstructorRx.test(value)) {
if (options.strict) {
throw new Error("[destr] Possible prototype pollution");
}
return JSON.parse(value, jsonParseTransform);
}
return JSON.parse(value);
} catch (error) {
if (options.strict) {
throw error;
}
return value;
}
}
const HASH_RE = /#/g;
const AMPERSAND_RE = /&/g;
const SLASH_RE = /\//g;
const EQUAL_RE = /=/g;
const PLUS_RE = /\+/g;
const ENC_CARET_RE = /%5e/gi;
const ENC_BACKTICK_RE = /%60/gi;
const ENC_PIPE_RE = /%7c/gi;
const ENC_SPACE_RE = /%20/gi;
const ENC_SLASH_RE = /%2f/gi;
function encode(text) {
return encodeURI("" + text).replace(ENC_PIPE_RE, "|");
}
function encodeQueryValue(input) {
return encode(typeof input === "string" ? input : JSON.stringify(input)).replace(PLUS_RE, "%2B").replace(ENC_SPACE_RE, "+").replace(HASH_RE, "%23").replace(AMPERSAND_RE, "%26").replace(ENC_BACKTICK_RE, "`").replace(ENC_CARET_RE, "^").replace(SLASH_RE, "%2F");
}
function encodeQueryKey(text) {
return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
}
function decode(text = "") {
try {
return decodeURIComponent("" + text);
} catch {
return "" + text;
}
}
function decodePath(text) {
return decode(text.replace(ENC_SLASH_RE, "%252F"));
}
function decodeQueryKey(text) {
return decode(text.replace(PLUS_RE, " "));
}
function decodeQueryValue(text) {
return decode(text.replace(PLUS_RE, " "));
}
function parseQuery(parametersString = "") {
const object = {};
if (parametersString[0] === "?") {
parametersString = parametersString.slice(1);
}
for (const parameter of parametersString.split("&")) {
const s = parameter.match(/([^=]+)=?(.*)/) || [];
if (s.length < 2) {
continue;
}
const key = decodeQueryKey(s[1]);
if (key === "__proto__" || key === "constructor") {
continue;
}
const value = decodeQueryValue(s[2] || "");
if (object[key] === void 0) {
object[key] = value;
} else if (Array.isArray(object[key])) {
object[key].push(value);
} else {
object[key] = [object[key], value];
}
}
return object;
}
function encodeQueryItem(key, value) {
if (typeof value === "number" || typeof value === "boolean") {
value = String(value);
}
if (!value) {
return encodeQueryKey(key);
}
if (Array.isArray(value)) {
return value.map((_value) => `${encodeQueryKey(key)}=${encodeQueryValue(_value)}`).join("&");
}
return `${encodeQueryKey(key)}=${encodeQueryValue(value)}`;
}
function stringifyQuery(query) {
return Object.keys(query).filter((k) => query[k] !== void 0).map((k) => encodeQueryItem(k, query[k])).filter(Boolean).join("&");
}
const PROTOCOL_STRICT_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{1,2})/;
const PROTOCOL_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{2})?/;
const PROTOCOL_RELATIVE_REGEX = /^([/\\]\s*){2,}[^/\\]/;
const JOIN_LEADING_SLASH_RE = /^\.?\//;
function hasProtocol(inputString, opts = {}) {
if (typeof opts === "boolean") {
opts = { acceptRelative: opts };
}
if (opts.strict) {
return PROTOCOL_STRICT_REGEX.test(inputString);
}
return PROTOCOL_REGEX.test(inputString) || (opts.acceptRelative ? PROTOCOL_RELATIVE_REGEX.test(inputString) : false);
}
function hasTrailingSlash(input = "", respectQueryAndFragment) {
{
return input.endsWith("/");
}
}
function withoutTrailingSlash(input = "", respectQueryAndFragment) {
{
return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || "/";
}
}
function withTrailingSlash(input = "", respectQueryAndFragment) {
{
return input.endsWith("/") ? input : input + "/";
}
}
function hasLeadingSlash(input = "") {
return input.startsWith("/");
}
function withLeadingSlash(input = "") {
return hasLeadingSlash(input) ? input : "/" + input;
}
function withBase(input, base) {
if (isEmptyURL(base) || hasProtocol(input)) {
return input;
}
const _base = withoutTrailingSlash(base);
if (input.startsWith(_base)) {
return input;
}
return joinURL(_base, input);
}
function withoutBase(input, base) {
if (isEmptyURL(base)) {
return input;
}
const _base = withoutTrailingSlash(base);
if (!input.startsWith(_base)) {
return input;
}
const trimmed = input.slice(_base.length);
return trimmed[0] === "/" ? trimmed : "/" + trimmed;
}
function withQuery(input, query) {
const parsed = parseURL(input);
const mergedQuery = { ...parseQuery(parsed.search), ...query };
parsed.search = stringifyQuery(mergedQuery);
return stringifyParsedURL(parsed);
}
function getQuery(input) {
return parseQuery(parseURL(input).search);
}
function isEmptyURL(url) {
return !url || url === "/";
}
function isNonEmptyURL(url) {
return url && url !== "/";
}
function joinURL(base, ...input) {
let url = base || "";
for (const segment of input.filter((url2) => isNonEmptyURL(url2))) {
if (url) {
const _segment = segment.replace(JOIN_LEADING_SLASH_RE, "");
url = withTrailingSlash(url) + _segment;
} else {
url = segment;
}
}
return url;
}
const protocolRelative = Symbol.for("ufo:protocolRelative");
function parseURL(input = "", defaultProto) {
const _specialProtoMatch = input.match(
/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i
);
if (_specialProtoMatch) {
const [, _proto, _pathname = ""] = _specialProtoMatch;
return {
protocol: _proto.toLowerCase(),
pathname: _pathname,
href: _proto + _pathname,
auth: "",
host: "",
search: "",
hash: ""
};
}
if (!hasProtocol(input, { acceptRelative: true })) {
return parsePath(input);
}
const [, protocol = "", auth, hostAndPath = ""] = input.replace(/\\/g, "/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/) || [];
let [, host = "", path = ""] = hostAndPath.match(/([^#/?]*)(.*)?/) || [];
if (protocol === "file:") {
path = path.replace(/\/(?=[A-Za-z]:)/, "");
}
const { pathname, search, hash } = parsePath(path);
return {
protocol: protocol.toLowerCase(),
auth: auth ? auth.slice(0, Math.max(0, auth.length - 1)) : "",
host,
pathname,
search,
hash,
[protocolRelative]: !protocol
};
}
function parsePath(input = "") {
const [pathname = "", search = "", hash = ""] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1);
return {
pathname,
search,
hash
};
}
function stringifyParsedURL(parsed) {
const pathname = parsed.pathname || "";
const search = parsed.search ? (parsed.search.startsWith("?") ? "" : "?") + parsed.search : "";
const hash = parsed.hash || "";
const auth = parsed.auth ? parsed.auth + "@" : "";
const host = parsed.host || "";
const proto = parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || "") + "//" : "";
return proto + auth + host + pathname + search + hash;
}
const NODE_TYPES = {
NORMAL: 0,
WILDCARD: 1,
PLACEHOLDER: 2
};
function createRouter$1(options = {}) {
const ctx = {
options,
rootNode: createRadixNode(),
staticRoutesMap: {}
};
const normalizeTrailingSlash = (p) => options.strictTrailingSlash ? p : p.replace(/\/$/, "") || "/";
if (options.routes) {
for (const path in options.routes) {
insert(ctx, normalizeTrailingSlash(path), options.routes[path]);
}
}
return {
ctx,
lookup: (path) => lookup(ctx, normalizeTrailingSlash(path)),
insert: (path, data) => insert(ctx, normalizeTrailingSlash(path), data),
remove: (path) => remove(ctx, normalizeTrailingSlash(path))
};
}
function lookup(ctx, path) {
const staticPathNode = ctx.staticRoutesMap[path];
if (staticPathNode) {
return staticPathNode.data;
}
const sections = path.split("/");
const params = {};
let paramsFound = false;
let wildcardNode = null;
let node = ctx.rootNode;
let wildCardParam = null;
for (let i = 0; i < sections.length; i++) {
const section = sections[i];
if (node.wildcardChildNode !== null) {
wildcardNode = node.wildcardChildNode;
wildCardParam = sections.slice(i).join("/");
}
const nextNode = node.children.get(section);
if (nextNode === void 0) {
if (node && node.placeholderChildren.length > 1) {
const remaining = sections.length - i;
node = node.placeholderChildren.find((c) => c.maxDepth === remaining) || null;
} else {
node = node.placeholderChildren[0] || null;
}
if (!node) {
break;
}
if (node.paramName) {
params[node.paramName] = section;
}
paramsFound = true;
} else {
node = nextNode;
}
}
if ((node === null || node.data === null) && wildcardNode !== null) {
node = wildcardNode;
params[node.paramName || "_"] = wildCardParam;
paramsFound = true;
}
if (!node) {
return null;
}
if (paramsFound) {
return {
...node.data,
params: paramsFound ? params : void 0
};
}
return node.data;
}
function insert(ctx, path, data) {
let isStaticRoute = true;
const sections = path.split("/");
let node = ctx.rootNode;
let _unnamedPlaceholderCtr = 0;
const matchedNodes = [node];
for (const section of sections) {
let childNode;
if (childNode = node.children.get(section)) {
node = childNode;
} else {
const type = getNodeType(section);
childNode = createRadixNode({ type, parent: node });
node.children.set(section, childNode);
if (type === NODE_TYPES.PLACEHOLDER) {
childNode.paramName = section === "*" ? `_${_unnamedPlaceholderCtr++}` : section.slice(1);
node.placeholderChildren.push(childNode);
isStaticRoute = false;
} else if (type === NODE_TYPES.WILDCARD) {
node.wildcardChildNode = childNode;
childNode.paramName = section.slice(
3
/* "**:" */
) || "_";
isStaticRoute = false;
}
matchedNodes.push(childNode);
node = childNode;
}
}
for (const [depth, node2] of matchedNodes.entries()) {
node2.maxDepth = Math.max(matchedNodes.length - depth, node2.maxDepth || 0);
}
node.data = data;
if (isStaticRoute === true) {
ctx.staticRoutesMap[path] = node;
}
return node;
}
function remove(ctx, path) {
let success = false;
const sections = path.split("/");
let node = ctx.rootNode;
for (const section of sections) {
node = node.children.get(section);
if (!node) {
return success;
}
}
if (node.data) {
const lastSection = sections.at(-1) || "";
node.data = null;
if (Object.keys(node.children).length === 0 && node.parent) {
node.parent.children.delete(lastSection);
node.parent.wildcardChildNode = null;
node.parent.placeholderChildren = [];
}
success = true;
}
return success;
}
function createRadixNode(options = {}) {
return {
type: options.type || NODE_TYPES.NORMAL,
maxDepth: 0,
parent: options.parent || null,
children: /* @__PURE__ */ new Map(),
data: options.data || null,
paramName: options.paramName || null,
wildcardChildNode: null,
placeholderChildren: []
};
}
function getNodeType(str) {
if (str.startsWith("**")) {
return NODE_TYPES.WILDCARD;
}
if (str[0] === ":" || str === "*") {
return NODE_TYPES.PLACEHOLDER;
}
return NODE_TYPES.NORMAL;
}
function toRouteMatcher(router) {
const table = _routerNodeToTable("", router.ctx.rootNode);
return _createMatcher(table, router.ctx.options.strictTrailingSlash);
}
function _createMatcher(table, strictTrailingSlash) {
return {
ctx: { table },
matchAll: (path) => _matchRoutes(path, table, strictTrailingSlash)
};
}
function _createRouteTable() {
return {
static: /* @__PURE__ */ new Map(),
wildcard: /* @__PURE__ */ new Map(),
dynamic: /* @__PURE__ */ new Map()
};
}
function _matchRoutes(path, table, strictTrailingSlash) {
if (strictTrailingSlash !== true && path.endsWith("/")) {
path = path.slice(0, -1) || "/";
}
const matches = [];
for (const [key, value] of _sortRoutesMap(table.wildcard)) {
if (path === key || path.startsWith(key + "/")) {
matches.push(value);
}
}
for (const [key, value] of _sortRoutesMap(table.dynamic)) {
if (path.startsWith(key + "/")) {
const subPath = "/" + path.slice(key.length).split("/").splice(2).join("/");
matches.push(..._matchRoutes(subPath, value));
}
}
const staticMatch = table.static.get(path);
if (staticMatch) {
matches.push(staticMatch);
}
return matches.filter(Boolean);
}
function _sortRoutesMap(m) {
return [...m.entries()].sort((a, b) => a[0].length - b[0].length);
}
function _routerNodeToTable(initialPath, initialNode) {
const table = _createRouteTable();
function _addNode(path, node) {
if (path) {
if (node.type === NODE_TYPES.NORMAL && !(path.includes("*") || path.includes(":"))) {
if (node.data) {
table.static.set(path, node.data);
}
} else if (node.type === NODE_TYPES.WILDCARD) {
table.wildcard.set(path.replace("/**", ""), node.data);
} else if (node.type === NODE_TYPES.PLACEHOLDER) {
const subTable = _routerNodeToTable("", node);
if (node.data) {
subTable.static.set("/", node.data);
}
table.dynamic.set(path.replace(/\/\*|\/:\w+/, ""), subTable);
return;
}
}
for (const [childPath, child] of node.children.entries()) {
_addNode(`${path}/${childPath}`.replace("//", "/"), child);
}
}
_addNode(initialPath, initialNode);
return table;
}
function isPlainObject(value) {
if (value === null || typeof value !== "object") {
return false;
}
const prototype = Object.getPrototypeOf(value);
if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) {
return false;
}
if (Symbol.iterator in value) {
return false;
}
if (Symbol.toStringTag in value) {
return Object.prototype.toString.call(value) === "[object Module]";
}
return true;
}
function _defu(baseObject, defaults, namespace = ".", merger) {
if (!isPlainObject(defaults)) {
return _defu(baseObject, {}, namespace, merger);
}
const object = Object.assign({}, defaults);
for (const key in baseObject) {
if (key === "__proto__" || key === "constructor") {
continue;
}
const value = baseObject[key];
if (value === null || value === void 0) {
continue;
}
if (merger && merger(object, key, value, namespace)) {
continue;
}
if (Array.isArray(value) && Array.isArray(object[key])) {
object[key] = [...value, ...object[key]];
} else if (isPlainObject(value) && isPlainObject(object[key])) {
object[key] = _defu(
value,
object[key],
(namespace ? `${namespace}.` : "") + key.toString(),
merger
);
} else {
object[key] = value;
}
}
return object;
}
function createDefu(merger) {
return (...arguments_) => (
// eslint-disable-next-line unicorn/no-array-reduce
arguments_.reduce((p, c) => _defu(p, c, "", merger), {})
);
}
const defu = createDefu();
const defuFn = createDefu((object, key, currentValue) => {
if (object[key] !== void 0 && typeof currentValue === "function") {
object[key] = currentValue(object[key]);
return true;
}
});
function o(n){throw new Error(`${n} is not implemented yet!`)}let i$1 = class i extends EventEmitter{__unenv__={};readableEncoding=null;readableEnded=true;readableFlowing=false;readableHighWaterMark=0;readableLength=0;readableObjectMode=false;readableAborted=false;readableDidRead=false;closed=false;errored=null;readable=false;destroyed=false;static from(e,t){return new i(t)}constructor(e){super();}_read(e){}read(e){}setEncoding(e){return this}pause(){return this}resume(){return this}isPaused(){return true}unpipe(e){return this}unshift(e,t){}wrap(e){return this}push(e,t){return false}_destroy(e,t){this.removeAllListeners();}destroy(e){return this.destroyed=true,this._destroy(e),this}pipe(e,t){return {}}compose(e,t){throw new Error("Method not implemented.")}[Symbol.asyncDispose](){return this.destroy(),Promise.resolve()}async*[Symbol.asyncIterator](){throw o("Readable.asyncIterator")}iterator(e){throw o("Readable.iterator")}map(e,t){throw o("Readable.map")}filter(e,t){throw o("Readable.filter")}forEach(e,t){throw o("Readable.forEach")}reduce(e,t,r){throw o("Readable.reduce")}find(e,t){throw o("Readable.find")}findIndex(e,t){throw o("Readable.findIndex")}some(e,t){throw o("Readable.some")}toArray(e){throw o("Readable.toArray")}every(e,t){throw o("Readable.every")}flatMap(e,t){throw o("Readable.flatMap")}drop(e,t){throw o("Readable.drop")}take(e,t){throw o("Readable.take")}asIndexedPairs(e){throw o("Readable.asIndexedPairs")}};let l$1 = class l extends EventEmitter{__unenv__={};writable=true;writableEnded=false;writableFinished=false;writableHighWaterMark=0;writableLength=0;writableObjectMode=false;writableCorked=0;closed=false;errored=null;writableNeedDrain=false;destroyed=false;_data;_encoding="utf8";constructor(e){super();}pipe(e,t){return {}}_write(e,t,r){if(this.writableEnded){r&&r();return}if(this._data===void 0)this._data=e;else {const s=typeof this._data=="string"?Buffer$1.from(this._data,this._encoding||t||"utf8"):this._data,a=typeof e=="string"?Buffer$1.from(e,t||this._encoding||"utf8"):e;this._data=Buffer$1.concat([s,a]);}this._encoding=t,r&&r();}_writev(e,t){}_destroy(e,t){}_final(e){}write(e,t,r){const s=typeof t=="string"?this._encoding:"utf8",a=typeof t=="function"?t:typeof r=="function"?r:void 0;return this._write(e,s,a),true}setDefaultEncoding(e){return this}end(e,t,r){const s=typeof e=="function"?e:typeof t=="function"?t:typeof r=="function"?r:void 0;if(this.writableEnded)return s&&s(),this;const a=e===s?void 0:e;if(a){const u=t===s?void 0:t;this.write(a,u,s);}return this.writableEnded=true,this.writableFinished=true,this.emit("close"),this.emit("finish"),this}cork(){}uncork(){}destroy(e){return this.destroyed=true,delete this._data,this.removeAllListeners(),this}compose(e,t){throw new Error("Method not implemented.")}};const c=class{allowHalfOpen=true;_destroy;constructor(e=new i$1,t=new l$1){Object.assign(this,e),Object.assign(this,t),this._destroy=g(e._destroy,t._destroy);}};function _(){return Object.assign(c.prototype,i$1.prototype),Object.assign(c.prototype,l$1.prototype),c}function g(...n){return function(...e){for(const t of n)t(...e);}}const m=_();class A extends m{__unenv__={};bufferSize=0;bytesRead=0;bytesWritten=0;connecting=false;destroyed=false;pending=false;localAddress="";localPort=0;remoteAddress="";remoteFamily="";remotePort=0;autoSelectFamilyAttemptedAddresses=[];readyState="readOnly";constructor(e){super();}write(e,t,r){return false}connect(e,t,r){return this}end(e,t,r){return this}setEncoding(e){return this}pause(){return this}resume(){return this}setTimeout(e,t){return this}setNoDelay(e){return this}setKeepAlive(e,t){return this}address(){return {}}unref(){return this}ref(){return this}destroySoon(){this.destroy();}resetAndDestroy(){const e=new Error("ERR_SOCKET_CLOSED");return e.code="ERR_SOCKET_CLOSED",this.destroy(e),this}}class y extends i$1{aborted=false;httpVersion="1.1";httpVersionMajor=1;httpVersionMinor=1;complete=true;connection;socket;headers={};trailers={};method="GET";url="/";statusCode=200;statusMessage="";closed=false;errored=null;readable=false;constructor(e){super(),this.socket=this.connection=e||new A;}get rawHeaders(){const e=this.headers,t=[];for(const r in e)if(Array.isArray(e[r]))for(const s of e[r])t.push(r,s);else t.push(r,e[r]);return t}get rawTrailers(){return []}setTimeout(e,t){return this}get headersDistinct(){return p(this.headers)}get trailersDistinct(){return p(this.trailers)}}function p(n){const e={};for(const[t,r]of Object.entries(n))t&&(e[t]=(Array.isArray(r)?r:[r]).filter(Boolean));return e}class w extends l$1{statusCode=200;statusMessage="";upgrading=false;chunkedEncoding=false;shouldKeepAlive=false;useChunkedEncodingByDefault=false;sendDate=false;finished=false;headersSent=false;strictContentLength=false;connection=null;socket=null;req;_headers={};constructor(e){super(),this.req=e;}assignSocket(e){e._httpMessage=this,this.socket=e,this.connection=e,this.emit("socket",e),this._flush();}_flush(){this.flushHeaders();}detachSocket(e){}writeContinue(e){}writeHead(e,t,r){e&&(this.statusCode=e),typeof t=="string"&&(this.statusMessage=t,t=void 0);const s=r||t;if(s&&!Array.isArray(s))for(const a in s)this.setHeader(a,s[a]);return this.headersSent=true,this}writeProcessing(){}setTimeout(e,t){return this}appendHeader(e,t){e=e.toLowerCase();const r=this._headers[e],s=[...Array.isArray(r)?r:[r],...Array.isArray(t)?t:[t]].filter(Boolean);return this._headers[e]=s.length>1?s:s[0],this}setHeader(e,t){return this._headers[e.toLowerCase()]=t,this}setHeaders(e){for(const[t,r]of Object.entries(e))this.setHeader(t,r);return this}getHeader(e){return this._headers[e.toLowerCase()]}getHeaders(){return this._headers}getHeaderNames(){return Object.keys(this._headers)}hasHeader(e){return e.toLowerCase()in this._headers}removeHeader(e){delete this._headers[e.toLowerCase()];}addTrailers(e){}flushHeaders(){}writeEarlyHints(e,t){typeof t=="function"&&t();}}const E=(()=>{const n=function(){};return n.prototype=Object.create(null),n})();function R(n={}){const e=new E,t=Array.isArray(n)||H(n)?n:Object.entries(n);for(const[r,s]of t)if(s){if(e[r]===void 0){e[r]=s;continue}e[r]=[...Array.isArray(e[r])?e[r]:[e[r]],...Array.isArray(s)?s:[s]];}return e}function H(n){return typeof n?.entries=="function"}function S(n={}){if(n instanceof Headers)return n;const e=new Headers;for(const[t,r]of Object.entries(n))if(r!==void 0){if(Array.isArray(r)){for(const s of r)e.append(t,String(s));continue}e.set(t,String(r));}return e}const C=new Set([101,204,205,304]);async function b(n,e){const t=new y,r=new w(t);t.url=e.url?.toString()||"/";let s;if(!t.url.startsWith("/")){const d=new URL(t.url);s=d.host,t.url=d.pathname+d.search+d.hash;}t.method=e.method||"GET",t.headers=R(e.headers||{}),t.headers.host||(t.headers.host=e.host||s||"localhost"),t.connection.encrypted=t.connection.encrypted||e.protocol==="https",t.body=e.body||null,t.__unenv__=e.context,await n(t,r);let a=r._data;(C.has(r.statusCode)||t.method.toUpperCase()==="HEAD")&&(a=null,delete r._headers["content-length"]);const u={status:r.statusCode,statusText:r.statusMessage,headers:r._headers,body:a};return t.destroy(),r.destroy(),u}async function O(n,e,t={}){try{const r=await b(n,{url:e,...t});return new Response(r.body,{status:r.status,statusText:r.statusText,headers:S(r.headers)})}catch(r){return new Response(r.toString(),{status:Number.parseInt(r.statusCode||r.code)||500,statusText:r.statusText})}}
function hasProp(obj, prop) {
try {
return prop in obj;
} catch {
return false;
}
}
class H3Error extends Error {
static __h3_error__ = true;
statusCode = 500;
fatal = false;
unhandled = false;
statusMessage;
data;
cause;
constructor(message, opts = {}) {
super(message, opts);
if (opts.cause && !this.cause) {
this.cause = opts.cause;
}
}
toJSON() {
const obj = {
message: this.message,
statusCode: sanitizeStatusCode(this.statusCode, 500)
};
if (this.statusMessage) {
obj.statusMessage = sanitizeStatusMessage(this.statusMessage);
}
if (this.data !== undefined) {
obj.data = this.data;
}
return obj;
}
}
function createError$1(input) {
if (typeof input === "string") {
return new H3Error(input);
}
if (isError(input)) {
return input;
}
const err = new H3Error(input.message ?? input.statusMessage ?? "", {
cause: input.cause || input
});
if (hasProp(input, "stack")) {
try {
Object.defineProperty(err, "stack", {
get() {
return input.stack;
}
});
} catch {
try {
err.stack = input.stack;
} catch {
}
}
}
if (input.data) {
err.data = input.data;
}
if (input.statusCode) {
err.statusCode = sanitizeStatusCode(input.statusCode, err.statusCode);
} else if (input.status) {
err.statusCode = sanitizeStatusCode(input.status, err.statusCode);
}
if (input.statusMessage) {
err.statusMessage = input.statusMessage;
} else if (input.statusText) {
err.statusMessage = input.statusText;
}
if (err.statusMessage) {
const originalMessage = err.statusMessage;
const sanitizedMessage = sanitizeStatusMessage(err.statusMessage);
if (sanitizedMessage !== originalMessage) {
console.warn(
"[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future, `statusMessage` will be sanitized by default."
);
}
}
if (input.fatal !== undefined) {
err.fatal = input.fatal;
}
if (input.unhandled !== undefined) {
err.unhandled = input.unhandled;
}
return err;
}
function sendError(event, error, debug) {
if (event.handled) {
return;
}
const h3Error = isError(error) ? error : createError$1(error);
const responseBody = {
statusCode: h3Error.statusCode,
statusMessage: h3Error.statusMessage,
stack: [],
data: h3Error.data
};
if (debug) {
responseBody.stack = (h3Error.stack || "").split("\n").map((l) => l.trim());
}
if (event.handled) {
return;
}
const _code = Number.parseInt(h3Error.statusCode);
setResponseStatus(event, _code, h3Error.statusMessage);
event.node.res.setHeader("content-type", MIMES.json);
event.node.res.end(JSON.stringify(responseBody, undefined, 2));
}
function isError(input) {
return input?.constructor?.__h3_error__ === true;
}
function isMethod(event, expected, allowHead) {
if (typeof expected === "string") {
if (event.method === expected) {
return true;
}
} else if (expected.includes(event.method)) {
return true;
}
return false;
}
function assertMethod(event, expected, allowHead) {
if (!isMethod(event, expected)) {
throw createError$1({
statusCode: 405,
statusMessage: "HTTP method is not allowed."
});
}
}
function getRequestHeaders(event) {
const _headers = {};
for (const key in event.node.req.headers) {
const val = event.node.req.headers[key];
_headers[key] = Array.isArray(val) ? val.filter(Boolean).join(", ") : val;
}
return _headers;
}
function getRequestHeader(event, name) {
const headers = getRequestHeaders(event);
const value = headers[name.toLowerCase()];
return value;
}
function getRequestHost(event, opts = {}) {
if (opts.xForwardedHost) {
const xForwardedHost = event.node.req.headers["x-forwarded-host"];
if (xForwardedHost) {
return xForwardedHost;
}
}
return event.node.req.headers.host || "localhost";
}
function getRequestProtocol(event, opts = {}) {
if (opts.xForwardedProto !== false && event.node.req.headers["x-forwarded-proto"] === "https") {
return "https";
}
return event.node.req.connection?.encrypted ? "https" : "http";
}
function getRequestURL(event, opts = {}) {
const host = getRequestHost(event, opts);
const protocol = getRequestProtocol(event, opts);
const path = (event.node.req.originalUrl || event.path).replace(
/^[/\\]+/g,
"/"
);
return new URL(path, `${protocol}://${host}`);
}
const RawBodySymbol = Symbol.for("h3RawBody");
const PayloadMethods$1 = ["PATCH", "POST", "PUT", "DELETE"];
function readRawBody(event, encoding = "utf8") {
assertMethod(event, PayloadMethods$1);
const _rawBody = event._requestBody || event.web?.request?.body || event.node.req[RawBodySymbol] || event.node.req.rawBody || event.node.req.body;
if (_rawBody) {
const promise2 = Promise.resolve(_rawBody).then((_resolved) => {
if (Buffer.isBuffer(_resolved)) {
return _resolved;
}
if (typeof _resolved.pipeTo === "function") {
return new Promise((resolve, reject) => {
const chunks = [];
_resolved.pipeTo(
new WritableStream({
write(chunk) {
chunks.push(chunk);
},
close() {
resolve(Buffer.concat(chunks));
},
abort(reason) {
reject(reason);
}
})
).catch(reject);
});
} else if (typeof _resolved.pipe === "function") {
return new Promise((resolve, reject) => {
const chunks = [];
_resolved.on("data", (chunk) => {
chunks.push(chunk);
}).on("end", () => {
resolve(Buffer.concat(chunks));
}).on("error", reject);
});
}
if (_resolved.constructor === Object) {
return Buffer.from(JSON.stringify(_resolved));
}
if (_resolved instanceof URLSearchParams) {
return Buffer.from(_resolved.toString());
}
return Buffer.from(_resolved);
});
return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
}
if (!Number.parseInt(event.node.req.headers["content-length"] || "") && !String(event.node.req.headers["transfer-encoding"] ?? "").split(",").map((e) => e.trim()).filter(Boolean).includes("chunked")) {
return Promise.resolve(undefined);
}
const promise = event.node.req[RawBodySymbol] = new Promise(
(resolve, reject) => {
const bodyData = [];
event.node.req.on("error", (err) => {
reject(err);
}).on("data", (chunk) => {
bodyData.push(chunk);
}).on("end", () => {
resolve(Buffer.concat(bodyData));
});
}
);
const result = encoding ? promise.then((buff) => buff.toString(encoding)) : promise;
return result;
}
function getRequestWebStream(event) {
if (!PayloadMethods$1.includes(event.method)) {
return;
}
const bodyStream = event.web?.request?.body || event._requestBody;
if (bodyStream) {
return bodyStream;
}
const _hasRawBody = RawBodySymbol in event.node.req || "rawBody" in event.node.req || "body" in event.node.req || "__unenv__" in event.node.req;
if (_hasRawBody) {
return new ReadableStream({
async start(controller) {
const _rawBody = await readRawBody(event, false);
if (_rawBody) {
controller.enqueue(_rawBody);
}
controller.close();
}
});
}
return new ReadableStream({
start: (controller) => {
event.node.req.on("data", (chunk) => {
controller.enqueue(chunk);
});
event.node.req.on("end", () => {
controller.close();
});
event.node.req.on("error", (err) => {
controller.error(err);
});
}
});
}
function handleCacheHeaders(event, opts) {
const cacheControls = ["public", ...opts.cacheControls || []];
let cacheMatched = false;
if (opts.maxAge !== undefined) {
cacheControls.push(`max-age=${+opts.maxAge}`, `s-maxage=${+opts.maxAge}`);
}
if (opts.modifiedTime) {
const modifiedTime = new Date(opts.modifiedTime);
const ifModifiedSince = event.node.req.headers["if-modified-since"];
event.node.res.setHeader("last-modified", modifiedTime.toUTCString());
if (ifModifiedSince && new Date(ifModifiedSince) >= opts.modifiedTime) {
cacheMatched = true;
}
}
if (opts.etag) {
event.node.res.setHeader("etag", opts.etag);
const ifNonMatch = event.node.req.headers["if-none-match"];
if (ifNonMatch === opts.etag) {
cacheMatched = true;
}
}
event.node.res.setHeader("cache-control", cacheControls.join(", "));
if (cacheMatched) {
event.node.res.statusCode = 304;
if (!event.handled) {
event.node.res.end();
}
return true;
}
return false;
}
const MIMES = {
html: "text/html",
json: "application/json"
};
const 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 = Number.parseInt(statusCode, 10);
}
if (statusCode < 100 || statusCode > 999) {
return defaultStatusCode;
}
return statusCode;
}
function splitCookiesString(cookiesString) {
if (Array.isArray(cookiesString)) {
return cookiesString.flatMap((c) => splitCookiesString(c));
}
if (typeof cookiesString !== "string") {
return [];
}
const cookiesStrings = [];
let pos = 0;
let start;
let ch;
let lastComma;
let nextStart;
let cookiesSeparatorFound;
const skipWhitespace = () => {
while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) {
pos += 1;
}
return pos < cookiesString.length;
};
const notSpecialChar = () => {
ch = cookiesString.charAt(pos);
return ch !== "=" && ch !== ";" && ch !== ",";
};
while (pos < cookiesString.length) {
start = pos;
cookiesSeparatorFound = false;
while (skipWhitespace()) {
ch = cookiesString.charAt(pos);
if (ch === ",") {
lastComma = pos;
pos += 1;
skipWhitespace();
nextStart = pos;
while (pos < cookiesString.length && notSpecialChar()) {
pos += 1;
}
if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") {
cookiesSeparatorFound = true;
pos = nextStart;
cookiesStrings.push(cookiesString.slice(start, lastComma));
start = pos;
} else {
pos = lastComma + 1;
}
} else {
pos += 1;
}
}
if (!cookiesSeparatorFound || pos >= cookiesString.length) {
cookiesStrings.push(cookiesString.slice(start));
}
}
return cookiesStrings;
}
const defer = typeof setImmediate === "undefined" ? (fn) => fn() : setImmediate;
function send(event, data, type) {
if (type) {
defaultContentType(event, type);
}
return new Promise((resolve) => {
defer(() => {
if (!event.handled) {
event.node.res.end(data);
}
resolve();
});
});
}
function sendNoContent(event, code) {
if (event.handled) {
return;
}
if (!code && event.node.res.statusCode !== 200) {
code = event.node.res.statusCode;
}
const _code = sanitizeStatusCode(code, 204);
if (_code === 204) {
event.node.res.removeHeader("content-length");
}
event.node.res.writeHead(_code);
event.node.res.end();
}
function setResponseStatus(event, code, text) {
if (code) {
event.node.res.statusCode = sanitizeStatusCode(
code,
event.node.res.statusCode
);
}
if (text) {
event.node.res.statusMessage = sanitizeStatusMessage(text);
}
}
function defaultContentType(event, type) {
if (type && event.node.res.statusCode !== 304 && !event.node.res.getHeader("content-type")) {
event.node.res.setHeader("content-type", type);
}
}
function sendRedirect(event, location, code = 302) {
event.node.res.statusCode = sanitizeStatusCode(
code,
event.node.res.statusCode
);
event.node.res.setHeader("location", location);
const encodedLoc = location.replace(/"/g, "%22");
const html = `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`;
return send(event, html, MIMES.html);
}
function getResponseHeader(event, name) {
return event.node.res.getHeader(name);
}
function setResponseHeaders(event, headers) {
for (const [name, value] of Object.entries(headers)) {
event.node.res.setHeader(
name,
value
);
}
}
const setHeaders = setResponseHeaders;
function setResponseHeader(event, name, value) {
event.node.res.setHeader(name, value);
}
function appendResponseHeader(event, name, value) {
let current = event.node.res.getHeader(name);
if (!current) {
event.node.res.setHeader(name, value);
return;
}
if (!Array.isArray(current)) {
current = [current.toString()];
}
event.node.res.setHeader(name, [...current, value]);
}
function removeResponseHeader(event, name) {
return event.node.res.removeHeader(name);
}
function isStream(data) {
if (!data || typeof data !== "object") {
return false;
}
if (typeof data.pipe === "function") {
if (typeof data._read === "function") {
return true;
}
if (typeof data.abort === "function") {
return true;
}
}
if (typeof data.pipeTo === "function") {
return true;
}
return false;
}
function isWebResponse(data) {
return typeof Response !== "undefined" && data instanceof Response;
}
function sendStream(event, stream) {
if (!stream || typeof stream !== "object") {
throw new Error("[h3] Invalid stream provided.");
}
event.node.res._data = stream;
if (!event.node.res.socket) {
event._handled = true;
return Promise.resolve();
}
if (hasProp(stream, "pipeTo") && typeof stream.pipeTo === "function") {
return stream.pipeTo(
new WritableStream({
write(chunk) {
event.node.res.write(chunk);
}
})
).then(() => {
event.node.res.end();
});
}
if (hasProp(stream, "pipe") && typeof stream.pipe === "function") {
return new Promise((resolve, reject) => {
stream.pipe(event.node.res);
if (stream.on) {
stream.on("end", () => {
event.node.res.end();
resolve();
});
stream.on("error", (error) => {
reject(error);
});
}
event.node.res.on("close", () => {
if (stream.abort) {
stream.abort();
}
});
});
}
throw new Error("[h3] Invalid or incompatible stream provided.");
}
function sendWebResponse(event, response) {
for (const [key, value] of response.headers) {
if (key === "set-cookie") {
event.node.res.appendHeader(key, splitCookiesString(value));
} else {
event.node.res.setHeader(key, value);
}
}
if (response.status) {
event.node.res.statusCode = sanitizeStatusCode(
response.status,
event.node.res.statusCode
);
}
if (response.statusText) {
event.node.res.statusMessage = sanitizeStatusMessage(response.statusText);
}
if (response.redirected) {
event.node.res.setHeader("location", response.url);
}
if (!response.body) {
event.node.res.end();
return;
}
return sendStream(event, response.body);
}
const PayloadMethods = /* @__PURE__ */ new Set(["PATCH", "POST", "PUT", "DELETE"]);
const ignoredHeaders = /* @__PURE__ */ new Set([
"transfer-encoding",
"accept-encoding",
"connection",
"keep-alive",
"upgrade",
"expect",
"host",
"accept"
]);
async function proxyRequest(event, target, opts = {}) {
let body;
let duplex;
if (PayloadMethods.has(event.method)) {
if (opts.streamRequest) {
body = getRequestWebStream(event);
duplex = "half";
} else {
body = await readRawBody(event, false).catch(() => undefined);
}
}
const method = opts.fetchOptions?.method || event.method;
const fetchHeaders = mergeHeaders$1(
getProxyRequestHeaders(event, { host: target.startsWith("/") }),
opts.fetchOptions?.headers,
opts.headers
);
return sendProxy(event, target, {
...opts,
fetchOptions: {
method,
body,
duplex,
...opts.fetchOptions,
headers: fetchHeaders
}
});
}
async function sendProxy(event, target, opts = {}) {
let response;
try {
response = await _getFetch(opts.fetch)(target, {
headers: opts.headers,
ignoreResponseError: true,
// make $ofetch.raw transparent
...opts.fetchOptions
});
} catch (error) {
throw createError$1({
status: 502,
statusMessage: "Bad Gateway",
cause: error
});
}
event.node.res.statusCode = sanitizeStatusCode(
response.status,
event.node.res.statusCode
);
event.node.res.statusMessage = sanitizeStatusMessage(response.statusText);
const cookies = [];
for (const [key, value] of response.headers.entries()) {
if (key === "content-encoding") {
continue;
}
if (key === "content-length") {
continue;
}
if (key === "set-cookie") {
cookies.push(...splitCookiesString(value));
continue;
}
event.node.res.setHeader(key, value);
}
if (cookies.length > 0) {
event.node.res.setHeader(
"set-cookie",
cookies.map((cookie) => {
if (opts.cookieDomainRewrite) {
cookie = rewriteCookieProperty(
cookie,
opts.cookieDomainRewrite,
"domain"
);
}
if (opts.cookiePathRewrite) {
cookie = rewriteCookieProperty(
cookie,
opts.cookiePathRewrite,
"path"
);
}
return cookie;
})
);
}
if (opts.onResponse) {
await opts.onResponse(event, response);
}
if (response._data !== undefined) {
return response._data;
}
if (event.handled) {
return;
}
if (opts.sendStream === false) {
const data = new Uint8Array(await response.arrayBuffer());
return event.node.res.end(data);
}
if (response.body) {
for await (const chunk of response.body) {
event.node.res.write(chunk);
}
}
return event.node.res.end();
}
function getProxyRequestHeaders(event, opts) {
const headers = /* @__PURE__ */ Object.create(null);
const reqHeaders = getRequestHeaders(event);
for (const name in reqHeaders) {
if (!ignoredHeaders.has(name) || name === "host" && opts?.host) {
headers[name] = reqHeaders[name];
}
}
return headers;
}
function fetchWithEvent(event, req, init, options) {
return _getFetch(options?.fetch)(req, {
...init,
context: init?.context || event.context,
headers: {
...getProxyRequestHeaders(event, {
host: typeof req === "string" && req.startsWith("/")
}),
...init?.headers
}
});
}
function _getFetch(_fetch) {
if (_fetch) {
return _fetch;
}
if (globalThis.fetch) {
return globalThis.fetch;
}
throw new Error(
"fetch is not available. Try importing `node-fetch-native/polyfill` for Node.js."
);
}
function rewriteCookieProperty(header, map, property) {
const _map = typeof map === "string" ? { "*": map } : map;
return header.replace(
new RegExp(`(;\\s*${property}=)([^;]+)`, "gi"),
(match, prefix, previousValue) => {
let newValue;
if (previousValue in _map) {
newValue = _map[previousValue];
} else if ("*" in _map) {
newValue = _map["*"];
} else {
return match;
}
return newValue ? prefix + newValue : "";
}
);
}
function mergeHeaders$1(defaults, ...inputs) {
const _inputs = inputs.filter(Boolean);
if (_inputs.length === 0) {
return defaults;
}
const merged = new Headers(defaults);
for (const input of _inputs) {
for (const [key, value] of Object.entries(input)) {
if (value !== undefined) {
merged.set(key, value);
}
}
}
return merged;
}
class H3Event {
"__is_event__" = true;
// Context
node;
// Node
web;
// Web
context = {};
// Shared
// Request
_method;
_path;
_headers;
_requestBody;
// Response
_handled = false;
// Hooks
_onBeforeResponseCalled;
_onAfterResponseCalled;
constructor(req, res) {
this.node = { req, res };
}
// --- Request ---
get method() {
if (!this._method) {
this._method = (this.node.req.method || "GET").toUpperCase();
}
return this._method;
}
get path() {
return this._path || this.node.req.url || "/";
}
get headers() {
if (!this._headers) {
this._headers = _normalizeNodeHeaders(this.node.req.headers);
}
return this._headers;
}
// --- Respoonse ---
get handled() {
return this._handled || this.node.res.writableEnded || this.node.res.headersSent;
}
respondWith(response) {
return Promise.resolve(response).then(
(_response) => sendWebResponse(this, _response)
);
}
// --- Utils ---
toString() {
return `[${this.method}] ${this.path}`;
}
toJSON() {
return this.toString();
}
// --- Deprecated ---
/** @deprecated Please use `event.node.req` instead. */
get req() {
return this.node.req;
}
/** @deprecated Please use `event.node.res` instead. */
get res() {
return this.node.res;
}
}
function isEvent(input) {
return hasProp(input, "__is_event__");
}
function createEvent(req, res) {
return new H3Event(req, res);
}
function _normalizeNodeHeaders(nodeHeaders) {
const headers = new Headers();
for (const [name, value] of Object.entries(nodeHeaders)) {
if (Array.isArray(value)) {
for (const item of value) {
headers.append(name, item);
}
} else if (value) {
headers.set(name, value);
}
}
return headers;
}
function defineEventHandler(handler) {
if (typeof handler === "function") {
handler.__is_handler__ = true;
return handler;
}
const _hooks = {
onRequest: _normalizeArray(handler.onRequest),
onBeforeResponse: _normalizeArray(handler.onBeforeResponse)
};
const _handler = (event) => {
return _callHandler(event, handler.handler, _hooks);
};
_handler.__is_handler__ = true;
_handler.__resolve__ = handler.handler.__resolve__;
_handler.__websocket__ = handler.websocket;
return _handler;
}
function _normalizeArray(input) {
return input ? Array.isArray(input) ? input : [input] : undefined;
}
async function _callHandler(event, handler, hooks) {
if (hooks.onRequest) {
for (const hook of hooks.onRequest) {
await hook(event);
if (event.handled) {
return;
}
}
}
const body = await handler(event);
const response = { body };
if (hooks.onBeforeResponse) {
for (const hook of hooks.onBeforeResponse) {
await hook(event, response);
}
}
return response.body;
}
const eventHandler = defineEventHandler;
function isEventHandler(input) {
return hasProp(input, "__is_handler__");
}
function toEventHandler(input, _, _route) {
if (!isEventHandler(input)) {
console.warn(
"[h3] Implicit event handler conversion is deprecated. Use `eventHandler()` or `fromNodeMiddleware()` to define event handlers.",
_route && _route !== "/" ? `
Route: ${_route}` : "",
`
Handler: ${input}`
);
}
return input;
}
function defineLazyEventHandler(factory) {
let _promise;
let _resolved;
const resolveHandler = () => {
if (_resolved) {
return Promise.resolve(_resolved);
}
if (!_promise) {
_promise = Promise.resolve(factory()).then((r) => {
const handler2 = r.default || r;
if (typeof handler2 !== "function") {
throw new TypeError(
"Invalid lazy handler result. It should be a function:",
handler2
);
}
_resolved = { handler: toEventHandler(r.default || r) };
return _resolved;
});
}
return _promise;
};
const handler = eventHandler((event) => {
if (_resolved) {
return _resolved.handler(event);
}
return resolveHandler().then((r) => r.handler(event));
});
handler.__resolve__ = resolveHandler;
return handler;
}
const lazyEventHandler = defineLazyEventHandler;
function createApp(options = {}) {
const stack = [];
const handler = createAppEventHandler(stack, options);
const resolve = createResolver(stack);
handler.__resolve__ = resolve;
const getWebsocket = cachedFn(() => websocketOptions(resolve, options));
const app = {
// @ts-expect-error
use: (arg1, arg2, arg3) => use(app, arg1, arg2, arg3),
resolve,
handler,
stack,
options,
get websocket() {
return getWebsocket();
}
};
return app;
}
function use(app, arg1, arg2, arg3) {
if (