diff --git a/.gitignore b/.gitignore index 1a21a13..a61f401 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ uploads apps/web/dist apps/server/dist packages/*/dist +# keep packages/dsh-plugin/bundle (prebuilt for remote install) +packages/dsh-plugin/bundle/_testdata diff --git a/apps/server/src/create-server.ts b/apps/server/src/create-server.ts index 1070f26..1e2919f 100644 --- a/apps/server/src/create-server.ts +++ b/apps/server/src/create-server.ts @@ -57,7 +57,19 @@ async function callDshBridge(path: string, init?: RequestInit) { } const __dirname = path.dirname(fileURLToPath(import.meta.url)); -export const mindMapRoot = path.resolve(__dirname, "../../.."); +/** Monorepo root, or plugin package root when launched from packaged bundle. */ +export const mindMapRoot = process.env.MINDMAP_ROOT + ? path.resolve(process.env.MINDMAP_ROOT) + : path.resolve(__dirname, "../../.."); + +export function resolveWebDist(root = mindMapRoot) { + if (process.env.MINDMAP_WEB_DIST) { + return path.resolve(process.env.MINDMAP_WEB_DIST); + } + const bundled = path.join(root, "bundle", "web"); + if (fs.existsSync(path.join(bundled, "index.html"))) return bundled; + return path.join(root, "apps", "web", "dist"); +} export function loadDotEnv(root = mindMapRoot) { try { @@ -642,14 +654,13 @@ export function startMindMapServer( } }); - // Static UI: cwd is mind-map root when launched by the plugin. - const webDistRel = "apps/web/dist"; - const webDistAbs = path.join(root, "apps/web/dist"); - if (fs.existsSync(webDistAbs) || fs.existsSync(path.join(process.cwd(), webDistRel))) { + // Static UI: monorepo apps/web/dist, or packaged bundle/web via MINDMAP_WEB_DIST. + const webDistAbs = resolveWebDist(root); + if (fs.existsSync(path.join(webDistAbs, "index.html"))) { app.use( "/*", serveStatic({ - root: fs.existsSync(webDistAbs) ? webDistAbs : webDistRel, + root: webDistAbs, index: "index.html", }), ); @@ -659,13 +670,10 @@ export function startMindMapServer( if (p.startsWith("/api") || p === "/health" || p.startsWith("/ws") || p.startsWith("/uploads")) { return c.notFound() } - const indexPath = path.join( - fs.existsSync(webDistAbs) ? webDistAbs : path.join(process.cwd(), webDistRel), - "index.html", - ); + const indexPath = path.join(webDistAbs, "index.html"); if (!fs.existsSync(indexPath)) { return c.text( - "Mind Map UI not built. From mind-map repo run: pnpm --filter @mind-map/web build", + "Mind Map UI not built. From mind-map repo run: pnpm --filter @mind-map/web build && pnpm pack:plugin", 503, ); } @@ -674,7 +682,7 @@ export function startMindMapServer( } else { app.get("/", (c) => c.text( - "Mind Map UI missing (apps/web/dist). Run: pnpm --filter @mind-map/web build", + `Mind Map UI missing (${webDistAbs}). Run: pnpm pack:plugin`, 503, ), ); diff --git a/package.json b/package.json index 7570f64..9d407f7 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,14 @@ "dev:server": "pnpm --filter @mind-map/server dev", "dev:web": "pnpm --filter @mind-map/web dev", "build": "pnpm -r run build", + "pack:plugin": "node packages/dsh-plugin/scripts/pack-bundle.mjs", "test": "pnpm -r run test", "start": "pnpm --filter @mind-map/server start", "typecheck": "pnpm -r run typecheck", "stress": "tsx scripts/stress-10k.mts" }, "devDependencies": { + "esbuild": "^0.25.12", "tsx": "^4.19.3" }, "engines": { diff --git a/packages/dsh-plugin/INSTALL.md b/packages/dsh-plugin/INSTALL.md index 235063b..d2a9dca 100644 --- a/packages/dsh-plugin/INSTALL.md +++ b/packages/dsh-plugin/INSTALL.md @@ -1,15 +1,30 @@ -# dsh-mind-map 本地安装到 DSH web profile(开发用) +# dsh-mind-map 安装 -```powershell -$plugin = "d:\project\chatgpt\mind-map\packages\dsh-plugin" -# 用 dsh plugin add 链到本地包,或在 profile 里 link -dsh plugin --profile web add -w $plugin +## 远程安装(推荐) + +仓库需包含预构建 `packages/dsh-plugin/bundle`(维护者执行 `pnpm pack:plugin` 后推送)。 + +```bash +dsh plugin --profile web add -w "github:hansjone/mind-map#path:packages/dsh-plugin" ``` -装好后: +装好后重启 `dsh web`,硬刷新浏览器。依赖:`dsh-better-sidebar`。 -1. 重启 `dsh web`,浏览器硬刷新(Ctrl+Shift+R) -2. 右侧栏「+」选 **思维导图**,或 设置 → Mind Map → **打开思维导图 Tab** -3. 拓扑占满右侧内容区;对话继续用中间 DSH 输入框 +启动日志应出现: -依赖:已安装 `dsh-better-sidebar`(提供 `ctx.betterSidebar.registerTab`)。 +```text +[dsh-mind-map] starting packaged bundle/server.mjs +``` + +若仍出现 `building web UI…`,说明装到的版本没有 `bundle/`,请更新插件或改用本地完整仓库。 + +## 本地开发(link 整个 monorepo) + +```powershell +cd d:\project\chatgpt\mind-map +pnpm install +pnpm pack:plugin +dsh plugin --profile web add -w "d:\project\chatgpt\mind-map\packages\dsh-plugin" +``` + +开发改 UI 时可继续用 monorepo 源码启动(无 bundle 时会自动 `pnpm --filter @mind-map/web build`)。 diff --git a/packages/dsh-plugin/bundle/README.txt b/packages/dsh-plugin/bundle/README.txt new file mode 100644 index 0000000..556dd23 --- /dev/null +++ b/packages/dsh-plugin/bundle/README.txt @@ -0,0 +1 @@ +Prebuilt assets for remote dsh plugin install. Regenerated by: node packages/dsh-plugin/scripts/pack-bundle.mjs diff --git a/packages/dsh-plugin/bundle/server.mjs b/packages/dsh-plugin/bundle/server.mjs new file mode 100644 index 0000000..9530370 --- /dev/null +++ b/packages/dsh-plugin/bundle/server.mjs @@ -0,0 +1,28067 @@ +import { createRequire as __mmCr } from 'node:module'; const require = __mmCr(import.meta.url); +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { + get: (a, b) => (typeof require !== "undefined" ? require : a)[b] +}) : x)(function(x) { + if (typeof require !== "undefined") return require.apply(this, arguments); + throw Error('Dynamic require of "' + x + '" is not supported'); +}); +var __commonJS = (cb, mod) => function __require2() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __export = (target, all) => { + for (var name17 in all) + __defProp(target, name17, { get: all[name17], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); + +// node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/constants.js +var require_constants = __commonJS({ + "node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/constants.js"(exports, module) { + "use strict"; + var BINARY_TYPES = ["nodebuffer", "arraybuffer", "fragments"]; + var hasBlob = typeof Blob !== "undefined"; + if (hasBlob) BINARY_TYPES.push("blob"); + module.exports = { + BINARY_TYPES, + CLOSE_TIMEOUT: 3e4, + EMPTY_BUFFER: Buffer.alloc(0), + GUID: "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", + hasBlob, + kForOnEventAttribute: Symbol("kIsForOnEventAttribute"), + kListener: Symbol("kListener"), + kStatusCode: Symbol("status-code"), + kWebSocket: Symbol("websocket"), + NOOP: () => { + } + }; + } +}); + +// node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/buffer-util.js +var require_buffer_util = __commonJS({ + "node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/buffer-util.js"(exports, module) { + "use strict"; + var { EMPTY_BUFFER } = require_constants(); + var FastBuffer = Buffer[Symbol.species]; + function concat(list, totalLength) { + if (list.length === 0) return EMPTY_BUFFER; + if (list.length === 1) return list[0]; + const target = Buffer.allocUnsafe(totalLength); + let offset = 0; + for (let i = 0; i < list.length; i++) { + const buf = list[i]; + target.set(buf, offset); + offset += buf.length; + } + if (offset < totalLength) { + return new FastBuffer(target.buffer, target.byteOffset, offset); + } + return target; + } + function _mask(source, mask, output, offset, length) { + for (let i = 0; i < length; i++) { + output[offset + i] = source[i] ^ mask[i & 3]; + } + } + function _unmask(buffer, mask) { + for (let i = 0; i < buffer.length; i++) { + buffer[i] ^= mask[i & 3]; + } + } + function toArrayBuffer(buf) { + if (buf.length === buf.buffer.byteLength) { + return buf.buffer; + } + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length); + } + function toBuffer(data) { + toBuffer.readOnly = true; + if (Buffer.isBuffer(data)) return data; + let buf; + if (data instanceof ArrayBuffer) { + buf = new FastBuffer(data); + } else if (ArrayBuffer.isView(data)) { + buf = new FastBuffer(data.buffer, data.byteOffset, data.byteLength); + } else { + buf = Buffer.from(data); + toBuffer.readOnly = false; + } + return buf; + } + module.exports = { + concat, + mask: _mask, + toArrayBuffer, + toBuffer, + unmask: _unmask + }; + if (!process.env.WS_NO_BUFFER_UTIL) { + try { + const bufferUtil = __require("bufferutil"); + module.exports.mask = function(source, mask, output, offset, length) { + if (length < 48) _mask(source, mask, output, offset, length); + else bufferUtil.mask(source, mask, output, offset, length); + }; + module.exports.unmask = function(buffer, mask) { + if (buffer.length < 32) _unmask(buffer, mask); + else bufferUtil.unmask(buffer, mask); + }; + } catch (e) { + } + } + } +}); + +// node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/limiter.js +var require_limiter = __commonJS({ + "node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/limiter.js"(exports, module) { + "use strict"; + var kDone = Symbol("kDone"); + var kRun = Symbol("kRun"); + var Limiter = class { + /** + * Creates a new `Limiter`. + * + * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed + * to run concurrently + */ + constructor(concurrency) { + this[kDone] = () => { + this.pending--; + this[kRun](); + }; + this.concurrency = concurrency || Infinity; + this.jobs = []; + this.pending = 0; + } + /** + * Adds a job to the queue. + * + * @param {Function} job The job to run + * @public + */ + add(job) { + this.jobs.push(job); + this[kRun](); + } + /** + * Removes a job from the queue and runs it if possible. + * + * @private + */ + [kRun]() { + if (this.pending === this.concurrency) return; + if (this.jobs.length) { + const job = this.jobs.shift(); + this.pending++; + job(this[kDone]); + } + } + }; + module.exports = Limiter; + } +}); + +// node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/permessage-deflate.js +var require_permessage_deflate = __commonJS({ + "node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/permessage-deflate.js"(exports, module) { + "use strict"; + var zlib = __require("zlib"); + var bufferUtil = require_buffer_util(); + var Limiter = require_limiter(); + var { kStatusCode } = require_constants(); + var FastBuffer = Buffer[Symbol.species]; + var TRAILER = Buffer.from([0, 0, 255, 255]); + var kPerMessageDeflate = Symbol("permessage-deflate"); + var kTotalLength = Symbol("total-length"); + var kCallback = Symbol("callback"); + var kBuffers = Symbol("buffers"); + var kError = Symbol("error"); + var zlibLimiter; + var PerMessageDeflate2 = class { + /** + * Creates a PerMessageDeflate instance. + * + * @param {Object} [options] Configuration options + * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support + * for, or request, a custom client window size + * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/ + * acknowledge disabling of client context takeover + * @param {Number} [options.concurrencyLimit=10] The number of concurrent + * calls to zlib + * @param {Boolean} [options.isServer=false] Create the instance in either + * server or client mode + * @param {Number} [options.maxPayload=0] The maximum allowed message length + * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the + * use of a custom server window size + * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept + * disabling of server context takeover + * @param {Number} [options.threshold=1024] Size (in bytes) below which + * messages should not be compressed if context takeover is disabled + * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on + * deflate + * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on + * inflate + */ + constructor(options) { + this._options = options || {}; + this._threshold = this._options.threshold !== void 0 ? this._options.threshold : 1024; + this._maxPayload = this._options.maxPayload | 0; + this._isServer = !!this._options.isServer; + this._deflate = null; + this._inflate = null; + this.params = null; + if (!zlibLimiter) { + const concurrency = this._options.concurrencyLimit !== void 0 ? this._options.concurrencyLimit : 10; + zlibLimiter = new Limiter(concurrency); + } + } + /** + * @type {String} + */ + static get extensionName() { + return "permessage-deflate"; + } + /** + * Create an extension negotiation offer. + * + * @return {Object} Extension parameters + * @public + */ + offer() { + const params = {}; + if (this._options.serverNoContextTakeover) { + params.server_no_context_takeover = true; + } + if (this._options.clientNoContextTakeover) { + params.client_no_context_takeover = true; + } + if (this._options.serverMaxWindowBits) { + params.server_max_window_bits = this._options.serverMaxWindowBits; + } + if (this._options.clientMaxWindowBits) { + params.client_max_window_bits = this._options.clientMaxWindowBits; + } else if (this._options.clientMaxWindowBits == null) { + params.client_max_window_bits = true; + } + return params; + } + /** + * Accept an extension negotiation offer/response. + * + * @param {Array} configurations The extension negotiation offers/reponse + * @return {Object} Accepted configuration + * @public + */ + accept(configurations) { + configurations = this.normalizeParams(configurations); + this.params = this._isServer ? this.acceptAsServer(configurations) : this.acceptAsClient(configurations); + return this.params; + } + /** + * Releases all resources used by the extension. + * + * @public + */ + cleanup() { + if (this._inflate) { + this._inflate.close(); + this._inflate = null; + } + if (this._deflate) { + const callback = this._deflate[kCallback]; + this._deflate.close(); + this._deflate = null; + if (callback) { + callback( + new Error( + "The deflate stream was closed while data was being processed" + ) + ); + } + } + } + /** + * Accept an extension negotiation offer. + * + * @param {Array} offers The extension negotiation offers + * @return {Object} Accepted configuration + * @private + */ + acceptAsServer(offers) { + const opts = this._options; + const accepted = offers.find((params) => { + if (opts.serverNoContextTakeover === false && params.server_no_context_takeover || params.server_max_window_bits && (opts.serverMaxWindowBits === false || typeof opts.serverMaxWindowBits === "number" && opts.serverMaxWindowBits > params.server_max_window_bits) || typeof opts.clientMaxWindowBits === "number" && (typeof params.client_max_window_bits === "number" ? opts.clientMaxWindowBits > params.client_max_window_bits : !params.client_max_window_bits)) { + return false; + } + return true; + }); + if (!accepted) { + throw new Error("None of the extension offers can be accepted"); + } + if (opts.serverNoContextTakeover) { + accepted.server_no_context_takeover = true; + } + if (opts.clientNoContextTakeover) { + accepted.client_no_context_takeover = true; + } + if (typeof opts.serverMaxWindowBits === "number") { + accepted.server_max_window_bits = opts.serverMaxWindowBits; + } + if (typeof opts.clientMaxWindowBits === "number") { + accepted.client_max_window_bits = opts.clientMaxWindowBits; + } else if (accepted.client_max_window_bits === true || opts.clientMaxWindowBits === false) { + delete accepted.client_max_window_bits; + } + return accepted; + } + /** + * Accept the extension negotiation response. + * + * @param {Array} response The extension negotiation response + * @return {Object} Accepted configuration + * @private + */ + acceptAsClient(response) { + const params = response[0]; + if (this._options.clientNoContextTakeover === false && params.client_no_context_takeover) { + throw new Error('Unexpected parameter "client_no_context_takeover"'); + } + if (!params.client_max_window_bits) { + if (typeof this._options.clientMaxWindowBits === "number") { + params.client_max_window_bits = this._options.clientMaxWindowBits; + } + } else if (this._options.clientMaxWindowBits === false || typeof this._options.clientMaxWindowBits === "number" && params.client_max_window_bits > this._options.clientMaxWindowBits) { + throw new Error( + 'Unexpected or invalid parameter "client_max_window_bits"' + ); + } + return params; + } + /** + * Normalize parameters. + * + * @param {Array} configurations The extension negotiation offers/reponse + * @return {Array} The offers/response with normalized parameters + * @private + */ + normalizeParams(configurations) { + configurations.forEach((params) => { + Object.keys(params).forEach((key) => { + let value = params[key]; + if (value.length > 1) { + throw new Error(`Parameter "${key}" must have only a single value`); + } + value = value[0]; + if (key === "client_max_window_bits") { + if (value !== true) { + const num = +value; + if (!Number.isInteger(num) || num < 8 || num > 15) { + throw new TypeError( + `Invalid value for parameter "${key}": ${value}` + ); + } + value = num; + } else if (!this._isServer) { + throw new TypeError( + `Invalid value for parameter "${key}": ${value}` + ); + } + } else if (key === "server_max_window_bits") { + const num = +value; + if (!Number.isInteger(num) || num < 8 || num > 15) { + throw new TypeError( + `Invalid value for parameter "${key}": ${value}` + ); + } + value = num; + } else if (key === "client_no_context_takeover" || key === "server_no_context_takeover") { + if (value !== true) { + throw new TypeError( + `Invalid value for parameter "${key}": ${value}` + ); + } + } else { + throw new Error(`Unknown parameter "${key}"`); + } + params[key] = value; + }); + }); + return configurations; + } + /** + * Decompress data. Concurrency limited. + * + * @param {Buffer} data Compressed data + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @public + */ + decompress(data, fin, callback) { + zlibLimiter.add((done) => { + this._decompress(data, fin, (err, result) => { + done(); + callback(err, result); + }); + }); + } + /** + * Compress data. Concurrency limited. + * + * @param {(Buffer|String)} data Data to compress + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @public + */ + compress(data, fin, callback) { + zlibLimiter.add((done) => { + this._compress(data, fin, (err, result) => { + done(); + callback(err, result); + }); + }); + } + /** + * Decompress data. + * + * @param {Buffer} data Compressed data + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @private + */ + _decompress(data, fin, callback) { + const endpoint = this._isServer ? "client" : "server"; + if (!this._inflate) { + const key = `${endpoint}_max_window_bits`; + const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key]; + this._inflate = zlib.createInflateRaw({ + ...this._options.zlibInflateOptions, + windowBits + }); + this._inflate[kPerMessageDeflate] = this; + this._inflate[kTotalLength] = 0; + this._inflate[kBuffers] = []; + this._inflate.on("error", inflateOnError); + this._inflate.on("data", inflateOnData); + } + this._inflate[kCallback] = callback; + this._inflate.write(data); + if (fin) this._inflate.write(TRAILER); + this._inflate.flush(() => { + const err = this._inflate[kError]; + if (err) { + this._inflate.close(); + this._inflate = null; + callback(err); + return; + } + const data2 = bufferUtil.concat( + this._inflate[kBuffers], + this._inflate[kTotalLength] + ); + if (this._inflate._readableState.endEmitted) { + this._inflate.close(); + this._inflate = null; + } else { + this._inflate[kTotalLength] = 0; + this._inflate[kBuffers] = []; + if (fin && this.params[`${endpoint}_no_context_takeover`]) { + this._inflate.reset(); + } + } + callback(null, data2); + }); + } + /** + * Compress data. + * + * @param {(Buffer|String)} data Data to compress + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @private + */ + _compress(data, fin, callback) { + const endpoint = this._isServer ? "server" : "client"; + if (!this._deflate) { + const key = `${endpoint}_max_window_bits`; + const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key]; + this._deflate = zlib.createDeflateRaw({ + ...this._options.zlibDeflateOptions, + windowBits + }); + this._deflate[kTotalLength] = 0; + this._deflate[kBuffers] = []; + this._deflate.on("data", deflateOnData); + } + this._deflate[kCallback] = callback; + this._deflate.write(data); + this._deflate.flush(zlib.Z_SYNC_FLUSH, () => { + if (!this._deflate) { + return; + } + let data2 = bufferUtil.concat( + this._deflate[kBuffers], + this._deflate[kTotalLength] + ); + if (fin) { + data2 = new FastBuffer(data2.buffer, data2.byteOffset, data2.length - 4); + } + this._deflate[kCallback] = null; + this._deflate[kTotalLength] = 0; + this._deflate[kBuffers] = []; + if (fin && this.params[`${endpoint}_no_context_takeover`]) { + this._deflate.reset(); + } + callback(null, data2); + }); + } + }; + module.exports = PerMessageDeflate2; + function deflateOnData(chunk) { + this[kBuffers].push(chunk); + this[kTotalLength] += chunk.length; + } + function inflateOnData(chunk) { + this[kTotalLength] += chunk.length; + if (this[kPerMessageDeflate]._maxPayload < 1 || this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload) { + this[kBuffers].push(chunk); + return; + } + this[kError] = new RangeError("Max payload size exceeded"); + this[kError].code = "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"; + this[kError][kStatusCode] = 1009; + this.removeListener("data", inflateOnData); + this.reset(); + } + function inflateOnError(err) { + this[kPerMessageDeflate]._inflate = null; + if (this[kError]) { + this[kCallback](this[kError]); + return; + } + err[kStatusCode] = 1007; + this[kCallback](err); + } + } +}); + +// node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/validation.js +var require_validation = __commonJS({ + "node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/validation.js"(exports, module) { + "use strict"; + var { isUtf8 } = __require("buffer"); + var { hasBlob } = require_constants(); + var tokenChars = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + // 0 - 15 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + // 16 - 31 + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + // 32 - 47 + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + // 48 - 63 + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + // 64 - 79 + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + // 80 - 95 + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + // 96 - 111 + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0 + // 112 - 127 + ]; + function isValidStatusCode(code) { + return code >= 1e3 && code <= 1014 && code !== 1004 && code !== 1005 && code !== 1006 || code >= 3e3 && code <= 4999; + } + function _isValidUTF8(buf) { + const len = buf.length; + let i = 0; + while (i < len) { + if ((buf[i] & 128) === 0) { + i++; + } else if ((buf[i] & 224) === 192) { + if (i + 1 === len || (buf[i + 1] & 192) !== 128 || (buf[i] & 254) === 192) { + return false; + } + i += 2; + } else if ((buf[i] & 240) === 224) { + if (i + 2 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || buf[i] === 224 && (buf[i + 1] & 224) === 128 || // Overlong + buf[i] === 237 && (buf[i + 1] & 224) === 160) { + return false; + } + i += 3; + } else if ((buf[i] & 248) === 240) { + if (i + 3 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || (buf[i + 3] & 192) !== 128 || buf[i] === 240 && (buf[i + 1] & 240) === 128 || // Overlong + buf[i] === 244 && buf[i + 1] > 143 || buf[i] > 244) { + return false; + } + i += 4; + } else { + return false; + } + } + return true; + } + function isBlob(value) { + return hasBlob && typeof value === "object" && typeof value.arrayBuffer === "function" && typeof value.type === "string" && typeof value.stream === "function" && (value[Symbol.toStringTag] === "Blob" || value[Symbol.toStringTag] === "File"); + } + module.exports = { + isBlob, + isValidStatusCode, + isValidUTF8: _isValidUTF8, + tokenChars + }; + if (isUtf8) { + module.exports.isValidUTF8 = function(buf) { + return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf); + }; + } else if (!process.env.WS_NO_UTF_8_VALIDATE) { + try { + const isValidUTF8 = __require("utf-8-validate"); + module.exports.isValidUTF8 = function(buf) { + return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf); + }; + } catch (e) { + } + } + } +}); + +// node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/receiver.js +var require_receiver = __commonJS({ + "node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/receiver.js"(exports, module) { + "use strict"; + var { Writable } = __require("stream"); + var PerMessageDeflate2 = require_permessage_deflate(); + var { + BINARY_TYPES, + EMPTY_BUFFER, + kStatusCode, + kWebSocket + } = require_constants(); + var { concat, toArrayBuffer, unmask } = require_buffer_util(); + var { isValidStatusCode, isValidUTF8 } = require_validation(); + var FastBuffer = Buffer[Symbol.species]; + var GET_INFO = 0; + var GET_PAYLOAD_LENGTH_16 = 1; + var GET_PAYLOAD_LENGTH_64 = 2; + var GET_MASK = 3; + var GET_DATA = 4; + var INFLATING = 5; + var DEFER_EVENT = 6; + var Receiver2 = class extends Writable { + /** + * Creates a Receiver instance. + * + * @param {Object} [options] Options object + * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether + * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted + * multiple times in the same tick + * @param {String} [options.binaryType=nodebuffer] The type for binary data + * @param {Object} [options.extensions] An object containing the negotiated + * extensions + * @param {Boolean} [options.isServer=false] Specifies whether to operate in + * client or server mode + * @param {Number} [options.maxBufferedChunks=0] The maximum number of + * buffered data chunks + * @param {Number} [options.maxFragments=0] The maximum number of message + * fragments + * @param {Number} [options.maxPayload=0] The maximum allowed message length + * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or + * not to skip UTF-8 validation for text and close messages + */ + constructor(options = {}) { + super(); + this._allowSynchronousEvents = options.allowSynchronousEvents !== void 0 ? options.allowSynchronousEvents : true; + this._binaryType = options.binaryType || BINARY_TYPES[0]; + this._extensions = options.extensions || {}; + this._isServer = !!options.isServer; + this._maxBufferedChunks = options.maxBufferedChunks | 0; + this._maxFragments = options.maxFragments | 0; + this._maxPayload = options.maxPayload | 0; + this._skipUTF8Validation = !!options.skipUTF8Validation; + this[kWebSocket] = void 0; + this._bufferedBytes = 0; + this._buffers = []; + this._compressed = false; + this._payloadLength = 0; + this._mask = void 0; + this._fragmented = 0; + this._masked = false; + this._fin = false; + this._opcode = 0; + this._totalPayloadLength = 0; + this._messageLength = 0; + this._numFragments = 0; + this._fragments = []; + this._errored = false; + this._loop = false; + this._state = GET_INFO; + } + /** + * Implements `Writable.prototype._write()`. + * + * @param {Buffer} chunk The chunk of data to write + * @param {String} encoding The character encoding of `chunk` + * @param {Function} cb Callback + * @private + */ + _write(chunk, encoding, cb) { + if (this._opcode === 8 && this._state == GET_INFO) return cb(); + if (this._maxBufferedChunks > 0 && this._buffers.length >= this._maxBufferedChunks) { + cb( + this.createError( + RangeError, + "Too many buffered chunks", + false, + 1008, + "WS_ERR_TOO_MANY_BUFFERED_PARTS" + ) + ); + return; + } + this._bufferedBytes += chunk.length; + this._buffers.push(chunk); + this.startLoop(cb); + } + /** + * Consumes `n` bytes from the buffered data. + * + * @param {Number} n The number of bytes to consume + * @return {Buffer} The consumed bytes + * @private + */ + consume(n) { + this._bufferedBytes -= n; + if (n === this._buffers[0].length) return this._buffers.shift(); + if (n < this._buffers[0].length) { + const buf = this._buffers[0]; + this._buffers[0] = new FastBuffer( + buf.buffer, + buf.byteOffset + n, + buf.length - n + ); + return new FastBuffer(buf.buffer, buf.byteOffset, n); + } + const dst = Buffer.allocUnsafe(n); + do { + const buf = this._buffers[0]; + const offset = dst.length - n; + if (n >= buf.length) { + dst.set(this._buffers.shift(), offset); + } else { + dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset); + this._buffers[0] = new FastBuffer( + buf.buffer, + buf.byteOffset + n, + buf.length - n + ); + } + n -= buf.length; + } while (n > 0); + return dst; + } + /** + * Starts the parsing loop. + * + * @param {Function} cb Callback + * @private + */ + startLoop(cb) { + this._loop = true; + do { + switch (this._state) { + case GET_INFO: + this.getInfo(cb); + break; + case GET_PAYLOAD_LENGTH_16: + this.getPayloadLength16(cb); + break; + case GET_PAYLOAD_LENGTH_64: + this.getPayloadLength64(cb); + break; + case GET_MASK: + this.getMask(); + break; + case GET_DATA: + this.getData(cb); + break; + case INFLATING: + case DEFER_EVENT: + this._loop = false; + return; + } + } while (this._loop); + if (!this._errored) cb(); + } + /** + * Reads the first two bytes of a frame. + * + * @param {Function} cb Callback + * @private + */ + getInfo(cb) { + if (this._bufferedBytes < 2) { + this._loop = false; + return; + } + const buf = this.consume(2); + if ((buf[0] & 48) !== 0) { + const error = this.createError( + RangeError, + "RSV2 and RSV3 must be clear", + true, + 1002, + "WS_ERR_UNEXPECTED_RSV_2_3" + ); + cb(error); + return; + } + const compressed = (buf[0] & 64) === 64; + if (compressed && !this._extensions[PerMessageDeflate2.extensionName]) { + const error = this.createError( + RangeError, + "RSV1 must be clear", + true, + 1002, + "WS_ERR_UNEXPECTED_RSV_1" + ); + cb(error); + return; + } + this._fin = (buf[0] & 128) === 128; + this._opcode = buf[0] & 15; + this._payloadLength = buf[1] & 127; + if (this._opcode === 0) { + if (compressed) { + const error = this.createError( + RangeError, + "RSV1 must be clear", + true, + 1002, + "WS_ERR_UNEXPECTED_RSV_1" + ); + cb(error); + return; + } + if (!this._fragmented) { + const error = this.createError( + RangeError, + "invalid opcode 0", + true, + 1002, + "WS_ERR_INVALID_OPCODE" + ); + cb(error); + return; + } + this._opcode = this._fragmented; + } else if (this._opcode === 1 || this._opcode === 2) { + if (this._fragmented) { + const error = this.createError( + RangeError, + `invalid opcode ${this._opcode}`, + true, + 1002, + "WS_ERR_INVALID_OPCODE" + ); + cb(error); + return; + } + this._compressed = compressed; + } else if (this._opcode > 7 && this._opcode < 11) { + if (!this._fin) { + const error = this.createError( + RangeError, + "FIN must be set", + true, + 1002, + "WS_ERR_EXPECTED_FIN" + ); + cb(error); + return; + } + if (compressed) { + const error = this.createError( + RangeError, + "RSV1 must be clear", + true, + 1002, + "WS_ERR_UNEXPECTED_RSV_1" + ); + cb(error); + return; + } + if (this._payloadLength > 125 || this._opcode === 8 && this._payloadLength === 1) { + const error = this.createError( + RangeError, + `invalid payload length ${this._payloadLength}`, + true, + 1002, + "WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH" + ); + cb(error); + return; + } + } else { + const error = this.createError( + RangeError, + `invalid opcode ${this._opcode}`, + true, + 1002, + "WS_ERR_INVALID_OPCODE" + ); + cb(error); + return; + } + if (!this._fin && !this._fragmented) this._fragmented = this._opcode; + this._masked = (buf[1] & 128) === 128; + if (this._isServer) { + if (!this._masked) { + const error = this.createError( + RangeError, + "MASK must be set", + true, + 1002, + "WS_ERR_EXPECTED_MASK" + ); + cb(error); + return; + } + } else if (this._masked) { + const error = this.createError( + RangeError, + "MASK must be clear", + true, + 1002, + "WS_ERR_UNEXPECTED_MASK" + ); + cb(error); + return; + } + if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16; + else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64; + else this.haveLength(cb); + } + /** + * Gets extended payload length (7+16). + * + * @param {Function} cb Callback + * @private + */ + getPayloadLength16(cb) { + if (this._bufferedBytes < 2) { + this._loop = false; + return; + } + this._payloadLength = this.consume(2).readUInt16BE(0); + this.haveLength(cb); + } + /** + * Gets extended payload length (7+64). + * + * @param {Function} cb Callback + * @private + */ + getPayloadLength64(cb) { + if (this._bufferedBytes < 8) { + this._loop = false; + return; + } + const buf = this.consume(8); + const num = buf.readUInt32BE(0); + if (num > Math.pow(2, 53 - 32) - 1) { + const error = this.createError( + RangeError, + "Unsupported WebSocket frame: payload length > 2^53 - 1", + false, + 1009, + "WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH" + ); + cb(error); + return; + } + this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4); + this.haveLength(cb); + } + /** + * Payload length has been read. + * + * @param {Function} cb Callback + * @private + */ + haveLength(cb) { + if (this._payloadLength && this._opcode < 8) { + this._totalPayloadLength += this._payloadLength; + if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) { + const error = this.createError( + RangeError, + "Max payload size exceeded", + false, + 1009, + "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH" + ); + cb(error); + return; + } + } + if (this._masked) this._state = GET_MASK; + else this._state = GET_DATA; + } + /** + * Reads mask bytes. + * + * @private + */ + getMask() { + if (this._bufferedBytes < 4) { + this._loop = false; + return; + } + this._mask = this.consume(4); + this._state = GET_DATA; + } + /** + * Reads data bytes. + * + * @param {Function} cb Callback + * @private + */ + getData(cb) { + let data = EMPTY_BUFFER; + if (this._payloadLength) { + if (this._bufferedBytes < this._payloadLength) { + this._loop = false; + return; + } + data = this.consume(this._payloadLength); + if (this._masked && (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0) { + unmask(data, this._mask); + } + } + if (this._opcode > 7) { + this.controlMessage(data, cb); + return; + } + if (this._maxFragments > 0 && ++this._numFragments > this._maxFragments) { + const error = this.createError( + RangeError, + "Too many message fragments", + false, + 1008, + "WS_ERR_TOO_MANY_BUFFERED_PARTS" + ); + cb(error); + return; + } + if (this._compressed) { + this._state = INFLATING; + this.decompress(data, cb); + return; + } + if (data.length) { + this._messageLength = this._totalPayloadLength; + this._fragments.push(data); + } + this.dataMessage(cb); + } + /** + * Decompresses data. + * + * @param {Buffer} data Compressed data + * @param {Function} cb Callback + * @private + */ + decompress(data, cb) { + const perMessageDeflate = this._extensions[PerMessageDeflate2.extensionName]; + perMessageDeflate.decompress(data, this._fin, (err, buf) => { + if (err) return cb(err); + if (buf.length) { + this._messageLength += buf.length; + if (this._messageLength > this._maxPayload && this._maxPayload > 0) { + const error = this.createError( + RangeError, + "Max payload size exceeded", + false, + 1009, + "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH" + ); + cb(error); + return; + } + this._fragments.push(buf); + } + this.dataMessage(cb); + if (this._state === GET_INFO) this.startLoop(cb); + }); + } + /** + * Handles a data message. + * + * @param {Function} cb Callback + * @private + */ + dataMessage(cb) { + if (!this._fin) { + this._state = GET_INFO; + return; + } + const messageLength = this._messageLength; + const fragments = this._fragments; + this._totalPayloadLength = 0; + this._messageLength = 0; + this._fragmented = 0; + this._numFragments = 0; + this._fragments = []; + if (this._opcode === 2) { + let data; + if (this._binaryType === "nodebuffer") { + data = concat(fragments, messageLength); + } else if (this._binaryType === "arraybuffer") { + data = toArrayBuffer(concat(fragments, messageLength)); + } else if (this._binaryType === "blob") { + data = new Blob(fragments); + } else { + data = fragments; + } + if (this._allowSynchronousEvents) { + this.emit("message", data, true); + this._state = GET_INFO; + } else { + this._state = DEFER_EVENT; + setImmediate(() => { + this.emit("message", data, true); + this._state = GET_INFO; + this.startLoop(cb); + }); + } + } else { + const buf = concat(fragments, messageLength); + if (!this._skipUTF8Validation && !isValidUTF8(buf)) { + const error = this.createError( + Error, + "invalid UTF-8 sequence", + true, + 1007, + "WS_ERR_INVALID_UTF8" + ); + cb(error); + return; + } + if (this._state === INFLATING || this._allowSynchronousEvents) { + this.emit("message", buf, false); + this._state = GET_INFO; + } else { + this._state = DEFER_EVENT; + setImmediate(() => { + this.emit("message", buf, false); + this._state = GET_INFO; + this.startLoop(cb); + }); + } + } + } + /** + * Handles a control message. + * + * @param {Buffer} data Data to handle + * @return {(Error|RangeError|undefined)} A possible error + * @private + */ + controlMessage(data, cb) { + if (this._opcode === 8) { + if (data.length === 0) { + this._loop = false; + this.emit("conclude", 1005, EMPTY_BUFFER); + this.end(); + } else { + const code = data.readUInt16BE(0); + if (!isValidStatusCode(code)) { + const error = this.createError( + RangeError, + `invalid status code ${code}`, + true, + 1002, + "WS_ERR_INVALID_CLOSE_CODE" + ); + cb(error); + return; + } + const buf = new FastBuffer( + data.buffer, + data.byteOffset + 2, + data.length - 2 + ); + if (!this._skipUTF8Validation && !isValidUTF8(buf)) { + const error = this.createError( + Error, + "invalid UTF-8 sequence", + true, + 1007, + "WS_ERR_INVALID_UTF8" + ); + cb(error); + return; + } + this._loop = false; + this.emit("conclude", code, buf); + this.end(); + } + this._state = GET_INFO; + return; + } + if (this._allowSynchronousEvents) { + this.emit(this._opcode === 9 ? "ping" : "pong", data); + this._state = GET_INFO; + } else { + this._state = DEFER_EVENT; + setImmediate(() => { + this.emit(this._opcode === 9 ? "ping" : "pong", data); + this._state = GET_INFO; + this.startLoop(cb); + }); + } + } + /** + * Builds an error object. + * + * @param {function(new:Error|RangeError)} ErrorCtor The error constructor + * @param {String} message The error message + * @param {Boolean} prefix Specifies whether or not to add a default prefix to + * `message` + * @param {Number} statusCode The status code + * @param {String} errorCode The exposed error code + * @return {(Error|RangeError)} The error + * @private + */ + createError(ErrorCtor, message, prefix, statusCode, errorCode) { + this._loop = false; + this._errored = true; + const err = new ErrorCtor( + prefix ? `Invalid WebSocket frame: ${message}` : message + ); + Error.captureStackTrace(err, this.createError); + err.code = errorCode; + err[kStatusCode] = statusCode; + return err; + } + }; + module.exports = Receiver2; + } +}); + +// node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/sender.js +var require_sender = __commonJS({ + "node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/sender.js"(exports, module) { + "use strict"; + var { Duplex } = __require("stream"); + var { randomFillSync } = __require("crypto"); + var { + types: { isUint8Array } + } = __require("util"); + var PerMessageDeflate2 = require_permessage_deflate(); + var { EMPTY_BUFFER, kWebSocket, NOOP } = require_constants(); + var { isBlob, isValidStatusCode } = require_validation(); + var { mask: applyMask, toBuffer } = require_buffer_util(); + var kByteLength = Symbol("kByteLength"); + var maskBuffer = Buffer.alloc(4); + var RANDOM_POOL_SIZE = 8 * 1024; + var randomPool; + var randomPoolPointer = RANDOM_POOL_SIZE; + var DEFAULT = 0; + var DEFLATING = 1; + var GET_BLOB_DATA = 2; + var Sender2 = class _Sender { + /** + * Creates a Sender instance. + * + * @param {Duplex} socket The connection socket + * @param {Object} [extensions] An object containing the negotiated extensions + * @param {Function} [generateMask] The function used to generate the masking + * key + */ + constructor(socket, extensions, generateMask) { + this._extensions = extensions || {}; + if (generateMask) { + this._generateMask = generateMask; + this._maskBuffer = Buffer.alloc(4); + } + this._socket = socket; + this._firstFragment = true; + this._compress = false; + this._bufferedBytes = 0; + this._queue = []; + this._state = DEFAULT; + this.onerror = NOOP; + this[kWebSocket] = void 0; + } + /** + * Frames a piece of data according to the HyBi WebSocket protocol. + * + * @param {(Buffer|String)} data The data to frame + * @param {Object} options Options object + * @param {Boolean} [options.fin=false] Specifies whether or not to set the + * FIN bit + * @param {Function} [options.generateMask] The function used to generate the + * masking key + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Buffer} [options.maskBuffer] The buffer used to store the masking + * key + * @param {Number} options.opcode The opcode + * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be + * modified + * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the + * RSV1 bit + * @return {(Buffer|String)[]} The framed data + * @public + */ + static frame(data, options) { + let mask; + let merge = false; + let offset = 2; + let skipMasking = false; + if (options.mask) { + mask = options.maskBuffer || maskBuffer; + if (options.generateMask) { + options.generateMask(mask); + } else { + if (randomPoolPointer === RANDOM_POOL_SIZE) { + if (randomPool === void 0) { + randomPool = Buffer.alloc(RANDOM_POOL_SIZE); + } + randomFillSync(randomPool, 0, RANDOM_POOL_SIZE); + randomPoolPointer = 0; + } + mask[0] = randomPool[randomPoolPointer++]; + mask[1] = randomPool[randomPoolPointer++]; + mask[2] = randomPool[randomPoolPointer++]; + mask[3] = randomPool[randomPoolPointer++]; + } + skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0; + offset = 6; + } + let dataLength; + if (typeof data === "string") { + if ((!options.mask || skipMasking) && options[kByteLength] !== void 0) { + dataLength = options[kByteLength]; + } else { + data = Buffer.from(data); + dataLength = data.length; + } + } else { + dataLength = data.length; + merge = options.mask && options.readOnly && !skipMasking; + } + let payloadLength = dataLength; + if (dataLength >= 65536) { + offset += 8; + payloadLength = 127; + } else if (dataLength > 125) { + offset += 2; + payloadLength = 126; + } + const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset); + target[0] = options.fin ? options.opcode | 128 : options.opcode; + if (options.rsv1) target[0] |= 64; + target[1] = payloadLength; + if (payloadLength === 126) { + target.writeUInt16BE(dataLength, 2); + } else if (payloadLength === 127) { + target[2] = target[3] = 0; + target.writeUIntBE(dataLength, 4, 6); + } + if (!options.mask) return [target, data]; + target[1] |= 128; + target[offset - 4] = mask[0]; + target[offset - 3] = mask[1]; + target[offset - 2] = mask[2]; + target[offset - 1] = mask[3]; + if (skipMasking) return [target, data]; + if (merge) { + applyMask(data, mask, target, offset, dataLength); + return [target]; + } + applyMask(data, mask, data, 0, dataLength); + return [target, data]; + } + /** + * Sends a close message to the other peer. + * + * @param {Number} [code] The status code component of the body + * @param {(String|Buffer)} [data] The message component of the body + * @param {Boolean} [mask=false] Specifies whether or not to mask the message + * @param {Function} [cb] Callback + * @public + */ + close(code, data, mask, cb) { + let buf; + if (code === void 0) { + buf = EMPTY_BUFFER; + } else if (typeof code !== "number" || !isValidStatusCode(code)) { + throw new TypeError("First argument must be a valid error code number"); + } else if (data === void 0 || !data.length) { + buf = Buffer.allocUnsafe(2); + buf.writeUInt16BE(code, 0); + } else { + const length = Buffer.byteLength(data); + if (length > 123) { + throw new RangeError("The message must not be greater than 123 bytes"); + } + buf = Buffer.allocUnsafe(2 + length); + buf.writeUInt16BE(code, 0); + if (typeof data === "string") { + buf.write(data, 2); + } else if (isUint8Array(data)) { + buf.set(data, 2); + } else { + throw new TypeError("Second argument must be a string or a Uint8Array"); + } + } + const options = { + [kByteLength]: buf.length, + fin: true, + generateMask: this._generateMask, + mask, + maskBuffer: this._maskBuffer, + opcode: 8, + readOnly: false, + rsv1: false + }; + if (this._state !== DEFAULT) { + this.enqueue([this.dispatch, buf, false, options, cb]); + } else { + this.sendFrame(_Sender.frame(buf, options), cb); + } + } + /** + * Sends a ping message to the other peer. + * + * @param {*} data The message to send + * @param {Boolean} [mask=false] Specifies whether or not to mask `data` + * @param {Function} [cb] Callback + * @public + */ + ping(data, mask, cb) { + let byteLength; + let readOnly; + if (typeof data === "string") { + byteLength = Buffer.byteLength(data); + readOnly = false; + } else if (isBlob(data)) { + byteLength = data.size; + readOnly = false; + } else { + data = toBuffer(data); + byteLength = data.length; + readOnly = toBuffer.readOnly; + } + if (byteLength > 125) { + throw new RangeError("The data size must not be greater than 125 bytes"); + } + const options = { + [kByteLength]: byteLength, + fin: true, + generateMask: this._generateMask, + mask, + maskBuffer: this._maskBuffer, + opcode: 9, + readOnly, + rsv1: false + }; + if (isBlob(data)) { + if (this._state !== DEFAULT) { + this.enqueue([this.getBlobData, data, false, options, cb]); + } else { + this.getBlobData(data, false, options, cb); + } + } else if (this._state !== DEFAULT) { + this.enqueue([this.dispatch, data, false, options, cb]); + } else { + this.sendFrame(_Sender.frame(data, options), cb); + } + } + /** + * Sends a pong message to the other peer. + * + * @param {*} data The message to send + * @param {Boolean} [mask=false] Specifies whether or not to mask `data` + * @param {Function} [cb] Callback + * @public + */ + pong(data, mask, cb) { + let byteLength; + let readOnly; + if (typeof data === "string") { + byteLength = Buffer.byteLength(data); + readOnly = false; + } else if (isBlob(data)) { + byteLength = data.size; + readOnly = false; + } else { + data = toBuffer(data); + byteLength = data.length; + readOnly = toBuffer.readOnly; + } + if (byteLength > 125) { + throw new RangeError("The data size must not be greater than 125 bytes"); + } + const options = { + [kByteLength]: byteLength, + fin: true, + generateMask: this._generateMask, + mask, + maskBuffer: this._maskBuffer, + opcode: 10, + readOnly, + rsv1: false + }; + if (isBlob(data)) { + if (this._state !== DEFAULT) { + this.enqueue([this.getBlobData, data, false, options, cb]); + } else { + this.getBlobData(data, false, options, cb); + } + } else if (this._state !== DEFAULT) { + this.enqueue([this.dispatch, data, false, options, cb]); + } else { + this.sendFrame(_Sender.frame(data, options), cb); + } + } + /** + * Sends a data message to the other peer. + * + * @param {*} data The message to send + * @param {Object} options Options object + * @param {Boolean} [options.binary=false] Specifies whether `data` is binary + * or text + * @param {Boolean} [options.compress=false] Specifies whether or not to + * compress `data` + * @param {Boolean} [options.fin=false] Specifies whether the fragment is the + * last one + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Function} [cb] Callback + * @public + */ + send(data, options, cb) { + const perMessageDeflate = this._extensions[PerMessageDeflate2.extensionName]; + let opcode = options.binary ? 2 : 1; + let rsv1 = options.compress; + let byteLength; + let readOnly; + if (typeof data === "string") { + byteLength = Buffer.byteLength(data); + readOnly = false; + } else if (isBlob(data)) { + byteLength = data.size; + readOnly = false; + } else { + data = toBuffer(data); + byteLength = data.length; + readOnly = toBuffer.readOnly; + } + if (this._firstFragment) { + this._firstFragment = false; + if (rsv1 && perMessageDeflate && perMessageDeflate.params[perMessageDeflate._isServer ? "server_no_context_takeover" : "client_no_context_takeover"]) { + rsv1 = byteLength >= perMessageDeflate._threshold; + } + this._compress = rsv1; + } else { + rsv1 = false; + opcode = 0; + } + if (options.fin) this._firstFragment = true; + const opts = { + [kByteLength]: byteLength, + fin: options.fin, + generateMask: this._generateMask, + mask: options.mask, + maskBuffer: this._maskBuffer, + opcode, + readOnly, + rsv1 + }; + if (isBlob(data)) { + if (this._state !== DEFAULT) { + this.enqueue([this.getBlobData, data, this._compress, opts, cb]); + } else { + this.getBlobData(data, this._compress, opts, cb); + } + } else if (this._state !== DEFAULT) { + this.enqueue([this.dispatch, data, this._compress, opts, cb]); + } else { + this.dispatch(data, this._compress, opts, cb); + } + } + /** + * Gets the contents of a blob as binary data. + * + * @param {Blob} blob The blob + * @param {Boolean} [compress=false] Specifies whether or not to compress + * the data + * @param {Object} options Options object + * @param {Boolean} [options.fin=false] Specifies whether or not to set the + * FIN bit + * @param {Function} [options.generateMask] The function used to generate the + * masking key + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Buffer} [options.maskBuffer] The buffer used to store the masking + * key + * @param {Number} options.opcode The opcode + * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be + * modified + * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the + * RSV1 bit + * @param {Function} [cb] Callback + * @private + */ + getBlobData(blob, compress, options, cb) { + this._bufferedBytes += options[kByteLength]; + this._state = GET_BLOB_DATA; + blob.arrayBuffer().then((arrayBuffer) => { + if (this._socket.destroyed) { + const err = new Error( + "The socket was closed while the blob was being read" + ); + process.nextTick(callCallbacks, this, err, cb); + return; + } + this._bufferedBytes -= options[kByteLength]; + const data = toBuffer(arrayBuffer); + if (!compress) { + this._state = DEFAULT; + this.sendFrame(_Sender.frame(data, options), cb); + this.dequeue(); + } else { + this.dispatch(data, compress, options, cb); + } + }).catch((err) => { + process.nextTick(onError, this, err, cb); + }); + } + /** + * Dispatches a message. + * + * @param {(Buffer|String)} data The message to send + * @param {Boolean} [compress=false] Specifies whether or not to compress + * `data` + * @param {Object} options Options object + * @param {Boolean} [options.fin=false] Specifies whether or not to set the + * FIN bit + * @param {Function} [options.generateMask] The function used to generate the + * masking key + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Buffer} [options.maskBuffer] The buffer used to store the masking + * key + * @param {Number} options.opcode The opcode + * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be + * modified + * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the + * RSV1 bit + * @param {Function} [cb] Callback + * @private + */ + dispatch(data, compress, options, cb) { + if (!compress) { + this.sendFrame(_Sender.frame(data, options), cb); + return; + } + const perMessageDeflate = this._extensions[PerMessageDeflate2.extensionName]; + this._bufferedBytes += options[kByteLength]; + this._state = DEFLATING; + perMessageDeflate.compress(data, options.fin, (_, buf) => { + if (this._socket.destroyed) { + const err = new Error( + "The socket was closed while data was being compressed" + ); + callCallbacks(this, err, cb); + return; + } + this._bufferedBytes -= options[kByteLength]; + this._state = DEFAULT; + options.readOnly = false; + this.sendFrame(_Sender.frame(buf, options), cb); + this.dequeue(); + }); + } + /** + * Executes queued send operations. + * + * @private + */ + dequeue() { + while (this._state === DEFAULT && this._queue.length) { + const params = this._queue.shift(); + this._bufferedBytes -= params[3][kByteLength]; + Reflect.apply(params[0], this, params.slice(1)); + } + } + /** + * Enqueues a send operation. + * + * @param {Array} params Send operation parameters. + * @private + */ + enqueue(params) { + this._bufferedBytes += params[3][kByteLength]; + this._queue.push(params); + } + /** + * Sends a frame. + * + * @param {(Buffer | String)[]} list The frame to send + * @param {Function} [cb] Callback + * @private + */ + sendFrame(list, cb) { + if (list.length === 2) { + this._socket.cork(); + this._socket.write(list[0]); + this._socket.write(list[1], cb); + this._socket.uncork(); + } else { + this._socket.write(list[0], cb); + } + } + }; + module.exports = Sender2; + function callCallbacks(sender, err, cb) { + if (typeof cb === "function") cb(err); + for (let i = 0; i < sender._queue.length; i++) { + const params = sender._queue[i]; + const callback = params[params.length - 1]; + if (typeof callback === "function") callback(err); + } + } + function onError(sender, err, cb) { + callCallbacks(sender, err, cb); + sender.onerror(err); + } + } +}); + +// node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/event-target.js +var require_event_target = __commonJS({ + "node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/event-target.js"(exports, module) { + "use strict"; + var { kForOnEventAttribute, kListener } = require_constants(); + var kCode = Symbol("kCode"); + var kData = Symbol("kData"); + var kError = Symbol("kError"); + var kMessage = Symbol("kMessage"); + var kReason = Symbol("kReason"); + var kTarget = Symbol("kTarget"); + var kType = Symbol("kType"); + var kWasClean = Symbol("kWasClean"); + var Event = class { + /** + * Create a new `Event`. + * + * @param {String} type The name of the event + * @throws {TypeError} If the `type` argument is not specified + */ + constructor(type) { + this[kTarget] = null; + this[kType] = type; + } + /** + * @type {*} + */ + get target() { + return this[kTarget]; + } + /** + * @type {String} + */ + get type() { + return this[kType]; + } + }; + Object.defineProperty(Event.prototype, "target", { enumerable: true }); + Object.defineProperty(Event.prototype, "type", { enumerable: true }); + var CloseEvent = class extends Event { + /** + * Create a new `CloseEvent`. + * + * @param {String} type The name of the event + * @param {Object} [options] A dictionary object that allows for setting + * attributes via object members of the same name + * @param {Number} [options.code=0] The status code explaining why the + * connection was closed + * @param {String} [options.reason=''] A human-readable string explaining why + * the connection was closed + * @param {Boolean} [options.wasClean=false] Indicates whether or not the + * connection was cleanly closed + */ + constructor(type, options = {}) { + super(type); + this[kCode] = options.code === void 0 ? 0 : options.code; + this[kReason] = options.reason === void 0 ? "" : options.reason; + this[kWasClean] = options.wasClean === void 0 ? false : options.wasClean; + } + /** + * @type {Number} + */ + get code() { + return this[kCode]; + } + /** + * @type {String} + */ + get reason() { + return this[kReason]; + } + /** + * @type {Boolean} + */ + get wasClean() { + return this[kWasClean]; + } + }; + Object.defineProperty(CloseEvent.prototype, "code", { enumerable: true }); + Object.defineProperty(CloseEvent.prototype, "reason", { enumerable: true }); + Object.defineProperty(CloseEvent.prototype, "wasClean", { enumerable: true }); + var ErrorEvent = class extends Event { + /** + * Create a new `ErrorEvent`. + * + * @param {String} type The name of the event + * @param {Object} [options] A dictionary object that allows for setting + * attributes via object members of the same name + * @param {*} [options.error=null] The error that generated this event + * @param {String} [options.message=''] The error message + */ + constructor(type, options = {}) { + super(type); + this[kError] = options.error === void 0 ? null : options.error; + this[kMessage] = options.message === void 0 ? "" : options.message; + } + /** + * @type {*} + */ + get error() { + return this[kError]; + } + /** + * @type {String} + */ + get message() { + return this[kMessage]; + } + }; + Object.defineProperty(ErrorEvent.prototype, "error", { enumerable: true }); + Object.defineProperty(ErrorEvent.prototype, "message", { enumerable: true }); + var MessageEvent = class extends Event { + /** + * Create a new `MessageEvent`. + * + * @param {String} type The name of the event + * @param {Object} [options] A dictionary object that allows for setting + * attributes via object members of the same name + * @param {*} [options.data=null] The message content + */ + constructor(type, options = {}) { + super(type); + this[kData] = options.data === void 0 ? null : options.data; + } + /** + * @type {*} + */ + get data() { + return this[kData]; + } + }; + Object.defineProperty(MessageEvent.prototype, "data", { enumerable: true }); + var EventTarget = { + /** + * Register an event listener. + * + * @param {String} type A string representing the event type to listen for + * @param {(Function|Object)} handler The listener to add + * @param {Object} [options] An options object specifies characteristics about + * the event listener + * @param {Boolean} [options.once=false] A `Boolean` indicating that the + * listener should be invoked at most once after being added. If `true`, + * the listener would be automatically removed when invoked. + * @public + */ + addEventListener(type, handler, options = {}) { + for (const listener of this.listeners(type)) { + if (!options[kForOnEventAttribute] && listener[kListener] === handler && !listener[kForOnEventAttribute]) { + return; + } + } + let wrapper; + if (type === "message") { + wrapper = function onMessage(data, isBinary) { + const event = new MessageEvent("message", { + data: isBinary ? data : data.toString() + }); + event[kTarget] = this; + callListener(handler, this, event); + }; + } else if (type === "close") { + wrapper = function onClose(code, message) { + const event = new CloseEvent("close", { + code, + reason: message.toString(), + wasClean: this._closeFrameReceived && this._closeFrameSent + }); + event[kTarget] = this; + callListener(handler, this, event); + }; + } else if (type === "error") { + wrapper = function onError(error) { + const event = new ErrorEvent("error", { + error, + message: error.message + }); + event[kTarget] = this; + callListener(handler, this, event); + }; + } else if (type === "open") { + wrapper = function onOpen() { + const event = new Event("open"); + event[kTarget] = this; + callListener(handler, this, event); + }; + } else { + return; + } + wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute]; + wrapper[kListener] = handler; + if (options.once) { + this.once(type, wrapper); + } else { + this.on(type, wrapper); + } + }, + /** + * Remove an event listener. + * + * @param {String} type A string representing the event type to remove + * @param {(Function|Object)} handler The listener to remove + * @public + */ + removeEventListener(type, handler) { + for (const listener of this.listeners(type)) { + if (listener[kListener] === handler && !listener[kForOnEventAttribute]) { + this.removeListener(type, listener); + break; + } + } + } + }; + module.exports = { + CloseEvent, + ErrorEvent, + Event, + EventTarget, + MessageEvent + }; + function callListener(listener, thisArg, event) { + if (typeof listener === "object" && listener.handleEvent) { + listener.handleEvent.call(listener, event); + } else { + listener.call(thisArg, event); + } + } + } +}); + +// node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/extension.js +var require_extension = __commonJS({ + "node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/extension.js"(exports, module) { + "use strict"; + var { tokenChars } = require_validation(); + function push(dest, name17, elem) { + if (dest[name17] === void 0) dest[name17] = [elem]; + else dest[name17].push(elem); + } + function parse(header) { + const offers = /* @__PURE__ */ Object.create(null); + let params = /* @__PURE__ */ Object.create(null); + let mustUnescape = false; + let isEscaping = false; + let inQuotes = false; + let extensionName; + let paramName; + let start = -1; + let code = -1; + let end = -1; + let i = 0; + for (; i < header.length; i++) { + code = header.charCodeAt(i); + if (extensionName === void 0) { + if (end === -1 && tokenChars[code] === 1) { + if (start === -1) start = i; + } else if (i !== 0 && (code === 32 || code === 9)) { + if (end === -1 && start !== -1) end = i; + } else if (code === 59 || code === 44) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (end === -1) end = i; + const name17 = header.slice(start, end); + if (code === 44) { + push(offers, name17, params); + params = /* @__PURE__ */ Object.create(null); + } else { + extensionName = name17; + } + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } else if (paramName === void 0) { + if (end === -1 && tokenChars[code] === 1) { + if (start === -1) start = i; + } else if (code === 32 || code === 9) { + if (end === -1 && start !== -1) end = i; + } else if (code === 59 || code === 44) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (end === -1) end = i; + push(params, header.slice(start, end), true); + if (code === 44) { + push(offers, extensionName, params); + params = /* @__PURE__ */ Object.create(null); + extensionName = void 0; + } + start = end = -1; + } else if (code === 61 && start !== -1 && end === -1) { + paramName = header.slice(start, i); + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } else { + if (isEscaping) { + if (tokenChars[code] !== 1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (start === -1) start = i; + else if (!mustUnescape) mustUnescape = true; + isEscaping = false; + } else if (inQuotes) { + if (tokenChars[code] === 1) { + if (start === -1) start = i; + } else if (code === 34 && start !== -1) { + inQuotes = false; + end = i; + } else if (code === 92) { + isEscaping = true; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } else if (code === 34 && header.charCodeAt(i - 1) === 61) { + inQuotes = true; + } else if (end === -1 && tokenChars[code] === 1) { + if (start === -1) start = i; + } else if (start !== -1 && (code === 32 || code === 9)) { + if (end === -1) end = i; + } else if (code === 59 || code === 44) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (end === -1) end = i; + let value = header.slice(start, end); + if (mustUnescape) { + value = value.replace(/\\/g, ""); + mustUnescape = false; + } + push(params, paramName, value); + if (code === 44) { + push(offers, extensionName, params); + params = /* @__PURE__ */ Object.create(null); + extensionName = void 0; + } + paramName = void 0; + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } + } + if (start === -1 || inQuotes || code === 32 || code === 9) { + throw new SyntaxError("Unexpected end of input"); + } + if (end === -1) end = i; + const token = header.slice(start, end); + if (extensionName === void 0) { + push(offers, token, params); + } else { + if (paramName === void 0) { + push(params, token, true); + } else if (mustUnescape) { + push(params, paramName, token.replace(/\\/g, "")); + } else { + push(params, paramName, token); + } + push(offers, extensionName, params); + } + return offers; + } + function format(extensions) { + return Object.keys(extensions).map((extension2) => { + let configurations = extensions[extension2]; + if (!Array.isArray(configurations)) configurations = [configurations]; + return configurations.map((params) => { + return [extension2].concat( + Object.keys(params).map((k) => { + let values = params[k]; + if (!Array.isArray(values)) values = [values]; + return values.map((v) => v === true ? k : `${k}=${v}`).join("; "); + }) + ).join("; "); + }).join(", "); + }).join(", "); + } + module.exports = { format, parse }; + } +}); + +// node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/websocket.js +var require_websocket = __commonJS({ + "node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/websocket.js"(exports, module) { + "use strict"; + var EventEmitter = __require("events"); + var https = __require("https"); + var http = __require("http"); + var net = __require("net"); + var tls = __require("tls"); + var { randomBytes, createHash } = __require("crypto"); + var { Duplex, Readable: Readable3 } = __require("stream"); + var { URL: URL2 } = __require("url"); + var PerMessageDeflate2 = require_permessage_deflate(); + var Receiver2 = require_receiver(); + var Sender2 = require_sender(); + var { isBlob } = require_validation(); + var { + BINARY_TYPES, + CLOSE_TIMEOUT, + EMPTY_BUFFER, + GUID, + kForOnEventAttribute, + kListener, + kStatusCode, + kWebSocket, + NOOP + } = require_constants(); + var { + EventTarget: { addEventListener: addEventListener2, removeEventListener } + } = require_event_target(); + var { format, parse } = require_extension(); + var { toBuffer } = require_buffer_util(); + var kAborted = Symbol("kAborted"); + var protocolVersions = [8, 13]; + var readyStates = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"]; + var subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/; + var WebSocket2 = class _WebSocket extends EventEmitter { + /** + * Create a new `WebSocket`. + * + * @param {(String|URL)} address The URL to which to connect + * @param {(String|String[])} [protocols] The subprotocols + * @param {Object} [options] Connection options + */ + constructor(address, protocols, options) { + super(); + this._binaryType = BINARY_TYPES[0]; + this._closeCode = 1006; + this._closeFrameReceived = false; + this._closeFrameSent = false; + this._closeMessage = EMPTY_BUFFER; + this._closeTimer = null; + this._errorEmitted = false; + this._extensions = {}; + this._paused = false; + this._protocol = ""; + this._readyState = _WebSocket.CONNECTING; + this._receiver = null; + this._sender = null; + this._socket = null; + if (address !== null) { + this._bufferedAmount = 0; + this._isServer = false; + this._redirects = 0; + if (protocols === void 0) { + protocols = []; + } else if (!Array.isArray(protocols)) { + if (typeof protocols === "object" && protocols !== null) { + options = protocols; + protocols = []; + } else { + protocols = [protocols]; + } + } + initAsClient(this, address, protocols, options); + } else { + this._autoPong = options.autoPong; + this._closeTimeout = options.closeTimeout; + this._isServer = true; + } + } + /** + * For historical reasons, the custom "nodebuffer" type is used by the default + * instead of "blob". + * + * @type {String} + */ + get binaryType() { + return this._binaryType; + } + set binaryType(type) { + if (!BINARY_TYPES.includes(type)) return; + this._binaryType = type; + if (this._receiver) this._receiver._binaryType = type; + } + /** + * @type {Number} + */ + get bufferedAmount() { + if (!this._socket) return this._bufferedAmount; + return this._socket._writableState.length + this._sender._bufferedBytes; + } + /** + * @type {String} + */ + get extensions() { + return Object.keys(this._extensions).join(); + } + /** + * @type {Boolean} + */ + get isPaused() { + return this._paused; + } + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onclose() { + return null; + } + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onerror() { + return null; + } + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onopen() { + return null; + } + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onmessage() { + return null; + } + /** + * @type {String} + */ + get protocol() { + return this._protocol; + } + /** + * @type {Number} + */ + get readyState() { + return this._readyState; + } + /** + * @type {String} + */ + get url() { + return this._url; + } + /** + * Set up the socket and the internal resources. + * + * @param {Duplex} socket The network socket between the server and client + * @param {Buffer} head The first packet of the upgraded stream + * @param {Object} options Options object + * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether + * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted + * multiple times in the same tick + * @param {Function} [options.generateMask] The function used to generate the + * masking key + * @param {Number} [options.maxBufferedChunks=0] The maximum number of + * buffered data chunks + * @param {Number} [options.maxFragments=0] The maximum number of message + * fragments + * @param {Number} [options.maxPayload=0] The maximum allowed message size + * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or + * not to skip UTF-8 validation for text and close messages + * @private + */ + setSocket(socket, head, options) { + const receiver = new Receiver2({ + allowSynchronousEvents: options.allowSynchronousEvents, + binaryType: this.binaryType, + extensions: this._extensions, + isServer: this._isServer, + maxBufferedChunks: options.maxBufferedChunks, + maxFragments: options.maxFragments, + maxPayload: options.maxPayload, + skipUTF8Validation: options.skipUTF8Validation + }); + const sender = new Sender2(socket, this._extensions, options.generateMask); + this._receiver = receiver; + this._sender = sender; + this._socket = socket; + receiver[kWebSocket] = this; + sender[kWebSocket] = this; + socket[kWebSocket] = this; + receiver.on("conclude", receiverOnConclude); + receiver.on("drain", receiverOnDrain); + receiver.on("error", receiverOnError); + receiver.on("message", receiverOnMessage); + receiver.on("ping", receiverOnPing); + receiver.on("pong", receiverOnPong); + sender.onerror = senderOnError; + if (socket.setTimeout) socket.setTimeout(0); + if (socket.setNoDelay) socket.setNoDelay(); + if (head.length > 0) socket.unshift(head); + socket.on("close", socketOnClose); + socket.on("data", socketOnData); + socket.on("end", socketOnEnd); + socket.on("error", socketOnError); + this._readyState = _WebSocket.OPEN; + this.emit("open"); + } + /** + * Emit the `'close'` event. + * + * @private + */ + emitClose() { + if (!this._socket) { + this._readyState = _WebSocket.CLOSED; + this.emit("close", this._closeCode, this._closeMessage); + return; + } + if (this._extensions[PerMessageDeflate2.extensionName]) { + this._extensions[PerMessageDeflate2.extensionName].cleanup(); + } + this._receiver.removeAllListeners(); + this._readyState = _WebSocket.CLOSED; + this.emit("close", this._closeCode, this._closeMessage); + } + /** + * Start a closing handshake. + * + * +----------+ +-----------+ +----------+ + * - - -|ws.close()|-->|close frame|-->|ws.close()|- - - + * | +----------+ +-----------+ +----------+ | + * +----------+ +-----------+ | + * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING + * +----------+ +-----------+ | + * | | | +---+ | + * +------------------------+-->|fin| - - - - + * | +---+ | +---+ + * - - - - -|fin|<---------------------+ + * +---+ + * + * @param {Number} [code] Status code explaining why the connection is closing + * @param {(String|Buffer)} [data] The reason why the connection is + * closing + * @public + */ + close(code, data) { + if (this.readyState === _WebSocket.CLOSED) return; + if (this.readyState === _WebSocket.CONNECTING) { + const msg = "WebSocket was closed before the connection was established"; + abortHandshake(this, this._req, msg); + return; + } + if (this.readyState === _WebSocket.CLOSING) { + if (this._closeFrameSent && (this._closeFrameReceived || this._receiver._writableState.errorEmitted)) { + this._socket.end(); + } + return; + } + this._readyState = _WebSocket.CLOSING; + this._sender.close(code, data, !this._isServer, (err) => { + if (err) return; + this._closeFrameSent = true; + if (this._closeFrameReceived || this._receiver._writableState.errorEmitted) { + this._socket.end(); + } + }); + setCloseTimer(this); + } + /** + * Pause the socket. + * + * @public + */ + pause() { + if (this.readyState === _WebSocket.CONNECTING || this.readyState === _WebSocket.CLOSED) { + return; + } + this._paused = true; + this._socket.pause(); + } + /** + * Send a ping. + * + * @param {*} [data] The data to send + * @param {Boolean} [mask] Indicates whether or not to mask `data` + * @param {Function} [cb] Callback which is executed when the ping is sent + * @public + */ + ping(data, mask, cb) { + if (this.readyState === _WebSocket.CONNECTING) { + throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); + } + if (typeof data === "function") { + cb = data; + data = mask = void 0; + } else if (typeof mask === "function") { + cb = mask; + mask = void 0; + } + if (typeof data === "number") data = data.toString(); + if (this.readyState !== _WebSocket.OPEN) { + sendAfterClose(this, data, cb); + return; + } + if (mask === void 0) mask = !this._isServer; + this._sender.ping(data || EMPTY_BUFFER, mask, cb); + } + /** + * Send a pong. + * + * @param {*} [data] The data to send + * @param {Boolean} [mask] Indicates whether or not to mask `data` + * @param {Function} [cb] Callback which is executed when the pong is sent + * @public + */ + pong(data, mask, cb) { + if (this.readyState === _WebSocket.CONNECTING) { + throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); + } + if (typeof data === "function") { + cb = data; + data = mask = void 0; + } else if (typeof mask === "function") { + cb = mask; + mask = void 0; + } + if (typeof data === "number") data = data.toString(); + if (this.readyState !== _WebSocket.OPEN) { + sendAfterClose(this, data, cb); + return; + } + if (mask === void 0) mask = !this._isServer; + this._sender.pong(data || EMPTY_BUFFER, mask, cb); + } + /** + * Resume the socket. + * + * @public + */ + resume() { + if (this.readyState === _WebSocket.CONNECTING || this.readyState === _WebSocket.CLOSED) { + return; + } + this._paused = false; + if (!this._receiver._writableState.needDrain) this._socket.resume(); + } + /** + * Send a data message. + * + * @param {*} data The message to send + * @param {Object} [options] Options object + * @param {Boolean} [options.binary] Specifies whether `data` is binary or + * text + * @param {Boolean} [options.compress] Specifies whether or not to compress + * `data` + * @param {Boolean} [options.fin=true] Specifies whether the fragment is the + * last one + * @param {Boolean} [options.mask] Specifies whether or not to mask `data` + * @param {Function} [cb] Callback which is executed when data is written out + * @public + */ + send(data, options, cb) { + if (this.readyState === _WebSocket.CONNECTING) { + throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); + } + if (typeof options === "function") { + cb = options; + options = {}; + } + if (typeof data === "number") data = data.toString(); + if (this.readyState !== _WebSocket.OPEN) { + sendAfterClose(this, data, cb); + return; + } + const opts = { + binary: typeof data !== "string", + mask: !this._isServer, + compress: true, + fin: true, + ...options + }; + if (!this._extensions[PerMessageDeflate2.extensionName]) { + opts.compress = false; + } + this._sender.send(data || EMPTY_BUFFER, opts, cb); + } + /** + * Forcibly close the connection. + * + * @public + */ + terminate() { + if (this.readyState === _WebSocket.CLOSED) return; + if (this.readyState === _WebSocket.CONNECTING) { + const msg = "WebSocket was closed before the connection was established"; + abortHandshake(this, this._req, msg); + return; + } + if (this._socket) { + this._readyState = _WebSocket.CLOSING; + this._socket.destroy(); + } + } + }; + Object.defineProperty(WebSocket2, "CONNECTING", { + enumerable: true, + value: readyStates.indexOf("CONNECTING") + }); + Object.defineProperty(WebSocket2.prototype, "CONNECTING", { + enumerable: true, + value: readyStates.indexOf("CONNECTING") + }); + Object.defineProperty(WebSocket2, "OPEN", { + enumerable: true, + value: readyStates.indexOf("OPEN") + }); + Object.defineProperty(WebSocket2.prototype, "OPEN", { + enumerable: true, + value: readyStates.indexOf("OPEN") + }); + Object.defineProperty(WebSocket2, "CLOSING", { + enumerable: true, + value: readyStates.indexOf("CLOSING") + }); + Object.defineProperty(WebSocket2.prototype, "CLOSING", { + enumerable: true, + value: readyStates.indexOf("CLOSING") + }); + Object.defineProperty(WebSocket2, "CLOSED", { + enumerable: true, + value: readyStates.indexOf("CLOSED") + }); + Object.defineProperty(WebSocket2.prototype, "CLOSED", { + enumerable: true, + value: readyStates.indexOf("CLOSED") + }); + [ + "binaryType", + "bufferedAmount", + "extensions", + "isPaused", + "protocol", + "readyState", + "url" + ].forEach((property) => { + Object.defineProperty(WebSocket2.prototype, property, { enumerable: true }); + }); + ["open", "error", "close", "message"].forEach((method) => { + Object.defineProperty(WebSocket2.prototype, `on${method}`, { + enumerable: true, + get() { + for (const listener of this.listeners(method)) { + if (listener[kForOnEventAttribute]) return listener[kListener]; + } + return null; + }, + set(handler) { + for (const listener of this.listeners(method)) { + if (listener[kForOnEventAttribute]) { + this.removeListener(method, listener); + break; + } + } + if (typeof handler !== "function") return; + this.addEventListener(method, handler, { + [kForOnEventAttribute]: true + }); + } + }); + }); + WebSocket2.prototype.addEventListener = addEventListener2; + WebSocket2.prototype.removeEventListener = removeEventListener; + module.exports = WebSocket2; + function initAsClient(websocket, address, protocols, options) { + const opts = { + allowSynchronousEvents: true, + autoPong: true, + closeTimeout: CLOSE_TIMEOUT, + protocolVersion: protocolVersions[1], + maxBufferedChunks: 256 * 1024, + maxFragments: 16 * 1024, + maxPayload: 100 * 1024 * 1024, + skipUTF8Validation: false, + perMessageDeflate: true, + followRedirects: false, + maxRedirects: 10, + ...options, + socketPath: void 0, + hostname: void 0, + protocol: void 0, + timeout: void 0, + method: "GET", + host: void 0, + path: void 0, + port: void 0 + }; + websocket._autoPong = opts.autoPong; + websocket._closeTimeout = opts.closeTimeout; + if (!protocolVersions.includes(opts.protocolVersion)) { + throw new RangeError( + `Unsupported protocol version: ${opts.protocolVersion} (supported versions: ${protocolVersions.join(", ")})` + ); + } + let parsedUrl; + if (address instanceof URL2) { + parsedUrl = address; + } else { + try { + parsedUrl = new URL2(address); + } catch { + throw new SyntaxError(`Invalid URL: ${address}`); + } + } + if (parsedUrl.protocol === "http:") { + parsedUrl.protocol = "ws:"; + } else if (parsedUrl.protocol === "https:") { + parsedUrl.protocol = "wss:"; + } + websocket._url = parsedUrl.href; + const isSecure = parsedUrl.protocol === "wss:"; + const isIpcUrl = parsedUrl.protocol === "ws+unix:"; + let invalidUrlMessage; + if (parsedUrl.protocol !== "ws:" && !isSecure && !isIpcUrl) { + invalidUrlMessage = `The URL's protocol must be one of "ws:", "wss:", "http:", "https:", or "ws+unix:"`; + } else if (isIpcUrl && !parsedUrl.pathname) { + invalidUrlMessage = "The URL's pathname is empty"; + } else if (parsedUrl.hash) { + invalidUrlMessage = "The URL contains a fragment identifier"; + } + if (invalidUrlMessage) { + const err = new SyntaxError(invalidUrlMessage); + if (websocket._redirects === 0) { + throw err; + } else { + emitErrorAndClose(websocket, err); + return; + } + } + const defaultPort = isSecure ? 443 : 80; + const key = randomBytes(16).toString("base64"); + const request = isSecure ? https.request : http.request; + const protocolSet = /* @__PURE__ */ new Set(); + let perMessageDeflate; + opts.createConnection = opts.createConnection || (isSecure ? tlsConnect : netConnect); + opts.defaultPort = opts.defaultPort || defaultPort; + opts.port = parsedUrl.port || defaultPort; + opts.host = parsedUrl.hostname.startsWith("[") ? parsedUrl.hostname.slice(1, -1) : parsedUrl.hostname; + opts.headers = { + ...opts.headers, + "Sec-WebSocket-Version": opts.protocolVersion, + "Sec-WebSocket-Key": key, + Connection: "Upgrade", + Upgrade: "websocket" + }; + opts.path = parsedUrl.pathname + parsedUrl.search; + opts.timeout = opts.handshakeTimeout; + if (opts.perMessageDeflate) { + perMessageDeflate = new PerMessageDeflate2({ + ...opts.perMessageDeflate, + isServer: false, + maxPayload: opts.maxPayload + }); + opts.headers["Sec-WebSocket-Extensions"] = format({ + [PerMessageDeflate2.extensionName]: perMessageDeflate.offer() + }); + } + if (protocols.length) { + for (const protocol of protocols) { + if (typeof protocol !== "string" || !subprotocolRegex.test(protocol) || protocolSet.has(protocol)) { + throw new SyntaxError( + "An invalid or duplicated subprotocol was specified" + ); + } + protocolSet.add(protocol); + } + opts.headers["Sec-WebSocket-Protocol"] = protocols.join(","); + } + if (opts.origin) { + if (opts.protocolVersion < 13) { + opts.headers["Sec-WebSocket-Origin"] = opts.origin; + } else { + opts.headers.Origin = opts.origin; + } + } + if (parsedUrl.username || parsedUrl.password) { + opts.auth = `${parsedUrl.username}:${parsedUrl.password}`; + } + if (isIpcUrl) { + const parts = opts.path.split(":"); + opts.socketPath = parts[0]; + opts.path = parts[1]; + } + let req; + if (opts.followRedirects) { + if (websocket._redirects === 0) { + websocket._originalIpc = isIpcUrl; + websocket._originalSecure = isSecure; + websocket._originalHostOrSocketPath = isIpcUrl ? opts.socketPath : parsedUrl.host; + const headers = options && options.headers; + options = { ...options, headers: {} }; + if (headers) { + for (const [key2, value] of Object.entries(headers)) { + options.headers[key2.toLowerCase()] = value; + } + } + } else if (websocket.listenerCount("redirect") === 0) { + const isSameHost = isIpcUrl ? websocket._originalIpc ? opts.socketPath === websocket._originalHostOrSocketPath : false : websocket._originalIpc ? false : parsedUrl.host === websocket._originalHostOrSocketPath; + if (!isSameHost || websocket._originalSecure && !isSecure) { + delete opts.headers.authorization; + delete opts.headers.cookie; + if (!isSameHost) delete opts.headers.host; + opts.auth = void 0; + } + } + if (opts.auth && !options.headers.authorization) { + options.headers.authorization = "Basic " + Buffer.from(opts.auth).toString("base64"); + } + req = websocket._req = request(opts); + if (websocket._redirects) { + websocket.emit("redirect", websocket.url, req); + } + } else { + req = websocket._req = request(opts); + } + if (opts.timeout) { + req.on("timeout", () => { + abortHandshake(websocket, req, "Opening handshake has timed out"); + }); + } + req.on("error", (err) => { + if (req === null || req[kAborted]) return; + req = websocket._req = null; + emitErrorAndClose(websocket, err); + }); + req.on("response", (res) => { + const location = res.headers.location; + const statusCode = res.statusCode; + if (location && opts.followRedirects && statusCode >= 300 && statusCode < 400) { + if (++websocket._redirects > opts.maxRedirects) { + abortHandshake(websocket, req, "Maximum redirects exceeded"); + return; + } + req.abort(); + let addr; + try { + addr = new URL2(location, address); + } catch (e) { + const err = new SyntaxError(`Invalid URL: ${location}`); + emitErrorAndClose(websocket, err); + return; + } + initAsClient(websocket, addr, protocols, options); + } else if (!websocket.emit("unexpected-response", req, res)) { + abortHandshake( + websocket, + req, + `Unexpected server response: ${res.statusCode}` + ); + } + }); + req.on("upgrade", (res, socket, head) => { + websocket.emit("upgrade", res); + if (websocket.readyState !== WebSocket2.CONNECTING) return; + req = websocket._req = null; + const upgrade = res.headers.upgrade; + if (upgrade === void 0 || upgrade.toLowerCase() !== "websocket") { + abortHandshake(websocket, socket, "Invalid Upgrade header"); + return; + } + const digest = createHash("sha1").update(key + GUID).digest("base64"); + if (res.headers["sec-websocket-accept"] !== digest) { + abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header"); + return; + } + const serverProt = res.headers["sec-websocket-protocol"]; + let protError; + if (serverProt !== void 0) { + if (!protocolSet.size) { + protError = "Server sent a subprotocol but none was requested"; + } else if (!protocolSet.has(serverProt)) { + protError = "Server sent an invalid subprotocol"; + } + } else if (protocolSet.size) { + protError = "Server sent no subprotocol"; + } + if (protError) { + abortHandshake(websocket, socket, protError); + return; + } + if (serverProt) websocket._protocol = serverProt; + const secWebSocketExtensions = res.headers["sec-websocket-extensions"]; + if (secWebSocketExtensions !== void 0) { + if (!perMessageDeflate) { + const message = "Server sent a Sec-WebSocket-Extensions header but no extension was requested"; + abortHandshake(websocket, socket, message); + return; + } + let extensions; + try { + extensions = parse(secWebSocketExtensions); + } catch (err) { + const message = "Invalid Sec-WebSocket-Extensions header"; + abortHandshake(websocket, socket, message); + return; + } + const extensionNames = Object.keys(extensions); + if (extensionNames.length !== 1 || extensionNames[0] !== PerMessageDeflate2.extensionName) { + const message = "Server indicated an extension that was not requested"; + abortHandshake(websocket, socket, message); + return; + } + try { + perMessageDeflate.accept(extensions[PerMessageDeflate2.extensionName]); + } catch (err) { + const message = "Invalid Sec-WebSocket-Extensions header"; + abortHandshake(websocket, socket, message); + return; + } + websocket._extensions[PerMessageDeflate2.extensionName] = perMessageDeflate; + } + websocket.setSocket(socket, head, { + allowSynchronousEvents: opts.allowSynchronousEvents, + generateMask: opts.generateMask, + maxBufferedChunks: opts.maxBufferedChunks, + maxFragments: opts.maxFragments, + maxPayload: opts.maxPayload, + skipUTF8Validation: opts.skipUTF8Validation + }); + }); + if (opts.finishRequest) { + opts.finishRequest(req, websocket); + } else { + req.end(); + } + } + function emitErrorAndClose(websocket, err) { + websocket._readyState = WebSocket2.CLOSING; + websocket._errorEmitted = true; + websocket.emit("error", err); + websocket.emitClose(); + } + function netConnect(options) { + options.path = options.socketPath; + return net.connect(options); + } + function tlsConnect(options) { + options.path = void 0; + if (!options.servername && options.servername !== "") { + options.servername = net.isIP(options.host) ? "" : options.host; + } + return tls.connect(options); + } + function abortHandshake(websocket, stream, message) { + websocket._readyState = WebSocket2.CLOSING; + const err = new Error(message); + Error.captureStackTrace(err, abortHandshake); + if (stream.setHeader) { + stream[kAborted] = true; + stream.abort(); + if (stream.socket && !stream.socket.destroyed) { + stream.socket.destroy(); + } + process.nextTick(emitErrorAndClose, websocket, err); + } else { + stream.destroy(err); + stream.once("error", websocket.emit.bind(websocket, "error")); + stream.once("close", websocket.emitClose.bind(websocket)); + } + } + function sendAfterClose(websocket, data, cb) { + if (data) { + const length = isBlob(data) ? data.size : toBuffer(data).length; + if (websocket._socket) websocket._sender._bufferedBytes += length; + else websocket._bufferedAmount += length; + } + if (cb) { + const err = new Error( + `WebSocket is not open: readyState ${websocket.readyState} (${readyStates[websocket.readyState]})` + ); + process.nextTick(cb, err); + } + } + function receiverOnConclude(code, reason) { + const websocket = this[kWebSocket]; + websocket._closeFrameReceived = true; + websocket._closeMessage = reason; + websocket._closeCode = code; + if (websocket._socket[kWebSocket] === void 0) return; + websocket._socket.removeListener("data", socketOnData); + process.nextTick(resume, websocket._socket); + if (code === 1005) websocket.close(); + else websocket.close(code, reason); + } + function receiverOnDrain() { + const websocket = this[kWebSocket]; + if (!websocket.isPaused) websocket._socket.resume(); + } + function receiverOnError(err) { + const websocket = this[kWebSocket]; + if (websocket._socket[kWebSocket] !== void 0) { + websocket._socket.removeListener("data", socketOnData); + process.nextTick(resume, websocket._socket); + websocket.close(err[kStatusCode]); + } + if (!websocket._errorEmitted) { + websocket._errorEmitted = true; + websocket.emit("error", err); + } + } + function receiverOnFinish() { + this[kWebSocket].emitClose(); + } + function receiverOnMessage(data, isBinary) { + this[kWebSocket].emit("message", data, isBinary); + } + function receiverOnPing(data) { + const websocket = this[kWebSocket]; + if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP); + websocket.emit("ping", data); + } + function receiverOnPong(data) { + this[kWebSocket].emit("pong", data); + } + function resume(stream) { + stream.resume(); + } + function senderOnError(err) { + const websocket = this[kWebSocket]; + if (websocket.readyState === WebSocket2.CLOSED) return; + if (websocket.readyState === WebSocket2.OPEN) { + websocket._readyState = WebSocket2.CLOSING; + setCloseTimer(websocket); + } + this._socket.end(); + if (!websocket._errorEmitted) { + websocket._errorEmitted = true; + websocket.emit("error", err); + } + } + function setCloseTimer(websocket) { + websocket._closeTimer = setTimeout( + websocket._socket.destroy.bind(websocket._socket), + websocket._closeTimeout + ); + } + function socketOnClose() { + const websocket = this[kWebSocket]; + this.removeListener("close", socketOnClose); + this.removeListener("data", socketOnData); + this.removeListener("end", socketOnEnd); + websocket._readyState = WebSocket2.CLOSING; + if (!this._readableState.endEmitted && !websocket._closeFrameReceived && !websocket._receiver._writableState.errorEmitted && this._readableState.length !== 0) { + const chunk = this.read(this._readableState.length); + websocket._receiver.write(chunk); + } + websocket._receiver.end(); + this[kWebSocket] = void 0; + clearTimeout(websocket._closeTimer); + if (websocket._receiver._writableState.finished || websocket._receiver._writableState.errorEmitted) { + websocket.emitClose(); + } else { + websocket._receiver.on("error", receiverOnFinish); + websocket._receiver.on("finish", receiverOnFinish); + } + } + function socketOnData(chunk) { + if (!this[kWebSocket]._receiver.write(chunk)) { + this.pause(); + } + } + function socketOnEnd() { + const websocket = this[kWebSocket]; + websocket._readyState = WebSocket2.CLOSING; + websocket._receiver.end(); + this.end(); + } + function socketOnError() { + const websocket = this[kWebSocket]; + this.removeListener("error", socketOnError); + this.on("error", NOOP); + if (websocket) { + websocket._readyState = WebSocket2.CLOSING; + this.destroy(); + } + } + } +}); + +// node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/stream.js +var require_stream = __commonJS({ + "node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/stream.js"(exports, module) { + "use strict"; + var WebSocket2 = require_websocket(); + var { Duplex } = __require("stream"); + function emitClose(stream) { + stream.emit("close"); + } + function duplexOnEnd() { + if (!this.destroyed && this._writableState.finished) { + this.destroy(); + } + } + function duplexOnError(err) { + this.removeListener("error", duplexOnError); + this.destroy(); + if (this.listenerCount("error") === 0) { + this.emit("error", err); + } + } + function createWebSocketStream2(ws, options) { + let terminateOnDestroy = true; + const duplex = new Duplex({ + ...options, + autoDestroy: false, + emitClose: false, + objectMode: false, + writableObjectMode: false + }); + ws.on("message", function message(msg, isBinary) { + const data = !isBinary && duplex._readableState.objectMode ? msg.toString() : msg; + if (!duplex.push(data)) ws.pause(); + }); + ws.once("error", function error(err) { + if (duplex.destroyed) return; + terminateOnDestroy = false; + duplex.destroy(err); + }); + ws.once("close", function close() { + if (duplex.destroyed) return; + duplex.push(null); + }); + duplex._destroy = function(err, callback) { + if (ws.readyState === ws.CLOSED) { + callback(err); + process.nextTick(emitClose, duplex); + return; + } + let called = false; + ws.once("error", function error(err2) { + called = true; + callback(err2); + }); + ws.once("close", function close() { + if (!called) callback(err); + process.nextTick(emitClose, duplex); + }); + if (terminateOnDestroy) ws.terminate(); + }; + duplex._final = function(callback) { + if (ws.readyState === ws.CONNECTING) { + ws.once("open", function open() { + duplex._final(callback); + }); + return; + } + if (ws._socket === null) return; + if (ws._socket._writableState.finished) { + callback(); + if (duplex._readableState.endEmitted) duplex.destroy(); + } else { + ws._socket.once("finish", function finish() { + callback(); + }); + ws.close(); + } + }; + duplex._read = function() { + if (ws.isPaused) ws.resume(); + }; + duplex._write = function(chunk, encoding, callback) { + if (ws.readyState === ws.CONNECTING) { + ws.once("open", function open() { + duplex._write(chunk, encoding, callback); + }); + return; + } + ws.send(chunk, callback); + }; + duplex.on("end", duplexOnEnd); + duplex.on("error", duplexOnError); + return duplex; + } + module.exports = createWebSocketStream2; + } +}); + +// node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/subprotocol.js +var require_subprotocol = __commonJS({ + "node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/subprotocol.js"(exports, module) { + "use strict"; + var { tokenChars } = require_validation(); + function parse(header) { + const protocols = /* @__PURE__ */ new Set(); + let start = -1; + let end = -1; + let i = 0; + for (i; i < header.length; i++) { + const code = header.charCodeAt(i); + if (end === -1 && tokenChars[code] === 1) { + if (start === -1) start = i; + } else if (i !== 0 && (code === 32 || code === 9)) { + if (end === -1 && start !== -1) end = i; + } else if (code === 44) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (end === -1) end = i; + const protocol2 = header.slice(start, end); + if (protocols.has(protocol2)) { + throw new SyntaxError(`The "${protocol2}" subprotocol is duplicated`); + } + protocols.add(protocol2); + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } + if (start === -1 || end !== -1) { + throw new SyntaxError("Unexpected end of input"); + } + const protocol = header.slice(start, i); + if (protocols.has(protocol)) { + throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`); + } + protocols.add(protocol); + return protocols; + } + module.exports = { parse }; + } +}); + +// node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/websocket-server.js +var require_websocket_server = __commonJS({ + "node_modules/.pnpm/ws@8.21.3/node_modules/ws/lib/websocket-server.js"(exports, module) { + "use strict"; + var EventEmitter = __require("events"); + var http = __require("http"); + var { Duplex } = __require("stream"); + var { createHash } = __require("crypto"); + var extension2 = require_extension(); + var PerMessageDeflate2 = require_permessage_deflate(); + var subprotocol2 = require_subprotocol(); + var WebSocket2 = require_websocket(); + var { CLOSE_TIMEOUT, GUID, kWebSocket } = require_constants(); + var keyRegex = /^[+/0-9A-Za-z]{22}==$/; + var RUNNING = 0; + var CLOSING = 1; + var CLOSED = 2; + var WebSocketServer2 = class extends EventEmitter { + /** + * Create a `WebSocketServer` instance. + * + * @param {Object} options Configuration options + * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether + * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted + * multiple times in the same tick + * @param {Boolean} [options.autoPong=true] Specifies whether or not to + * automatically send a pong in response to a ping + * @param {Number} [options.backlog=511] The maximum length of the queue of + * pending connections + * @param {Boolean} [options.clientTracking=true] Specifies whether or not to + * track clients + * @param {Number} [options.closeTimeout=30000] Duration in milliseconds to + * wait for the closing handshake to finish after `websocket.close()` is + * called + * @param {Function} [options.handleProtocols] A hook to handle protocols + * @param {String} [options.host] The hostname where to bind the server + * @param {Number} [options.maxBufferedChunks=262144] The maximum number of + * buffered data chunks + * @param {Number} [options.maxFragments=16384] The maximum number of message + * fragments + * @param {Number} [options.maxPayload=104857600] The maximum allowed message + * size + * @param {Boolean} [options.noServer=false] Enable no server mode + * @param {String} [options.path] Accept only connections matching this path + * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable + * permessage-deflate + * @param {Number} [options.port] The port where to bind the server + * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S + * server to use + * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or + * not to skip UTF-8 validation for text and close messages + * @param {Function} [options.verifyClient] A hook to reject connections + * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket` + * class to use. It must be the `WebSocket` class or class that extends it + * @param {Function} [callback] A listener for the `listening` event + */ + constructor(options, callback) { + super(); + options = { + allowSynchronousEvents: true, + autoPong: true, + maxBufferedChunks: 256 * 1024, + maxFragments: 16 * 1024, + maxPayload: 100 * 1024 * 1024, + skipUTF8Validation: false, + perMessageDeflate: false, + handleProtocols: null, + clientTracking: true, + closeTimeout: CLOSE_TIMEOUT, + verifyClient: null, + noServer: false, + backlog: null, + // use default (511 as implemented in net.js) + server: null, + host: null, + path: null, + port: null, + WebSocket: WebSocket2, + ...options + }; + if (options.port == null && !options.server && !options.noServer || options.port != null && (options.server || options.noServer) || options.server && options.noServer) { + throw new TypeError( + 'One and only one of the "port", "server", or "noServer" options must be specified' + ); + } + if (options.port != null) { + this._server = http.createServer((req, res) => { + const body = http.STATUS_CODES[426]; + res.writeHead(426, { + "Content-Length": body.length, + "Content-Type": "text/plain" + }); + res.end(body); + }); + this._server.listen( + options.port, + options.host, + options.backlog, + callback + ); + } else if (options.server) { + this._server = options.server; + } + if (this._server) { + const emitConnection = this.emit.bind(this, "connection"); + this._removeListeners = addListeners(this._server, { + listening: this.emit.bind(this, "listening"), + error: this.emit.bind(this, "error"), + upgrade: (req, socket, head) => { + this.handleUpgrade(req, socket, head, emitConnection); + } + }); + } + if (options.perMessageDeflate === true) options.perMessageDeflate = {}; + if (options.clientTracking) { + this.clients = /* @__PURE__ */ new Set(); + this._shouldEmitClose = false; + } + this.options = options; + this._state = RUNNING; + } + /** + * Returns the bound address, the address family name, and port of the server + * as reported by the operating system if listening on an IP socket. + * If the server is listening on a pipe or UNIX domain socket, the name is + * returned as a string. + * + * @return {(Object|String|null)} The address of the server + * @public + */ + address() { + if (this.options.noServer) { + throw new Error('The server is operating in "noServer" mode'); + } + if (!this._server) return null; + return this._server.address(); + } + /** + * Stop the server from accepting new connections and emit the `'close'` event + * when all existing connections are closed. + * + * @param {Function} [cb] A one-time listener for the `'close'` event + * @public + */ + close(cb) { + if (this._state === CLOSED) { + if (cb) { + this.once("close", () => { + cb(new Error("The server is not running")); + }); + } + process.nextTick(emitClose, this); + return; + } + if (cb) this.once("close", cb); + if (this._state === CLOSING) return; + this._state = CLOSING; + if (this.options.noServer || this.options.server) { + if (this._server) { + this._removeListeners(); + this._removeListeners = this._server = null; + } + if (this.clients) { + if (!this.clients.size) { + process.nextTick(emitClose, this); + } else { + this._shouldEmitClose = true; + } + } else { + process.nextTick(emitClose, this); + } + } else { + const server = this._server; + this._removeListeners(); + this._removeListeners = this._server = null; + server.close(() => { + emitClose(this); + }); + } + } + /** + * See if a given request should be handled by this server instance. + * + * @param {http.IncomingMessage} req Request object to inspect + * @return {Boolean} `true` if the request is valid, else `false` + * @public + */ + shouldHandle(req) { + if (this.options.path) { + const index = req.url.indexOf("?"); + const pathname = index !== -1 ? req.url.slice(0, index) : req.url; + if (pathname !== this.options.path) return false; + } + return true; + } + /** + * Handle a HTTP Upgrade request. + * + * @param {http.IncomingMessage} req The request object + * @param {Duplex} socket The network socket between the server and client + * @param {Buffer} head The first packet of the upgraded stream + * @param {Function} cb Callback + * @public + */ + handleUpgrade(req, socket, head, cb) { + socket.on("error", socketOnError); + const key = req.headers["sec-websocket-key"]; + const upgrade = req.headers.upgrade; + const version = +req.headers["sec-websocket-version"]; + if (req.method !== "GET") { + const message = "Invalid HTTP method"; + abortHandshakeOrEmitwsClientError(this, req, socket, 405, message); + return; + } + if (upgrade === void 0 || upgrade.toLowerCase() !== "websocket") { + const message = "Invalid Upgrade header"; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + if (key === void 0 || !keyRegex.test(key)) { + const message = "Missing or invalid Sec-WebSocket-Key header"; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + if (version !== 13 && version !== 8) { + const message = "Missing or invalid Sec-WebSocket-Version header"; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message, { + "Sec-WebSocket-Version": "13, 8" + }); + return; + } + if (!this.shouldHandle(req)) { + abortHandshake(socket, 400); + return; + } + const secWebSocketProtocol = req.headers["sec-websocket-protocol"]; + let protocols = /* @__PURE__ */ new Set(); + if (secWebSocketProtocol !== void 0) { + try { + protocols = subprotocol2.parse(secWebSocketProtocol); + } catch (err) { + const message = "Invalid Sec-WebSocket-Protocol header"; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + } + const secWebSocketExtensions = req.headers["sec-websocket-extensions"]; + const extensions = {}; + if (this.options.perMessageDeflate && secWebSocketExtensions !== void 0) { + const perMessageDeflate = new PerMessageDeflate2({ + ...this.options.perMessageDeflate, + isServer: true, + maxPayload: this.options.maxPayload + }); + try { + const offers = extension2.parse(secWebSocketExtensions); + if (offers[PerMessageDeflate2.extensionName]) { + perMessageDeflate.accept(offers[PerMessageDeflate2.extensionName]); + extensions[PerMessageDeflate2.extensionName] = perMessageDeflate; + } + } catch (err) { + const message = "Invalid or unacceptable Sec-WebSocket-Extensions header"; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + } + if (this.options.verifyClient) { + const info = { + origin: req.headers[`${version === 8 ? "sec-websocket-origin" : "origin"}`], + secure: !!(req.socket.authorized || req.socket.encrypted), + req + }; + if (this.options.verifyClient.length === 2) { + this.options.verifyClient(info, (verified, code, message, headers) => { + if (!verified) { + return abortHandshake(socket, code || 401, message, headers); + } + this.completeUpgrade( + extensions, + key, + protocols, + req, + socket, + head, + cb + ); + }); + return; + } + if (!this.options.verifyClient(info)) return abortHandshake(socket, 401); + } + this.completeUpgrade(extensions, key, protocols, req, socket, head, cb); + } + /** + * Upgrade the connection to WebSocket. + * + * @param {Object} extensions The accepted extensions + * @param {String} key The value of the `Sec-WebSocket-Key` header + * @param {Set} protocols The subprotocols + * @param {http.IncomingMessage} req The request object + * @param {Duplex} socket The network socket between the server and client + * @param {Buffer} head The first packet of the upgraded stream + * @param {Function} cb Callback + * @throws {Error} If called more than once with the same socket + * @private + */ + completeUpgrade(extensions, key, protocols, req, socket, head, cb) { + if (!socket.readable || !socket.writable) return socket.destroy(); + if (socket[kWebSocket]) { + throw new Error( + "server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration" + ); + } + if (this._state > RUNNING) return abortHandshake(socket, 503); + const digest = createHash("sha1").update(key + GUID).digest("base64"); + const headers = [ + "HTTP/1.1 101 Switching Protocols", + "Upgrade: websocket", + "Connection: Upgrade", + `Sec-WebSocket-Accept: ${digest}` + ]; + const ws = new this.options.WebSocket(null, void 0, this.options); + if (protocols.size) { + const protocol = this.options.handleProtocols ? this.options.handleProtocols(protocols, req) : protocols.values().next().value; + if (protocol) { + headers.push(`Sec-WebSocket-Protocol: ${protocol}`); + ws._protocol = protocol; + } + } + if (extensions[PerMessageDeflate2.extensionName]) { + const params = extensions[PerMessageDeflate2.extensionName].params; + const value = extension2.format({ + [PerMessageDeflate2.extensionName]: [params] + }); + headers.push(`Sec-WebSocket-Extensions: ${value}`); + ws._extensions = extensions; + } + this.emit("headers", headers, req); + socket.write(headers.concat("\r\n").join("\r\n")); + socket.removeListener("error", socketOnError); + ws.setSocket(socket, head, { + allowSynchronousEvents: this.options.allowSynchronousEvents, + maxBufferedChunks: this.options.maxBufferedChunks, + maxFragments: this.options.maxFragments, + maxPayload: this.options.maxPayload, + skipUTF8Validation: this.options.skipUTF8Validation + }); + if (this.clients) { + this.clients.add(ws); + ws.on("close", () => { + this.clients.delete(ws); + if (this._shouldEmitClose && !this.clients.size) { + process.nextTick(emitClose, this); + } + }); + } + cb(ws, req); + } + }; + module.exports = WebSocketServer2; + function addListeners(server, map) { + for (const event of Object.keys(map)) server.on(event, map[event]); + return function removeListeners() { + for (const event of Object.keys(map)) { + server.removeListener(event, map[event]); + } + }; + } + function emitClose(server) { + server._state = CLOSED; + server.emit("close"); + } + function socketOnError() { + this.destroy(); + } + function abortHandshake(socket, code, message, headers) { + message = message || http.STATUS_CODES[code]; + headers = { + Connection: "close", + "Content-Type": "text/html", + "Content-Length": Buffer.byteLength(message), + ...headers + }; + socket.once("finish", socket.destroy); + socket.end( + `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r +` + Object.keys(headers).map((h) => `${h}: ${headers[h]}`).join("\r\n") + "\r\n\r\n" + message + ); + } + function abortHandshakeOrEmitwsClientError(server, req, socket, code, message, headers) { + if (server.listenerCount("wsClientError")) { + const err = new Error(message); + Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError); + server.emit("wsClientError", err, socket, req); + } else { + abortHandshake(socket, code, message, headers); + } + } + } +}); + +// node_modules/.pnpm/secure-json-parse@2.7.0/node_modules/secure-json-parse/index.js +var require_secure_json_parse = __commonJS({ + "node_modules/.pnpm/secure-json-parse@2.7.0/node_modules/secure-json-parse/index.js"(exports, module) { + "use strict"; + var hasBuffer = typeof Buffer !== "undefined"; + var suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/; + var 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*:/; + function _parse(text2, reviver, options) { + if (options == null) { + if (reviver !== null && typeof reviver === "object") { + options = reviver; + reviver = void 0; + } + } + if (hasBuffer && Buffer.isBuffer(text2)) { + text2 = text2.toString(); + } + if (text2 && text2.charCodeAt(0) === 65279) { + text2 = text2.slice(1); + } + const obj = JSON.parse(text2, reviver); + if (obj === null || typeof obj !== "object") { + return obj; + } + const protoAction = options && options.protoAction || "error"; + const constructorAction = options && options.constructorAction || "error"; + if (protoAction === "ignore" && constructorAction === "ignore") { + return obj; + } + if (protoAction !== "ignore" && constructorAction !== "ignore") { + if (suspectProtoRx.test(text2) === false && suspectConstructorRx.test(text2) === false) { + return obj; + } + } else if (protoAction !== "ignore" && constructorAction === "ignore") { + if (suspectProtoRx.test(text2) === false) { + return obj; + } + } else { + if (suspectConstructorRx.test(text2) === false) { + return obj; + } + } + return filter(obj, { protoAction, constructorAction, safe: options && options.safe }); + } + function filter(obj, { protoAction = "error", constructorAction = "error", safe } = {}) { + let next = [obj]; + while (next.length) { + const nodes = next; + next = []; + for (const node of nodes) { + if (protoAction !== "ignore" && Object.prototype.hasOwnProperty.call(node, "__proto__")) { + if (safe === true) { + return null; + } else if (protoAction === "error") { + throw new SyntaxError("Object contains forbidden prototype property"); + } + delete node.__proto__; + } + if (constructorAction !== "ignore" && Object.prototype.hasOwnProperty.call(node, "constructor") && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) { + if (safe === true) { + return null; + } else if (constructorAction === "error") { + throw new SyntaxError("Object contains forbidden prototype property"); + } + delete node.constructor; + } + for (const key in node) { + const value = node[key]; + if (value && typeof value === "object") { + next.push(value); + } + } + } + } + return obj; + } + function parse(text2, reviver, options) { + const stackTraceLimit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; + try { + return _parse(text2, reviver, options); + } finally { + Error.stackTraceLimit = stackTraceLimit; + } + } + function safeParse(text2, reviver) { + const stackTraceLimit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; + try { + return _parse(text2, reviver, { safe: true }); + } catch (_e) { + return null; + } finally { + Error.stackTraceLimit = stackTraceLimit; + } + } + module.exports = parse; + module.exports.default = parse; + module.exports.parse = parse; + module.exports.safeParse = safeParse; + module.exports.scan = filter; + } +}); + +// node_modules/.pnpm/d3-flextree@2.1.2/node_modules/d3-flextree/build/d3-flextree.js +var require_d3_flextree = __commonJS({ + "node_modules/.pnpm/d3-flextree@2.1.2/node_modules/d3-flextree/build/d3-flextree.js"(exports, module) { + (function(global2, factory) { + typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : factory(global2.d3 = global2.d3 || {}); + })(exports, (function(exports2) { + "use strict"; + function count(node) { + var sum = 0, children = node.children, i = children && children.length; + if (!i) sum = 1; + else while (--i >= 0) sum += children[i].value; + node.value = sum; + } + function node_count() { + return this.eachAfter(count); + } + function node_each(callback) { + var node = this, current, next = [node], children, i, n; + do { + current = next.reverse(), next = []; + while (node = current.pop()) { + callback(node), children = node.children; + if (children) for (i = 0, n = children.length; i < n; ++i) { + next.push(children[i]); + } + } + } while (next.length); + return this; + } + function node_eachBefore(callback) { + var node = this, nodes = [node], children, i; + while (node = nodes.pop()) { + callback(node), children = node.children; + if (children) for (i = children.length - 1; i >= 0; --i) { + nodes.push(children[i]); + } + } + return this; + } + function node_eachAfter(callback) { + var node = this, nodes = [node], next = [], children, i, n; + while (node = nodes.pop()) { + next.push(node), children = node.children; + if (children) for (i = 0, n = children.length; i < n; ++i) { + nodes.push(children[i]); + } + } + while (node = next.pop()) { + callback(node); + } + return this; + } + function node_sum(value) { + return this.eachAfter(function(node) { + var sum = +value(node.data) || 0, children = node.children, i = children && children.length; + while (--i >= 0) sum += children[i].value; + node.value = sum; + }); + } + function node_sort(compare) { + return this.eachBefore(function(node) { + if (node.children) { + node.children.sort(compare); + } + }); + } + function node_path(end) { + var start = this, ancestor = leastCommonAncestor(start, end), nodes = [start]; + while (start !== ancestor) { + start = start.parent; + nodes.push(start); + } + var k = nodes.length; + while (end !== ancestor) { + nodes.splice(k, 0, end); + end = end.parent; + } + return nodes; + } + function leastCommonAncestor(a, b) { + if (a === b) return a; + var aNodes = a.ancestors(), bNodes = b.ancestors(), c = null; + a = aNodes.pop(); + b = bNodes.pop(); + while (a === b) { + c = a; + a = aNodes.pop(); + b = bNodes.pop(); + } + return c; + } + function node_ancestors() { + var node = this, nodes = [node]; + while (node = node.parent) { + nodes.push(node); + } + return nodes; + } + function node_descendants() { + var nodes = []; + this.each(function(node) { + nodes.push(node); + }); + return nodes; + } + function node_leaves() { + var leaves = []; + this.eachBefore(function(node) { + if (!node.children) { + leaves.push(node); + } + }); + return leaves; + } + function node_links() { + var root = this, links = []; + root.each(function(node) { + if (node !== root) { + links.push({ source: node.parent, target: node }); + } + }); + return links; + } + function hierarchy(data, children) { + var root = new Node3(data), valued = +data.value && (root.value = data.value), node, nodes = [root], child, childs, i, n; + if (children == null) children = defaultChildren; + while (node = nodes.pop()) { + if (valued) node.value = +node.data.value; + if ((childs = children(node.data)) && (n = childs.length)) { + node.children = new Array(n); + for (i = n - 1; i >= 0; --i) { + nodes.push(child = node.children[i] = new Node3(childs[i])); + child.parent = node; + child.depth = node.depth + 1; + } + } + } + return root.eachBefore(computeHeight); + } + function node_copy() { + return hierarchy(this).eachBefore(copyData); + } + function defaultChildren(d) { + return d.children; + } + function copyData(node) { + node.data = node.data.data; + } + function computeHeight(node) { + var height = 0; + do + node.height = height; + while ((node = node.parent) && node.height < ++height); + } + function Node3(data) { + this.data = data; + this.depth = this.height = 0; + this.parent = null; + } + Node3.prototype = hierarchy.prototype = { + constructor: Node3, + count: node_count, + each: node_each, + eachAfter: node_eachAfter, + eachBefore: node_eachBefore, + sum: node_sum, + sort: node_sort, + path: node_path, + ancestors: node_ancestors, + descendants: node_descendants, + leaves: node_leaves, + links: node_links, + copy: node_copy + }; + var name17 = "d3-flextree"; + var version = "2.1.2"; + var main = "build/d3-flextree.js"; + var module$1 = "index"; + var author = { "name": "Chris Maloney", "url": "http://chrismaloney.org" }; + var description = "Flexible tree layout algorithm that allows for variable node sizes."; + var keywords = ["d3", "d3-module", "layout", "tree", "hierarchy", "d3-hierarchy", "plugin", "d3-plugin", "infovis", "visualization", "2d"]; + var homepage = "https://github.com/klortho/d3-flextree"; + var license = "WTFPL"; + var repository = { "type": "git", "url": "https://github.com/klortho/d3-flextree.git" }; + var scripts = { "clean": "rm -rf build demo test", "build:demo": "rollup -c --environment BUILD:demo", "build:dev": "rollup -c --environment BUILD:dev", "build:prod": "rollup -c --environment BUILD:prod", "build:test": "rollup -c --environment BUILD:test", "build": "rollup -c", "lint": "eslint index.js src", "test:main": "node test/bundle.js", "test:browser": "node test/browser-tests.js", "test": "npm-run-all test:*", "prepare": "npm-run-all clean build lint test" }; + var dependencies = { "d3-hierarchy": "^1.1.5" }; + var devDependencies = { "babel-plugin-external-helpers": "^6.22.0", "babel-preset-es2015-rollup": "^3.0.0", "d3": "^4.13.0", "d3-selection-multi": "^1.0.1", "eslint": "^4.19.1", "jsdom": "^11.6.2", "npm-run-all": "^4.1.2", "rollup": "^0.55.3", "rollup-plugin-babel": "^2.7.1", "rollup-plugin-commonjs": "^8.0.2", "rollup-plugin-copy": "^0.2.3", "rollup-plugin-json": "^2.3.0", "rollup-plugin-node-resolve": "^3.0.2", "rollup-plugin-uglify": "^3.0.0", "uglify-es": "^3.3.9" }; + var packageInfo = { + name: name17, + version, + main, + module: module$1, + author, + description, + keywords, + homepage, + license, + repository, + scripts, + dependencies, + devDependencies, + "jsnext:main": "index" + }; + var classCallCheck = function(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + }; + var createClass = /* @__PURE__ */ (function() { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + return function(Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + })(); + var inherits = function(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + } + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; + }; + var possibleConstructorReturn = function(self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + return call && (typeof call === "object" || typeof call === "function") ? call : self; + }; + var slicedToArray = /* @__PURE__ */ (function() { + function sliceIterator(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = void 0; + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"]) _i["return"](); + } finally { + if (_d) throw _e; + } + } + return _arr; + } + return function(arr, i) { + if (Array.isArray(arr)) { + return arr; + } else if (Symbol.iterator in Object(arr)) { + return sliceIterator(arr, i); + } else { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + }; + })(); + var version$1 = packageInfo.version; + var defaults$1 = Object.freeze({ + children: function children(data) { + return data.children; + }, + nodeSize: function nodeSize(node) { + return node.data.size; + }, + spacing: 0 + }); + function flextree2(options) { + var opts = Object.assign({}, defaults$1, options); + function accessor(name$$1) { + var opt = opts[name$$1]; + return typeof opt === "function" ? opt : function() { + return opt; + }; + } + function layout2(tree) { + var wtree = wrap(getWrapper(), tree, function(node) { + return node.children; + }); + wtree.update(); + return wtree.data; + } + function getFlexNode() { + var nodeSize = accessor("nodeSize"); + var _spacing = accessor("spacing"); + return (function(_hierarchy$prototype$) { + inherits(FlexNode, _hierarchy$prototype$); + function FlexNode(data) { + classCallCheck(this, FlexNode); + return possibleConstructorReturn(this, (FlexNode.__proto__ || Object.getPrototypeOf(FlexNode)).call(this, data)); + } + createClass(FlexNode, [{ + key: "copy", + value: function copy() { + var c = wrap(this.constructor, this, function(node) { + return node.children; + }); + c.each(function(node) { + return node.data = node.data.data; + }); + return c; + } + }, { + key: "spacing", + value: function spacing(oNode) { + return _spacing(this, oNode); + } + }, { + key: "size", + get: function get$$1() { + return nodeSize(this); + } + }, { + key: "nodes", + get: function get$$1() { + return this.descendants(); + } + }, { + key: "xSize", + get: function get$$1() { + return this.size[0]; + } + }, { + key: "ySize", + get: function get$$1() { + return this.size[1]; + } + }, { + key: "top", + get: function get$$1() { + return this.y; + } + }, { + key: "bottom", + get: function get$$1() { + return this.y + this.ySize; + } + }, { + key: "left", + get: function get$$1() { + return this.x - this.xSize / 2; + } + }, { + key: "right", + get: function get$$1() { + return this.x + this.xSize / 2; + } + }, { + key: "root", + get: function get$$1() { + var ancs = this.ancestors(); + return ancs[ancs.length - 1]; + } + }, { + key: "numChildren", + get: function get$$1() { + return this.hasChildren ? this.children.length : 0; + } + }, { + key: "hasChildren", + get: function get$$1() { + return !this.noChildren; + } + }, { + key: "noChildren", + get: function get$$1() { + return this.children === null; + } + }, { + key: "firstChild", + get: function get$$1() { + return this.hasChildren ? this.children[0] : null; + } + }, { + key: "lastChild", + get: function get$$1() { + return this.hasChildren ? this.children[this.numChildren - 1] : null; + } + }, { + key: "extents", + get: function get$$1() { + return (this.children || []).reduce(function(acc, kid) { + return FlexNode.maxExtents(acc, kid.extents); + }, this.nodeExtents); + } + }, { + key: "nodeExtents", + get: function get$$1() { + return { + top: this.top, + bottom: this.bottom, + left: this.left, + right: this.right + }; + } + }], [{ + key: "maxExtents", + value: function maxExtents(e0, e1) { + return { + top: Math.min(e0.top, e1.top), + bottom: Math.max(e0.bottom, e1.bottom), + left: Math.min(e0.left, e1.left), + right: Math.max(e0.right, e1.right) + }; + } + }]); + return FlexNode; + })(hierarchy.prototype.constructor); + } + function getWrapper() { + var FlexNode = getFlexNode(); + var nodeSize = accessor("nodeSize"); + var _spacing2 = accessor("spacing"); + return (function(_FlexNode) { + inherits(_class, _FlexNode); + function _class(data) { + classCallCheck(this, _class); + var _this2 = possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).call(this, data)); + Object.assign(_this2, { + x: 0, + y: 0, + relX: 0, + prelim: 0, + shift: 0, + change: 0, + lExt: _this2, + lExtRelX: 0, + lThr: null, + rExt: _this2, + rExtRelX: 0, + rThr: null + }); + return _this2; + } + createClass(_class, [{ + key: "spacing", + value: function spacing(oNode) { + return _spacing2(this.data, oNode.data); + } + }, { + key: "update", + value: function update() { + layoutChildren(this); + resolveX(this); + return this; + } + }, { + key: "size", + get: function get$$1() { + return nodeSize(this.data); + } + }, { + key: "x", + get: function get$$1() { + return this.data.x; + }, + set: function set$$1(v) { + this.data.x = v; + } + }, { + key: "y", + get: function get$$1() { + return this.data.y; + }, + set: function set$$1(v) { + this.data.y = v; + } + }]); + return _class; + })(FlexNode); + } + function wrap(FlexClass, treeData, children) { + var _wrap = function _wrap2(data, parent) { + var node = new FlexClass(data); + Object.assign(node, { + parent, + depth: parent === null ? 0 : parent.depth + 1, + height: 0, + length: 1 + }); + var kidsData = children(data) || []; + node.children = kidsData.length === 0 ? null : kidsData.map(function(kd) { + return _wrap2(kd, node); + }); + if (node.children) { + Object.assign(node, node.children.reduce(function(hl, kid) { + return { + height: Math.max(hl.height, kid.height + 1), + length: hl.length + kid.length + }; + }, node)); + } + return node; + }; + return _wrap(treeData, null); + } + Object.assign(layout2, { + nodeSize: function nodeSize(arg) { + return arguments.length ? (opts.nodeSize = arg, layout2) : opts.nodeSize; + }, + spacing: function spacing(arg) { + return arguments.length ? (opts.spacing = arg, layout2) : opts.spacing; + }, + children: function children(arg) { + return arguments.length ? (opts.children = arg, layout2) : opts.children; + }, + hierarchy: function hierarchy2(treeData, children) { + var kids = typeof children === "undefined" ? opts.children : children; + return wrap(getFlexNode(), treeData, kids); + }, + dump: function dump(tree) { + var nodeSize = accessor("nodeSize"); + var _dump = function _dump2(i0) { + return function(node) { + var i1 = i0 + " "; + var i2 = i0 + " "; + var x = node.x, y = node.y; + var size = nodeSize(node); + var kids = node.children || []; + var kdumps = kids.length === 0 ? " " : "," + i1 + "children: [" + i2 + kids.map(_dump2(i2)).join(i2) + i1 + "]," + i0; + return "{ size: [" + size.join(", ") + "]," + i1 + "x: " + x + ", y: " + y + kdumps + "},"; + }; + }; + return _dump("\n")(tree); + } + }); + return layout2; + } + flextree2.version = version$1; + var layoutChildren = function layoutChildren2(w) { + var y = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0; + w.y = y; + (w.children || []).reduce(function(acc, kid) { + var _acc = slicedToArray(acc, 2), i = _acc[0], lastLows = _acc[1]; + layoutChildren2(kid, w.y + w.ySize); + var lowY = (i === 0 ? kid.lExt : kid.rExt).bottom; + if (i !== 0) separate(w, i, lastLows); + var lows = updateLows(lowY, i, lastLows); + return [i + 1, lows]; + }, [0, null]); + shiftChange(w); + positionRoot(w); + return w; + }; + var resolveX = function resolveX2(w, prevSum, parentX) { + if (typeof prevSum === "undefined") { + prevSum = -w.relX - w.prelim; + parentX = 0; + } + var sum = prevSum + w.relX; + w.relX = sum + w.prelim - parentX; + w.prelim = 0; + w.x = parentX + w.relX; + (w.children || []).forEach(function(k) { + return resolveX2(k, sum, w.x); + }); + return w; + }; + var shiftChange = function shiftChange2(w) { + (w.children || []).reduce(function(acc, child) { + var _acc2 = slicedToArray(acc, 2), lastShiftSum = _acc2[0], lastChangeSum = _acc2[1]; + var shiftSum = lastShiftSum + child.shift; + var changeSum = lastChangeSum + shiftSum + child.change; + child.relX += changeSum; + return [shiftSum, changeSum]; + }, [0, 0]); + }; + var separate = function separate2(w, i, lows) { + var lSib = w.children[i - 1]; + var curSubtree = w.children[i]; + var rContour = lSib; + var rSumMods = lSib.relX; + var lContour = curSubtree; + var lSumMods = curSubtree.relX; + var isFirst = true; + while (rContour && lContour) { + if (rContour.bottom > lows.lowY) lows = lows.next; + var dist = rSumMods + rContour.prelim - (lSumMods + lContour.prelim) + rContour.xSize / 2 + lContour.xSize / 2 + rContour.spacing(lContour); + if (dist > 0 || dist < 0 && isFirst) { + lSumMods += dist; + moveSubtree$1(curSubtree, dist); + distributeExtra(w, i, lows.index, dist); + } + isFirst = false; + var rightBottom = rContour.bottom; + var leftBottom = lContour.bottom; + if (rightBottom <= leftBottom) { + rContour = nextRContour(rContour); + if (rContour) rSumMods += rContour.relX; + } + if (rightBottom >= leftBottom) { + lContour = nextLContour(lContour); + if (lContour) lSumMods += lContour.relX; + } + } + if (!rContour && lContour) setLThr(w, i, lContour, lSumMods); + else if (rContour && !lContour) setRThr(w, i, rContour, rSumMods); + }; + var moveSubtree$1 = function moveSubtree(subtree, distance) { + subtree.relX += distance; + subtree.lExtRelX += distance; + subtree.rExtRelX += distance; + }; + var distributeExtra = function distributeExtra2(w, curSubtreeI, leftSibI, dist) { + var curSubtree = w.children[curSubtreeI]; + var n = curSubtreeI - leftSibI; + if (n > 1) { + var delta = dist / n; + w.children[leftSibI + 1].shift += delta; + curSubtree.shift -= delta; + curSubtree.change -= dist - delta; + } + }; + var nextLContour = function nextLContour2(w) { + return w.hasChildren ? w.firstChild : w.lThr; + }; + var nextRContour = function nextRContour2(w) { + return w.hasChildren ? w.lastChild : w.rThr; + }; + var setLThr = function setLThr2(w, i, lContour, lSumMods) { + var firstChild = w.firstChild; + var lExt = firstChild.lExt; + var curSubtree = w.children[i]; + lExt.lThr = lContour; + var diff = lSumMods - lContour.relX - firstChild.lExtRelX; + lExt.relX += diff; + lExt.prelim -= diff; + firstChild.lExt = curSubtree.lExt; + firstChild.lExtRelX = curSubtree.lExtRelX; + }; + var setRThr = function setRThr2(w, i, rContour, rSumMods) { + var curSubtree = w.children[i]; + var rExt = curSubtree.rExt; + var lSib = w.children[i - 1]; + rExt.rThr = rContour; + var diff = rSumMods - rContour.relX - curSubtree.rExtRelX; + rExt.relX += diff; + rExt.prelim -= diff; + curSubtree.rExt = lSib.rExt; + curSubtree.rExtRelX = lSib.rExtRelX; + }; + var positionRoot = function positionRoot2(w) { + if (w.hasChildren) { + var k0 = w.firstChild; + var kf = w.lastChild; + var prelim = (k0.prelim + k0.relX - k0.xSize / 2 + kf.relX + kf.prelim + kf.xSize / 2) / 2; + Object.assign(w, { + prelim, + lExt: k0.lExt, + lExtRelX: k0.lExtRelX, + rExt: kf.rExt, + rExtRelX: kf.rExtRelX + }); + } + }; + var updateLows = function updateLows2(lowY, index, lastLows) { + while (lastLows !== null && lowY >= lastLows.lowY) { + lastLows = lastLows.next; + } + return { + lowY, + index, + next: lastLows + }; + }; + exports2.flextree = flextree2; + Object.defineProperty(exports2, "__esModule", { value: true }); + })); + } +}); + +// apps/server/src/create-server.ts +import fs2 from "node:fs"; + +// node_modules/.pnpm/@hono+node-server@1.19.17_hono@4.13.7/node_modules/@hono/node-server/dist/index.mjs +import { createServer as createServerHTTP } from "http"; +import { Http2ServerRequest as Http2ServerRequest2, constants as h2constants } from "http2"; +import { Http2ServerRequest } from "http2"; +import { Readable } from "stream"; +import crypto2 from "crypto"; +var RequestError = class extends Error { + constructor(message, options) { + super(message, options); + this.name = "RequestError"; + } +}; +var toRequestError = (e) => { + if (e instanceof RequestError) { + return e; + } + return new RequestError(e.message, { cause: e }); +}; +var GlobalRequest = global.Request; +var Request2 = class extends GlobalRequest { + constructor(input, options) { + if (typeof input === "object" && getRequestCache in input) { + input = input[getRequestCache](); + } + if (typeof options?.body?.getReader !== "undefined") { + ; + options.duplex ??= "half"; + } + super(input, options); + } +}; +var newHeadersFromIncoming = (incoming) => { + const headerRecord = []; + const rawHeaders = incoming.rawHeaders; + for (let i = 0; i < rawHeaders.length; i += 2) { + const { [i]: key, [i + 1]: value } = rawHeaders; + if (key.charCodeAt(0) !== /*:*/ + 58) { + headerRecord.push([key, value]); + } + } + return new Headers(headerRecord); +}; +var wrapBodyStream = Symbol("wrapBodyStream"); +var newRequestFromIncoming = (method, url, headers, incoming, abortController) => { + const init = { + method, + headers, + signal: abortController.signal + }; + if (method === "TRACE") { + init.method = "GET"; + const req = new Request2(url, init); + Object.defineProperty(req, "method", { + get() { + return "TRACE"; + } + }); + return req; + } + if (!(method === "GET" || method === "HEAD")) { + if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) { + init.body = new ReadableStream({ + start(controller) { + controller.enqueue(incoming.rawBody); + controller.close(); + } + }); + } else if (incoming[wrapBodyStream]) { + let reader; + init.body = new ReadableStream({ + async pull(controller) { + try { + reader ||= Readable.toWeb(incoming).getReader(); + const { done, value } = await reader.read(); + if (done) { + controller.close(); + } else { + controller.enqueue(value); + } + } catch (error) { + controller.error(error); + } + } + }); + } else { + init.body = Readable.toWeb(incoming); + } + } + return new Request2(url, init); +}; +var getRequestCache = Symbol("getRequestCache"); +var requestCache = Symbol("requestCache"); +var incomingKey = Symbol("incomingKey"); +var urlKey = Symbol("urlKey"); +var headersKey = Symbol("headersKey"); +var abortControllerKey = Symbol("abortControllerKey"); +var getAbortController = Symbol("getAbortController"); +var requestPrototype = { + get method() { + return this[incomingKey].method || "GET"; + }, + get url() { + return this[urlKey]; + }, + get headers() { + return this[headersKey] ||= newHeadersFromIncoming(this[incomingKey]); + }, + [getAbortController]() { + this[getRequestCache](); + return this[abortControllerKey]; + }, + [getRequestCache]() { + this[abortControllerKey] ||= new AbortController(); + return this[requestCache] ||= newRequestFromIncoming( + this.method, + this[urlKey], + this.headers, + this[incomingKey], + this[abortControllerKey] + ); + } +}; +[ + "body", + "bodyUsed", + "cache", + "credentials", + "destination", + "integrity", + "mode", + "redirect", + "referrer", + "referrerPolicy", + "signal", + "keepalive" +].forEach((k) => { + Object.defineProperty(requestPrototype, k, { + get() { + return this[getRequestCache]()[k]; + } + }); +}); +["arrayBuffer", "blob", "clone", "formData", "json", "text"].forEach((k) => { + Object.defineProperty(requestPrototype, k, { + value: function() { + return this[getRequestCache]()[k](); + } + }); +}); +Object.defineProperty(requestPrototype, Symbol.for("nodejs.util.inspect.custom"), { + value: function(depth, options, inspectFn) { + const props = { + method: this.method, + url: this.url, + headers: this.headers, + nativeRequest: this[requestCache] + }; + return `Request (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`; + } +}); +Object.setPrototypeOf(requestPrototype, Request2.prototype); +var newRequest = (incoming, defaultHostname) => { + const req = Object.create(requestPrototype); + req[incomingKey] = incoming; + const incomingUrl = incoming.url || ""; + if (incomingUrl[0] !== "/" && // short-circuit for performance. most requests are relative URL. + (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) { + if (incoming instanceof Http2ServerRequest) { + throw new RequestError("Absolute URL for :path is not allowed in HTTP/2"); + } + try { + const url2 = new URL(incomingUrl); + req[urlKey] = url2.href; + } catch (e) { + throw new RequestError("Invalid absolute URL", { cause: e }); + } + return req; + } + const host = (incoming instanceof Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname; + if (!host) { + throw new RequestError("Missing host header"); + } + let scheme; + if (incoming instanceof Http2ServerRequest) { + scheme = incoming.scheme; + if (!(scheme === "http" || scheme === "https")) { + throw new RequestError("Unsupported scheme"); + } + } else { + scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http"; + } + const url = new URL(`${scheme}://${host}${incomingUrl}`); + if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) { + throw new RequestError("Invalid host header"); + } + req[urlKey] = url.href; + return req; +}; +var responseCache = Symbol("responseCache"); +var getResponseCache = Symbol("getResponseCache"); +var cacheKey = Symbol("cache"); +var GlobalResponse = global.Response; +var Response2 = class _Response { + #body; + #init; + [getResponseCache]() { + delete this[cacheKey]; + return this[responseCache] ||= new GlobalResponse(this.#body, this.#init); + } + constructor(body, init) { + let headers; + this.#body = body; + if (init instanceof _Response) { + const cachedGlobalResponse = init[responseCache]; + if (cachedGlobalResponse) { + this.#init = cachedGlobalResponse; + this[getResponseCache](); + return; + } else { + this.#init = init.#init; + headers = new Headers(init.#init.headers); + } + } else { + this.#init = init; + } + if (typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) { + ; + this[cacheKey] = [init?.status || 200, body, headers || init?.headers]; + } + } + get headers() { + const cache = this[cacheKey]; + if (cache) { + if (!(cache[2] instanceof Headers)) { + cache[2] = new Headers( + cache[2] || { "content-type": "text/plain; charset=UTF-8" } + ); + } + return cache[2]; + } + return this[getResponseCache]().headers; + } + get status() { + return this[cacheKey]?.[0] ?? this[getResponseCache]().status; + } + get ok() { + const status = this.status; + return status >= 200 && status < 300; + } +}; +["body", "bodyUsed", "redirected", "statusText", "trailers", "type", "url"].forEach((k) => { + Object.defineProperty(Response2.prototype, k, { + get() { + return this[getResponseCache]()[k]; + } + }); +}); +["arrayBuffer", "blob", "clone", "formData", "json", "text"].forEach((k) => { + Object.defineProperty(Response2.prototype, k, { + value: function() { + return this[getResponseCache]()[k](); + } + }); +}); +Object.defineProperty(Response2.prototype, Symbol.for("nodejs.util.inspect.custom"), { + value: function(depth, options, inspectFn) { + const props = { + status: this.status, + headers: this.headers, + ok: this.ok, + nativeResponse: this[responseCache] + }; + return `Response (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`; + } +}); +Object.setPrototypeOf(Response2, GlobalResponse); +Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype); +async function readWithoutBlocking(readPromise) { + return Promise.race([readPromise, Promise.resolve().then(() => Promise.resolve(void 0))]); +} +function writeFromReadableStreamDefaultReader(reader, writable, currentReadPromise) { + const cancel = (error) => { + reader.cancel(error).catch(() => { + }); + }; + writable.on("close", cancel); + writable.on("error", cancel); + (currentReadPromise ?? reader.read()).then(flow, handleStreamError); + return reader.closed.finally(() => { + writable.off("close", cancel); + writable.off("error", cancel); + }); + function handleStreamError(error) { + if (error) { + writable.destroy(error); + } + } + function onDrain() { + reader.read().then(flow, handleStreamError); + } + function flow({ done, value }) { + try { + if (done) { + writable.end(); + } else if (!writable.write(value)) { + writable.once("drain", onDrain); + } else { + return reader.read().then(flow, handleStreamError); + } + } catch (e) { + handleStreamError(e); + } + } +} +function writeFromReadableStream(stream, writable) { + if (stream.locked) { + throw new TypeError("ReadableStream is locked."); + } else if (writable.destroyed) { + return; + } + return writeFromReadableStreamDefaultReader(stream.getReader(), writable); +} +var buildOutgoingHttpHeaders = (headers) => { + const res = {}; + if (!(headers instanceof Headers)) { + headers = new Headers(headers ?? void 0); + } + const cookies = []; + for (const [k, v] of headers) { + if (k === "set-cookie") { + cookies.push(v); + } else { + res[k] = v; + } + } + if (cookies.length > 0) { + res["set-cookie"] = cookies; + } + res["content-type"] ??= "text/plain; charset=UTF-8"; + return res; +}; +var X_ALREADY_SENT = "x-hono-already-sent"; +if (typeof global.crypto === "undefined") { + global.crypto = crypto2; +} +var outgoingEnded = Symbol("outgoingEnded"); +var incomingDraining = Symbol("incomingDraining"); +var DRAIN_TIMEOUT_MS = 500; +var MAX_DRAIN_BYTES = 64 * 1024 * 1024; +var drainIncoming = (incoming) => { + const incomingWithDrainState = incoming; + if (incoming.destroyed || incomingWithDrainState[incomingDraining]) { + return; + } + incomingWithDrainState[incomingDraining] = true; + if (incoming instanceof Http2ServerRequest2) { + try { + ; + incoming.stream?.close?.(h2constants.NGHTTP2_NO_ERROR); + } catch { + } + return; + } + let bytesRead = 0; + const cleanup = () => { + clearTimeout(timer); + incoming.off("data", onData); + incoming.off("end", cleanup); + incoming.off("error", cleanup); + }; + const forceClose = () => { + cleanup(); + const socket = incoming.socket; + if (socket && !socket.destroyed) { + socket.destroySoon(); + } + }; + const timer = setTimeout(forceClose, DRAIN_TIMEOUT_MS); + timer.unref?.(); + const onData = (chunk) => { + bytesRead += chunk.length; + if (bytesRead > MAX_DRAIN_BYTES) { + forceClose(); + } + }; + incoming.on("data", onData); + incoming.on("end", cleanup); + incoming.on("error", cleanup); + incoming.resume(); +}; +var handleRequestError = () => new Response(null, { + status: 400 +}); +var handleFetchError = (e) => new Response(null, { + status: e instanceof Error && (e.name === "TimeoutError" || e.constructor.name === "TimeoutError") ? 504 : 500 +}); +var handleResponseError = (e, outgoing) => { + const err = e instanceof Error ? e : new Error("unknown error", { cause: e }); + if (err.code === "ERR_STREAM_PREMATURE_CLOSE") { + console.info("The user aborted a request."); + } else { + console.error(e); + if (!outgoing.headersSent) { + outgoing.writeHead(500, { "Content-Type": "text/plain" }); + } + outgoing.end(`Error: ${err.message}`); + outgoing.destroy(err); + } +}; +var flushHeaders = (outgoing) => { + if ("flushHeaders" in outgoing && outgoing.writable) { + outgoing.flushHeaders(); + } +}; +var responseViaCache = async (res, outgoing) => { + let [status, body, header] = res[cacheKey]; + let hasContentLength = false; + if (!header) { + header = { "content-type": "text/plain; charset=UTF-8" }; + } else if (header instanceof Headers) { + hasContentLength = header.has("content-length"); + header = buildOutgoingHttpHeaders(header); + } else if (Array.isArray(header)) { + const headerObj = new Headers(header); + hasContentLength = headerObj.has("content-length"); + header = buildOutgoingHttpHeaders(headerObj); + } else { + for (const key in header) { + if (key.length === 14 && key.toLowerCase() === "content-length") { + hasContentLength = true; + break; + } + } + } + if (!hasContentLength) { + if (typeof body === "string") { + header["Content-Length"] = Buffer.byteLength(body); + } else if (body instanceof Uint8Array) { + header["Content-Length"] = body.byteLength; + } else if (body instanceof Blob) { + header["Content-Length"] = body.size; + } + } + outgoing.writeHead(status, header); + if (typeof body === "string" || body instanceof Uint8Array) { + outgoing.end(body); + } else if (body instanceof Blob) { + outgoing.end(new Uint8Array(await body.arrayBuffer())); + } else { + flushHeaders(outgoing); + await writeFromReadableStream(body, outgoing)?.catch( + (e) => handleResponseError(e, outgoing) + ); + } + ; + outgoing[outgoingEnded]?.(); +}; +var isPromise = (res) => typeof res.then === "function"; +var responseViaResponseObject = async (res, outgoing, options = {}) => { + if (isPromise(res)) { + if (options.errorHandler) { + try { + res = await res; + } catch (err) { + const errRes = await options.errorHandler(err); + if (!errRes) { + return; + } + res = errRes; + } + } else { + res = await res.catch(handleFetchError); + } + } + if (cacheKey in res) { + return responseViaCache(res, outgoing); + } + const resHeaderRecord = buildOutgoingHttpHeaders(res.headers); + if (res.body) { + const reader = res.body.getReader(); + const values = []; + let done = false; + let currentReadPromise = void 0; + if (resHeaderRecord["transfer-encoding"] !== "chunked") { + let maxReadCount = 2; + for (let i = 0; i < maxReadCount; i++) { + currentReadPromise ||= reader.read(); + const chunk = await readWithoutBlocking(currentReadPromise).catch((e) => { + console.error(e); + done = true; + }); + if (!chunk) { + if (i === 1) { + await new Promise((resolve) => setTimeout(resolve)); + maxReadCount = 3; + continue; + } + break; + } + currentReadPromise = void 0; + if (chunk.value) { + values.push(chunk.value); + } + if (chunk.done) { + done = true; + break; + } + } + if (done && !("content-length" in resHeaderRecord)) { + resHeaderRecord["content-length"] = values.reduce((acc, value) => acc + value.length, 0); + } + } + outgoing.writeHead(res.status, resHeaderRecord); + values.forEach((value) => { + ; + outgoing.write(value); + }); + if (done) { + outgoing.end(); + } else { + if (values.length === 0) { + flushHeaders(outgoing); + } + await writeFromReadableStreamDefaultReader(reader, outgoing, currentReadPromise); + } + } else if (resHeaderRecord[X_ALREADY_SENT]) { + } else { + outgoing.writeHead(res.status, resHeaderRecord); + outgoing.end(); + } + ; + outgoing[outgoingEnded]?.(); +}; +var getRequestListener = (fetchCallback, options = {}) => { + const autoCleanupIncoming = options.autoCleanupIncoming ?? true; + if (options.overrideGlobalObjects !== false && global.Request !== Request2) { + Object.defineProperty(global, "Request", { + value: Request2 + }); + Object.defineProperty(global, "Response", { + value: Response2 + }); + } + return async (incoming, outgoing) => { + let res, req; + try { + req = newRequest(incoming, options.hostname); + let incomingEnded = !autoCleanupIncoming || incoming.method === "GET" || incoming.method === "HEAD"; + if (!incomingEnded) { + ; + incoming[wrapBodyStream] = true; + incoming.on("end", () => { + incomingEnded = true; + }); + if (incoming instanceof Http2ServerRequest2) { + ; + outgoing[outgoingEnded] = () => { + if (!incomingEnded) { + setTimeout(() => { + if (!incomingEnded) { + setTimeout(() => { + drainIncoming(incoming); + }); + } + }); + } + }; + } + outgoing.on("finish", () => { + if (!incomingEnded) { + drainIncoming(incoming); + } + }); + } + outgoing.on("close", () => { + const abortController = req[abortControllerKey]; + if (abortController) { + if (incoming.errored) { + req[abortControllerKey].abort(incoming.errored.toString()); + } else if (!outgoing.writableFinished) { + req[abortControllerKey].abort("Client connection prematurely closed."); + } + } + if (!incomingEnded) { + setTimeout(() => { + if (!incomingEnded) { + setTimeout(() => { + drainIncoming(incoming); + }); + } + }); + } + }); + res = fetchCallback(req, { incoming, outgoing }); + if (cacheKey in res) { + return responseViaCache(res, outgoing); + } + } catch (e) { + if (!res) { + if (options.errorHandler) { + res = await options.errorHandler(req ? e : toRequestError(e)); + if (!res) { + return; + } + } else if (!req) { + res = handleRequestError(); + } else { + res = handleFetchError(e); + } + } else { + return handleResponseError(e, outgoing); + } + } + try { + return await responseViaResponseObject(res, outgoing, options); + } catch (e) { + return handleResponseError(e, outgoing); + } + }; +}; +var createAdaptorServer = (options) => { + const fetchCallback = options.fetch; + const requestListener = getRequestListener(fetchCallback, { + hostname: options.hostname, + overrideGlobalObjects: options.overrideGlobalObjects, + autoCleanupIncoming: options.autoCleanupIncoming + }); + const createServer = options.createServer || createServerHTTP; + const server = createServer(options.serverOptions || {}, requestListener); + return server; +}; +var serve = (options, listeningListener) => { + const server = createAdaptorServer(options); + server.listen(options?.port ?? 3e3, options.hostname, () => { + const serverInfo = server.address(); + listeningListener && listeningListener(serverInfo); + }); + return server; +}; + +// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/utils/mime.js +var getMimeType = (filename, mimes = baseMimes) => { + const regexp = /\.([a-zA-Z0-9]+?)$/; + const match2 = filename.match(regexp); + if (!match2) { + return; + } + return mimes[match2[1].toLowerCase()]; +}; +var _baseMimes = { + aac: "audio/aac", + avi: "video/x-msvideo", + avif: "image/avif", + av1: "video/av1", + bin: "application/octet-stream", + bmp: "image/bmp", + css: "text/css; charset=utf-8", + csv: "text/csv; charset=utf-8", + eot: "application/vnd.ms-fontobject", + epub: "application/epub+zip", + gif: "image/gif", + gz: "application/gzip", + htm: "text/html; charset=utf-8", + html: "text/html; charset=utf-8", + ico: "image/x-icon", + ics: "text/calendar; charset=utf-8", + jpeg: "image/jpeg", + jpg: "image/jpeg", + js: "text/javascript; charset=utf-8", + json: "application/json", + jsonld: "application/ld+json", + map: "application/json", + mid: "audio/x-midi", + midi: "audio/x-midi", + mjs: "text/javascript; charset=utf-8", + mp3: "audio/mpeg", + mp4: "video/mp4", + mpeg: "video/mpeg", + oga: "audio/ogg", + ogv: "video/ogg", + ogx: "application/ogg", + opus: "audio/opus", + otf: "font/otf", + pdf: "application/pdf", + png: "image/png", + rtf: "application/rtf", + svg: "image/svg+xml; charset=utf-8", + tif: "image/tiff", + tiff: "image/tiff", + ts: "video/mp2t", + ttf: "font/ttf", + txt: "text/plain; charset=utf-8", + wasm: "application/wasm", + webm: "video/webm", + weba: "audio/webm", + webmanifest: "application/manifest+json", + webp: "image/webp", + woff: "font/woff", + woff2: "font/woff2", + xhtml: "application/xhtml+xml; charset=utf-8", + xml: "application/xml; charset=utf-8", + zip: "application/zip", + "3gp": "video/3gpp", + "3g2": "video/3gpp2", + gltf: "model/gltf+json", + glb: "model/gltf-binary" +}; +var baseMimes = _baseMimes; + +// node_modules/.pnpm/@hono+node-server@1.19.17_hono@4.13.7/node_modules/@hono/node-server/dist/serve-static.mjs +import { createReadStream, statSync, existsSync } from "fs"; +import { join } from "path"; +import { versions } from "process"; +import { Readable as Readable2 } from "stream"; +var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i; +var ENCODINGS = { + br: ".br", + zstd: ".zst", + gzip: ".gz" +}; +var ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS); +var pr54206Applied = () => { + const [major2, minor] = versions.node.split(".").map((component) => parseInt(component)); + return major2 >= 23 || major2 === 22 && minor >= 7 || major2 === 20 && minor >= 18; +}; +var useReadableToWeb = pr54206Applied(); +var createStreamBody = (stream) => { + if (useReadableToWeb) { + return Readable2.toWeb(stream); + } + const body = new ReadableStream({ + start(controller) { + stream.on("data", (chunk) => { + controller.enqueue(chunk); + }); + stream.on("error", (err) => { + controller.error(err); + }); + stream.on("end", () => { + controller.close(); + }); + }, + cancel() { + stream.destroy(); + } + }); + return body; +}; +var getStats = (path3) => { + let stats; + try { + stats = statSync(path3); + } catch { + } + return stats; +}; +var tryDecode = (str, decoder) => { + try { + return decoder(str); + } catch { + return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match2) => { + try { + return decoder(match2); + } catch { + return match2; + } + }); + } +}; +var tryDecodeURI = (str) => tryDecode(str, decodeURI); +var serveStatic = (options = { root: "" }) => { + const root = options.root || ""; + const optionPath = options.path; + if (root !== "" && !existsSync(root)) { + console.error(`serveStatic: root path '${root}' is not found, are you sure it's correct?`); + } + return async (c, next) => { + if (c.finalized) { + return next(); + } + let filename; + if (optionPath) { + filename = optionPath; + } else { + try { + filename = tryDecodeURI(c.req.path); + if (/(?:^|[\/\\])\.{1,2}(?:$|[\/\\])|[\/\\]{2,}|\\/.test(filename)) { + throw new Error(); + } + } catch { + await options.onNotFound?.(c.req.path, c); + return next(); + } + } + let path3 = join( + root, + !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename + ); + let stats = getStats(path3); + if (stats && stats.isDirectory()) { + const indexFile = options.index ?? "index.html"; + path3 = join(path3, indexFile); + stats = getStats(path3); + } + if (!stats) { + await options.onNotFound?.(path3, c); + return next(); + } + const mimeType = getMimeType(path3); + c.header("Content-Type", mimeType || "application/octet-stream"); + if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) { + const acceptEncodingSet = new Set( + c.req.header("Accept-Encoding")?.split(",").map((encoding) => encoding.trim()) + ); + for (const encoding of ENCODINGS_ORDERED_KEYS) { + if (!acceptEncodingSet.has(encoding)) { + continue; + } + const precompressedStats = getStats(path3 + ENCODINGS[encoding]); + if (precompressedStats) { + c.header("Content-Encoding", encoding); + c.header("Vary", "Accept-Encoding", { append: true }); + stats = precompressedStats; + path3 = path3 + ENCODINGS[encoding]; + break; + } + } + } + let result; + const size = stats.size; + const range = c.req.header("range") || ""; + if (c.req.method == "HEAD" || c.req.method == "OPTIONS") { + c.header("Content-Length", size.toString()); + c.status(200); + result = c.body(null); + } else if (!range) { + c.header("Content-Length", size.toString()); + result = c.body(createStreamBody(createReadStream(path3)), 200); + } else { + c.header("Accept-Ranges", "bytes"); + c.header("Date", stats.birthtime.toUTCString()); + const parts = range.replace(/bytes=/, "").split("-", 2); + const start = parseInt(parts[0], 10) || 0; + let end = parseInt(parts[1], 10) || size - 1; + if (size < end - start + 1) { + end = size - 1; + } + const chunksize = end - start + 1; + const stream = createReadStream(path3, { start, end }); + c.header("Content-Length", chunksize.toString()); + c.header("Content-Range", `bytes ${start}-${end}/${stats.size}`); + result = c.body(createStreamBody(stream), 206); + } + await options.onFound?.(path3, c); + return result; + }; +}; + +// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/compose.js +var compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err) { + if (err instanceof Error && onError) { + context.error = err; + res = await onError(err, context); + isError = true; + } else { + throw err; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; +}; + +// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + +// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/utils/buffer.js +var bufferToFormData = (arrayBuffer, contentType) => { + const response = new Response(arrayBuffer, { + headers: { + // Normalize the media type (case-insensitive) while keeping parameters like the boundary + "Content-Type": contentType.replace(/^[^;]+/, (mediaType) => mediaType.toLowerCase()) + } + }); + return response.formData(); +}; + +// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/utils/body.js +var MAX_NESTING_DEPTH = 32; +var MAX_NESTED_OBJECTS = 1e4; +var isRawRequest = (request) => "headers" in request; +var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => { + const { all = false, dot = false } = options; + const headers = isRawRequest(request) ? request.headers : request.raw.headers; + const contentType = headers.get("Content-Type"); + const mediaType = contentType?.split(";")[0].trim().toLowerCase(); + if (mediaType === "multipart/form-data" || mediaType === "application/x-www-form-urlencoded") { + return parseFormData(request, { all, dot }); + } + return {}; +}; +async function parseFormData(request, options) { + if (!isRawRequest(request) && request.bodyCache.formData) { + return convertFormDataToBodyData( + await request.bodyCache.formData, + options + ); + } + const headers = isRawRequest(request) ? request.headers : request.raw.headers; + const arrayBuffer = await request.arrayBuffer(); + const formDataPromise = bufferToFormData(arrayBuffer, headers.get("Content-Type") || ""); + if (!isRawRequest(request)) { + request.bodyCache.formData = formDataPromise; + } + const formData = await formDataPromise; + if (formData) { + return convertFormDataToBodyData(formData, options); + } + return {}; +} +function convertFormDataToBodyData(formData, options) { + const form = /* @__PURE__ */ Object.create(null); + const nestingState = { count: 0 }; + formData.forEach((value, key) => { + const shouldParseAllValues = options.all || key.endsWith("[]"); + if (!shouldParseAllValues) { + form[key] = value; + } else { + handleParsingAllValues(form, key, value); + } + }); + if (options.dot) { + Object.entries(form).forEach(([key, value]) => { + const shouldParseDotValues = key.includes("."); + if (shouldParseDotValues) { + handleParsingNestedValues(form, key, value, nestingState); + delete form[key]; + } + }); + } + return form; +} +var handleParsingAllValues = (form, key, value) => { + if (form[key] !== void 0) { + if (Array.isArray(form[key])) { + ; + form[key].push(value); + } else { + form[key] = [form[key], value]; + } + } else { + if (!key.endsWith("[]")) { + form[key] = value; + } else { + form[key] = [value]; + } + } +}; +var handleParsingNestedValues = (form, key, value, state) => { + if (/(?:^|\.)__proto__\./.test(key)) { + return; + } + let nestedForm = form; + const keys = key.split(".", MAX_NESTING_DEPTH + 2); + if (keys.length > MAX_NESTING_DEPTH + 1) { + throwNestingLimitExceeded(); + } + keys.forEach((key2, index) => { + if (index === keys.length - 1) { + nestedForm[key2] = value; + } else { + if (!nestedForm[key2] || typeof nestedForm[key2] !== "object" || Array.isArray(nestedForm[key2]) || nestedForm[key2] instanceof File) { + if (state.count++ >= MAX_NESTED_OBJECTS) { + throwNestingLimitExceeded(); + } + nestedForm[key2] = /* @__PURE__ */ Object.create(null); + } + nestedForm = nestedForm[key2]; + } + }); +}; +var throwNestingLimitExceeded = () => { + throw new Error("Nesting limit exceeded"); +}; + +// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/utils/url.js +var splitPath = (path3) => { + const paths = path3.split("/"); + if (paths[0] === "") { + paths.shift(); + } + return paths; +}; +var splitRoutingPath = (routePath) => { + const { groups, path: path3 } = extractGroupsFromPath(routePath); + const paths = splitPath(path3); + return replaceGroupMarks(paths, groups); +}; +var extractGroupsFromPath = (path3) => { + const groups = []; + path3 = path3.replace(/\{[^}]+\}/g, (match2, index) => { + const mark = `@${index}`; + groups.push([mark, match2]); + return mark; + }); + return { groups, path: path3 }; +}; +var replaceGroupMarks = (paths, groups) => { + for (let i = groups.length - 1; i >= 0; i--) { + const [mark] = groups[i]; + for (let j = paths.length - 1; j >= 0; j--) { + if (paths[j].includes(mark)) { + paths[j] = paths[j].replace(mark, groups[i][1]); + break; + } + } + } + return paths; +}; +var patternCache = {}; +var getPattern = (label, next) => { + if (label === "*") { + return "*"; + } + const match2 = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/); + if (match2) { + const cacheKey2 = `${label}#${next}`; + if (!patternCache[cacheKey2]) { + if (match2[2]) { + patternCache[cacheKey2] = next && next[0] !== ":" && next[0] !== "*" ? [cacheKey2, match2[1], new RegExp(`^${match2[2]}(?=/${next})`)] : [label, match2[1], new RegExp(`^${match2[2]}$`)]; + } else { + patternCache[cacheKey2] = [label, match2[1], true]; + } + } + return patternCache[cacheKey2]; + } + return null; +}; +var tryDecode2 = (str, decoder) => { + try { + return decoder(str); + } catch { + return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match2) => { + try { + return decoder(match2); + } catch { + return match2; + } + }); + } +}; +var tryDecodeURI2 = (str) => tryDecode2(str, decodeURI); +var getPath = (request) => { + const url = request.url; + const start = url.indexOf("/", url.indexOf(":") + 4); + let i = start; + for (; i < url.length; i++) { + const charCode = url.charCodeAt(i); + if (charCode === 37) { + const queryIndex = url.indexOf("?", i); + const hashIndex = url.indexOf("#", i); + const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex); + const path3 = url.slice(start, end); + return tryDecodeURI2(path3.includes("%25") ? path3.replace(/%25/g, "%2525") : path3); + } else if (charCode === 63 || charCode === 35) { + break; + } + } + return url.slice(start, i); +}; +var getPathNoStrict = (request) => { + const result = getPath(request); + return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result; +}; +var mergePath = (base, sub, ...rest) => { + if (rest.length) { + sub = mergePath(sub, ...rest); + } + return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`; +}; +var checkOptionalParameter = (path3) => { + if (path3.charCodeAt(path3.length - 1) !== 63 || !path3.includes(":")) { + return null; + } + const segments = path3.split("/"); + const results = []; + let basePath = ""; + segments.forEach((segment) => { + if (segment !== "" && !/\:/.test(segment)) { + basePath += "/" + segment; + } else if (/\:/.test(segment)) { + if (segment.charCodeAt(segment.length - 1) === 63) { + if (results.length === 0 && basePath === "") { + results.push("/"); + } else { + results.push(basePath); + } + const optionalSegment = segment.slice(0, -1); + basePath += "/" + optionalSegment; + results.push(basePath); + } else { + basePath += "/" + segment; + } + } + }); + return results.filter((v, i, a) => a.indexOf(v) === i); +}; +var tryDecodeURIComponent = (str) => str.indexOf("%") !== -1 ? tryDecode2(str, decodeURIComponent_) : str; +var _decodeURI = (value) => { + if (value.indexOf("+") !== -1) { + value = value.replace(/\+/g, " "); + } + return tryDecodeURIComponent(value); +}; +var _getQueryParam = (url, key, multiple) => { + const hashIndex = url.indexOf("#", 8); + if (hashIndex !== -1) { + url = url.slice(0, hashIndex); + } + let encoded; + if (!multiple && key && key.indexOf("%") === -1 && key.indexOf("+") === -1) { + let keyIndex2 = url.indexOf("?", 8); + if (keyIndex2 === -1) { + return void 0; + } + if (!url.startsWith(key, keyIndex2 + 1)) { + keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1); + } + while (keyIndex2 !== -1) { + const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1); + if (trailingKeyCode === 61) { + const valueIndex = keyIndex2 + key.length + 2; + const endIndex = url.indexOf("&", valueIndex); + return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex)); + } else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) { + return ""; + } + keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1); + } + encoded = /[%+]/.test(url); + if (!encoded) { + return void 0; + } + } + const results = /* @__PURE__ */ Object.create(null); + encoded ??= /[%+]/.test(url); + let keyIndex = url.indexOf("?", 8); + while (keyIndex !== -1) { + const nextKeyIndex = url.indexOf("&", keyIndex + 1); + let valueIndex = url.indexOf("=", keyIndex); + if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) { + valueIndex = -1; + } + let name17 = url.slice( + keyIndex + 1, + valueIndex === -1 ? nextKeyIndex === -1 ? void 0 : nextKeyIndex : valueIndex + ); + if (encoded) { + name17 = _decodeURI(name17); + } + keyIndex = nextKeyIndex; + if (name17 === "") { + continue; + } + let value; + if (valueIndex === -1) { + value = ""; + } else { + value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? void 0 : nextKeyIndex); + if (encoded) { + value = _decodeURI(value); + } + } + if (multiple) { + if (!(results[name17] && Array.isArray(results[name17]))) { + results[name17] = []; + } + ; + results[name17].push(value); + } else { + results[name17] ??= value; + } + } + return key ? results[key] : results; +}; +var getQueryParam = _getQueryParam; +var getQueryParams = (url, key) => { + return _getQueryParam(url, key, true); +}; +var decodeURIComponent_ = decodeURIComponent; + +// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/request.js +var HonoRequest = class { + /** + * `.raw` can get the raw Request object. + * + * @see {@link https://hono.dev/docs/api/request#raw} + * + * @example + * ```ts + * // For Cloudflare Workers + * app.post('/', async (c) => { + * const metadata = c.req.raw.cf?.hostMetadata? + * ... + * }) + * ``` + */ + raw; + #validatedData; + // Short name of validatedData + #matchResult; + routeIndex = 0; + /** + * `.path` can get the pathname of the request. + * + * @see {@link https://hono.dev/docs/api/request#path} + * + * @example + * ```ts + * app.get('/about/me', (c) => { + * const pathname = c.req.path // `/about/me` + * }) + * ``` + */ + path; + bodyCache = {}; + constructor(request, path3 = "/", matchResult = [[]]) { + this.raw = request; + this.path = path3; + this.#matchResult = matchResult; + } + param(key) { + return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams(); + } + #getDecodedParam(key) { + const paramKey = this.#matchResult[0][this.routeIndex]?.[1][key]; + const param = this.#getParamValue(paramKey); + return param && tryDecodeURIComponent(param); + } + #getAllDecodedParams() { + const decoded = {}; + const keys = Object.keys(this.#matchResult[0][this.routeIndex]?.[1] ?? {}); + for (const key of keys) { + const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]); + if (value !== void 0) { + decoded[key] = tryDecodeURIComponent(value); + } + } + return decoded; + } + #getParamValue(paramKey) { + return this.#matchResult[1] ? this.#matchResult[1][paramKey] : paramKey; + } + query(key) { + return getQueryParam(this.url, key); + } + queries(key) { + return getQueryParams(this.url, key); + } + header(name17) { + if (name17) { + return this.raw.headers.get(name17) ?? void 0; + } + const headerData = /* @__PURE__ */ Object.create(null); + this.raw.headers.forEach((value, key) => { + headerData[key] = value; + }); + return headerData; + } + async parseBody(options) { + return parseBody(this, options); + } + #cachedBody = (key) => { + const { bodyCache, raw: raw2 } = this; + const cachedBody = bodyCache[key]; + if (cachedBody) { + return cachedBody; + } + for (const anyCachedKey in bodyCache) { + return bodyCache[anyCachedKey].then((body) => { + if (anyCachedKey === "json") { + body = JSON.stringify(body); + } + return new Response(body)[key](); + }); + } + return bodyCache[key] = raw2[key](); + }; + /** + * `.json()` can parse Request body of type `application/json` + * + * @see {@link https://hono.dev/docs/api/request#json} + * + * @example + * ```ts + * app.post('/entry', async (c) => { + * const body = await c.req.json() + * }) + * ``` + */ + json() { + return this.#cachedBody("text").then((text2) => JSON.parse(text2)); + } + /** + * `.text()` can parse Request body of type `text/plain` + * + * @see {@link https://hono.dev/docs/api/request#text} + * + * @example + * ```ts + * app.post('/entry', async (c) => { + * const body = await c.req.text() + * }) + * ``` + */ + text() { + return this.#cachedBody("text"); + } + /** + * `.arrayBuffer()` parse Request body as an `ArrayBuffer` + * + * @see {@link https://hono.dev/docs/api/request#arraybuffer} + * + * @example + * ```ts + * app.post('/entry', async (c) => { + * const body = await c.req.arrayBuffer() + * }) + * ``` + */ + arrayBuffer() { + return this.#cachedBody("arrayBuffer"); + } + /** + * `.bytes()` parses the request body as a `Uint8Array`. + * + * @see {@link https://hono.dev/docs/api/request#bytes} + * + * @example + * ```ts + * app.post('/entry', async (c) => { + * const body = await c.req.bytes() + * }) + * ``` + */ + bytes() { + return this.#cachedBody("arrayBuffer").then((buffer) => new Uint8Array(buffer)); + } + /** + * Parses the request body as a `Blob`. + * @example + * ```ts + * app.post('/entry', async (c) => { + * const body = await c.req.blob(); + * }); + * ``` + * @see https://hono.dev/docs/api/request#blob + */ + blob() { + return this.#cachedBody("blob"); + } + /** + * Parses the request body as `FormData`. + * @example + * ```ts + * app.post('/entry', async (c) => { + * const body = await c.req.formData(); + * }); + * ``` + * @see https://hono.dev/docs/api/request#formdata + */ + formData() { + return this.#cachedBody("formData"); + } + /** + * Adds validated data to the request. + * + * @param target - The target of the validation. + * @param data - The validated data to add. + */ + addValidatedData(target, data) { + ; + (this.#validatedData ??= {})[target] = data; + } + valid(target) { + return this.#validatedData?.[target]; + } + /** + * `.url()` can get the request url strings. + * + * @see {@link https://hono.dev/docs/api/request#url} + * + * @example + * ```ts + * app.get('/about/me', (c) => { + * const url = c.req.url // `http://localhost:8787/about/me` + * ... + * }) + * ``` + */ + get url() { + return this.raw.url; + } + /** + * `.method()` can get the method name of the request. + * + * @see {@link https://hono.dev/docs/api/request#method} + * + * @example + * ```ts + * app.get('/about/me', (c) => { + * const method = c.req.method // `GET` + * }) + * ``` + */ + get method() { + return this.raw.method; + } + get [GET_MATCH_RESULT]() { + return this.#matchResult; + } + /** + * `.matchedRoutes()` can return a matched route in the handler + * + * @deprecated + * + * Use matchedRoutes helper defined in "hono/route" instead. + * + * @see {@link https://hono.dev/docs/api/request#matchedroutes} + * + * @example + * ```ts + * app.use('*', async function logger(c, next) { + * await next() + * c.req.matchedRoutes.forEach(({ handler, method, path }, i) => { + * const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]') + * console.log( + * method, + * ' ', + * path, + * ' '.repeat(Math.max(10 - path.length, 0)), + * name, + * i === c.req.routeIndex ? '<- respond from here' : '' + * ) + * }) + * }) + * ``` + */ + get matchedRoutes() { + return this.#matchResult[0].map(([[, route]]) => route); + } + /** + * `routePath()` can retrieve the path registered within the handler + * + * @deprecated + * + * Use routePath helper defined in "hono/route" instead. + * + * @see {@link https://hono.dev/docs/api/request#routepath} + * + * @example + * ```ts + * app.get('/posts/:id', (c) => { + * return c.json({ path: c.req.routePath }) + * }) + * ``` + */ + get routePath() { + return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path; + } +}; + +// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/utils/html.js +var HtmlEscapedCallbackPhase = { + Stringify: 1, + BeforeStream: 2, + Stream: 3 +}; +var raw = (value, callbacks) => { + const escapedString = new String(value); + escapedString.isEscaped = true; + escapedString.callbacks = callbacks; + return escapedString; +}; +var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => { + if (typeof str === "object" && !(str instanceof String)) { + if (!(str instanceof Promise)) { + str = str.toString(); + } + if (str instanceof Promise) { + str = await str; + } + } + const callbacks = str.callbacks; + if (!callbacks?.length) { + return Promise.resolve(str); + } + if (buffer) { + buffer[0] += str; + } else { + buffer = [str]; + } + const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context }))).then( + (res) => Promise.all( + res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context, buffer)) + ).then(() => buffer[0]) + ); + if (preserveCallbacks) { + return raw(await resStr, callbacks); + } else { + return resStr; + } +}; + +// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/context.js +var TEXT_PLAIN = "text/plain; charset=UTF-8"; +var setDefaultContentType = (contentType, headers) => { + return { + "Content-Type": contentType, + ...headers + }; +}; +var createResponseInstance = (body, init) => new Response(body, init); +var Context = class { + #rawRequest; + #req; + /** + * `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers. + * + * @see {@link https://hono.dev/docs/api/context#env} + * + * @example + * ```ts + * // Environment object for Cloudflare Workers + * app.get('*', async c => { + * const counter = c.env.COUNTER + * }) + * ``` + */ + env = {}; + #var; + finalized = false; + /** + * `.error` can get the error object from the middleware if the Handler throws an error. + * + * @see {@link https://hono.dev/docs/api/context#error} + * + * @example + * ```ts + * app.use('*', async (c, next) => { + * await next() + * if (c.error) { + * // do something... + * } + * }) + * ``` + */ + error; + #status; + #executionCtx; + #res; + #layout; + #renderer; + #notFoundHandler; + #preparedHeaders; + #matchResult; + #path; + /** + * Creates an instance of the Context class. + * + * @param req - The Request object. + * @param options - Optional configuration options for the context. + */ + constructor(req, options) { + this.#rawRequest = req; + if (options) { + this.#executionCtx = options.executionCtx; + this.env = options.env; + this.#notFoundHandler = options.notFoundHandler; + this.#path = options.path; + this.#matchResult = options.matchResult; + } + } + /** + * `.req` is the instance of {@link HonoRequest}. + */ + get req() { + this.#req ??= new HonoRequest(this.#rawRequest, this.#path, this.#matchResult); + return this.#req; + } + /** + * @see {@link https://hono.dev/docs/api/context#event} + * The FetchEvent associated with the current request. + * + * @throws Will throw an error if the context does not have a FetchEvent. + */ + get event() { + if (this.#executionCtx && "respondWith" in this.#executionCtx) { + return this.#executionCtx; + } else { + throw Error("This context has no FetchEvent"); + } + } + /** + * @see {@link https://hono.dev/docs/api/context#executionctx} + * The ExecutionContext associated with the current request. + * + * @throws Will throw an error if the context does not have an ExecutionContext. + */ + get executionCtx() { + if (this.#executionCtx) { + return this.#executionCtx; + } else { + throw Error("This context has no ExecutionContext"); + } + } + /** + * @see {@link https://hono.dev/docs/api/context#res} + * The Response object for the current request. + */ + get res() { + return this.#res ||= createResponseInstance(null, { + headers: this.#preparedHeaders ??= new Headers() + }); + } + /** + * Sets the Response object for the current request. + * + * @param _res - The Response object to set. + */ + set res(_res) { + if (this.#res && _res) { + _res = createResponseInstance(_res.body, _res); + for (const [k, v] of this.#res.headers.entries()) { + if (k === "content-type") { + continue; + } + if (k === "set-cookie") { + const cookies = this.#res.headers.getSetCookie(); + _res.headers.delete("set-cookie"); + for (const cookie of cookies) { + _res.headers.append("set-cookie", cookie); + } + } else { + _res.headers.set(k, v); + } + } + } + this.#res = _res; + this.finalized = true; + } + /** + * `.render()` can create a response within a layout. + * + * @see {@link https://hono.dev/docs/api/context#render-setrenderer} + * + * @example + * ```ts + * app.get('/', (c) => { + * return c.render('Hello!') + * }) + * ``` + */ + render = (...args) => { + this.#renderer ??= (content) => this.html(content); + return this.#renderer(...args); + }; + /** + * Sets the layout for the response. + * + * @param layout - The layout to set. + * @returns The layout function. + */ + setLayout = (layout2) => this.#layout = layout2; + /** + * Gets the current layout for the response. + * + * @returns The current layout function. + */ + getLayout = () => this.#layout; + /** + * `.setRenderer()` can set the layout in the custom middleware. + * + * @see {@link https://hono.dev/docs/api/context#render-setrenderer} + * + * @example + * ```tsx + * app.use('*', async (c, next) => { + * c.setRenderer((content) => { + * return c.html( + * + *
+ *{content}
+ * + * + * ) + * }) + * await next() + * }) + * ``` + */ + setRenderer = (renderer) => { + this.#renderer = renderer; + }; + /** + * `.header()` can set headers. + * + * @see {@link https://hono.dev/docs/api/context#header} + * + * @example + * ```ts + * app.get('/welcome', (c) => { + * // Set headers + * c.header('X-Message', 'Hello!') + * c.header('Content-Type', 'text/plain') + * + * // Append multiple headers using the append option (e.g. Vary) + * c.header('Vary', 'Accept-Encoding', { append: true }) + * c.header('Vary', 'User-Agent', { append: true }) + * + * return c.body('Thank you for coming') + * }) + * ``` + */ + header = (name17, value, options) => { + if (this.finalized) { + this.#res = createResponseInstance(this.#res.body, this.#res); + } + const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers(); + if (value === void 0) { + headers.delete(name17); + } else if (options?.append) { + headers.append(name17, value); + } else { + headers.set(name17, value); + } + }; + status = (status) => { + this.#status = status; + }; + /** + * `.set()` can set the value specified by the key. + * + * @see {@link https://hono.dev/docs/api/context#set-get} + * + * @example + * ```ts + * app.use('*', async (c, next) => { + * c.set('message', 'Hono is hot!!') + * await next() + * }) + * ``` + */ + set = (key, value) => { + this.#var ??= /* @__PURE__ */ new Map(); + this.#var.set(key, value); + }; + /** + * `.get()` can use the value specified by the key. + * + * @see {@link https://hono.dev/docs/api/context#set-get} + * + * @example + * ```ts + * app.get('/', (c) => { + * const message = c.get('message') + * return c.text(`The message is "${message}"`) + * }) + * ``` + */ + get = (key) => { + return this.#var ? this.#var.get(key) : void 0; + }; + /** + * `.var` can access the value of a variable. + * + * @see {@link https://hono.dev/docs/api/context#var} + * + * @example + * ```ts + * const result = c.var.client.oneMethod() + * ``` + */ + // c.var.propName is a read-only + get var() { + if (!this.#var) { + return {}; + } + return Object.fromEntries(this.#var); + } + #newResponse(data, arg, headers) { + let responseHeaders = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders; + if (typeof arg === "object" && arg.headers) { + responseHeaders ??= new Headers(); + for (const [key, value] of new Headers(arg.headers)) { + if (key === "set-cookie") { + responseHeaders.append(key, value); + } else { + responseHeaders.set(key, value); + } + } + } + if (headers) { + if (!responseHeaders) { + let count = 0; + for (const k in headers) { + if (++count > 1 || typeof headers[k] !== "string") { + responseHeaders = new Headers(); + break; + } + } + } + if (responseHeaders) { + for (const k in headers) { + const v = headers[k]; + if (typeof v === "string") { + responseHeaders.set(k, v); + } else { + responseHeaders.delete(k); + for (const v2 of v) { + responseHeaders.append(k, v2); + } + } + } + } + } + const status = typeof arg === "number" ? arg : arg?.status ?? this.#status; + return createResponseInstance(data, { + status, + headers: responseHeaders ?? headers + }); + } + newResponse = (...args) => this.#newResponse(...args); + /** + * `.body()` can return the HTTP response. + * You can set headers with `.header()` and set HTTP status code with `.status`. + * This can also be set in `.text()`, `.json()` and so on. + * + * @see {@link https://hono.dev/docs/api/context#body} + * + * @example + * ```ts + * app.get('/welcome', (c) => { + * // Set headers + * c.header('X-Message', 'Hello!') + * c.header('Content-Type', 'text/plain') + * // Set HTTP status code + * c.status(201) + * + * // Return the response body + * return c.body('Thank you for coming') + * }) + * ``` + */ + body = (data, arg, headers) => this.#newResponse(data, arg, headers); + /** + * `.text()` can render text as `Content-Type:text/plain`. + * + * @see {@link https://hono.dev/docs/api/context#text} + * + * @example + * ```ts + * app.get('/say', (c) => { + * return c.text('Hello!') + * }) + * ``` + */ + text = (text2, arg, headers) => { + return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text2) : this.#newResponse( + text2, + arg, + setDefaultContentType(TEXT_PLAIN, headers) + ); + }; + /** + * `.json()` can render JSON as `Content-Type:application/json`. + * + * @see {@link https://hono.dev/docs/api/context#json} + * + * @example + * ```ts + * app.get('/api', (c) => { + * return c.json({ message: 'Hello!' }) + * }) + * ``` + */ + json = (object2, arg, headers) => { + return this.#newResponse( + JSON.stringify(object2), + arg, + setDefaultContentType("application/json", headers) + ); + }; + html = (html, arg, headers) => { + const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType("text/html; charset=UTF-8", headers)); + return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html); + }; + /** + * `.redirect()` can Redirect, default status code is 302. + * + * @see {@link https://hono.dev/docs/api/context#redirect} + * + * @example + * ```ts + * app.get('/redirect', (c) => { + * return c.redirect('/') + * }) + * app.get('/redirect-permanently', (c) => { + * return c.redirect('/', 301) + * }) + * ``` + */ + redirect = (location, status) => { + const locationString = String(location); + this.header( + "Location", + // Multibyes should be encoded + // eslint-disable-next-line no-control-regex + !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString) + ); + return this.newResponse(null, status ?? 302); + }; + /** + * `.notFound()` can return the Not Found Response. + * + * @see {@link https://hono.dev/docs/api/context#notfound} + * + * @example + * ```ts + * app.get('/notfound', (c) => { + * return c.notFound() + * }) + * ``` + */ + notFound = () => { + this.#notFoundHandler ??= () => createResponseInstance(); + return this.#notFoundHandler(this); + }; +}; + +// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/router.js +var METHOD_NAME_ALL = "ALL"; +var METHOD_NAME_ALL_LOWERCASE = "all"; +var METHODS = ["get", "post", "put", "delete", "options", "patch", "query"]; +var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built."; +var UnsupportedPathError = class extends Error { +}; + +// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + +// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/hono-base.js +var notFoundHandler = (c) => { + return c.text("404 Not Found", 404); +}; +var errorHandler = (err, c) => { + if ("getResponse" in err) { + const res = err.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err); + return c.text("Internal Server Error", 500); +}; +var Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + query; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + const methodName = method.toUpperCase(); + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(methodName, this.#path, args1); + } + args.forEach((handler) => { + this.#addRoute(methodName, this.#path, handler); + }); + return this; + }; + }); + this.on = (method, path3, ...handlers) => { + for (const p of [path3].flat()) { + this.#path = p; + for (const m of [method].flat()) { + const methodName = m.toUpperCase(); + for (const handler of handlers) { + this.#addRoute(methodName, this.#path, handler); + } + } + } + return this; + }; + this.use = (arg1, ...handlers) => { + if (typeof arg1 === "string") { + this.#path = arg1; + } else { + this.#path = "*"; + handlers.unshift(arg1); + } + handlers.forEach((handler) => { + this.#addRoute(METHOD_NAME_ALL, this.#path, handler); + }); + return this; + }; + const { strict, ...optionsWithoutStrict } = options; + Object.assign(this, optionsWithoutStrict); + this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict; + } + #clone() { + const clone = new _Hono({ + router: this.router, + getPath: this.getPath + }); + clone.errorHandler = this.errorHandler; + clone.#notFoundHandler = this.#notFoundHandler; + clone.routes = this.routes; + return clone; + } + #notFoundHandler = notFoundHandler; + // Cannot use `#` because it requires visibility at JavaScript runtime. + errorHandler = errorHandler; + /** + * `.route()` allows grouping other Hono instance in routes. + * + * @see {@link https://hono.dev/docs/api/routing#grouping} + * + * @param {string} path - base Path + * @param {Hono} app - other Hono instance + * @returns {Hono} routed Hono instance + * + * @example + * ```ts + * const app = new Hono() + * const app2 = new Hono() + * + * app2.get("/user", (c) => c.text("user")) + * app.route("/api", app2) // GET /api/user + * ``` + */ + route(path3, app) { + const subApp = this.basePath(path3); + app.routes.map((r) => { + let handler; + if (app.errorHandler === errorHandler) { + handler = r.handler; + } else { + handler = async (c, next) => (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res; + handler[COMPOSED_HANDLER] = r.handler; + } + subApp.#addRoute(r.method, r.path, handler, r.basePath); + }); + return this; + } + /** + * `.basePath()` allows base paths to be specified. + * + * @see {@link https://hono.dev/docs/api/routing#base-path} + * + * @param {string} path - base Path + * @returns {Hono} changed Hono instance + * + * @example + * ```ts + * const api = new Hono().basePath('/api') + * ``` + */ + basePath(path3) { + const subApp = this.#clone(); + subApp._basePath = mergePath(this._basePath, path3); + return subApp; + } + /** + * `.onError()` handles an error and returns a customized Response. + * + * @see {@link https://hono.dev/docs/api/hono#error-handling} + * + * @param {ErrorHandler} handler - request Handler for error + * @returns {Hono} changed Hono instance + * + * @example + * ```ts + * app.onError((err, c) => { + * console.error(`${err}`) + * return c.text('Custom Error Message', 500) + * }) + * ``` + */ + onError = (handler) => { + this.errorHandler = handler; + return this; + }; + /** + * `.notFound()` allows you to customize a Not Found Response. + * + * @see {@link https://hono.dev/docs/api/hono#not-found} + * + * @param {NotFoundHandler} handler - request handler for not-found + * @returns {Hono} changed Hono instance + * + * @example + * ```ts + * app.notFound((c) => { + * return c.text('Custom 404 Message', 404) + * }) + * ``` + */ + notFound = (handler) => { + this.#notFoundHandler = handler; + return this; + }; + /** + * `.mount()` allows you to mount applications built with other frameworks into your Hono application. + * + * @see {@link https://hono.dev/docs/api/hono#mount} + * + * @param {string} path - base Path + * @param {Function} applicationHandler - other Request Handler + * @param {MountOptions} [options] - options of `.mount()` + * @returns {Hono} mounted Hono instance + * + * @example + * ```ts + * import { Router as IttyRouter } from 'itty-router' + * import { Hono } from 'hono' + * // Create itty-router application + * const ittyRouter = IttyRouter() + * // GET /itty-router/hello + * ittyRouter.get('/hello', () => new Response('Hello from itty-router')) + * + * const app = new Hono() + * app.mount('/itty-router', ittyRouter.handle) + * ``` + * + * @example + * ```ts + * const app = new Hono() + * // Send the request to another application without modification. + * app.mount('/app', anotherApp, { + * replaceRequest: (req) => req, + * }) + * ``` + */ + mount(path3, applicationHandler, options) { + let replaceRequest; + let optionHandler; + if (options) { + if (typeof options === "function") { + optionHandler = options; + } else { + optionHandler = options.optionHandler; + if (options.replaceRequest === false) { + replaceRequest = (request) => request; + } else { + replaceRequest = options.replaceRequest; + } + } + } + const getOptions = optionHandler ? (c) => { + const options2 = optionHandler(c); + return Array.isArray(options2) ? options2 : [options2]; + } : (c) => { + let executionContext = void 0; + try { + executionContext = c.executionCtx; + } catch { + } + return [c.env, executionContext]; + }; + replaceRequest ||= (() => { + const mergedPath = mergePath(this._basePath, path3); + const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length; + return (request) => { + const url = new URL(request.url); + url.pathname = this.getPath(request).slice(pathPrefixLength) || "/"; + return new Request(url, request); + }; + })(); + const handler = async (c, next) => { + const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c)); + if (res) { + return res; + } + await next(); + }; + this.#addRoute(METHOD_NAME_ALL, mergePath(path3, "*"), handler); + return this; + } + #addRoute(method, path3, handler, baseRoutePath) { + path3 = mergePath(this._basePath, path3); + const r = { + basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath, + path: path3, + method, + handler + }; + this.router.add(method, path3, [handler, r]); + this.routes.push(r); + } + #handleError(err, c) { + if (err instanceof Error) { + return this.errorHandler(err, c); + } + throw err; + } + #dispatch(request, executionCtx, env, method) { + if (method === "HEAD") { + return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))(); + } + const path3 = this.getPath(request, { env }); + const matchResult = this.router.match(method, path3); + const c = new Context(request, { + path: path3, + matchResult, + env, + executionCtx, + notFoundHandler: this.#notFoundHandler + }); + if (matchResult[0].length === 1) { + let res; + try { + res = matchResult[0][0][0][0](c, async () => { + c.res = await this.#notFoundHandler(c); + }); + } catch (err) { + return this.#handleError(err, c); + } + return res instanceof Promise ? res.then( + (resolved) => resolved || (c.finalized ? c.res : this.#notFoundHandler(c)) + ).catch((err) => this.#handleError(err, c)) : res ?? this.#notFoundHandler(c); + } + const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler); + return (async () => { + try { + const context = await composed(c); + if (!context.finalized) { + throw new Error( + "Context is not finalized. Did you forget to return a Response object or `await next()`?" + ); + } + return context.res; + } catch (err) { + return this.#handleError(err, c); + } + })(); + } + /** + * `.fetch()` will be entry point of your app. + * + * @see {@link https://hono.dev/docs/api/hono#fetch} + * + * @param {Request} request - request Object of request + * @param {Env} env - env Object + * @param {ExecutionContext} executionCtx - context of execution + * @returns {Response | Promise>>1;jt"u"?null:document;function Md(t,l,e){var a=_n;if(a&&typeof l=="string"&&l){var n=le(l);n='link[rel="'+t+'"][href="'+n+'"]',typeof e=="string"&&(n+='[crossorigin="'+e+'"]'),Ad.has(n)||(Ad.add(n),t={rel:t,crossOrigin:e,href:l},a.querySelector(n)===null&&(l=a.createElement("link"),Nl(l,"link",t),dl(l),a.head.appendChild(l)))}}function f0(t){ke.D(t),Md("dns-prefetch",t,null)}function s0(t,l){ke.C(t,l),Md("preconnect",t,l)}function o0(t,l,e){ke.L(t,l,e);var a=_n;if(a&&t&&l){var n='link[rel="preload"][as="'+le(l)+'"]';l==="image"&&e&&e.imageSrcSet?(n+='[imagesrcset="'+le(e.imageSrcSet)+'"]',typeof e.imageSizes=="string"&&(n+='[imagesizes="'+le(e.imageSizes)+'"]')):n+='[href="'+le(t)+'"]';var u=n;switch(l){case"style":u=En(t);break;case"script":u=An(t)}se.has(u)||(t=O({rel:"preload",href:l==="image"&&e&&e.imageSrcSet?void 0:t,as:l},e),se.set(u,t),a.querySelector(n)!==null||l==="style"&&a.querySelector(yu(u))||l==="script"&&a.querySelector(vu(u))||(l=a.createElement("link"),Nl(l,"link",t),dl(l),a.head.appendChild(l)))}}function r0(t,l){ke.m(t,l);var e=_n;if(e&&t){var a=l&&typeof l.as=="string"?l.as:"script",n='link[rel="modulepreload"][as="'+le(a)+'"][href="'+le(t)+'"]',u=n;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":u=An(t)}if(!se.has(u)&&(t=O({rel:"modulepreload",href:t},l),se.set(u,t),e.querySelector(n)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(e.querySelector(vu(u)))return}a=e.createElement("link"),Nl(a,"link",t),dl(a),e.head.appendChild(a)}}}function d0(t,l,e){ke.S(t,l,e);var a=_n;if(a&&t){var n=ta(a).hoistableStyles,u=En(t);l=l||"default";var c=n.get(u);if(!c){var s={loading:0,preload:null};if(c=a.querySelector(yu(u)))s.loading=5;else{t=O({rel:"stylesheet",href:t,"data-precedence":l},e),(e=se.get(u))&&Lf(t,e);var d=c=a.createElement("link");dl(d),Nl(d,"link",t),d._p=new Promise(function(_,D){d.onload=_,d.onerror=D}),d.addEventListener("load",function(){s.loading|=1}),d.addEventListener("error",function(){s.loading|=2}),s.loading|=4,Ai(c,l,a)}c={type:"stylesheet",instance:c,count:1,state:s},n.set(u,c)}}}function h0(t,l){ke.X(t,l);var e=_n;if(e&&t){var a=ta(e).hoistableScripts,n=An(t),u=a.get(n);u||(u=e.querySelector(vu(n)),u||(t=O({src:t,async:!0},l),(l=se.get(n))&&Gf(t,l),u=e.createElement("script"),dl(u),Nl(u,"link",t),e.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function m0(t,l){ke.M(t,l);var e=_n;if(e&&t){var a=ta(e).hoistableScripts,n=An(t),u=a.get(n);u||(u=e.querySelector(vu(n)),u||(t=O({src:t,async:!0,type:"module"},l),(l=se.get(n))&&Gf(t,l),u=e.createElement("script"),dl(u),Nl(u,"link",t),e.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function Nd(t,l,e,a){var n=(n=ft.current)?Ei(n):null;if(!n)throw Error(f(446));switch(t){case"meta":case"title":return null;case"style":return typeof e.precedence=="string"&&typeof e.href=="string"?(l=En(e.href),e=ta(n).hoistableStyles,a=e.get(l),a||(a={type:"style",instance:null,count:0,state:null},e.set(l,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(e.rel==="stylesheet"&&typeof e.href=="string"&&typeof e.precedence=="string"){t=En(e.href);var u=ta(n).hoistableStyles,c=u.get(t);if(c||(n=n.ownerDocument||n,c={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},u.set(t,c),(u=n.querySelector(yu(t)))&&!u._p&&(c.instance=u,c.state.loading=5),se.has(t)||(e={rel:"preload",as:"style",href:e.href,crossOrigin:e.crossOrigin,integrity:e.integrity,media:e.media,hrefLang:e.hrefLang,referrerPolicy:e.referrerPolicy},se.set(t,e),u||y0(n,t,e,c.state))),l&&a===null)throw Error(f(528,""));return c}if(l&&a!==null)throw Error(f(529,""));return null;case"script":return l=e.async,e=e.src,typeof e=="string"&&l&&typeof l!="function"&&typeof l!="symbol"?(l=An(e),e=ta(n).hoistableScripts,a=e.get(l),a||(a={type:"script",instance:null,count:0,state:null},e.set(l,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(f(444,t))}}function En(t){return'href="'+le(t)+'"'}function yu(t){return'link[rel="stylesheet"]['+t+"]"}function Od(t){return O({},t,{"data-precedence":t.precedence,precedence:null})}function y0(t,l,e,a){t.querySelector('link[rel="preload"][as="style"]['+l+"]")?a.loading=1:(l=t.createElement("link"),a.preload=l,l.addEventListener("load",function(){return a.loading|=1}),l.addEventListener("error",function(){return a.loading|=2}),Nl(l,"link",e),dl(l),t.head.appendChild(l))}function An(t){return'[src="'+le(t)+'"]'}function vu(t){return"script[async]"+t}function Dd(t,l,e){if(l.count++,l.instance===null)switch(l.type){case"style":var a=t.querySelector('style[data-href~="'+le(e.href)+'"]');if(a)return l.instance=a,dl(a),a;var n=O({},e,{"data-href":e.href,"data-precedence":e.precedence,href:null,precedence:null});return a=(t.ownerDocument||t).createElement("style"),dl(a),Nl(a,"style",n),Ai(a,e.precedence,t),l.instance=a;case"stylesheet":n=En(e.href);var u=t.querySelector(yu(n));if(u)return l.state.loading|=4,l.instance=u,dl(u),u;a=Od(e),(n=se.get(n))&&Lf(a,n),u=(t.ownerDocument||t).createElement("link"),dl(u);var c=u;return c._p=new Promise(function(s,d){c.onload=s,c.onerror=d}),Nl(u,"link",a),l.state.loading|=4,Ai(u,e.precedence,t),l.instance=u;case"script":return u=An(e.src),(n=t.querySelector(vu(u)))?(l.instance=n,dl(n),n):(a=e,(n=se.get(u))&&(a=O({},e),Gf(a,n)),t=t.ownerDocument||t,n=t.createElement("script"),dl(n),Nl(n,"link",a),t.head.appendChild(n),l.instance=n);case"void":return null;default:throw Error(f(443,l.type))}else l.type==="stylesheet"&&(l.state.loading&4)===0&&(a=l.instance,l.state.loading|=4,Ai(a,e.precedence,t));return l.instance}function Ai(t,l,e){for(var a=e.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),n=a.length?a[a.length-1]:null,u=n,c=0;c