UNPKG

@universal-middleware/compress

Version:
366 lines (361 loc) 10.9 kB
import { bindUniversal, universalSymbol, contextSymbol, getAdapterRuntime } from './chunk-A5W3PKM7.js'; import { middleware_default } from './chunk-OE4YTAMF.js'; // ../../node_modules/.pnpm/h3@1.15.11/node_modules/h3/dist/index.mjs function hasProp(obj, prop) { try { return prop in obj; } catch { return false; } } var H3Error = class 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 !== void 0) { obj.data = this.data; } return obj; } }; function createError(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 !== void 0) { err.fatal = input.fatal; } if (input.unhandled !== void 0) { err.unhandled = input.unhandled; } return err; } 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({ statusCode: 405, statusMessage: "HTTP method is not allowed." }); } } function getRequestHost(event, opts = {}) { if (opts.xForwardedHost) { const _header = event.node.req.headers["x-forwarded-host"]; const xForwardedHost = (_header || "").split(",").shift()?.trim(); 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}`); } function toWebRequest(event) { return event.web?.request || new Request(getRequestURL(event), { // @ts-ignore Undici option duplex: "half", method: event.method, headers: event.headers, body: getRequestWebStream(event) }); } var RawBodySymbol = /* @__PURE__ */ Symbol.for("h3RawBody"); var 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()); } if (_resolved instanceof FormData) { return new Response(_resolved).bytes().then((uint8arr) => Buffer.from(uint8arr)); } return Buffer.from(_resolved); }); return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2; } if (!Number.parseInt(event.node.req.headers["content-length"] || "") && !/\bchunked\b/i.test( String(event.node.req.headers["transfer-encoding"] ?? "") )) { return Promise.resolve(void 0); } 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); }); } }); } 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 = Number.parseInt(statusCode, 10); } if (statusCode < 100 || statusCode > 999) { return defaultStatusCode; } return statusCode; } 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] : void 0; } 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; } var eventHandler = defineEventHandler; // ../adapter-h3/dist/index.js var pendingMiddlewaresSymbol = /* @__PURE__ */ Symbol.for("unPendingMiddlewares"); var wrappedResponseSymbol = /* @__PURE__ */ Symbol.for("unWrappedResponse"); function memToWebRequest(event) { if (!event.web?.request) { event.web ??= {}; event.web.request = toWebRequest(event); } return event.web.request; } function createMiddleware(middlewareFactory) { return (...args) => { const middleware = middlewareFactory(...args); return bindUniversal( middleware, eventHandler(async function universalMiddlewareH3(event) { const ctx = initContext(event); const response = await this[universalSymbol](memToWebRequest(event), ctx, getRuntime(event)); if (typeof response === "function") { event.context[pendingMiddlewaresSymbol] ??= []; event.context[wrappedResponseSymbol] = false; event.context[pendingMiddlewaresSymbol].push(response); } else if (response !== null && typeof response === "object") { if (response instanceof Response) { return response; } event.context[contextSymbol] = response; } }), eventHandler ); }; } function initContext(event) { event.context[contextSymbol] ??= {}; return event.context[contextSymbol]; } function getRuntime(event) { return getAdapterRuntime( "h3", { params: event.context.params, h3: event }, { ...event.context.cloudflare, req: event.node.req, res: event.node.res }, memToWebRequest(event) ); } // virtual:universal-middleware:virtual:universal-middleware:h3:middleware:src/middleware.ts var middleware_default2 = createMiddleware(middleware_default); export { middleware_default2 as default };