vercel.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  1. "use strict";
  2. var __create = Object.create;
  3. var __defProp = Object.defineProperty;
  4. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  5. var __getOwnPropNames = Object.getOwnPropertyNames;
  6. var __getProtoOf = Object.getPrototypeOf;
  7. var __hasOwnProp = Object.prototype.hasOwnProperty;
  8. var __export = (target, all) => {
  9. for (var name in all)
  10. __defProp(target, name, { get: all[name], enumerable: true });
  11. };
  12. var __copyProps = (to, from, except, desc) => {
  13. if (from && typeof from === "object" || typeof from === "function") {
  14. for (let key of __getOwnPropNames(from))
  15. if (!__hasOwnProp.call(to, key) && key !== except)
  16. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  17. }
  18. return to;
  19. };
  20. var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  21. // If the importer is in node compatibility mode or this is not an ESM
  22. // file that has been converted to a CommonJS file using a Babel-
  23. // compatible transform (i.e. "__esModule" has not been set), then set
  24. // "default" to the CommonJS "module.exports" for node compatibility.
  25. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  26. mod
  27. ));
  28. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  29. // src/vercel.ts
  30. var vercel_exports = {};
  31. __export(vercel_exports, {
  32. handle: () => handle
  33. });
  34. module.exports = __toCommonJS(vercel_exports);
  35. // src/listener.ts
  36. var import_node_http22 = require("http2");
  37. // src/request.ts
  38. var import_node_http2 = require("http2");
  39. var import_node_stream = require("stream");
  40. var RequestError = class extends Error {
  41. constructor(message, options) {
  42. super(message, options);
  43. this.name = "RequestError";
  44. }
  45. };
  46. var toRequestError = (e) => {
  47. if (e instanceof RequestError) {
  48. return e;
  49. }
  50. return new RequestError(e.message, { cause: e });
  51. };
  52. var GlobalRequest = global.Request;
  53. var Request = class extends GlobalRequest {
  54. constructor(input, options) {
  55. if (typeof input === "object" && getRequestCache in input) {
  56. input = input[getRequestCache]();
  57. }
  58. if (typeof options?.body?.getReader !== "undefined") {
  59. ;
  60. options.duplex ??= "half";
  61. }
  62. super(input, options);
  63. }
  64. };
  65. var newHeadersFromIncoming = (incoming) => {
  66. const headerRecord = [];
  67. const rawHeaders = incoming.rawHeaders;
  68. for (let i = 0; i < rawHeaders.length; i += 2) {
  69. const { [i]: key, [i + 1]: value } = rawHeaders;
  70. if (key.charCodeAt(0) !== /*:*/
  71. 58) {
  72. headerRecord.push([key, value]);
  73. }
  74. }
  75. return new Headers(headerRecord);
  76. };
  77. var wrapBodyStream = Symbol("wrapBodyStream");
  78. var newRequestFromIncoming = (method, url, headers, incoming, abortController) => {
  79. const init = {
  80. method,
  81. headers,
  82. signal: abortController.signal
  83. };
  84. if (method === "TRACE") {
  85. init.method = "GET";
  86. const req = new Request(url, init);
  87. Object.defineProperty(req, "method", {
  88. get() {
  89. return "TRACE";
  90. }
  91. });
  92. return req;
  93. }
  94. if (!(method === "GET" || method === "HEAD")) {
  95. if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) {
  96. init.body = new ReadableStream({
  97. start(controller) {
  98. controller.enqueue(incoming.rawBody);
  99. controller.close();
  100. }
  101. });
  102. } else if (incoming[wrapBodyStream]) {
  103. let reader;
  104. init.body = new ReadableStream({
  105. async pull(controller) {
  106. try {
  107. reader ||= import_node_stream.Readable.toWeb(incoming).getReader();
  108. const { done, value } = await reader.read();
  109. if (done) {
  110. controller.close();
  111. } else {
  112. controller.enqueue(value);
  113. }
  114. } catch (error) {
  115. controller.error(error);
  116. }
  117. }
  118. });
  119. } else {
  120. init.body = import_node_stream.Readable.toWeb(incoming);
  121. }
  122. }
  123. return new Request(url, init);
  124. };
  125. var getRequestCache = Symbol("getRequestCache");
  126. var requestCache = Symbol("requestCache");
  127. var incomingKey = Symbol("incomingKey");
  128. var urlKey = Symbol("urlKey");
  129. var headersKey = Symbol("headersKey");
  130. var abortControllerKey = Symbol("abortControllerKey");
  131. var getAbortController = Symbol("getAbortController");
  132. var requestPrototype = {
  133. get method() {
  134. return this[incomingKey].method || "GET";
  135. },
  136. get url() {
  137. return this[urlKey];
  138. },
  139. get headers() {
  140. return this[headersKey] ||= newHeadersFromIncoming(this[incomingKey]);
  141. },
  142. [getAbortController]() {
  143. this[getRequestCache]();
  144. return this[abortControllerKey];
  145. },
  146. [getRequestCache]() {
  147. this[abortControllerKey] ||= new AbortController();
  148. return this[requestCache] ||= newRequestFromIncoming(
  149. this.method,
  150. this[urlKey],
  151. this.headers,
  152. this[incomingKey],
  153. this[abortControllerKey]
  154. );
  155. }
  156. };
  157. [
  158. "body",
  159. "bodyUsed",
  160. "cache",
  161. "credentials",
  162. "destination",
  163. "integrity",
  164. "mode",
  165. "redirect",
  166. "referrer",
  167. "referrerPolicy",
  168. "signal",
  169. "keepalive"
  170. ].forEach((k) => {
  171. Object.defineProperty(requestPrototype, k, {
  172. get() {
  173. return this[getRequestCache]()[k];
  174. }
  175. });
  176. });
  177. ["arrayBuffer", "blob", "clone", "formData", "json", "text"].forEach((k) => {
  178. Object.defineProperty(requestPrototype, k, {
  179. value: function() {
  180. return this[getRequestCache]()[k]();
  181. }
  182. });
  183. });
  184. Object.setPrototypeOf(requestPrototype, Request.prototype);
  185. var newRequest = (incoming, defaultHostname) => {
  186. const req = Object.create(requestPrototype);
  187. req[incomingKey] = incoming;
  188. const incomingUrl = incoming.url || "";
  189. if (incomingUrl[0] !== "/" && // short-circuit for performance. most requests are relative URL.
  190. (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
  191. if (incoming instanceof import_node_http2.Http2ServerRequest) {
  192. throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
  193. }
  194. try {
  195. const url2 = new URL(incomingUrl);
  196. req[urlKey] = url2.href;
  197. } catch (e) {
  198. throw new RequestError("Invalid absolute URL", { cause: e });
  199. }
  200. return req;
  201. }
  202. const host = (incoming instanceof import_node_http2.Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
  203. if (!host) {
  204. throw new RequestError("Missing host header");
  205. }
  206. let scheme;
  207. if (incoming instanceof import_node_http2.Http2ServerRequest) {
  208. scheme = incoming.scheme;
  209. if (!(scheme === "http" || scheme === "https")) {
  210. throw new RequestError("Unsupported scheme");
  211. }
  212. } else {
  213. scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
  214. }
  215. const url = new URL(`${scheme}://${host}${incomingUrl}`);
  216. if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) {
  217. throw new RequestError("Invalid host header");
  218. }
  219. req[urlKey] = url.href;
  220. return req;
  221. };
  222. // src/response.ts
  223. var responseCache = Symbol("responseCache");
  224. var getResponseCache = Symbol("getResponseCache");
  225. var cacheKey = Symbol("cache");
  226. var GlobalResponse = global.Response;
  227. var Response2 = class _Response {
  228. #body;
  229. #init;
  230. [getResponseCache]() {
  231. delete this[cacheKey];
  232. return this[responseCache] ||= new GlobalResponse(this.#body, this.#init);
  233. }
  234. constructor(body, init) {
  235. let headers;
  236. this.#body = body;
  237. if (init instanceof _Response) {
  238. const cachedGlobalResponse = init[responseCache];
  239. if (cachedGlobalResponse) {
  240. this.#init = cachedGlobalResponse;
  241. this[getResponseCache]();
  242. return;
  243. } else {
  244. this.#init = init.#init;
  245. headers = new Headers(init.#init.headers);
  246. }
  247. } else {
  248. this.#init = init;
  249. }
  250. if (typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) {
  251. ;
  252. this[cacheKey] = [init?.status || 200, body, headers || init?.headers];
  253. }
  254. }
  255. get headers() {
  256. const cache = this[cacheKey];
  257. if (cache) {
  258. if (!(cache[2] instanceof Headers)) {
  259. cache[2] = new Headers(
  260. cache[2] || { "content-type": "text/plain; charset=UTF-8" }
  261. );
  262. }
  263. return cache[2];
  264. }
  265. return this[getResponseCache]().headers;
  266. }
  267. get status() {
  268. return this[cacheKey]?.[0] ?? this[getResponseCache]().status;
  269. }
  270. get ok() {
  271. const status = this.status;
  272. return status >= 200 && status < 300;
  273. }
  274. };
  275. ["body", "bodyUsed", "redirected", "statusText", "trailers", "type", "url"].forEach((k) => {
  276. Object.defineProperty(Response2.prototype, k, {
  277. get() {
  278. return this[getResponseCache]()[k];
  279. }
  280. });
  281. });
  282. ["arrayBuffer", "blob", "clone", "formData", "json", "text"].forEach((k) => {
  283. Object.defineProperty(Response2.prototype, k, {
  284. value: function() {
  285. return this[getResponseCache]()[k]();
  286. }
  287. });
  288. });
  289. Object.setPrototypeOf(Response2, GlobalResponse);
  290. Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype);
  291. // src/utils.ts
  292. async function readWithoutBlocking(readPromise) {
  293. return Promise.race([readPromise, Promise.resolve().then(() => Promise.resolve(void 0))]);
  294. }
  295. function writeFromReadableStreamDefaultReader(reader, writable, currentReadPromise) {
  296. const cancel = (error) => {
  297. reader.cancel(error).catch(() => {
  298. });
  299. };
  300. writable.on("close", cancel);
  301. writable.on("error", cancel);
  302. (currentReadPromise ?? reader.read()).then(flow, handleStreamError);
  303. return reader.closed.finally(() => {
  304. writable.off("close", cancel);
  305. writable.off("error", cancel);
  306. });
  307. function handleStreamError(error) {
  308. if (error) {
  309. writable.destroy(error);
  310. }
  311. }
  312. function onDrain() {
  313. reader.read().then(flow, handleStreamError);
  314. }
  315. function flow({ done, value }) {
  316. try {
  317. if (done) {
  318. writable.end();
  319. } else if (!writable.write(value)) {
  320. writable.once("drain", onDrain);
  321. } else {
  322. return reader.read().then(flow, handleStreamError);
  323. }
  324. } catch (e) {
  325. handleStreamError(e);
  326. }
  327. }
  328. }
  329. function writeFromReadableStream(stream, writable) {
  330. if (stream.locked) {
  331. throw new TypeError("ReadableStream is locked.");
  332. } else if (writable.destroyed) {
  333. return;
  334. }
  335. return writeFromReadableStreamDefaultReader(stream.getReader(), writable);
  336. }
  337. var buildOutgoingHttpHeaders = (headers) => {
  338. const res = {};
  339. if (!(headers instanceof Headers)) {
  340. headers = new Headers(headers ?? void 0);
  341. }
  342. const cookies = [];
  343. for (const [k, v] of headers) {
  344. if (k === "set-cookie") {
  345. cookies.push(v);
  346. } else {
  347. res[k] = v;
  348. }
  349. }
  350. if (cookies.length > 0) {
  351. res["set-cookie"] = cookies;
  352. }
  353. res["content-type"] ??= "text/plain; charset=UTF-8";
  354. return res;
  355. };
  356. // src/utils/response/constants.ts
  357. var X_ALREADY_SENT = "x-hono-already-sent";
  358. // src/globals.ts
  359. var import_node_crypto = __toESM(require("crypto"));
  360. if (typeof global.crypto === "undefined") {
  361. global.crypto = import_node_crypto.default;
  362. }
  363. // src/listener.ts
  364. var outgoingEnded = Symbol("outgoingEnded");
  365. var incomingDraining = Symbol("incomingDraining");
  366. var DRAIN_TIMEOUT_MS = 500;
  367. var MAX_DRAIN_BYTES = 64 * 1024 * 1024;
  368. var drainIncoming = (incoming) => {
  369. const incomingWithDrainState = incoming;
  370. if (incoming.destroyed || incomingWithDrainState[incomingDraining]) {
  371. return;
  372. }
  373. incomingWithDrainState[incomingDraining] = true;
  374. if (incoming instanceof import_node_http22.Http2ServerRequest) {
  375. try {
  376. ;
  377. incoming.stream?.close?.(import_node_http22.constants.NGHTTP2_NO_ERROR);
  378. } catch {
  379. }
  380. return;
  381. }
  382. let bytesRead = 0;
  383. const cleanup = () => {
  384. clearTimeout(timer);
  385. incoming.off("data", onData);
  386. incoming.off("end", cleanup);
  387. incoming.off("error", cleanup);
  388. };
  389. const forceClose = () => {
  390. cleanup();
  391. const socket = incoming.socket;
  392. if (socket && !socket.destroyed) {
  393. socket.destroySoon();
  394. }
  395. };
  396. const timer = setTimeout(forceClose, DRAIN_TIMEOUT_MS);
  397. timer.unref?.();
  398. const onData = (chunk) => {
  399. bytesRead += chunk.length;
  400. if (bytesRead > MAX_DRAIN_BYTES) {
  401. forceClose();
  402. }
  403. };
  404. incoming.on("data", onData);
  405. incoming.on("end", cleanup);
  406. incoming.on("error", cleanup);
  407. incoming.resume();
  408. };
  409. var handleRequestError = () => new Response(null, {
  410. status: 400
  411. });
  412. var handleFetchError = (e) => new Response(null, {
  413. status: e instanceof Error && (e.name === "TimeoutError" || e.constructor.name === "TimeoutError") ? 504 : 500
  414. });
  415. var handleResponseError = (e, outgoing) => {
  416. const err = e instanceof Error ? e : new Error("unknown error", { cause: e });
  417. if (err.code === "ERR_STREAM_PREMATURE_CLOSE") {
  418. console.info("The user aborted a request.");
  419. } else {
  420. console.error(e);
  421. if (!outgoing.headersSent) {
  422. outgoing.writeHead(500, { "Content-Type": "text/plain" });
  423. }
  424. outgoing.end(`Error: ${err.message}`);
  425. outgoing.destroy(err);
  426. }
  427. };
  428. var flushHeaders = (outgoing) => {
  429. if ("flushHeaders" in outgoing && outgoing.writable) {
  430. outgoing.flushHeaders();
  431. }
  432. };
  433. var responseViaCache = async (res, outgoing) => {
  434. let [status, body, header] = res[cacheKey];
  435. let hasContentLength = false;
  436. if (!header) {
  437. header = { "content-type": "text/plain; charset=UTF-8" };
  438. } else if (header instanceof Headers) {
  439. hasContentLength = header.has("content-length");
  440. header = buildOutgoingHttpHeaders(header);
  441. } else if (Array.isArray(header)) {
  442. const headerObj = new Headers(header);
  443. hasContentLength = headerObj.has("content-length");
  444. header = buildOutgoingHttpHeaders(headerObj);
  445. } else {
  446. for (const key in header) {
  447. if (key.length === 14 && key.toLowerCase() === "content-length") {
  448. hasContentLength = true;
  449. break;
  450. }
  451. }
  452. }
  453. if (!hasContentLength) {
  454. if (typeof body === "string") {
  455. header["Content-Length"] = Buffer.byteLength(body);
  456. } else if (body instanceof Uint8Array) {
  457. header["Content-Length"] = body.byteLength;
  458. } else if (body instanceof Blob) {
  459. header["Content-Length"] = body.size;
  460. }
  461. }
  462. outgoing.writeHead(status, header);
  463. if (typeof body === "string" || body instanceof Uint8Array) {
  464. outgoing.end(body);
  465. } else if (body instanceof Blob) {
  466. outgoing.end(new Uint8Array(await body.arrayBuffer()));
  467. } else {
  468. flushHeaders(outgoing);
  469. await writeFromReadableStream(body, outgoing)?.catch(
  470. (e) => handleResponseError(e, outgoing)
  471. );
  472. }
  473. ;
  474. outgoing[outgoingEnded]?.();
  475. };
  476. var isPromise = (res) => typeof res.then === "function";
  477. var responseViaResponseObject = async (res, outgoing, options = {}) => {
  478. if (isPromise(res)) {
  479. if (options.errorHandler) {
  480. try {
  481. res = await res;
  482. } catch (err) {
  483. const errRes = await options.errorHandler(err);
  484. if (!errRes) {
  485. return;
  486. }
  487. res = errRes;
  488. }
  489. } else {
  490. res = await res.catch(handleFetchError);
  491. }
  492. }
  493. if (cacheKey in res) {
  494. return responseViaCache(res, outgoing);
  495. }
  496. const resHeaderRecord = buildOutgoingHttpHeaders(res.headers);
  497. if (res.body) {
  498. const reader = res.body.getReader();
  499. const values = [];
  500. let done = false;
  501. let currentReadPromise = void 0;
  502. if (resHeaderRecord["transfer-encoding"] !== "chunked") {
  503. let maxReadCount = 2;
  504. for (let i = 0; i < maxReadCount; i++) {
  505. currentReadPromise ||= reader.read();
  506. const chunk = await readWithoutBlocking(currentReadPromise).catch((e) => {
  507. console.error(e);
  508. done = true;
  509. });
  510. if (!chunk) {
  511. if (i === 1) {
  512. await new Promise((resolve) => setTimeout(resolve));
  513. maxReadCount = 3;
  514. continue;
  515. }
  516. break;
  517. }
  518. currentReadPromise = void 0;
  519. if (chunk.value) {
  520. values.push(chunk.value);
  521. }
  522. if (chunk.done) {
  523. done = true;
  524. break;
  525. }
  526. }
  527. if (done && !("content-length" in resHeaderRecord)) {
  528. resHeaderRecord["content-length"] = values.reduce((acc, value) => acc + value.length, 0);
  529. }
  530. }
  531. outgoing.writeHead(res.status, resHeaderRecord);
  532. values.forEach((value) => {
  533. ;
  534. outgoing.write(value);
  535. });
  536. if (done) {
  537. outgoing.end();
  538. } else {
  539. if (values.length === 0) {
  540. flushHeaders(outgoing);
  541. }
  542. await writeFromReadableStreamDefaultReader(reader, outgoing, currentReadPromise);
  543. }
  544. } else if (resHeaderRecord[X_ALREADY_SENT]) {
  545. } else {
  546. outgoing.writeHead(res.status, resHeaderRecord);
  547. outgoing.end();
  548. }
  549. ;
  550. outgoing[outgoingEnded]?.();
  551. };
  552. var getRequestListener = (fetchCallback, options = {}) => {
  553. const autoCleanupIncoming = options.autoCleanupIncoming ?? true;
  554. if (options.overrideGlobalObjects !== false && global.Request !== Request) {
  555. Object.defineProperty(global, "Request", {
  556. value: Request
  557. });
  558. Object.defineProperty(global, "Response", {
  559. value: Response2
  560. });
  561. }
  562. return async (incoming, outgoing) => {
  563. let res, req;
  564. try {
  565. req = newRequest(incoming, options.hostname);
  566. let incomingEnded = !autoCleanupIncoming || incoming.method === "GET" || incoming.method === "HEAD";
  567. if (!incomingEnded) {
  568. ;
  569. incoming[wrapBodyStream] = true;
  570. incoming.on("end", () => {
  571. incomingEnded = true;
  572. });
  573. if (incoming instanceof import_node_http22.Http2ServerRequest) {
  574. ;
  575. outgoing[outgoingEnded] = () => {
  576. if (!incomingEnded) {
  577. setTimeout(() => {
  578. if (!incomingEnded) {
  579. setTimeout(() => {
  580. drainIncoming(incoming);
  581. });
  582. }
  583. });
  584. }
  585. };
  586. }
  587. outgoing.on("finish", () => {
  588. if (!incomingEnded) {
  589. drainIncoming(incoming);
  590. }
  591. });
  592. }
  593. outgoing.on("close", () => {
  594. const abortController = req[abortControllerKey];
  595. if (abortController) {
  596. if (incoming.errored) {
  597. req[abortControllerKey].abort(incoming.errored.toString());
  598. } else if (!outgoing.writableFinished) {
  599. req[abortControllerKey].abort("Client connection prematurely closed.");
  600. }
  601. }
  602. if (!incomingEnded) {
  603. setTimeout(() => {
  604. if (!incomingEnded) {
  605. setTimeout(() => {
  606. drainIncoming(incoming);
  607. });
  608. }
  609. });
  610. }
  611. });
  612. res = fetchCallback(req, { incoming, outgoing });
  613. if (cacheKey in res) {
  614. return responseViaCache(res, outgoing);
  615. }
  616. } catch (e) {
  617. if (!res) {
  618. if (options.errorHandler) {
  619. res = await options.errorHandler(req ? e : toRequestError(e));
  620. if (!res) {
  621. return;
  622. }
  623. } else if (!req) {
  624. res = handleRequestError();
  625. } else {
  626. res = handleFetchError(e);
  627. }
  628. } else {
  629. return handleResponseError(e, outgoing);
  630. }
  631. }
  632. try {
  633. return await responseViaResponseObject(res, outgoing, options);
  634. } catch (e) {
  635. return handleResponseError(e, outgoing);
  636. }
  637. };
  638. };
  639. // src/vercel.ts
  640. var handle = (app) => {
  641. return getRequestListener(app.fetch);
  642. };
  643. // Annotate the CommonJS export names for ESM import in node:
  644. 0 && (module.exports = {
  645. handle
  646. });