gamedig
Version:
Query for the status of any game server in Node.JS
1,391 lines (1,380 loc) • 492 kB
JavaScript
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 __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all2) => {
for (var name in all2)
__defProp(target, name, { get: all2[name], 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
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// node_modules/defer-to-connect/dist/source/index.js
var require_source = __commonJS({
"node_modules/defer-to-connect/dist/source/index.js"(exports2, module2) {
"use strict";
Object.defineProperty(exports2, "__esModule", { value: true });
function isTLSSocket(socket) {
return socket.encrypted;
}
var deferToConnect2 = (socket, fn) => {
let listeners;
if (typeof fn === "function") {
const connect2 = fn;
listeners = { connect: connect2 };
} else {
listeners = fn;
}
const hasConnectListener = typeof listeners.connect === "function";
const hasSecureConnectListener = typeof listeners.secureConnect === "function";
const hasCloseListener = typeof listeners.close === "function";
const onConnect = () => {
if (hasConnectListener) {
listeners.connect();
}
if (isTLSSocket(socket) && hasSecureConnectListener) {
if (socket.authorized) {
listeners.secureConnect();
} else if (!socket.authorizationError) {
socket.once("secureConnect", listeners.secureConnect);
}
}
if (hasCloseListener) {
socket.once("close", listeners.close);
}
};
if (socket.writable && !socket.connecting) {
onConnect();
} else if (socket.connecting) {
socket.once("connect", onConnect);
} else if (socket.destroyed && hasCloseListener) {
listeners.close(socket._hadError);
}
};
exports2.default = deferToConnect2;
module2.exports = deferToConnect2;
module2.exports.default = deferToConnect2;
}
});
// node_modules/get-stream/buffer-stream.js
var require_buffer_stream = __commonJS({
"node_modules/get-stream/buffer-stream.js"(exports2, module2) {
"use strict";
var { PassThrough: PassThroughStream2 } = require("stream");
module2.exports = (options) => {
options = { ...options };
const { array } = options;
let { encoding } = options;
const isBuffer = encoding === "buffer";
let objectMode = false;
if (array) {
objectMode = !(encoding || isBuffer);
} else {
encoding = encoding || "utf8";
}
if (isBuffer) {
encoding = null;
}
const stream2 = new PassThroughStream2({ objectMode });
if (encoding) {
stream2.setEncoding(encoding);
}
let length = 0;
const chunks = [];
stream2.on("data", (chunk) => {
chunks.push(chunk);
if (objectMode) {
length = chunks.length;
} else {
length += chunk.length;
}
});
stream2.getBufferedValue = () => {
if (array) {
return chunks;
}
return isBuffer ? Buffer.concat(chunks, length) : chunks.join("");
};
stream2.getBufferedLength = () => length;
return stream2;
};
}
});
// node_modules/get-stream/index.js
var require_get_stream = __commonJS({
"node_modules/get-stream/index.js"(exports2, module2) {
"use strict";
var { constants: BufferConstants } = require("buffer");
var stream2 = require("stream");
var { promisify: promisify5 } = require("util");
var bufferStream = require_buffer_stream();
var streamPipelinePromisified = promisify5(stream2.pipeline);
var MaxBufferError = class extends Error {
constructor() {
super("maxBuffer exceeded");
this.name = "MaxBufferError";
}
};
async function getStream3(inputStream, options) {
if (!inputStream) {
throw new Error("Expected a stream");
}
options = {
maxBuffer: Infinity,
...options
};
const { maxBuffer } = options;
const stream3 = bufferStream(options);
await new Promise((resolve, reject) => {
const rejectPromise = (error) => {
if (error && stream3.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
error.bufferedData = stream3.getBufferedValue();
}
reject(error);
};
(async () => {
try {
await streamPipelinePromisified(inputStream, stream3);
resolve();
} catch (error) {
rejectPromise(error);
}
})();
stream3.on("data", () => {
if (stream3.getBufferedLength() > maxBuffer) {
rejectPromise(new MaxBufferError());
}
});
});
return stream3.getBufferedValue();
}
module2.exports = getStream3;
module2.exports.buffer = (stream3, options) => getStream3(stream3, { ...options, encoding: "buffer" });
module2.exports.array = (stream3, options) => getStream3(stream3, { ...options, array: true });
module2.exports.MaxBufferError = MaxBufferError;
}
});
// node_modules/http-cache-semantics/index.js
var require_http_cache_semantics = __commonJS({
"node_modules/http-cache-semantics/index.js"(exports2, module2) {
"use strict";
var statusCodeCacheableByDefault = /* @__PURE__ */ new Set([
200,
203,
204,
206,
300,
301,
308,
404,
405,
410,
414,
501
]);
var understoodStatuses = /* @__PURE__ */ new Set([
200,
203,
204,
300,
301,
302,
303,
307,
308,
404,
405,
410,
414,
501
]);
var errorStatusCodes = /* @__PURE__ */ new Set([
500,
502,
503,
504
]);
var hopByHopHeaders = {
date: true,
// included, because we add Age update Date
connection: true,
"keep-alive": true,
"proxy-authenticate": true,
"proxy-authorization": true,
te: true,
trailer: true,
"transfer-encoding": true,
upgrade: true
};
var excludedFromRevalidationUpdate = {
// Since the old body is reused, it doesn't make sense to change properties of the body
"content-length": true,
"content-encoding": true,
"transfer-encoding": true,
"content-range": true
};
function toNumberOrZero(s) {
const n = parseInt(s, 10);
return isFinite(n) ? n : 0;
}
function isErrorResponse(response) {
if (!response) {
return true;
}
return errorStatusCodes.has(response.status);
}
function parseCacheControl(header) {
const cc = {};
if (!header)
return cc;
const parts = header.trim().split(/,/);
for (const part of parts) {
const [k, v] = part.split(/=/, 2);
cc[k.trim()] = v === void 0 ? true : v.trim().replace(/^"|"$/g, "");
}
return cc;
}
function formatCacheControl(cc) {
let parts = [];
for (const k in cc) {
const v = cc[k];
parts.push(v === true ? k : k + "=" + v);
}
if (!parts.length) {
return void 0;
}
return parts.join(", ");
}
module2.exports = class CachePolicy {
constructor(req, res, {
shared,
cacheHeuristic,
immutableMinTimeToLive,
ignoreCargoCult,
_fromObject
} = {}) {
if (_fromObject) {
this._fromObject(_fromObject);
return;
}
if (!res || !res.headers) {
throw Error("Response headers missing");
}
this._assertRequestHasHeaders(req);
this._responseTime = this.now();
this._isShared = shared !== false;
this._cacheHeuristic = void 0 !== cacheHeuristic ? cacheHeuristic : 0.1;
this._immutableMinTtl = void 0 !== immutableMinTimeToLive ? immutableMinTimeToLive : 24 * 3600 * 1e3;
this._status = "status" in res ? res.status : 200;
this._resHeaders = res.headers;
this._rescc = parseCacheControl(res.headers["cache-control"]);
this._method = "method" in req ? req.method : "GET";
this._url = req.url;
this._host = req.headers.host;
this._noAuthorization = !req.headers.authorization;
this._reqHeaders = res.headers.vary ? req.headers : null;
this._reqcc = parseCacheControl(req.headers["cache-control"]);
if (ignoreCargoCult && "pre-check" in this._rescc && "post-check" in this._rescc) {
delete this._rescc["pre-check"];
delete this._rescc["post-check"];
delete this._rescc["no-cache"];
delete this._rescc["no-store"];
delete this._rescc["must-revalidate"];
this._resHeaders = Object.assign({}, this._resHeaders, {
"cache-control": formatCacheControl(this._rescc)
});
delete this._resHeaders.expires;
delete this._resHeaders.pragma;
}
if (res.headers["cache-control"] == null && /no-cache/.test(res.headers.pragma)) {
this._rescc["no-cache"] = true;
}
}
now() {
return Date.now();
}
storable() {
return !!(!this._reqcc["no-store"] && // A cache MUST NOT store a response to any request, unless:
// The request method is understood by the cache and defined as being cacheable, and
("GET" === this._method || "HEAD" === this._method || "POST" === this._method && this._hasExplicitExpiration()) && // the response status code is understood by the cache, and
understoodStatuses.has(this._status) && // the "no-store" cache directive does not appear in request or response header fields, and
!this._rescc["no-store"] && // the "private" response directive does not appear in the response, if the cache is shared, and
(!this._isShared || !this._rescc.private) && // the Authorization header field does not appear in the request, if the cache is shared,
(!this._isShared || this._noAuthorization || this._allowsStoringAuthenticated()) && // the response either:
// contains an Expires header field, or
(this._resHeaders.expires || // contains a max-age response directive, or
// contains a s-maxage response directive and the cache is shared, or
// contains a public response directive.
this._rescc["max-age"] || this._isShared && this._rescc["s-maxage"] || this._rescc.public || // has a status code that is defined as cacheable by default
statusCodeCacheableByDefault.has(this._status)));
}
_hasExplicitExpiration() {
return this._isShared && this._rescc["s-maxage"] || this._rescc["max-age"] || this._resHeaders.expires;
}
_assertRequestHasHeaders(req) {
if (!req || !req.headers) {
throw Error("Request headers missing");
}
}
satisfiesWithoutRevalidation(req) {
this._assertRequestHasHeaders(req);
const requestCC = parseCacheControl(req.headers["cache-control"]);
if (requestCC["no-cache"] || /no-cache/.test(req.headers.pragma)) {
return false;
}
if (requestCC["max-age"] && this.age() > requestCC["max-age"]) {
return false;
}
if (requestCC["min-fresh"] && this.timeToLive() < 1e3 * requestCC["min-fresh"]) {
return false;
}
if (this.stale()) {
const allowsStale = requestCC["max-stale"] && !this._rescc["must-revalidate"] && (true === requestCC["max-stale"] || requestCC["max-stale"] > this.age() - this.maxAge());
if (!allowsStale) {
return false;
}
}
return this._requestMatches(req, false);
}
_requestMatches(req, allowHeadMethod) {
return (!this._url || this._url === req.url) && this._host === req.headers.host && // the request method associated with the stored response allows it to be used for the presented request, and
(!req.method || this._method === req.method || allowHeadMethod && "HEAD" === req.method) && // selecting header fields nominated by the stored response (if any) match those presented, and
this._varyMatches(req);
}
_allowsStoringAuthenticated() {
return this._rescc["must-revalidate"] || this._rescc.public || this._rescc["s-maxage"];
}
_varyMatches(req) {
if (!this._resHeaders.vary) {
return true;
}
if (this._resHeaders.vary === "*") {
return false;
}
const fields = this._resHeaders.vary.trim().toLowerCase().split(/\s*,\s*/);
for (const name of fields) {
if (req.headers[name] !== this._reqHeaders[name])
return false;
}
return true;
}
_copyWithoutHopByHopHeaders(inHeaders) {
const headers = {};
for (const name in inHeaders) {
if (hopByHopHeaders[name])
continue;
headers[name] = inHeaders[name];
}
if (inHeaders.connection) {
const tokens = inHeaders.connection.trim().split(/\s*,\s*/);
for (const name of tokens) {
delete headers[name];
}
}
if (headers.warning) {
const warnings = headers.warning.split(/,/).filter((warning) => {
return !/^\s*1[0-9][0-9]/.test(warning);
});
if (!warnings.length) {
delete headers.warning;
} else {
headers.warning = warnings.join(",").trim();
}
}
return headers;
}
responseHeaders() {
const headers = this._copyWithoutHopByHopHeaders(this._resHeaders);
const age = this.age();
if (age > 3600 * 24 && !this._hasExplicitExpiration() && this.maxAge() > 3600 * 24) {
headers.warning = (headers.warning ? `${headers.warning}, ` : "") + '113 - "rfc7234 5.5.4"';
}
headers.age = `${Math.round(age)}`;
headers.date = new Date(this.now()).toUTCString();
return headers;
}
/**
* Value of the Date response header or current time if Date was invalid
* @return timestamp
*/
date() {
const serverDate = Date.parse(this._resHeaders.date);
if (isFinite(serverDate)) {
return serverDate;
}
return this._responseTime;
}
/**
* Value of the Age header, in seconds, updated for the current time.
* May be fractional.
*
* @return Number
*/
age() {
let age = this._ageValue();
const residentTime = (this.now() - this._responseTime) / 1e3;
return age + residentTime;
}
_ageValue() {
return toNumberOrZero(this._resHeaders.age);
}
/**
* Value of applicable max-age (or heuristic equivalent) in seconds. This counts since response's `Date`.
*
* For an up-to-date value, see `timeToLive()`.
*
* @return Number
*/
maxAge() {
if (!this.storable() || this._rescc["no-cache"]) {
return 0;
}
if (this._isShared && (this._resHeaders["set-cookie"] && !this._rescc.public && !this._rescc.immutable)) {
return 0;
}
if (this._resHeaders.vary === "*") {
return 0;
}
if (this._isShared) {
if (this._rescc["proxy-revalidate"]) {
return 0;
}
if (this._rescc["s-maxage"]) {
return toNumberOrZero(this._rescc["s-maxage"]);
}
}
if (this._rescc["max-age"]) {
return toNumberOrZero(this._rescc["max-age"]);
}
const defaultMinTtl = this._rescc.immutable ? this._immutableMinTtl : 0;
const serverDate = this.date();
if (this._resHeaders.expires) {
const expires = Date.parse(this._resHeaders.expires);
if (Number.isNaN(expires) || expires < serverDate) {
return 0;
}
return Math.max(defaultMinTtl, (expires - serverDate) / 1e3);
}
if (this._resHeaders["last-modified"]) {
const lastModified = Date.parse(this._resHeaders["last-modified"]);
if (isFinite(lastModified) && serverDate > lastModified) {
return Math.max(
defaultMinTtl,
(serverDate - lastModified) / 1e3 * this._cacheHeuristic
);
}
}
return defaultMinTtl;
}
timeToLive() {
const age = this.maxAge() - this.age();
const staleIfErrorAge = age + toNumberOrZero(this._rescc["stale-if-error"]);
const staleWhileRevalidateAge = age + toNumberOrZero(this._rescc["stale-while-revalidate"]);
return Math.max(0, age, staleIfErrorAge, staleWhileRevalidateAge) * 1e3;
}
stale() {
return this.maxAge() <= this.age();
}
_useStaleIfError() {
return this.maxAge() + toNumberOrZero(this._rescc["stale-if-error"]) > this.age();
}
useStaleWhileRevalidate() {
return this.maxAge() + toNumberOrZero(this._rescc["stale-while-revalidate"]) > this.age();
}
static fromObject(obj) {
return new this(void 0, void 0, { _fromObject: obj });
}
_fromObject(obj) {
if (this._responseTime)
throw Error("Reinitialized");
if (!obj || obj.v !== 1)
throw Error("Invalid serialization");
this._responseTime = obj.t;
this._isShared = obj.sh;
this._cacheHeuristic = obj.ch;
this._immutableMinTtl = obj.imm !== void 0 ? obj.imm : 24 * 3600 * 1e3;
this._status = obj.st;
this._resHeaders = obj.resh;
this._rescc = obj.rescc;
this._method = obj.m;
this._url = obj.u;
this._host = obj.h;
this._noAuthorization = obj.a;
this._reqHeaders = obj.reqh;
this._reqcc = obj.reqcc;
}
toObject() {
return {
v: 1,
t: this._responseTime,
sh: this._isShared,
ch: this._cacheHeuristic,
imm: this._immutableMinTtl,
st: this._status,
resh: this._resHeaders,
rescc: this._rescc,
m: this._method,
u: this._url,
h: this._host,
a: this._noAuthorization,
reqh: this._reqHeaders,
reqcc: this._reqcc
};
}
/**
* Headers for sending to the origin server to revalidate stale response.
* Allows server to return 304 to allow reuse of the previous response.
*
* Hop by hop headers are always stripped.
* Revalidation headers may be added or removed, depending on request.
*/
revalidationHeaders(incomingReq) {
this._assertRequestHasHeaders(incomingReq);
const headers = this._copyWithoutHopByHopHeaders(incomingReq.headers);
delete headers["if-range"];
if (!this._requestMatches(incomingReq, true) || !this.storable()) {
delete headers["if-none-match"];
delete headers["if-modified-since"];
return headers;
}
if (this._resHeaders.etag) {
headers["if-none-match"] = headers["if-none-match"] ? `${headers["if-none-match"]}, ${this._resHeaders.etag}` : this._resHeaders.etag;
}
const forbidsWeakValidators = headers["accept-ranges"] || headers["if-match"] || headers["if-unmodified-since"] || this._method && this._method != "GET";
if (forbidsWeakValidators) {
delete headers["if-modified-since"];
if (headers["if-none-match"]) {
const etags = headers["if-none-match"].split(/,/).filter((etag) => {
return !/^\s*W\//.test(etag);
});
if (!etags.length) {
delete headers["if-none-match"];
} else {
headers["if-none-match"] = etags.join(",").trim();
}
}
} else if (this._resHeaders["last-modified"] && !headers["if-modified-since"]) {
headers["if-modified-since"] = this._resHeaders["last-modified"];
}
return headers;
}
/**
* Creates new CachePolicy with information combined from the previews response,
* and the new revalidation response.
*
* Returns {policy, modified} where modified is a boolean indicating
* whether the response body has been modified, and old cached body can't be used.
*
* @return {Object} {policy: CachePolicy, modified: Boolean}
*/
revalidatedPolicy(request, response) {
this._assertRequestHasHeaders(request);
if (this._useStaleIfError() && isErrorResponse(response)) {
return {
modified: false,
matches: false,
policy: this
};
}
if (!response || !response.headers) {
throw Error("Response headers missing");
}
let matches = false;
if (response.status !== void 0 && response.status != 304) {
matches = false;
} else if (response.headers.etag && !/^\s*W\//.test(response.headers.etag)) {
matches = this._resHeaders.etag && this._resHeaders.etag.replace(/^\s*W\//, "") === response.headers.etag;
} else if (this._resHeaders.etag && response.headers.etag) {
matches = this._resHeaders.etag.replace(/^\s*W\//, "") === response.headers.etag.replace(/^\s*W\//, "");
} else if (this._resHeaders["last-modified"]) {
matches = this._resHeaders["last-modified"] === response.headers["last-modified"];
} else {
if (!this._resHeaders.etag && !this._resHeaders["last-modified"] && !response.headers.etag && !response.headers["last-modified"]) {
matches = true;
}
}
if (!matches) {
return {
policy: new this.constructor(request, response),
// Client receiving 304 without body, even if it's invalid/mismatched has no option
// but to reuse a cached body. We don't have a good way to tell clients to do
// error recovery in such case.
modified: response.status != 304,
matches: false
};
}
const headers = {};
for (const k in this._resHeaders) {
headers[k] = k in response.headers && !excludedFromRevalidationUpdate[k] ? response.headers[k] : this._resHeaders[k];
}
const newResponse = Object.assign({}, response, {
status: this._status,
method: this._method,
headers
});
return {
policy: new this.constructor(request, newResponse, {
shared: this._isShared,
cacheHeuristic: this._cacheHeuristic,
immutableMinTimeToLive: this._immutableMinTtl
}),
modified: false,
matches: true
};
}
};
}
});
// node_modules/json-buffer/index.js
var require_json_buffer = __commonJS({
"node_modules/json-buffer/index.js"(exports2) {
exports2.stringify = function stringify(o) {
if ("undefined" == typeof o)
return o;
if (o && Buffer.isBuffer(o))
return JSON.stringify(":base64:" + o.toString("base64"));
if (o && o.toJSON)
o = o.toJSON();
if (o && "object" === typeof o) {
var s = "";
var array = Array.isArray(o);
s = array ? "[" : "{";
var first = true;
for (var k in o) {
var ignore = "function" == typeof o[k] || !array && "undefined" === typeof o[k];
if (Object.hasOwnProperty.call(o, k) && !ignore) {
if (!first)
s += ",";
first = false;
if (array) {
if (o[k] == void 0)
s += "null";
else
s += stringify(o[k]);
} else if (o[k] !== void 0) {
s += stringify(k) + ":" + stringify(o[k]);
}
}
}
s += array ? "]" : "}";
return s;
} else if ("string" === typeof o) {
return JSON.stringify(/^:/.test(o) ? ":" + o : o);
} else if ("undefined" === typeof o) {
return "null";
} else
return JSON.stringify(o);
};
exports2.parse = function(s) {
return JSON.parse(s, function(key, value) {
if ("string" === typeof value) {
if (/^:base64:/.test(value))
return Buffer.from(value.substring(8), "base64");
else
return /^:/.test(value) ? value.substring(1) : value;
}
return value;
});
};
}
});
// node_modules/keyv/src/index.js
var require_src = __commonJS({
"node_modules/keyv/src/index.js"(exports2, module2) {
"use strict";
var EventEmitter4 = require("events");
var JSONB = require_json_buffer();
var loadStore = (options) => {
const adapters = {
redis: "@keyv/redis",
rediss: "@keyv/redis",
mongodb: "@keyv/mongo",
mongo: "@keyv/mongo",
sqlite: "@keyv/sqlite",
postgresql: "@keyv/postgres",
postgres: "@keyv/postgres",
mysql: "@keyv/mysql",
etcd: "@keyv/etcd",
offline: "@keyv/offline",
tiered: "@keyv/tiered"
};
if (options.adapter || options.uri) {
const adapter = options.adapter || /^[^:+]*/.exec(options.uri)[0];
return new (require(adapters[adapter]))(options);
}
return /* @__PURE__ */ new Map();
};
var iterableAdapters = [
"sqlite",
"postgres",
"mysql",
"mongo",
"redis",
"tiered"
];
var Keyv2 = class extends EventEmitter4 {
constructor(uri, { emitErrors = true, ...options } = {}) {
super();
this.opts = {
namespace: "keyv",
serialize: JSONB.stringify,
deserialize: JSONB.parse,
...typeof uri === "string" ? { uri } : uri,
...options
};
if (!this.opts.store) {
const adapterOptions = { ...this.opts };
this.opts.store = loadStore(adapterOptions);
}
if (this.opts.compression) {
const compression = this.opts.compression;
this.opts.serialize = compression.serialize.bind(compression);
this.opts.deserialize = compression.deserialize.bind(compression);
}
if (typeof this.opts.store.on === "function" && emitErrors) {
this.opts.store.on("error", (error) => this.emit("error", error));
}
this.opts.store.namespace = this.opts.namespace;
const generateIterator = (iterator) => async function* () {
for await (const [key, raw] of typeof iterator === "function" ? iterator(this.opts.store.namespace) : iterator) {
const data = await this.opts.deserialize(raw);
if (this.opts.store.namespace && !key.includes(this.opts.store.namespace)) {
continue;
}
if (typeof data.expires === "number" && Date.now() > data.expires) {
this.delete(key);
continue;
}
yield [this._getKeyUnprefix(key), data.value];
}
};
if (typeof this.opts.store[Symbol.iterator] === "function" && this.opts.store instanceof Map) {
this.iterator = generateIterator(this.opts.store);
} else if (typeof this.opts.store.iterator === "function" && this.opts.store.opts && this._checkIterableAdaptar()) {
this.iterator = generateIterator(this.opts.store.iterator.bind(this.opts.store));
}
}
_checkIterableAdaptar() {
return iterableAdapters.includes(this.opts.store.opts.dialect) || iterableAdapters.findIndex((element) => this.opts.store.opts.url.includes(element)) >= 0;
}
_getKeyPrefix(key) {
return `${this.opts.namespace}:${key}`;
}
_getKeyPrefixArray(keys) {
return keys.map((key) => `${this.opts.namespace}:${key}`);
}
_getKeyUnprefix(key) {
return key.split(":").splice(1).join(":");
}
get(key, options) {
const { store } = this.opts;
const isArray = Array.isArray(key);
const keyPrefixed = isArray ? this._getKeyPrefixArray(key) : this._getKeyPrefix(key);
if (isArray && store.getMany === void 0) {
const promises = [];
for (const key2 of keyPrefixed) {
promises.push(
Promise.resolve().then(() => store.get(key2)).then((data) => typeof data === "string" ? this.opts.deserialize(data) : this.opts.compression ? this.opts.deserialize(data) : data).then((data) => {
if (data === void 0 || data === null) {
return void 0;
}
if (typeof data.expires === "number" && Date.now() > data.expires) {
return this.delete(key2).then(() => void 0);
}
return options && options.raw ? data : data.value;
})
);
}
return Promise.allSettled(promises).then((values) => {
const data = [];
for (const value of values) {
data.push(value.value);
}
return data;
});
}
return Promise.resolve().then(() => isArray ? store.getMany(keyPrefixed) : store.get(keyPrefixed)).then((data) => typeof data === "string" ? this.opts.deserialize(data) : this.opts.compression ? this.opts.deserialize(data) : data).then((data) => {
if (data === void 0 || data === null) {
return void 0;
}
if (isArray) {
const result = [];
for (let row of data) {
if (typeof row === "string") {
row = this.opts.deserialize(row);
}
if (row === void 0 || row === null) {
result.push(void 0);
continue;
}
if (typeof row.expires === "number" && Date.now() > row.expires) {
this.delete(key).then(() => void 0);
result.push(void 0);
} else {
result.push(options && options.raw ? row : row.value);
}
}
return result;
}
if (typeof data.expires === "number" && Date.now() > data.expires) {
return this.delete(key).then(() => void 0);
}
return options && options.raw ? data : data.value;
});
}
set(key, value, ttl2) {
const keyPrefixed = this._getKeyPrefix(key);
if (typeof ttl2 === "undefined") {
ttl2 = this.opts.ttl;
}
if (ttl2 === 0) {
ttl2 = void 0;
}
const { store } = this.opts;
return Promise.resolve().then(() => {
const expires = typeof ttl2 === "number" ? Date.now() + ttl2 : null;
if (typeof value === "symbol") {
this.emit("error", "symbol cannot be serialized");
}
value = { value, expires };
return this.opts.serialize(value);
}).then((value2) => store.set(keyPrefixed, value2, ttl2)).then(() => true);
}
delete(key) {
const { store } = this.opts;
if (Array.isArray(key)) {
const keyPrefixed2 = this._getKeyPrefixArray(key);
if (store.deleteMany === void 0) {
const promises = [];
for (const key2 of keyPrefixed2) {
promises.push(store.delete(key2));
}
return Promise.allSettled(promises).then((values) => values.every((x) => x.value === true));
}
return Promise.resolve().then(() => store.deleteMany(keyPrefixed2));
}
const keyPrefixed = this._getKeyPrefix(key);
return Promise.resolve().then(() => store.delete(keyPrefixed));
}
clear() {
const { store } = this.opts;
return Promise.resolve().then(() => store.clear());
}
has(key) {
const keyPrefixed = this._getKeyPrefix(key);
const { store } = this.opts;
return Promise.resolve().then(async () => {
if (typeof store.has === "function") {
return store.has(keyPrefixed);
}
const value = await store.get(keyPrefixed);
return value !== void 0;
});
}
disconnect() {
const { store } = this.opts;
if (typeof store.disconnect === "function") {
return store.disconnect();
}
}
};
module2.exports = Keyv2;
}
});
// node_modules/decompress-response/node_modules/mimic-response/index.js
var require_mimic_response = __commonJS({
"node_modules/decompress-response/node_modules/mimic-response/index.js"(exports2, module2) {
"use strict";
var knownProperties2 = [
"aborted",
"complete",
"headers",
"httpVersion",
"httpVersionMinor",
"httpVersionMajor",
"method",
"rawHeaders",
"rawTrailers",
"setTimeout",
"socket",
"statusCode",
"statusMessage",
"trailers",
"url"
];
module2.exports = (fromStream, toStream) => {
if (toStream._readableState.autoDestroy) {
throw new Error("The second stream must have the `autoDestroy` option set to `false`");
}
const fromProperties = new Set(Object.keys(fromStream).concat(knownProperties2));
const properties = {};
for (const property of fromProperties) {
if (property in toStream) {
continue;
}
properties[property] = {
get() {
const value = fromStream[property];
const isFunction2 = typeof value === "function";
return isFunction2 ? value.bind(fromStream) : value;
},
set(value) {
fromStream[property] = value;
},
enumerable: true,
configurable: false
};
}
Object.defineProperties(toStream, properties);
fromStream.once("aborted", () => {
toStream.destroy();
toStream.emit("aborted");
});
fromStream.once("close", () => {
if (fromStream.complete) {
if (toStream.readable) {
toStream.once("end", () => {
toStream.emit("close");
});
} else {
toStream.emit("close");
}
} else {
toStream.emit("close");
}
});
return toStream;
};
}
});
// node_modules/decompress-response/index.js
var require_decompress_response = __commonJS({
"node_modules/decompress-response/index.js"(exports2, module2) {
"use strict";
var { Transform, PassThrough } = require("stream");
var zlib = require("zlib");
var mimicResponse2 = require_mimic_response();
module2.exports = (response) => {
const contentEncoding = (response.headers["content-encoding"] || "").toLowerCase();
if (!["gzip", "deflate", "br"].includes(contentEncoding)) {
return response;
}
const isBrotli = contentEncoding === "br";
if (isBrotli && typeof zlib.createBrotliDecompress !== "function") {
response.destroy(new Error("Brotli is not supported on Node.js < 12"));
return response;
}
let isEmpty = true;
const checker = new Transform({
transform(data, _encoding, callback) {
isEmpty = false;
callback(null, data);
},
flush(callback) {
callback();
}
});
const finalStream = new PassThrough({
autoDestroy: false,
destroy(error, callback) {
response.destroy();
callback(error);
}
});
const decompressStream = isBrotli ? zlib.createBrotliDecompress() : zlib.createUnzip();
decompressStream.once("error", (error) => {
if (isEmpty && !response.readable) {
finalStream.end();
return;
}
finalStream.destroy(error);
});
mimicResponse2(response, finalStream);
response.pipe(checker).pipe(decompressStream).pipe(finalStream);
return finalStream;
};
}
});
// node_modules/quick-lru/index.js
var require_quick_lru = __commonJS({
"node_modules/quick-lru/index.js"(exports2, module2) {
"use strict";
var QuickLRU = class {
constructor(options = {}) {
if (!(options.maxSize && options.maxSize > 0)) {
throw new TypeError("`maxSize` must be a number greater than 0");
}
this.maxSize = options.maxSize;
this.onEviction = options.onEviction;
this.cache = /* @__PURE__ */ new Map();
this.oldCache = /* @__PURE__ */ new Map();
this._size = 0;
}
_set(key, value) {
this.cache.set(key, value);
this._size++;
if (this._size >= this.maxSize) {
this._size = 0;
if (typeof this.onEviction === "function") {
for (const [key2, value2] of this.oldCache.entries()) {
this.onEviction(key2, value2);
}
}
this.oldCache = this.cache;
this.cache = /* @__PURE__ */ new Map();
}
}
get(key) {
if (this.cache.has(key)) {
return this.cache.get(key);
}
if (this.oldCache.has(key)) {
const value = this.oldCache.get(key);
this.oldCache.delete(key);
this._set(key, value);
return value;
}
}
set(key, value) {
if (this.cache.has(key)) {
this.cache.set(key, value);
} else {
this._set(key, value);
}
return this;
}
has(key) {
return this.cache.has(key) || this.oldCache.has(key);
}
peek(key) {
if (this.cache.has(key)) {
return this.cache.get(key);
}
if (this.oldCache.has(key)) {
return this.oldCache.get(key);
}
}
delete(key) {
const deleted = this.cache.delete(key);
if (deleted) {
this._size--;
}
return this.oldCache.delete(key) || deleted;
}
clear() {
this.cache.clear();
this.oldCache.clear();
this._size = 0;
}
*keys() {
for (const [key] of this) {
yield key;
}
}
*values() {
for (const [, value] of this) {
yield value;
}
}
*[Symbol.iterator]() {
for (const item of this.cache) {
yield item;
}
for (const item of this.oldCache) {
const [key] = item;
if (!this.cache.has(key)) {
yield item;
}
}
}
get size() {
let oldCacheSize = 0;
for (const key of this.oldCache.keys()) {
if (!this.cache.has(key)) {
oldCacheSize++;
}
}
return Math.min(this._size + oldCacheSize, this.maxSize);
}
};
module2.exports = QuickLRU;
}
});
// node_modules/http2-wrapper/source/utils/delay-async-destroy.js
var require_delay_async_destroy = __commonJS({
"node_modules/http2-wrapper/source/utils/delay-async-destroy.js"(exports2, module2) {
"use strict";
module2.exports = (stream2) => {
if (stream2.listenerCount("error") !== 0) {
return stream2;
}
stream2.__destroy = stream2._destroy;
stream2._destroy = (...args) => {
const callback = args.pop();
stream2.__destroy(...args, async (error) => {
await Promise.resolve();
callback(error);
});
};
const onError = (error) => {
Promise.resolve().then(() => {
stream2.emit("error", error);
});
};
stream2.once("error", onError);
Promise.resolve().then(() => {
stream2.off("error", onError);
});
return stream2;
};
}
});
// node_modules/http2-wrapper/source/agent.js
var require_agent = __commonJS({
"node_modules/http2-wrapper/source/agent.js"(exports2, module2) {
"use strict";
var { URL: URL2 } = require("url");
var EventEmitter4 = require("events");
var tls = require("tls");
var http22 = require("http2");
var QuickLRU = require_quick_lru();
var delayAsyncDestroy = require_delay_async_destroy();
var kCurrentStreamCount = Symbol("currentStreamCount");
var kRequest = Symbol("request");
var kOriginSet = Symbol("cachedOriginSet");
var kGracefullyClosing = Symbol("gracefullyClosing");
var kLength = Symbol("length");
var nameKeys = [
// Not an Agent option actually
"createConnection",
// `http2.connect()` options
"maxDeflateDynamicTableSize",
"maxSettings",
"maxSessionMemory",
"maxHeaderListPairs",
"maxOutstandingPings",
"maxReservedRemoteStreams",
"maxSendHeaderBlockLength",
"paddingStrategy",
"peerMaxConcurrentStreams",
"settings",
// `tls.connect()` source options
"family",
"localAddress",
"rejectUnauthorized",
// `tls.connect()` secure context options
"pskCallback",
"minDHSize",
// `tls.connect()` destination options
// - `servername` is automatically validated, skip it
// - `host` and `port` just describe the destination server,
"path",
"socket",
// `tls.createSecureContext()` options
"ca",
"cert",
"sigalgs",
"ciphers",
"clientCertEngine",
"crl",
"dhparam",
"ecdhCurve",
"honorCipherOrder",
"key",
"privateKeyEngine",
"privateKeyIdentifier",
"maxVersion",
"minVersion",
"pfx",
"secureOptions",
"secureProtocol",
"sessionIdContext",
"ticketKeys"
];
var getSortedIndex = (array, value, compare) => {
let low = 0;
let high = array.length;
while (low < high) {
const mid = low + high >>> 1;
if (compare(array[mid], value)) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
};
var compareSessions = (a, b) => a.remoteSettings.maxConcurrentStreams > b.remoteSettings.maxConcurrentStreams;
var closeCoveredSessions = (where, session) => {
for (let index = 0; index < where.length; index++) {
const coveredSession = where[index];
if (
// Unfortunately `.every()` returns true for an empty array
coveredSession[kOriginSet].length > 0 && coveredSession[kOriginSet].length < session[kOriginSet].length && coveredSession[kOriginSet].every((origin) => session[kOriginSet].includes(origin)) && coveredSession[kCurrentStreamCount] + session[kCurrentStreamCount] <= session.remoteSettings.maxConcurrentStreams
) {
gracefullyClose(coveredSession);
}
}
};
var closeSessionIfCovered = (where, coveredSession) => {
for (let index = 0; index < where.length; index++) {
const session = where[index];
if (coveredSession[kOriginSet].length > 0 && coveredSession[kOriginSet].length < session[kOriginSet].length && coveredSession[kOriginSet].every((origin) => session[kOriginSet].includes(origin)) && coveredSession[kCurrentStreamCount] + session[kCurrentStreamCount] <= session.remoteSettings.maxConcurrentStreams) {
gracefullyClose(coveredSession);
return true;
}
}
return false;
};
var gracefullyClose = (session) => {
session[kGracefullyClosing] = true;
if (session[kCurrentStreamCount] === 0) {
session.close();
}
};
var Agent = class _Agent extends EventEmitter4 {
constructor({ timeout = 0, maxSessions = Number.POSITIVE_INFINITY, maxEmptySessions = 10, maxCachedTlsSessions = 100 } = {}) {
super();
this.sessions = {};
this.queue = {};
this.timeout = timeout;
this.maxSessions = maxSessions;
this.maxEmptySessions = maxEmptySessions;
this._emptySessionCount = 0;
this._sessionCount = 0;
this.settings = {
enablePush: false,
initialWindowSize: 1024 * 1024 * 32
// 32MB, see https://github.com/nodejs/node/issues/38426
};
this.tlsSessionCache = new QuickLRU({ maxSize: maxCachedTlsSessions });
}
get protocol() {
return "https:";
}
normalizeOptions(options) {
let normalized = "";
for (let index = 0; index < nameKeys.length; index++) {
const key = nameKeys[index];
normalized += ":";
if (options && options[key] !== void 0) {
normalized += options[key];
}
}
return normalized;
}
_processQueue() {
if (this._sessionCount >= this.maxSessions) {
this.closeEmptySessions(this.maxSessions - this._sessionCount + 1);
return;
}
for (const normalizedOptions in this.queue) {
for (const normalizedOrigin in this.queue[normalizedOptions]) {
const item = this.queue[normalizedOptions][normalizedOrigin];
if (!item.completed) {
item.completed = true;
item();
}
}
}
}
_isBetterSession(thisStreamCount, thatStreamCount) {
return thisStreamCount > thatStreamCount;
}
_accept(session, listeners, normalizedOrigin, options) {
let index = 0;
while (index < listeners.length && session[kCurrentStreamCount] < session.remoteSettings.maxConcurrentStreams) {
listeners[index].resolve(session);
index++;
}
listeners.splice(0, index);
if (listeners.length > 0) {
this.getSession(normalizedOrigin, options, listeners);
listeners.length = 0;
}
}
getSession(origin, options, listeners) {
return new Promise((resolve, reject) => {
if (Array.isArray(listeners) && listeners.length > 0) {
listeners = [...listeners];
resolve();
} else {
listeners = [{ resolve, reject }];
}
try {
if (typeof origin === "string") {
origin = new URL2(origin);
} else if (!(origin instanceof URL2)) {
throw new TypeError("The `origin` argument needs to be a string or an URL object");
}
if (options) {
const { servername } = options;
const { hostname } = origin;
if (servername && hostname !== servername) {
throw new Error(`Origin ${hostname} differs from servername ${servername}`);
}
}
} catch (error) {
for (let index = 0; index < listeners.length; index++) {
listeners[index].reject(error);
}
return;
}
const normalizedOptions = this.normalizeOptions(options);
const normalizedOrigin = origin.origin;
if (normalizedOptions in this.sessions) {
const sessions = this.sessions[normalizedOptions];
let maxConcurrentStreams = -1;
let currentStreamsCount = -1;
let optimalSession;
for (let index = 0; index < sessions.length; index++) {
const session = sessions[index];
const sessionMaxConcurrentStreams = session.remoteSettings.maxConcurrentStreams;
if (sessionMaxConcurrentStreams < maxConcurrentStreams) {
break;
}
if (!session[kOriginSet].includes(normalizedOrigin)) {
continue;
}
const sessionCurrentStreamsCount = session[kCurrentStreamCount];
if (sessionCurrentStreamsCount >= sessionMaxConcurrentStreams || session[kGracefullyClosing] || session.destroyed) {
continue;
}
if (!optimalSession) {
maxConcurrentStreams = sessionMaxConcurrentStreams;
}
if (this._isBetterSession(sessionCurrentStreamsCount, currentStreamsCount)) {
optimalSession = session;
currentStreamsCount = sessionCurrentStreamsCount;
}
}
if (optimalSession) {
this._accept(optimalSession, listeners, normalizedOrigin, options);
return;
}
}
if (normalizedOptions in this.queue) {
if (normalizedOrigin in this.queue[normalizedOptions]) {
this.queue[normalizedOptions][normalizedOrigin].listeners.push(...listeners);
return;
}
} else