UNPKG

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
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 (