@cloudflare/vitest-pool-workers
Version:
Workers Vitest integration for writing Vitest unit and integration tests that run inside the Workers runtime
1,392 lines (1,374 loc) • 128 kB
JavaScript
import { createRequire } from "node:module";
import assert from "node:assert";
import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import util from "node:util";
import os from "node:os";
import net from "node:net";
import fs$1 from "node:fs/promises";
import { Log, LogLevel, Miniflare, ModuleRuleTypeSchema, PLUGINS, Response, compileModuleRules, formatZodError, getNodeCompat, getRootPath, kCurrentWorker, kUnsafeEphemeralUniqueKey, maybeApply, mergeWorkerOptions, parseWithRootPath, structuredSerializableReducers, structuredSerializableRevivers, testRegExps } from "miniflare";
import { experimental_readRawConfig } from "wrangler";
import { build } from "esbuild";
import posixPath from "node:path/posix";
import * as cjsModuleLexer from "cjs-module-lexer";
import { z } from "zod";
//#region rolldown:runtime
var __create = Object.create;
var __defProp$1 = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp$1(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp$1(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
//#region ../workers-utils/dist/chunk-OZQVB3L3.mjs
var INHERIT_SYMBOL = Symbol.for("inherit_binding");
var SERVICE_TAG_PREFIX = "cf:service=";
var ENVIRONMENT_TAG_PREFIX = "cf:environment=";
//#endregion
//#region ../workers-utils/dist/chunk-DCOBXSFB.mjs
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", {
value,
configurable: true
});
//#endregion
//#region ../workers-utils/dist/chunk-BLWXWFJK.mjs
function isCompatDate(str) {
return /^\d{4}-\d{2}-\d{2}$/.test(str);
}
__name(isCompatDate, "isCompatDate");
function formatCompatibilityDate(date) {
const compatDate = date.toISOString().slice(0, 10);
assert(isCompatDate(compatDate));
return compatDate;
}
__name(formatCompatibilityDate, "formatCompatibilityDate");
function getTodaysCompatDate() {
return formatCompatibilityDate(/* @__PURE__ */ new Date());
}
__name(getTodaysCompatDate, "getTodaysCompatDate");
function assertNever(_value) {}
__name(assertNever, "assertNever");
function mapWorkerMetadataBindings(bindings) {
return bindings.filter((binding) => binding.type !== "secret_text").reduce((configObj, binding) => {
switch (binding.type) {
case "plain_text":
configObj.vars = {
...configObj.vars ?? {},
[binding.name]: binding.text
};
break;
case "json":
configObj.vars = {
...configObj.vars ?? {},
name: binding.name,
json: binding.json
};
break;
case "kv_namespace":
configObj.kv_namespaces = [...configObj.kv_namespaces ?? [], {
id: binding.namespace_id,
binding: binding.name
}];
break;
case "durable_object_namespace":
configObj.durable_objects = { bindings: [...configObj.durable_objects?.bindings ?? [], {
name: binding.name,
class_name: binding.class_name,
script_name: binding.script_name,
environment: binding.environment
}] };
break;
case "d1":
configObj.d1_databases = [...configObj.d1_databases ?? [], {
binding: binding.name,
database_id: binding.id
}];
break;
case "browser":
configObj.browser = { binding: binding.name };
break;
case "ai":
configObj.ai = { binding: binding.name };
break;
case "images":
configObj.images = { binding: binding.name };
break;
case "stream":
configObj.stream = { binding: binding.name };
break;
case "media":
configObj.media = { binding: binding.name };
break;
case "r2_bucket":
configObj.r2_buckets = [...configObj.r2_buckets ?? [], {
binding: binding.name,
bucket_name: binding.bucket_name,
jurisdiction: binding.jurisdiction
}];
break;
case "secrets_store_secret":
configObj.secrets_store_secrets = [...configObj.secrets_store_secrets ?? [], {
binding: binding.name,
store_id: binding.store_id,
secret_name: binding.secret_name
}];
break;
case "artifacts":
configObj.artifacts = [...configObj.artifacts ?? [], {
binding: binding.name,
namespace: binding.namespace
}];
break;
case "unsafe_hello_world":
configObj.unsafe_hello_world = [...configObj.unsafe_hello_world ?? [], {
binding: binding.name,
enable_timer: binding.enable_timer
}];
break;
case "flagship":
configObj.flagship = [...configObj.flagship ?? [], {
binding: binding.name,
app_id: binding.app_id
}];
break;
case "service":
configObj.services = [...configObj.services ?? [], {
binding: binding.name,
service: binding.service,
environment: binding.environment,
entrypoint: binding.entrypoint
}];
break;
case "analytics_engine":
configObj.analytics_engine_datasets = [...configObj.analytics_engine_datasets ?? [], {
binding: binding.name,
dataset: binding.dataset
}];
break;
case "dispatch_namespace":
configObj.dispatch_namespaces = [...configObj.dispatch_namespaces ?? [], {
binding: binding.name,
namespace: binding.namespace,
...binding.outbound && { outbound: {
service: binding.outbound.worker.service,
environment: binding.outbound.worker.environment,
parameters: binding.outbound.params?.map((p) => p.name) ?? []
} }
}];
break;
case "logfwdr":
configObj.logfwdr = { bindings: [...configObj.logfwdr?.bindings ?? [], {
name: binding.name,
destination: binding.destination
}] };
break;
case "wasm_module":
configObj.wasm_modules = {
...configObj.wasm_modules ?? {},
[binding.name]: binding.part
};
break;
case "text_blob":
configObj.text_blobs = {
...configObj.text_blobs ?? {},
[binding.name]: binding.part
};
break;
case "data_blob":
configObj.data_blobs = {
...configObj.data_blobs ?? {},
[binding.name]: binding.part
};
break;
case "secret_text": break;
case "version_metadata":
configObj.version_metadata = { binding: binding.name };
break;
case "send_email":
configObj.send_email = [...configObj.send_email ?? [], {
name: binding.name,
destination_address: binding.destination_address,
allowed_destination_addresses: binding.allowed_destination_addresses,
allowed_sender_addresses: binding.allowed_sender_addresses
}];
break;
case "queue":
configObj.queues ??= { producers: [] };
configObj.queues.producers = [...configObj.queues.producers ?? [], {
binding: binding.name,
queue: binding.queue_name,
delivery_delay: binding.delivery_delay
}];
break;
case "vectorize":
configObj.vectorize = [...configObj.vectorize ?? [], {
binding: binding.name,
index_name: binding.index_name
}];
break;
case "ai_search_namespace":
configObj.ai_search_namespaces = [...configObj.ai_search_namespaces ?? [], {
binding: binding.name,
namespace: binding.namespace
}];
break;
case "ai_search":
configObj.ai_search = [...configObj.ai_search ?? [], {
binding: binding.name,
instance_name: binding.instance_name
}];
break;
case "hyperdrive":
configObj.hyperdrive = [...configObj.hyperdrive ?? [], {
binding: binding.name,
id: binding.id
}];
break;
case "mtls_certificate":
configObj.mtls_certificates = [...configObj.mtls_certificates ?? [], {
binding: binding.name,
certificate_id: binding.certificate_id
}];
break;
case "pipelines":
configObj.pipelines = [...configObj.pipelines ?? [], {
binding: binding.name,
pipeline: binding.pipeline
}];
break;
case "assets":
configObj.assets = { binding: binding.name };
break;
case "inherit":
configObj.unsafe = {
bindings: [...configObj.unsafe?.bindings ?? [], binding],
metadata: configObj.unsafe?.metadata ?? void 0
};
break;
case "workflow":
configObj.workflows = [...configObj.workflows ?? [], {
binding: binding.name,
name: binding.workflow_name,
class_name: binding.class_name,
script_name: binding.script_name
}];
break;
case "worker_loader":
configObj.worker_loaders = [...configObj.worker_loaders ?? [], { binding: binding.name }];
break;
case "ratelimit":
configObj.ratelimits = [...configObj.ratelimits ?? [], {
name: binding.name,
namespace_id: binding.namespace_id,
simple: {
limit: binding.simple.limit,
period: binding.simple.period
}
}];
break;
case "vpc_service":
configObj.vpc_services = [...configObj.vpc_services ?? [], {
binding: binding.name,
service_id: binding.service_id
}];
break;
case "vpc_network":
if (binding.tunnel_id !== void 0) configObj.vpc_networks = [...configObj.vpc_networks ?? [], {
binding: binding.name,
tunnel_id: binding.tunnel_id
}];
else if (binding.network_id !== void 0) configObj.vpc_networks = [...configObj.vpc_networks ?? [], {
binding: binding.name,
network_id: binding.network_id
}];
break;
default: configObj.unsafe = {
bindings: [...configObj.unsafe?.bindings ?? [], binding],
metadata: configObj.unsafe?.metadata ?? void 0
};
}
return configObj;
}, {});
}
__name(mapWorkerMetadataBindings, "mapWorkerMetadataBindings");
function convertWorkerToWranglerConfig(config) {
const mappedBindings = mapWorkerMetadataBindings(config.bindings);
const durableObjectClassNames = config.bindings.filter((binding) => binding.type === "durable_object_namespace" && binding.script_name === config.name).map((durableObject) => durableObject.class_name);
const allRoutes = [...config.routes.map((r) => ({
pattern: r.pattern,
zone_name: r.zone_name
})), ...config.domains.map((c) => ({
pattern: c.hostname,
zone_name: c.zone_name,
custom_domain: true,
enabled: c.enabled,
previews_enabled: c.previews_enabled
}))];
return {
name: config.name,
main: config.entrypoint,
workers_dev: config.subdomain.enabled,
preview_urls: config.subdomain.previews_enabled,
compatibility_date: config.compatibility_date ?? getTodaysCompatDate(),
compatibility_flags: config.compatibility_flags,
...allRoutes.length ? { routes: allRoutes } : {},
placement: config.placement?.mode === "smart" ? { mode: "smart" } : void 0,
limits: config.limits,
...durableObjectClassNames.length && config.migration_tag ? { migrations: [{
tag: config.migration_tag,
new_classes: durableObjectClassNames
}] } : {},
...config.schedules.length ? { triggers: { crons: config.schedules.map((scheduled) => scheduled.cron) } } : {},
tail_consumers: config.tail_consumers ?? void 0,
observability: config.observability,
...mappedBindings
};
}
__name(convertWorkerToWranglerConfig, "convertWorkerToWranglerConfig");
function constructWranglerConfig(workerOrWorkers) {
let workers;
if (Array.isArray(workerOrWorkers)) workers = workerOrWorkers;
else workers = [workerOrWorkers];
const topLevelEnv = workers.find((w) => !w.tags?.some((t$4) => t$4.startsWith(ENVIRONMENT_TAG_PREFIX)));
const workerName = topLevelEnv?.name ?? workers[0].name;
const entrypoint = topLevelEnv?.entrypoint ?? workers[0].entrypoint;
let combinedConfig;
if (topLevelEnv) combinedConfig = convertWorkerToWranglerConfig(topLevelEnv);
else combinedConfig = {
name: workerName,
main: entrypoint
};
for (const env of workers) {
const serviceTag = env.tags?.find((t$4) => t$4 === `${SERVICE_TAG_PREFIX}${workerName}`);
const envTag = env.tags?.find((t$4) => t$4.startsWith(ENVIRONMENT_TAG_PREFIX));
if (serviceTag !== `${SERVICE_TAG_PREFIX}${workerName}` || envTag === void 0) continue;
const [_, envName] = envTag.split("=");
combinedConfig.env ??= {};
combinedConfig.env[envName] = convertWorkerToWranglerConfig(env);
}
return combinedConfig;
}
__name(constructWranglerConfig, "constructWranglerConfig");
//#endregion
//#region ../../node_modules/.pnpm/devalue@5.6.3/node_modules/devalue/src/utils.js
var DevalueError = class extends Error {
/**
* @param {string} message
* @param {string[]} keys
* @param {any} [value] - The value that failed to be serialized
* @param {any} [root] - The root value being serialized
*/
constructor(message, keys, value, root) {
super(message);
this.name = "DevalueError";
this.path = keys.join("");
this.value = value;
this.root = root;
}
};
/** @param {any} thing */
function is_primitive(thing) {
return Object(thing) !== thing;
}
const object_proto_names = /* @__PURE__ */ Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
/** @param {any} thing */
function is_plain_object(thing) {
const proto = Object.getPrototypeOf(thing);
return proto === Object.prototype || proto === null || Object.getPrototypeOf(proto) === null || Object.getOwnPropertyNames(proto).sort().join("\0") === object_proto_names;
}
/** @param {any} thing */
function get_type(thing) {
return Object.prototype.toString.call(thing).slice(8, -1);
}
/** @param {string} char */
function get_escaped_char(char) {
switch (char) {
case "\"": return "\\\"";
case "<": return "\\u003C";
case "\\": return "\\\\";
case "\n": return "\\n";
case "\r": return "\\r";
case " ": return "\\t";
case "\b": return "\\b";
case "\f": return "\\f";
case "\u2028": return "\\u2028";
case "\u2029": return "\\u2029";
default: return char < " " ? `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}` : "";
}
}
/** @param {string} str */
function stringify_string(str) {
let result = "";
let last_pos = 0;
const len = str.length;
for (let i = 0; i < len; i += 1) {
const char = str[i];
const replacement = get_escaped_char(char);
if (replacement) {
result += str.slice(last_pos, i) + replacement;
last_pos = i + 1;
}
}
return `"${last_pos === 0 ? str : result + str.slice(last_pos)}"`;
}
/** @param {Record<string | symbol, any>} object */
function enumerable_symbols(object) {
return Object.getOwnPropertySymbols(object).filter((symbol) => Object.getOwnPropertyDescriptor(object, symbol).enumerable);
}
const is_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
/** @param {string} key */
function stringify_key(key) {
return is_identifier.test(key) ? "." + key : "[" + JSON.stringify(key) + "]";
}
/** @param {string} s */
function is_valid_array_index(s) {
if (s.length === 0) return false;
if (s.length > 1 && s.charCodeAt(0) === 48) return false;
for (let i = 0; i < s.length; i++) {
const c = s.charCodeAt(i);
if (c < 48 || c > 57) return false;
}
const n = +s;
if (n >= 2 ** 32 - 1) return false;
if (n < 0) return false;
return true;
}
/**
* Finds the populated indices of an array.
* @param {unknown[]} array
*/
function valid_array_indices(array) {
const keys = Object.keys(array);
for (var i = keys.length - 1; i >= 0; i--) if (is_valid_array_index(keys[i])) break;
keys.length = i + 1;
return keys;
}
//#endregion
//#region ../../node_modules/.pnpm/devalue@5.6.3/node_modules/devalue/src/base64.js
/**
* Base64 Encodes an arraybuffer
* @param {ArrayBuffer} arraybuffer
* @returns {string}
*/
function encode64(arraybuffer) {
const dv = new DataView(arraybuffer);
let binaryString = "";
for (let i = 0; i < arraybuffer.byteLength; i++) binaryString += String.fromCharCode(dv.getUint8(i));
return binaryToAscii(binaryString);
}
/**
* Decodes a base64 string into an arraybuffer
* @param {string} string
* @returns {ArrayBuffer}
*/
function decode64(string) {
const binaryString = asciiToBinary(string);
const arraybuffer = new ArrayBuffer(binaryString.length);
const dv = new DataView(arraybuffer);
for (let i = 0; i < arraybuffer.byteLength; i++) dv.setUint8(i, binaryString.charCodeAt(i));
return arraybuffer;
}
const KEY_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/**
* Substitute for atob since it's deprecated in node.
* Does not do any input validation.
*
* @see https://github.com/jsdom/abab/blob/master/lib/atob.js
*
* @param {string} data
* @returns {string}
*/
function asciiToBinary(data) {
if (data.length % 4 === 0) data = data.replace(/==?$/, "");
let output = "";
let buffer = 0;
let accumulatedBits = 0;
for (let i = 0; i < data.length; i++) {
buffer <<= 6;
buffer |= KEY_STRING.indexOf(data[i]);
accumulatedBits += 6;
if (accumulatedBits === 24) {
output += String.fromCharCode((buffer & 16711680) >> 16);
output += String.fromCharCode((buffer & 65280) >> 8);
output += String.fromCharCode(buffer & 255);
buffer = accumulatedBits = 0;
}
}
if (accumulatedBits === 12) {
buffer >>= 4;
output += String.fromCharCode(buffer);
} else if (accumulatedBits === 18) {
buffer >>= 2;
output += String.fromCharCode((buffer & 65280) >> 8);
output += String.fromCharCode(buffer & 255);
}
return output;
}
/**
* Substitute for btoa since it's deprecated in node.
* Does not do any input validation.
*
* @see https://github.com/jsdom/abab/blob/master/lib/btoa.js
*
* @param {string} str
* @returns {string}
*/
function binaryToAscii(str) {
let out = "";
for (let i = 0; i < str.length; i += 3) {
/** @type {[number, number, number, number]} */
const groupsOfSix = [
void 0,
void 0,
void 0,
void 0
];
groupsOfSix[0] = str.charCodeAt(i) >> 2;
groupsOfSix[1] = (str.charCodeAt(i) & 3) << 4;
if (str.length > i + 1) {
groupsOfSix[1] |= str.charCodeAt(i + 1) >> 4;
groupsOfSix[2] = (str.charCodeAt(i + 1) & 15) << 2;
}
if (str.length > i + 2) {
groupsOfSix[2] |= str.charCodeAt(i + 2) >> 6;
groupsOfSix[3] = str.charCodeAt(i + 2) & 63;
}
for (let j = 0; j < groupsOfSix.length; j++) if (typeof groupsOfSix[j] === "undefined") out += "=";
else out += KEY_STRING[groupsOfSix[j]];
}
return out;
}
//#endregion
//#region ../../node_modules/.pnpm/devalue@5.6.3/node_modules/devalue/src/constants.js
const UNDEFINED = -1;
const HOLE = -2;
const NAN = -3;
const POSITIVE_INFINITY = -4;
const NEGATIVE_INFINITY = -5;
const NEGATIVE_ZERO = -6;
const SPARSE = -7;
//#endregion
//#region ../../node_modules/.pnpm/devalue@5.6.3/node_modules/devalue/src/parse.js
/**
* Revive a value serialized with `devalue.stringify`
* @param {string} serialized
* @param {Record<string, (value: any) => any>} [revivers]
*/
function parse(serialized, revivers) {
return unflatten(JSON.parse(serialized), revivers);
}
/**
* Revive a value flattened with `devalue.stringify`
* @param {number | any[]} parsed
* @param {Record<string, (value: any) => any>} [revivers]
*/
function unflatten(parsed, revivers) {
if (typeof parsed === "number") return hydrate(parsed, true);
if (!Array.isArray(parsed) || parsed.length === 0) throw new Error("Invalid input");
const values = parsed;
const hydrated = Array(values.length);
/**
* A set of values currently being hydrated with custom revivers,
* used to detect invalid cyclical dependencies
* @type {Set<number> | null}
*/
let hydrating = null;
/**
* @param {number} index
* @returns {any}
*/
function hydrate(index, standalone = false) {
if (index === UNDEFINED) return void 0;
if (index === NAN) return NaN;
if (index === POSITIVE_INFINITY) return Infinity;
if (index === NEGATIVE_INFINITY) return -Infinity;
if (index === NEGATIVE_ZERO) return -0;
if (standalone || typeof index !== "number") throw new Error(`Invalid input`);
if (index in hydrated) return hydrated[index];
const value = values[index];
if (!value || typeof value !== "object") hydrated[index] = value;
else if (Array.isArray(value)) if (typeof value[0] === "string") {
const type = value[0];
const reviver = revivers && Object.hasOwn(revivers, type) ? revivers[type] : void 0;
if (reviver) {
let i = value[1];
if (typeof i !== "number") i = values.push(value[1]) - 1;
hydrating ??= /* @__PURE__ */ new Set();
if (hydrating.has(i)) throw new Error("Invalid circular reference");
hydrating.add(i);
hydrated[index] = reviver(hydrate(i));
hydrating.delete(i);
return hydrated[index];
}
switch (type) {
case "Date":
hydrated[index] = new Date(value[1]);
break;
case "Set":
const set = /* @__PURE__ */ new Set();
hydrated[index] = set;
for (let i = 1; i < value.length; i += 1) set.add(hydrate(value[i]));
break;
case "Map":
const map = /* @__PURE__ */ new Map();
hydrated[index] = map;
for (let i = 1; i < value.length; i += 2) map.set(hydrate(value[i]), hydrate(value[i + 1]));
break;
case "RegExp":
hydrated[index] = new RegExp(value[1], value[2]);
break;
case "Object":
hydrated[index] = Object(value[1]);
break;
case "BigInt":
hydrated[index] = BigInt(value[1]);
break;
case "null":
const obj = Object.create(null);
hydrated[index] = obj;
for (let i = 1; i < value.length; i += 2) obj[value[i]] = hydrate(value[i + 1]);
break;
case "Int8Array":
case "Uint8Array":
case "Uint8ClampedArray":
case "Int16Array":
case "Uint16Array":
case "Int32Array":
case "Uint32Array":
case "Float32Array":
case "Float64Array":
case "BigInt64Array":
case "BigUint64Array": {
if (values[value[1]][0] !== "ArrayBuffer") throw new Error("Invalid data");
const TypedArrayConstructor = globalThis[type];
const typedArray = new TypedArrayConstructor(hydrate(value[1]));
hydrated[index] = value[2] !== void 0 ? typedArray.subarray(value[2], value[3]) : typedArray;
break;
}
case "ArrayBuffer": {
const base64 = value[1];
if (typeof base64 !== "string") throw new Error("Invalid ArrayBuffer encoding");
hydrated[index] = decode64(base64);
break;
}
case "Temporal.Duration":
case "Temporal.Instant":
case "Temporal.PlainDate":
case "Temporal.PlainTime":
case "Temporal.PlainDateTime":
case "Temporal.PlainMonthDay":
case "Temporal.PlainYearMonth":
case "Temporal.ZonedDateTime": {
const temporalName = type.slice(9);
hydrated[index] = Temporal[temporalName].from(value[1]);
break;
}
case "URL":
hydrated[index] = new URL(value[1]);
break;
case "URLSearchParams":
hydrated[index] = new URLSearchParams(value[1]);
break;
default: throw new Error(`Unknown type ${type}`);
}
} else if (value[0] === SPARSE) {
const len = value[1];
const array = new Array(len);
hydrated[index] = array;
for (let i = 2; i < value.length; i += 2) {
const idx = value[i];
array[idx] = hydrate(value[i + 1]);
}
} else {
const array = new Array(value.length);
hydrated[index] = array;
for (let i = 0; i < value.length; i += 1) {
const n = value[i];
if (n === HOLE) continue;
array[i] = hydrate(n);
}
}
else {
/** @type {Record<string, any>} */
const object = {};
hydrated[index] = object;
for (const key of Object.keys(value)) {
if (key === "__proto__") throw new Error("Cannot parse an object with a `__proto__` property");
const n = value[key];
object[key] = hydrate(n);
}
}
return hydrated[index];
}
return hydrate(0);
}
//#endregion
//#region ../../node_modules/.pnpm/devalue@5.6.3/node_modules/devalue/src/stringify.js
/**
* Turn a value into a JSON string that can be parsed with `devalue.parse`
* @param {any} value
* @param {Record<string, (value: any) => any>} [reducers]
*/
function stringify(value, reducers) {
/** @type {any[]} */
const stringified = [];
/** @type {Map<any, number>} */
const indexes = /* @__PURE__ */ new Map();
/** @type {Array<{ key: string, fn: (value: any) => any }>} */
const custom = [];
if (reducers) for (const key of Object.getOwnPropertyNames(reducers)) custom.push({
key,
fn: reducers[key]
});
/** @type {string[]} */
const keys = [];
let p = 0;
/** @param {any} thing */
function flatten(thing) {
if (thing === void 0) return UNDEFINED;
if (Number.isNaN(thing)) return NAN;
if (thing === Infinity) return POSITIVE_INFINITY;
if (thing === -Infinity) return NEGATIVE_INFINITY;
if (thing === 0 && 1 / thing < 0) return NEGATIVE_ZERO;
if (indexes.has(thing)) return indexes.get(thing);
const index$1 = p++;
indexes.set(thing, index$1);
for (const { key, fn } of custom) {
const value$1 = fn(thing);
if (value$1) {
stringified[index$1] = `["${key}",${flatten(value$1)}]`;
return index$1;
}
}
if (typeof thing === "function") throw new DevalueError(`Cannot stringify a function`, keys, thing, value);
let str = "";
if (is_primitive(thing)) str = stringify_primitive(thing);
else {
const type = get_type(thing);
switch (type) {
case "Number":
case "String":
case "Boolean":
str = `["Object",${stringify_primitive(thing)}]`;
break;
case "BigInt":
str = `["BigInt",${thing}]`;
break;
case "Date":
str = `["Date","${!isNaN(thing.getDate()) ? thing.toISOString() : ""}"]`;
break;
case "URL":
str = `["URL",${stringify_string(thing.toString())}]`;
break;
case "URLSearchParams":
str = `["URLSearchParams",${stringify_string(thing.toString())}]`;
break;
case "RegExp":
const { source, flags } = thing;
str = flags ? `["RegExp",${stringify_string(source)},"${flags}"]` : `["RegExp",${stringify_string(source)}]`;
break;
case "Array": {
let mostly_dense = false;
str = "[";
for (let i = 0; i < thing.length; i += 1) {
if (i > 0) str += ",";
if (Object.hasOwn(thing, i)) {
keys.push(`[${i}]`);
str += flatten(thing[i]);
keys.pop();
} else if (mostly_dense) str += HOLE;
else {
const populated_keys = valid_array_indices(thing);
const population = populated_keys.length;
const d = String(thing.length).length;
if ((thing.length - population) * 3 > 4 + d + population * (d + 1)) {
str = "[" + SPARSE + "," + thing.length;
for (let j = 0; j < populated_keys.length; j++) {
const key = populated_keys[j];
keys.push(`[${key}]`);
str += "," + key + "," + flatten(thing[key]);
keys.pop();
}
break;
} else {
mostly_dense = true;
str += HOLE;
}
}
}
str += "]";
break;
}
case "Set":
str = "[\"Set\"";
for (const value$1 of thing) str += `,${flatten(value$1)}`;
str += "]";
break;
case "Map":
str = "[\"Map\"";
for (const [key, value$1] of thing) {
keys.push(`.get(${is_primitive(key) ? stringify_primitive(key) : "..."})`);
str += `,${flatten(key)},${flatten(value$1)}`;
keys.pop();
}
str += "]";
break;
case "Int8Array":
case "Uint8Array":
case "Uint8ClampedArray":
case "Int16Array":
case "Uint16Array":
case "Int32Array":
case "Uint32Array":
case "Float32Array":
case "Float64Array":
case "BigInt64Array":
case "BigUint64Array": {
/** @type {import("./types.js").TypedArray} */
const typedArray = thing;
str = "[\"" + type + "\"," + flatten(typedArray.buffer);
const a = thing.byteOffset;
const b = a + thing.byteLength;
if (a > 0 || b !== typedArray.buffer.byteLength) {
const m = +/(\d+)/.exec(type)[1] / 8;
str += `,${a / m},${b / m}`;
}
str += "]";
break;
}
case "ArrayBuffer":
str = `["ArrayBuffer","${encode64(thing)}"]`;
break;
case "Temporal.Duration":
case "Temporal.Instant":
case "Temporal.PlainDate":
case "Temporal.PlainTime":
case "Temporal.PlainDateTime":
case "Temporal.PlainMonthDay":
case "Temporal.PlainYearMonth":
case "Temporal.ZonedDateTime":
str = `["${type}",${stringify_string(thing.toString())}]`;
break;
default:
if (!is_plain_object(thing)) throw new DevalueError(`Cannot stringify arbitrary non-POJOs`, keys, thing, value);
if (enumerable_symbols(thing).length > 0) throw new DevalueError(`Cannot stringify POJOs with symbolic keys`, keys, thing, value);
if (Object.getPrototypeOf(thing) === null) {
str = "[\"null\"";
for (const key of Object.keys(thing)) {
if (key === "__proto__") throw new DevalueError(`Cannot stringify objects with __proto__ keys`, keys, thing, value);
keys.push(stringify_key(key));
str += `,${stringify_string(key)},${flatten(thing[key])}`;
keys.pop();
}
str += "]";
} else {
str = "{";
let started = false;
for (const key of Object.keys(thing)) {
if (key === "__proto__") throw new DevalueError(`Cannot stringify objects with __proto__ keys`, keys, thing, value);
if (started) str += ",";
started = true;
keys.push(stringify_key(key));
str += `${stringify_string(key)}:${flatten(thing[key])}`;
keys.pop();
}
str += "}";
}
}
}
stringified[index$1] = str;
return index$1;
}
const index = flatten(value);
if (index < 0) return `${index}`;
return `[${stringified.join(",")}]`;
}
/**
* @param {any} thing
* @returns {string}
*/
function stringify_primitive(thing) {
const type = typeof thing;
if (type === "string") return stringify_string(thing);
if (thing instanceof String) return stringify_string(thing.toString());
if (thing === void 0) return UNDEFINED.toString();
if (thing === 0 && 1 / thing < 0) return NEGATIVE_ZERO.toString();
if (type === "bigint") return `["BigInt","${thing}"]`;
return String(thing);
}
//#endregion
//#region ../../node_modules/.pnpm/get-port@7.1.0/node_modules/get-port/index.js
var Locked = class extends Error {
constructor(port) {
super(`${port} is locked`);
}
};
const lockedPorts = {
old: /* @__PURE__ */ new Set(),
young: /* @__PURE__ */ new Set()
};
const releaseOldLockedPortsIntervalMs = 1e3 * 15;
const minPort = 1024;
const maxPort = 65535;
let timeout;
const getLocalHosts = () => {
const interfaces = os.networkInterfaces();
const results = new Set([void 0, "0.0.0.0"]);
for (const _interface of Object.values(interfaces)) for (const config of _interface) results.add(config.address);
return results;
};
const checkAvailablePort = (options) => new Promise((resolve$1, reject) => {
const server = net.createServer();
server.unref();
server.on("error", reject);
server.listen(options, () => {
const { port } = server.address();
server.close(() => {
resolve$1(port);
});
});
});
const getAvailablePort = async (options, hosts) => {
if (options.host || options.port === 0) return checkAvailablePort(options);
for (const host of hosts) try {
await checkAvailablePort({
port: options.port,
host
});
} catch (error) {
if (!["EADDRNOTAVAIL", "EINVAL"].includes(error.code)) throw error;
}
return options.port;
};
const portCheckSequence = function* (ports) {
if (ports) yield* ports;
yield 0;
};
async function getPorts(options) {
let ports;
let exclude = /* @__PURE__ */ new Set();
if (options) {
if (options.port) ports = typeof options.port === "number" ? [options.port] : options.port;
if (options.exclude) {
const excludeIterable = options.exclude;
if (typeof excludeIterable[Symbol.iterator] !== "function") throw new TypeError("The `exclude` option must be an iterable.");
for (const element of excludeIterable) {
if (typeof element !== "number") throw new TypeError("Each item in the `exclude` option must be a number corresponding to the port you want excluded.");
if (!Number.isSafeInteger(element)) throw new TypeError(`Number ${element} in the exclude option is not a safe integer and can't be used`);
}
exclude = new Set(excludeIterable);
}
}
if (timeout === void 0) {
timeout = setTimeout(() => {
timeout = void 0;
lockedPorts.old = lockedPorts.young;
lockedPorts.young = /* @__PURE__ */ new Set();
}, releaseOldLockedPortsIntervalMs);
if (timeout.unref) timeout.unref();
}
const hosts = getLocalHosts();
for (const port of portCheckSequence(ports)) try {
if (exclude.has(port)) continue;
let availablePort = await getAvailablePort({
...options,
port
}, hosts);
while (lockedPorts.old.has(availablePort) || lockedPorts.young.has(availablePort)) {
if (port !== 0) throw new Locked(port);
availablePort = await getAvailablePort({
...options,
port
}, hosts);
}
lockedPorts.young.add(availablePort);
return availablePort;
} catch (error) {
if (!["EADDRINUSE", "EACCES"].includes(error.code) && !(error instanceof Locked)) throw error;
}
throw new Error("No available ports found");
}
function portNumbers(from, to) {
if (!Number.isInteger(from) || !Number.isInteger(to)) throw new TypeError("`from` and `to` must be integer numbers");
if (from < minPort || from > maxPort) throw new RangeError(`'from' must be between ${minPort} and ${maxPort}`);
if (to < minPort || to > maxPort) throw new RangeError(`'to' must be between ${minPort} and ${maxPort}`);
if (from > to) throw new RangeError("`to` must be greater than or equal to `from`");
const generator = function* (from$1, to$1) {
for (let port = from$1; port <= to$1; port++) yield port;
};
return generator(from, to);
}
//#endregion
//#region ../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/internal/lrucache.js
var require_lrucache = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/internal/lrucache.js": ((exports, module) => {
var LRUCache = class {
constructor() {
this.max = 1e3;
this.map = /* @__PURE__ */ new Map();
}
get(key) {
const value = this.map.get(key);
if (value === void 0) return;
else {
this.map.delete(key);
this.map.set(key, value);
return value;
}
}
delete(key) {
return this.map.delete(key);
}
set(key, value) {
if (!this.delete(key) && value !== void 0) {
if (this.map.size >= this.max) {
const firstKey = this.map.keys().next().value;
this.delete(firstKey);
}
this.map.set(key, value);
}
return this;
}
};
module.exports = LRUCache;
}) });
//#endregion
//#region ../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/internal/parse-options.js
var require_parse_options = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/internal/parse-options.js": ((exports, module) => {
const looseOption = Object.freeze({ loose: true });
const emptyOpts = Object.freeze({});
const parseOptions$3 = (options) => {
if (!options) return emptyOpts;
if (typeof options !== "object") return looseOption;
return options;
};
module.exports = parseOptions$3;
}) });
//#endregion
//#region ../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/internal/constants.js
var require_constants = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/internal/constants.js": ((exports, module) => {
const SEMVER_SPEC_VERSION = "2.0.0";
const MAX_LENGTH$2 = 256;
const MAX_SAFE_INTEGER$1 = Number.MAX_SAFE_INTEGER || 9007199254740991;
const MAX_SAFE_COMPONENT_LENGTH$1 = 16;
const MAX_SAFE_BUILD_LENGTH$1 = MAX_LENGTH$2 - 6;
const RELEASE_TYPES = [
"major",
"premajor",
"minor",
"preminor",
"patch",
"prepatch",
"prerelease"
];
module.exports = {
MAX_LENGTH: MAX_LENGTH$2,
MAX_SAFE_COMPONENT_LENGTH: MAX_SAFE_COMPONENT_LENGTH$1,
MAX_SAFE_BUILD_LENGTH: MAX_SAFE_BUILD_LENGTH$1,
MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$1,
RELEASE_TYPES,
SEMVER_SPEC_VERSION,
FLAG_INCLUDE_PRERELEASE: 1,
FLAG_LOOSE: 2
};
}) });
//#endregion
//#region ../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/internal/debug.js
var require_debug = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/internal/debug.js": ((exports, module) => {
const debug$5 = typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error("SEMVER", ...args) : () => {};
module.exports = debug$5;
}) });
//#endregion
//#region ../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/internal/re.js
var require_re = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/internal/re.js": ((exports, module) => {
const { MAX_SAFE_COMPONENT_LENGTH, MAX_SAFE_BUILD_LENGTH, MAX_LENGTH: MAX_LENGTH$1 } = require_constants();
const debug$4 = require_debug();
exports = module.exports = {};
const re$3 = exports.re = [];
const safeRe = exports.safeRe = [];
const src$1 = exports.src = [];
const safeSrc = exports.safeSrc = [];
const t$3 = exports.t = {};
let R = 0;
const LETTERDASHNUMBER = "[a-zA-Z0-9-]";
const safeRegexReplacements = [
["\\s", 1],
["\\d", MAX_LENGTH$1],
[LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH]
];
const makeSafeRegex = (value) => {
for (const [token, max] of safeRegexReplacements) value = value.split(`${token}*`).join(`${token}{0,${max}}`).split(`${token}+`).join(`${token}{1,${max}}`);
return value;
};
const createToken = (name, value, isGlobal) => {
const safe = makeSafeRegex(value);
const index = R++;
debug$4(name, index, value);
t$3[name] = index;
src$1[index] = value;
safeSrc[index] = safe;
re$3[index] = new RegExp(value, isGlobal ? "g" : void 0);
safeRe[index] = new RegExp(safe, isGlobal ? "g" : void 0);
};
createToken("NUMERICIDENTIFIER", "0|[1-9]\\d*");
createToken("NUMERICIDENTIFIERLOOSE", "\\d+");
createToken("NONNUMERICIDENTIFIER", `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`);
createToken("MAINVERSION", `(${src$1[t$3.NUMERICIDENTIFIER]})\\.(${src$1[t$3.NUMERICIDENTIFIER]})\\.(${src$1[t$3.NUMERICIDENTIFIER]})`);
createToken("MAINVERSIONLOOSE", `(${src$1[t$3.NUMERICIDENTIFIERLOOSE]})\\.(${src$1[t$3.NUMERICIDENTIFIERLOOSE]})\\.(${src$1[t$3.NUMERICIDENTIFIERLOOSE]})`);
createToken("PRERELEASEIDENTIFIER", `(?:${src$1[t$3.NUMERICIDENTIFIER]}|${src$1[t$3.NONNUMERICIDENTIFIER]})`);
createToken("PRERELEASEIDENTIFIERLOOSE", `(?:${src$1[t$3.NUMERICIDENTIFIERLOOSE]}|${src$1[t$3.NONNUMERICIDENTIFIER]})`);
createToken("PRERELEASE", `(?:-(${src$1[t$3.PRERELEASEIDENTIFIER]}(?:\\.${src$1[t$3.PRERELEASEIDENTIFIER]})*))`);
createToken("PRERELEASELOOSE", `(?:-?(${src$1[t$3.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${src$1[t$3.PRERELEASEIDENTIFIERLOOSE]})*))`);
createToken("BUILDIDENTIFIER", `${LETTERDASHNUMBER}+`);
createToken("BUILD", `(?:\\+(${src$1[t$3.BUILDIDENTIFIER]}(?:\\.${src$1[t$3.BUILDIDENTIFIER]})*))`);
createToken("FULLPLAIN", `v?${src$1[t$3.MAINVERSION]}${src$1[t$3.PRERELEASE]}?${src$1[t$3.BUILD]}?`);
createToken("FULL", `^${src$1[t$3.FULLPLAIN]}$`);
createToken("LOOSEPLAIN", `[v=\\s]*${src$1[t$3.MAINVERSIONLOOSE]}${src$1[t$3.PRERELEASELOOSE]}?${src$1[t$3.BUILD]}?`);
createToken("LOOSE", `^${src$1[t$3.LOOSEPLAIN]}$`);
createToken("GTLT", "((?:<|>)?=?)");
createToken("XRANGEIDENTIFIERLOOSE", `${src$1[t$3.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);
createToken("XRANGEIDENTIFIER", `${src$1[t$3.NUMERICIDENTIFIER]}|x|X|\\*`);
createToken("XRANGEPLAIN", `[v=\\s]*(${src$1[t$3.XRANGEIDENTIFIER]})(?:\\.(${src$1[t$3.XRANGEIDENTIFIER]})(?:\\.(${src$1[t$3.XRANGEIDENTIFIER]})(?:${src$1[t$3.PRERELEASE]})?${src$1[t$3.BUILD]}?)?)?`);
createToken("XRANGEPLAINLOOSE", `[v=\\s]*(${src$1[t$3.XRANGEIDENTIFIERLOOSE]})(?:\\.(${src$1[t$3.XRANGEIDENTIFIERLOOSE]})(?:\\.(${src$1[t$3.XRANGEIDENTIFIERLOOSE]})(?:${src$1[t$3.PRERELEASELOOSE]})?${src$1[t$3.BUILD]}?)?)?`);
createToken("XRANGE", `^${src$1[t$3.GTLT]}\\s*${src$1[t$3.XRANGEPLAIN]}$`);
createToken("XRANGELOOSE", `^${src$1[t$3.GTLT]}\\s*${src$1[t$3.XRANGEPLAINLOOSE]}$`);
createToken("COERCEPLAIN", `(^|[^\\d])(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}})(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`);
createToken("COERCE", `${src$1[t$3.COERCEPLAIN]}(?:$|[^\\d])`);
createToken("COERCEFULL", src$1[t$3.COERCEPLAIN] + `(?:${src$1[t$3.PRERELEASE]})?(?:${src$1[t$3.BUILD]})?(?:$|[^\\d])`);
createToken("COERCERTL", src$1[t$3.COERCE], true);
createToken("COERCERTLFULL", src$1[t$3.COERCEFULL], true);
createToken("LONETILDE", "(?:~>?)");
createToken("TILDETRIM", `(\\s*)${src$1[t$3.LONETILDE]}\\s+`, true);
exports.tildeTrimReplace = "$1~";
createToken("TILDE", `^${src$1[t$3.LONETILDE]}${src$1[t$3.XRANGEPLAIN]}$`);
createToken("TILDELOOSE", `^${src$1[t$3.LONETILDE]}${src$1[t$3.XRANGEPLAINLOOSE]}$`);
createToken("LONECARET", "(?:\\^)");
createToken("CARETTRIM", `(\\s*)${src$1[t$3.LONECARET]}\\s+`, true);
exports.caretTrimReplace = "$1^";
createToken("CARET", `^${src$1[t$3.LONECARET]}${src$1[t$3.XRANGEPLAIN]}$`);
createToken("CARETLOOSE", `^${src$1[t$3.LONECARET]}${src$1[t$3.XRANGEPLAINLOOSE]}$`);
createToken("COMPARATORLOOSE", `^${src$1[t$3.GTLT]}\\s*(${src$1[t$3.LOOSEPLAIN]})$|^$`);
createToken("COMPARATOR", `^${src$1[t$3.GTLT]}\\s*(${src$1[t$3.FULLPLAIN]})$|^$`);
createToken("COMPARATORTRIM", `(\\s*)${src$1[t$3.GTLT]}\\s*(${src$1[t$3.LOOSEPLAIN]}|${src$1[t$3.XRANGEPLAIN]})`, true);
exports.comparatorTrimReplace = "$1$2$3";
createToken("HYPHENRANGE", `^\\s*(${src$1[t$3.XRANGEPLAIN]})\\s+-\\s+(${src$1[t$3.XRANGEPLAIN]})\\s*$`);
createToken("HYPHENRANGELOOSE", `^\\s*(${src$1[t$3.XRANGEPLAINLOOSE]})\\s+-\\s+(${src$1[t$3.XRANGEPLAINLOOSE]})\\s*$`);
createToken("STAR", "(<|>)?=?\\s*\\*");
createToken("GTE0", "^\\s*>=\\s*0\\.0\\.0\\s*$");
createToken("GTE0PRE", "^\\s*>=\\s*0\\.0\\.0-0\\s*$");
}) });
//#endregion
//#region ../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/internal/identifiers.js
var require_identifiers = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/internal/identifiers.js": ((exports, module) => {
const numeric = /^[0-9]+$/;
const compareIdentifiers$1 = (a, b) => {
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
a = +a;
b = +b;
}
return a === b ? 0 : anum && !bnum ? -1 : bnum && !anum ? 1 : a < b ? -1 : 1;
};
const rcompareIdentifiers = (a, b) => compareIdentifiers$1(b, a);
module.exports = {
compareIdentifiers: compareIdentifiers$1,
rcompareIdentifiers
};
}) });
//#endregion
//#region ../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/classes/semver.js
var require_semver = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/classes/semver.js": ((exports, module) => {
const debug$3 = require_debug();
const { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants();
const { safeRe: re$2, safeSrc: src, t: t$2 } = require_re();
const parseOptions$2 = require_parse_options();
const { compareIdentifiers } = require_identifiers();
var SemVer$3 = class SemVer$3 {
constructor(version, options) {
options = parseOptions$2(options);
if (version instanceof SemVer$3) if (version.loose === !!options.loose && version.includePrerelease === !!options.includePrerelease) return version;
else version = version.version;
else if (typeof version !== "string") throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`);
if (version.length > MAX_LENGTH) throw new TypeError(`version is longer than ${MAX_LENGTH} characters`);
debug$3("SemVer", version, options);
this.options = options;
this.loose = !!options.loose;
this.includePrerelease = !!options.includePrerelease;
const m = version.trim().match(options.loose ? re$2[t$2.LOOSE] : re$2[t$2.FULL]);
if (!m) throw new TypeError(`Invalid Version: ${version}`);
this.raw = version;
this.major = +m[1];
this.minor = +m[2];
this.patch = +m[3];
if (this.major > MAX_SAFE_INTEGER || this.major < 0) throw new TypeError("Invalid major version");
if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) throw new TypeError("Invalid minor version");
if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) throw new TypeError("Invalid patch version");
if (!m[4]) this.prerelease = [];
else this.prerelease = m[4].split(".").map((id) => {
if (/^[0-9]+$/.test(id)) {
const num = +id;
if (num >= 0 && num < MAX_SAFE_INTEGER) return num;
}
return id;
});
this.build = m[5] ? m[5].split(".") : [];
this.format();
}
format() {
this.version = `${this.major}.${this.minor}.${this.patch}`;
if (this.prerelease.length) this.version += `-${this.prerelease.join(".")}`;
return this.version;
}
toString() {
return this.version;
}
compare(other) {
debug$3("SemVer.compare", this.version, this.options, other);
if (!(other instanceof SemVer$3)) {
if (typeof other === "string" && other === this.version) return 0;
other = new SemVer$3(other, this.options);
}
if (other.version === this.version) return 0;
return this.compareMain(other) || this.comparePre(other);
}
compareMain(other) {
if (!(other instanceof SemVer$3)) other = new SemVer$3(other, this.options);
return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
}
comparePre(other) {
if (!(other instanceof SemVer$3)) other = new SemVer$3(other, this.options);
if (this.prerelease.length && !other.prerelease.length) return -1;
else if (!this.prerelease.length && other.prerelease.length) return 1;
else if (!this.prerelease.length && !other.prerelease.length) return 0;
let i = 0;
do {
const a = this.prerelease[i];
const b = other.prerelease[i];
debug$3("prerelease compare", i, a, b);
if (a === void 0 && b === void 0) return 0;
else if (b === void 0) return 1;
else if (a === void 0) return -1;
else if (a === b) continue;
else return compareIdentifiers(a, b);
} while (++i);
}
compareBuild(other) {
if (!(other instanceof SemVer$3)) other = new SemVer$3(other, this.options);
let i = 0;
do {
const a = this.build[i];
const b = other.build[i];
debug$3("build compare", i, a, b);
if (a === void 0 && b === void 0) return 0;
else if (b === void 0) return 1;
else if (a === void 0) return -1;
else if (a === b) continue;
else return compareIdentifiers(a, b);
} while (++i);
}
inc(release, identifier, identifierBase) {
if (release.startsWith("pre")) {
if (!identifier && identifierBase === false) throw new Error("invalid increment argument: identifier is empty");
if (identifier) {
const r = /* @__PURE__ */ new RegExp(`^${this.options.loose ? src[t$2.PRERELEASELOOSE] : src[t$2.PRERELEASE]}$`);
const match = `-${identifier}`.match(r);
if (!match || match[1] !== identifier) throw new Error(`invalid identifier: ${identifier}`);
}
}
switch (release) {
case "premajor":
this.prerelease.length = 0;
this.patch = 0;
this.minor = 0;
this.major++;
this.inc("pre", identifier, identifierBase);
break;
case "preminor":
this.prerelease.length = 0;
this.patch = 0;
this.minor++;
this.inc("pre", identifier, identifierBase);
break;
case "prepatch":
this.prerelease.length = 0;
this.inc("patch", identifier, identifierBase);
this.inc("pre", identifier, identifierBase);
break;
case "prerelease":
if (this.prerelease.length === 0) this.inc("patch", identifier, identifierBase);
this.inc("pre", identifier, identifierBase);
break;
case "release":
if (this.prerelease.length === 0) throw new Error(`version ${this.raw} is not a prerelease`);
this.prerelease.length = 0;
break;
case "major":
if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) this.major++;
this.minor = 0;
this.patch = 0;
this.prerelease = [];
break;
case "minor":
if (this.patch !== 0 || this.prerelease.length === 0) this.minor++;
this.patch = 0;
this.prerelease = [];
break;
case "patch":
if (this.prerelease.length === 0) this.patch++;
this.prerelease = [];
break;
case "pre": {
const base = Number(identifierBase) ? 1 : 0;
if (this.prerelease.length === 0) this.prerelease = [base];
else {
let i = this.prerelease.length;
while (--i >= 0) if (typeof this.prerelease[i] === "number") {
this.prerelease[i]++;
i = -2;
}
if (i === -1) {
if (identifier === this.prerelease.join(".") && identifierBase === false) throw new Error("invalid increment argument: identifier already exists");
this.prerelease.push(base);
}
}
if (identifier) {
let prerelease = [identifier, base];
if (identifierBase === false) prerelease = [identifier];
if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
if (isNaN(this.prerelease[1])) this.prerelease = prerelease;
} else this.prerelease = prerelease;
}
break;
}
default: throw new Error(`invalid increment argument: ${release}`);
}
this.raw = this.format();
if (this.build.length) this.raw += `+${this.build.join(".")}`;
return this;
}
};
module.exports = SemVer$3;
}) });
//#endregion
//#region ../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/functions/compare.js
var require_compare = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/functions/compare.js": ((exports,