UNPKG

zotero-plugin-scaffold

Version:
1,320 lines (1,296 loc) 166 kB
import { loadConfig as loadConfig$1, setupDotenv } from 'c12'; import { kebabCase, mapValues, toMerged, escapeRegExp, debounce, delay } from 'es-toolkit'; import { readJsonSync, copy, move, outputFile, readJSON, outputJSON, writeJson, emptyDir, pathExists, ensureDir, remove } from 'fs-extra/esm'; import { createHooks } from 'hookable'; import { l as logger, p as parseRepoUrl, d as dateFormat, t as template, b as toArray, s as styleText, c as replaceDefine, L as LOG_LEVEL } from './zotero-plugin-scaffold.CzBjWbS8.mjs'; import process$1 from 'node:process'; import { glob, globSync } from 'tinyglobby'; import path, { resolve as resolve$1, dirname, basename, join as join$1, isAbsolute as isAbsolute$1, extname as extname$1 } from 'node:path'; import { build, context } from 'esbuild'; import { readFile, writeFile, stat } from 'node:fs/promises'; import { parse, serialize, Transformer } from '@fluent/syntax'; import fs, { existsSync, createReadStream, lstatSync, realpathSync, statSync, promises } from 'node:fs'; import { parseSync, printSync } from '@swc/core'; import { createHash } from 'node:crypto'; import AdmZip from 'adm-zip'; import { execSync, spawn } from 'node:child_process'; import { isCI, isWindows as isWindows$1, isMacOS, isLinux, isDebug } from 'std-env'; import { versionBump, ProgressEvent } from 'bumpp'; import 'node:os'; import { fileURLToPath, pathToFileURL, URL as URL$1 } from 'node:url'; import assert from 'node:assert'; import v8 from 'node:v8'; import { format, inspect } from 'node:util'; import { Octokit } from 'octokit'; import chokidar from 'chokidar'; import net from 'node:net'; import { Buffer } from 'node:buffer'; import domain from 'node:domain'; import EventEmitter from 'node:events'; import { Xvfb } from 'xvfb-ts'; import http from 'node:http'; function defineConfig(userConfig) { return userConfig; } async function loadConfig(overrides) { const result = await loadConfig$1({ name: "zotero-plugin", dotenv: true, packageJson: true, // eslint-disable-next-line ts/no-use-before-define defaults: getDefaultConfig$1(), overrides }); return resolveConfig$1(result.config); } function resolveConfig$1(config) { logger.setLogLevel(config.logLevel); const pkgUser = readJsonSync("package.json", { encoding: "utf-8" }); const { name, version } = pkgUser; const { owner, repo } = parseRepoUrl(pkgUser.repository?.url); config.name ||= name; config.id ||= config.name; config.namespace ||= config.name; config.xpiName ||= kebabCase(config.name); config.build.prefs.prefix ||= pkgUser.config.prefsPrefix || `extensions.${config.namespace}`; const isPreRelease = version.includes("-"); const templateData = { owner, repo, version, isPreRelease, updateJson: isPreRelease ? "update-beta.json" : "update.json", xpiName: config.xpiName, buildTime: dateFormat("YYYY-mm-dd HH:MM:SS", /* @__PURE__ */ new Date()) }; config.updateURL = template(config.updateURL, templateData); config.xpiDownloadLink = template(config.xpiDownloadLink, templateData); config.build.define = mapValues(config.build.define, (v) => template(v, templateData)); config.release.github.repository = template(config.release.github.repository, templateData); const hooks = createHooks(); hooks.addHooks(config.build.hooks); hooks.addHooks(config.server.hooks); hooks.addHooks(config.release.hooks); hooks.addHooks(config.test.hooks); const ctx = { ...config, pkgUser, version, hooks, logger, templateData }; return ctx; } const defaultConfig = { source: "src", watchIgnore: [], dist: ".scaffold/build", name: "", id: "", namespace: "", xpiName: "", xpiDownloadLink: "https://github.com/{{owner}}/{{repo}}/releases/download/v{{version}}/{{xpiName}}.xpi", updateURL: "https://github.com/{{owner}}/{{repo}}/releases/download/release/{{updateJson}}", build: { assets: "addon/**/*.*", define: {}, fluent: { prefixFluentMessages: true, prefixLocaleFiles: true, ignore: [], dts: "typings/i10n.d.ts" }, prefs: { prefix: "", prefixPrefKeys: true, dts: "typings/prefs.d.ts" }, esbuildOptions: [], makeManifest: { enable: true, template: { manifest_version: 2, name: "", version: "", applications: { zotero: { id: "", update_url: "" } } } }, makeUpdateJson: { updates: [], hash: true }, hooks: {} }, server: { devtools: true, startArgs: [], asProxy: false, prebuild: true, // keepProfileChanges: true, createProfileIfMissing: true, hooks: {} }, addonLint: {}, release: { bumpp: { release: "prompt", preid: "beta", confirm: true, execute: "", all: false, commit: "chore(publish): release v%s", noVerify: false, tag: "v%s" }, changelog: "", github: { enable: "ci", repository: "{{owner}}/{{repo}}", updater: "release", comment: false, releaseNote: (ctx) => { return ctx.release.changelog; } }, hooks: {} }, test: { entries: "test", prefs: {}, mocha: { timeout: 1e4 }, abortOnFail: false, headless: false, startupDelay: 1e3, waitForPlugin: "() => true", watch: true, hooks: {} }, logLevel: "INFO" }; const getDefaultConfig$1 = () => defaultConfig; class Base { ctx; constructor(ctx) { this.ctx = ctx; } get logger() { return this.ctx.logger; } } const DEFAULT_IGNORE = ["node_modules", ".git"]; async function copyAssets(source, dist, assets) { const sourceArr = toArray(source); const paths = await glob(assets, { ignore: [...DEFAULT_IGNORE, dist] }); for (const file of paths) { const newPath = getNewPath(sourceArr, dist, file); await copy(file, newPath); logger.debug(`Copy ${file} to ${newPath}`); } } function getNewPath(sources, dist, path) { const pattern = new RegExp(sources.join("|")); const relativePath = path.replace(pattern, ""); return `${dist}/addon/${relativePath}`; } function resolveConfig(dist, esbuildOptions) { const distAbsolute = resolve$1(dist); return esbuildOptions.map((option, i) => { if (option.outfile && !resolve$1(option.outfile).startsWith(distAbsolute)) { logger.debug(`'outfile' of esbuildOptions[${i}] is not in dist folder, it will be overwritten.`); option.outfile = `${dist}/${option.outfile}`; } if (option.outdir && !resolve$1(option.outdir).startsWith(distAbsolute)) { logger.debug(`'outdir' of esbuildOptions[${i}] is not in dist folder, it will be overwritten.`); option.outdir = `${dist}/${option.outdir}`; } return option; }); } async function esbuild(dist, esbuildOptions) { if (esbuildOptions.length === 0) return; const options = resolveConfig(dist, esbuildOptions); return await Promise.all( options.map( (esbuildOption) => build(esbuildOption) ) ); } async function buildLocale(dist, namespace, options) { const ignores = toArray(options.ignore); const localeNames = await getLocales(dist); const messageManager = new MessageManager(ignores); await Promise.all(localeNames.map(async (locale) => { const paths = await glob(`${dist}/addon/locale/${locale}/**/*.ftl`); await Promise.all(paths.map(async (path) => { const fm = new FluentManager(); await fm.read(path); messageManager.addMessages(locale, fm.getMessages()); if (options.prefixFluentMessages) { fm.prefixMessages(namespace); await fm.write(path); } if (options.prefixLocaleFiles) { const newPath = `${dirname(path)}/${namespace}-${basename(path)}`; await move(path, newPath); logger.debug(`Renamed FTL: ${path} \u2192 ${newPath}`); } })); })); const htmlPaths = await glob([`${dist}/addon/**/*.xhtml`, `${dist}/addon/**/*.html`]); await Promise.all(htmlPaths.map(async (htmlPath) => { const content = await readFile(htmlPath, "utf-8"); const { processedContent, foundMessages } = processHTMLFile( content, namespace, messageManager.getFTLMessages(), ignores, htmlPath ); messageManager.addMessages("html", foundMessages); if (options.prefixFluentMessages) { await writeFile(htmlPath, processedContent); } })); messageManager.validateMessages(); if (options.dts) { const dtsContent = generateFluentDts([...messageManager.getFTLMessages()]); await outputFile(options.dts, dtsContent, "utf-8"); } } async function getLocales(dist) { const localePaths = await glob(`${dist}/addon/locale/*`, { onlyDirectories: true }); return localePaths.map((p) => basename(p)); } class FluentManager { source; resource; messages = []; constructor() { } // Parse Fluent source into an AST and extract messages parse(source) { this.source = source; this.resource = parse(source, {}); } // Read a file, parse its content, and extract messages async read(path) { const content = await readFile(path, "utf-8"); this.parse(content); } // Extract message IDs from the parsed resource getMessages() { if (!this.resource) { throw new Error("Resource must be parsed first."); } this.messages.length = 0; this.messages.push( ...this.resource.body.filter((entry) => entry.type === "Message").map((message) => message.id.name) ); return this.messages; } // Apply namespace prefix to message IDs in the resource prefixMessages(namespace) { if (!this.resource) { throw new Error("Resource must be parsed before applying prefix."); } new FluentTransformer(namespace).genericVisit(this.resource); } // Serialize the resource back into a string serialize() { if (!this.resource) { throw new Error("Resource not parsed. Cannot serialize."); } return serialize(this.resource, {}); } // Write the serialized resource to a file async write(path) { const result = this.serialize(); if (result !== this.source) await writeFile(path, this.serialize()); } } class FluentTransformer extends Transformer { constructor(prefix) { super(); this.prefix = prefix; } needsPrefix(name) { return !!this.prefix && !name.startsWith(this.prefix); } visitMessage(node) { if (this.needsPrefix(node.id.name)) { node.id.name = `${this.prefix}-${node.id.name}`; } return this.genericVisit(node); } visitMessageReference(node) { if (this.needsPrefix(node.id.name)) { node.id.name = `${this.prefix}-${node.id.name}`; } return this.genericVisit(node); } } class MessageManager { ftlMessages = /* @__PURE__ */ new Map(); htmlMessages = /* @__PURE__ */ new Set(); ignores; constructor(ignores) { this.ignores = ignores; } // Add a set of messages (FTL or HTML) for a specific locale or for HTML globally addMessages(target, messages) { if (target === "html") { messages.forEach((msg) => this.htmlMessages.add(msg)); } else { let ftlLocaleMessages = this.ftlMessages.get(target); if (!ftlLocaleMessages) { ftlLocaleMessages = /* @__PURE__ */ new Set(); this.ftlMessages.set(target, ftlLocaleMessages); } messages.forEach((msg) => ftlLocaleMessages.add(msg)); } } validateMessages() { this.htmlMessages.forEach((msg) => { if (this.ignores.includes(msg)) return; const missingLocales = [...this.ftlMessages.entries()].filter(([_, messages]) => !messages.has(msg)).map(([locale]) => locale); if (missingLocales.length > 0) logger.warn(`I10N id ${styleText.blue(msg)} missing in locale: ${missingLocales.join(", ")}`); }); } getFTLMessages() { const allMessages = /* @__PURE__ */ new Set(); this.ftlMessages.forEach((messages) => messages.forEach((msg) => allMessages.add(msg))); return allMessages; } // Get all FTL messages for a specific locale getFTLMessagesByLocale(locale) { return this.ftlMessages.get(locale) || /* @__PURE__ */ new Set(); } // Get all HTML messages getHTMLMessages() { return this.htmlMessages; } } function processHTMLFile(content, namespace, allMessages, ignores, filePath) { const foundMessages = /* @__PURE__ */ new Set(); const L10N_PATTERN = new RegExp(`(data-l10n-id)="((?!${namespace})\\S*)"`, "g"); const processed = content.replace(L10N_PATTERN, (match, attr, id) => { foundMessages.add(id); if (ignores.includes(id)) { logger.debug(`Skipped ignored ID: ${styleText.blue(id)} in ${styleText.gray(filePath)}`); return match; } if (!allMessages.has(id)) { logger.warn(`I10N id ${styleText.blue(id)} in path ${styleText.gray(filePath)} does not exist in any locale, skip renaming it.`); return match; } return `${attr}="${namespace}-${id}"`; }); return { processedContent: processed, foundMessages: [...foundMessages] }; } function generateFluentDts(messages) { return `// Generated by zotero-plugin-scaffold /* prettier-ignore */ /* eslint-disable */ // @ts-nocheck export type FluentMessageId = ${Array.from(messages).sort().map((id) => ` | '${id}'`).join("\n")}; `; } async function buildManifest(ctx) { if (!ctx.build.makeManifest.enable) return; const { name, id, updateURL, dist, version } = ctx; const userData = await readJSON( `${dist}/addon/manifest.json` ); const template = { ...userData, ...!userData.name && name && { name }, ...version && { version }, manifest_version: 2, applications: { zotero: { id, update_url: updateURL } } }; const data = toMerged(userData, template); logger.debug(`manifest: ${JSON.stringify(data, null, 2)}`); outputJSON(`${dist}/addon/manifest.json`, data, { spaces: 2 }); } function is32BitNumber(n) { return Number.isInteger(n) && n >= -2147483648 && n <= 2147483647; } class PrefsManager { namespace; prefs = {}; constructor(namespace) { this.namespace = namespace; } /** * Parse Method 3 - Using AST */ parse(content) { const _map = {}; const ast = parseSync(content, { syntax: "ecmascript" }); for (const node of ast.body) { if (node.type !== "ExpressionStatement" || node.expression.type !== "CallExpression" || node.expression.callee.type !== "Identifier" || node.expression.callee.value !== this.namespace || node.expression.arguments.length !== 2) { throw new Error("Invalid prefs.js file."); } const [arg1, arg2] = node.expression.arguments; if (arg1.expression.type !== "StringLiteral") { throw new Error("Invalid prefs.js file - unsupported key type."); } const key = arg1.expression.value.trim(); let value; switch (arg2.expression.type) { // https://babeljs.io/docs/babel-parser#output case "StringLiteral": case "NumericLiteral": case "BooleanLiteral": value = arg2.expression.value; break; // https://github.com/estree/estree/blob/master/es5.md#unaryexpression // https://github.com/northword/zotero-plugin-scaffold/issues/98 case "UnaryExpression": if (arg2.expression.argument.type !== "NumericLiteral") throw new Error("Invalid prefs.js file - unsupported value type."); if (arg2.expression.operator === "-") value = -arg2.expression.argument.value; else if (arg2.expression.operator === "+") value = arg2.expression.argument.value; else throw new Error("Invalid prefs.js file - unsupported value type."); break; case "TemplateLiteral": value = arg2.expression.quasis[0]?.cooked ?? ""; break; default: throw new Error("Invalid prefs.js file - unsupported value type."); } _map[key] = value; } return _map; } /** * Parse Method 1 - Using RegExp * @deprecated */ parseByRegExp(content) { const _map = {}; const prefPattern = /^(pref|user_pref)\s*\(\s*["']([^"']+)["']\s*,\s*(.+)\s*,?\s*\)\s*;?$/gm; const matches = content.matchAll(prefPattern); for (const match of matches) { const key = match[2].trim(); const value = match[3].trim(); _map[key] = this.cleanValue(value); } return _map; } /** * Parse Method 2 - Using eval * @deprecated */ // private parseByEval(content: string) { // const _map: Prefs = {}; // // eslint-disable-next-line unused-imports/no-unused-vars // const pref = (key: any, value: any) => { // _map[key.trim()] = this.cleanValue(value.trim()); // }; // // eslint-disable-next-line no-eval // eval(content); // return _map; // } cleanValue(value) { if (value === "true") return true; else if (value === "false") return false; else if (!Number.isNaN(Number(value))) return Number(value); else if (value.match(/^["'](.*)["']$/)) return value.replace(/^["'](.*)["']$/, "$1"); else return value; } /** * Render Method 2 - Using swc */ render() { const span = { start: 0, end: 0, ctxt: 0 }; function getExpression(value) { switch (typeof value) { case "string": return { type: "StringLiteral", span, value }; case "boolean": return { type: "BooleanLiteral", span, value }; case "number": if (value < 0) { return { type: "UnaryExpression", span, operator: "-", argument: { type: "NumericLiteral", span, value: Math.abs(value) } }; } return { type: "NumericLiteral", span, value }; default: throw new Error(`Unsupported value type: ${typeof value}`); } } const ast = { type: "Module", span, // @ts-expect-error no raw property body: Object.entries(this.prefs).map(([key, value]) => ({ type: "ExpressionStatement", span, expression: { type: "CallExpression", span, ctxt: 0, callee: { type: "Identifier", span, ctxt: 0, value: this.namespace, optional: false }, arguments: [ { expression: getExpression(key) }, { expression: getExpression(value) } ] } })) }; const { code } = printSync(ast); return code; } /** * Render Method 1 - Using string * @deprecated */ renderByString() { return Object.entries(this.prefs).map(([key, value]) => { const _v = typeof value === "string" ? `"${value.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"` : value; return `${this.namespace}("${key}", ${_v});`; }).join("\n"); } async read(path) { const content = await readFile(path, "utf-8"); const map = this.parse(content); this.setPrefs(map); } async write(path) { const content = this.render(); await outputFile(path, content, "utf-8"); logger.debug("The prefs.js has been modified."); } setPref(key, value) { if (value === null || value === void 0) { if (key in this.prefs) delete this.prefs[key]; return; } this.prefs[key] = value; } setPrefs(prefs) { Object.entries(prefs).forEach(([key, value]) => { this.setPref(key, value); }); } getPref(key) { return this.prefs[key] ?? void 0; } getPrefs() { return this.prefs; } clearPrefs() { this.prefs = {}; } getPrefsWithPrefix(prefix) { const _prefs = {}; for (const pref in this.prefs) { if (pref.startsWith(prefix)) _prefs[pref] = this.prefs[pref]; else _prefs[`${prefix}.${pref}`] = this.prefs[pref]; } return _prefs; } getPrefsWithoutPrefix(prefix) { const _prefs = {}; for (const pref in this.prefs) { _prefs[pref.replace(`${prefix}.`, "")] = this.prefs[pref]; } return _prefs; } } async function buildPrefs(dist, options) { const { dts, prefixPrefKeys, prefix } = options; if (!prefixPrefKeys && !dts) return; const prefsFilePath = join$1(dist, "addon", "prefs.js"); if (!existsSync(prefsFilePath)) return; const prefsManager = new PrefsManager("pref"); await prefsManager.read(prefsFilePath); const prefsWithPrefix = prefsManager.getPrefsWithPrefix(prefix); const prefsWithoutPrefix = prefsManager.getPrefsWithoutPrefix(prefix); const prefs = prefsManager.getPrefs(); Object.entries(prefs).forEach(([key, value]) => { if (typeof value === "number") { if (!is32BitNumber(value)) { logger.warn(`Pref key '${styleText.blue(key)}' is a number, but is more than 4 bytes, which can be problematic on some OS.`); } } }); if (dts) { const dtsContent = renderPluginPrefsDts(prefsWithoutPrefix); await outputFile(dts, dtsContent, "utf-8"); } if (prefixPrefKeys) { prefsManager.clearPrefs(); prefsManager.setPrefs(prefsWithPrefix); await prefsManager.write(prefsFilePath); } if (prefixPrefKeys) { const HTML_PREFERENCE_PATTERN = /preference="(\S*)"/g; const xhtmlPaths = await glob(`${dist}/addon/**/*.xhtml`); await Promise.all(xhtmlPaths.map(async (path) => { let content = await readFile(path, "utf-8"); const matchs = [...content.matchAll(HTML_PREFERENCE_PATTERN)]; for (const match of matchs) { const [matched, key] = match; if (key.startsWith(prefix)) { logger.debug(`Pref key '${styleText.blue(key)}' is already starts with '${prefix}', skip prefixing it.`); continue; } else if (key.startsWith("extensions.")) { logger.warn(`Pref key '${styleText.blue(key)}' in ${styleText.gray(path)} starts with 'extensions.' but not '${styleText.blue(prefix)}', skip prefixing it.`); continue; } else if (!(key in prefsWithPrefix) && !(key in prefsWithoutPrefix)) { logger.warn(`Pref key '${styleText.blue(key)}' in ${styleText.gray(path)} is not found in prefs.js, skip prefixing it.`); continue; } else { const prefixed = `${prefix}.${key}`; logger.debug(`Pref key '${styleText.blue(key)}' in ${styleText.gray(path)} is prefixed to ${styleText.blue(prefixed)}.`); content = content.replace(matched, `preference="${prefixed}"`); } } await outputFile(path, content, "utf-8"); })); } } function renderPluginPrefsDts(prefs) { return `// Generated by zotero-plugin-scaffold /* prettier-ignore */ /* eslint-disable */ // @ts-nocheck // prettier-ignore declare namespace _ZoteroTypes { interface Prefs { PluginPrefsMap: { ${Object.entries(prefs).map(([key, value]) => { return `"${key}": ${typeof value};`; }).join("\n ")} }; } } `; } function generateHash(filePath, algorithm) { return new Promise((resolve, reject) => { const hash = createHash(algorithm); const stream = createReadStream(filePath); stream.on("data", (data) => { hash.update(data); }); stream.on("end", () => { const fileHash = hash.digest("hex"); resolve(`${algorithm}:${fileHash}`); }); stream.on("error", (error) => { reject(error); }); }); } async function buildUpdateJson(ctx) { const { dist, xpiName, id, version, xpiDownloadLink, build } = ctx; const manifest = await readJSON( `${dist}/addon/manifest.json` ); const min = manifest.applications?.zotero?.strict_min_version; const max = manifest.applications?.zotero?.strict_max_version; const updateHash = await generateHash(`${dist}/${xpiName}.xpi`, "sha512"); const data = { addons: { [id]: { updates: [ ...build.makeUpdateJson.updates, { version, update_link: xpiDownloadLink, ...build.makeUpdateJson.hash && { update_hash: updateHash }, applications: { zotero: { ...min && { strict_min_version: min }, ...max && { strict_max_version: max } } } } ] } } }; await writeJson(`${dist}/update-beta.json`, data, { spaces: 2 }); if (!ctx.templateData.isPreRelease) await writeJson(`${dist}/update.json`, data, { spaces: 2 }); logger.debug( `Prepare Update.json for ${ctx.templateData.isPreRelease ? "\x1B[31m Prerelease \x1B[0m" : "\x1B[32m Release \x1B[0m"}` ); } async function pack(dist, xpiName) { const zip = new AdmZip(); zip.addLocalFolder(`${dist}/addon`); zip.writeZip(`${dist}/${xpiName}.xpi`); } class Build extends Base { buildTime; constructor(ctx) { super(ctx); process$1.env.NODE_ENV ??= "production"; this.buildTime = ""; } /** * Default build runner */ async run() { const { dist, version } = this.ctx; const t = /* @__PURE__ */ new Date(); this.buildTime = dateFormat("YYYY-mm-dd HH:MM:SS", t); this.logger.info(`Building version ${styleText.blue(version)} to ${styleText.blue(dist)} at ${styleText.blue(this.buildTime)} in ${styleText.blue(process$1.env.NODE_ENV)} mode.`); await this.ctx.hooks.callHook("build:init", this.ctx); this.logger.tip("Preparing static assets", { space: 1 }); await this.prepareAssets(); this.logger.tip("Bundling scripts", { space: 1 }); await this.bundle(); if (process$1.env.NODE_ENV === "production") { this.logger.tip("Packing plugin", { space: 1 }); this.buildInProduction(); } await this.ctx.hooks.callHook("build:done", this.ctx); this.logger.success(`Build finished in ${((/* @__PURE__ */ new Date()).getTime() - t.getTime()) / 1e3} s.`); } async prepareAssets() { const { source, namespace, dist, build } = this.ctx; await emptyDir(dist); await this.ctx.hooks.callHook("build:mkdir", this.ctx); await copyAssets(source, dist, build.assets); await replaceDefine(dist, build.define); await this.ctx.hooks.callHook("build:copyAssets", this.ctx); this.logger.debug("Preparing manifest", { space: 2 }); await buildManifest(this.ctx); await this.ctx.hooks.callHook("build:makeManifest", this.ctx); this.logger.debug("Preparing locale files", { space: 2 }); await buildLocale(dist, namespace, build.fluent); await this.ctx.hooks.callHook("build:fluent", this.ctx); this.logger.debug("Preparing preference files", { space: 2 }); await buildPrefs(dist, build.prefs); } async bundle() { const { dist, build: { esbuildOptions } } = this.ctx; await esbuild(dist, esbuildOptions); await this.ctx.hooks.callHook("build:bundle", this.ctx); } async buildInProduction() { const { dist, xpiName } = this.ctx; await pack(dist, xpiName); await this.ctx.hooks.callHook("build:pack", this.ctx); await buildUpdateJson(this.ctx); await this.ctx.hooks.callHook("build:makeUpdateJSON", this.ctx); } exit() { } } class ReleaseBase { isCI; ctx; constructor(ctx) { this.ctx = ctx; this.isCI = isCI; } checkFiles() { const { dist } = this.ctx; if (globSync(`${dist}/*.xpi`).length === 0) { throw new Error("No xpi file found, are you sure you have run build?"); } } get logger() { return this.ctx.logger; } } class Bump extends ReleaseBase { constructor(ctx) { super(ctx); } async run() { const bumppConfig = { ...this.ctx.release.bumpp, push: true, progress: this.bumppProgress }; const { version } = this.ctx; if (bumppConfig.release === version) { this.logger.debug("Commit, tag, and push are disabled because new version = old version."); bumppConfig.commit = false; bumppConfig.tag = false; bumppConfig.push = false; } const result = await versionBump(bumppConfig); this.ctx.version = result.newVersion; this.ctx.release.bumpp.tag = result.tag || this.ctx.release.bumpp.tag.toString().replace("%s", result.newVersion); this.ctx.release.bumpp.commit = result.commit || this.ctx.release.bumpp.commit.toString().replace("%s", result.newVersion); this.logger.debug(`The release context after bump: ", ${this.ctx.release}`); } /** * bumpp 显示进度的回调 * * @see https://github.com/antfu/bumpp/blob/main/src/cli/index.ts */ get bumppProgress() { return ({ event, script, updatedFiles, skippedFiles, newVersion }) => { switch (event) { case ProgressEvent.FileUpdated: this.logger.success(`Updated ${updatedFiles.pop()} to ${newVersion}`); break; case ProgressEvent.FileSkipped: this.logger.info(`${skippedFiles.pop()} did not need to be updated`); break; case ProgressEvent.GitCommit: this.logger.success("Git commit"); break; case ProgressEvent.GitTag: this.logger.success("Git tag"); break; case ProgressEvent.GitPush: this.logger.success("Git push"); break; case ProgressEvent.NpmScript: this.logger.success(`Npm run ${script}`); break; } }; } } const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; function normalizeWindowsPath(input = "") { if (!input) { return input; } return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); } const _UNC_REGEX = /^[/\\]{2}/; const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; const _DRIVE_LETTER_RE = /^[A-Za-z]:$/; const normalize = function(path) { if (path.length === 0) { return "."; } path = normalizeWindowsPath(path); const isUNCPath = path.match(_UNC_REGEX); const isPathAbsolute = isAbsolute(path); const trailingSeparator = path[path.length - 1] === "/"; path = normalizeString(path, !isPathAbsolute); if (path.length === 0) { if (isPathAbsolute) { return "/"; } return trailingSeparator ? "./" : "."; } if (trailingSeparator) { path += "/"; } if (_DRIVE_LETTER_RE.test(path)) { path += "/"; } if (isUNCPath) { if (!isPathAbsolute) { return `//./${path}`; } return `//${path}`; } return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; }; const join = function(...segments) { let path = ""; for (const seg of segments) { if (!seg) { continue; } if (path.length > 0) { const pathTrailing = path[path.length - 1] === "/"; const segLeading = seg[0] === "/"; const both = pathTrailing && segLeading; if (both) { path += seg.slice(1); } else { path += pathTrailing || segLeading ? seg : `/${seg}`; } } else { path += seg; } } return normalize(path); }; function cwd() { if (typeof process !== "undefined" && typeof process.cwd === "function") { return process.cwd().replace(/\\/g, "/"); } return "/"; } const resolve = function(...arguments_) { arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); let resolvedPath = ""; let resolvedAbsolute = false; for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { const path = index >= 0 ? arguments_[index] : cwd(); if (!path || path.length === 0) { continue; } resolvedPath = `${path}/${resolvedPath}`; resolvedAbsolute = isAbsolute(path); } resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); if (resolvedAbsolute && !isAbsolute(resolvedPath)) { return `/${resolvedPath}`; } return resolvedPath.length > 0 ? resolvedPath : "."; }; function normalizeString(path, allowAboveRoot) { let res = ""; let lastSegmentLength = 0; let lastSlash = -1; let dots = 0; let char = null; for (let index = 0; index <= path.length; ++index) { if (index < path.length) { char = path[index]; } else if (char === "/") { break; } else { char = "/"; } if (char === "/") { if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { if (res.length > 2) { const lastSlashIndex = res.lastIndexOf("/"); if (lastSlashIndex === -1) { res = ""; lastSegmentLength = 0; } else { res = res.slice(0, lastSlashIndex); lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); } lastSlash = index; dots = 0; continue; } else if (res.length > 0) { res = ""; lastSegmentLength = 0; lastSlash = index; dots = 0; continue; } } if (allowAboveRoot) { res += res.length > 0 ? "/.." : ".."; lastSegmentLength = 2; } } else { if (res.length > 0) { res += `/${path.slice(lastSlash + 1, index)}`; } else { res = path.slice(lastSlash + 1, index); } lastSegmentLength = index - lastSlash - 1; } lastSlash = index; dots = 0; } else if (char === "." && dots !== -1) { ++dots; } else { dots = -1; } } return res; } const isAbsolute = function(p) { return _IS_ABSOLUTE_RE.test(p); }; function upperFirst(str) { return str ? str[0].toUpperCase() + str.slice(1) : ""; } const gitmojis = { ":art:": "\u{1F3A8}", ":zap:": "\u26A1\uFE0F", ":fire:": "\u{1F525}", ":bug:": "\u{1F41B}", ":ambulance:": "\u{1F691}\uFE0F", ":sparkles:": "\u2728", ":memo:": "\u{1F4DD}", ":rocket:": "\u{1F680}", ":lipstick:": "\u{1F484}", ":tada:": "\u{1F389}", ":white_check_mark:": "\u2705", ":lock:": "\u{1F512}\uFE0F", ":closed_lock_with_key:": "\u{1F510}", ":bookmark:": "\u{1F516}", ":rotating_light:": "\u{1F6A8}", ":construction:": "\u{1F6A7}", ":green_heart:": "\u{1F49A}", ":arrow_down:": "\u2B07\uFE0F", ":arrow_up:": "\u2B06\uFE0F", ":pushpin:": "\u{1F4CC}", ":construction_worker:": "\u{1F477}", ":chart_with_upwards_trend:": "\u{1F4C8}", ":recycle:": "\u267B\uFE0F", ":heavy_plus_sign:": "\u2795", ":heavy_minus_sign:": "\u2796", ":wrench:": "\u{1F527}", ":hammer:": "\u{1F528}", ":globe_with_meridians:": "\u{1F310}", ":pencil2:": "\u270F\uFE0F", ":pencil:": "\u270F\uFE0F", ":poop:": "\u{1F4A9}", ":rewind:": "\u23EA\uFE0F", ":twisted_rightwards_arrows:": "\u{1F500}", ":package:": "\u{1F4E6}\uFE0F", ":alien:": "\u{1F47D}\uFE0F", ":truck:": "\u{1F69A}", ":page_facing_up:": "\u{1F4C4}", ":boom:": "\u{1F4A5}", ":bento:": "\u{1F371}", ":wheelchair:": "\u267F\uFE0F", ":bulb:": "\u{1F4A1}", ":beers:": "\u{1F37B}", ":speech_balloon:": "\u{1F4AC}", ":card_file_box:": "\u{1F5C3}\uFE0F", ":loud_sound:": "\u{1F50A}", ":mute:": "\u{1F507}", ":busts_in_silhouette:": "\u{1F465}", ":children_crossing:": "\u{1F6B8}", ":building_construction:": "\u{1F3D7}\uFE0F", ":iphone:": "\u{1F4F1}", ":clown_face:": "\u{1F921}", ":egg:": "\u{1F95A}", ":see_no_evil:": "\u{1F648}", ":camera_flash:": "\u{1F4F8}", ":alembic:": "\u2697\uFE0F", ":mag:": "\u{1F50D}\uFE0F", ":label:": "\u{1F3F7}\uFE0F", ":seedling:": "\u{1F331}", ":triangular_flag_on_post:": "\u{1F6A9}", ":goal_net:": "\u{1F945}", ":dizzy:": "\u{1F4AB}", ":wastebasket:": "\u{1F5D1}\uFE0F", ":passport_control:": "\u{1F6C2}", ":adhesive_bandage:": "\u{1FA79}", ":monocle_face:": "\u{1F9D0}", ":coffin:": "\u26B0\uFE0F", ":test_tube:": "\u{1F9EA}", ":necktie:": "\u{1F454}", ":stethoscope:": "\u{1FA7A}", ":bricks:": "\u{1F9F1}", ":technologist:": "\u{1F9D1}\u200D\u{1F4BB}", ":money_with_wings:": "\u{1F4B8}", ":thread:": "\u{1F9F5}", ":safety_vest:": "\u{1F9BA}" }; function convert(content, withSpace) { const re = new RegExp(Object.keys(gitmojis).join("|"), "gi"); return content.replace(re, function(matched) { switch (withSpace) { case true: case "trailing": return `${gitmojis[matched.toLowerCase()]} `; case "leading": return ` ${gitmojis[matched.toLowerCase()]}`; case "both": return ` ${gitmojis[matched.toLowerCase()]} `; default: return gitmojis[matched.toLowerCase()]; } }); } const l=globalThis.fetch||(()=>{throw new Error("[node-fetch-native] Failed to fetch: `globalThis.fetch` is not available!")}); const m=Symbol.for("__confbox_fmt__"),k=/^(\s+)/,v=/(\s+)$/;function x$1(e,t={}){const n=t.indent===void 0&&t.preserveIndentation!==false&&e.slice(0,t?.sampleSize||1024),s=t.preserveWhitespace===false?void 0:{start:k.exec(e)?.[0]||"",end:v.exec(e)?.[0]||""};return {sample:n,whiteSpace:s}}function N$1(e,t,n){!t||typeof t!="object"||Object.defineProperty(t,m,{enumerable:false,configurable:true,writable:true,value:x$1(e,n)});} function $(n,l=false){const g=n.length;let e=0,u="",p=0,k=16,A=0,o=0,O=0,B=0,b=0;function I(i,T){let s=0,c=0;for(;s<i;){let t=n.charCodeAt(e);if(t>=48&&t<=57)c=c*16+t-48;else if(t>=65&&t<=70)c=c*16+t-65+10;else if(t>=97&&t<=102)c=c*16+t-97+10;else break;e++,s++;}return s<i&&(c=-1),c}function V(i){e=i,u="",p=0,k=16,b=0;}function F(){let i=e;if(n.charCodeAt(e)===48)e++;else for(e++;e<n.length&&L(n.charCodeAt(e));)e++;if(e<n.length&&n.charCodeAt(e)===46)if(e++,e<n.length&&L(n.charCodeAt(e)))for(e++;e<n.length&&L(n.charCodeAt(e));)e++;else return b=3,n.substring(i,e);let T=e;if(e<n.length&&(n.charCodeAt(e)===69||n.charCodeAt(e)===101))if(e++,(e<n.length&&n.charCodeAt(e)===43||n.charCodeAt(e)===45)&&e++,e<n.length&&L(n.charCodeAt(e))){for(e++;e<n.length&&L(n.charCodeAt(e));)e++;T=e;}else b=3;return n.substring(i,T)}function a(){let i="",T=e;for(;;){if(e>=g){i+=n.substring(T,e),b=2;break}const s=n.charCodeAt(e);if(s===34){i+=n.substring(T,e),e++;break}if(s===92){if(i+=n.substring(T,e),e++,e>=g){b=2;break}switch(n.charCodeAt(e++)){case 34:i+='"';break;case 92:i+="\\";break;case 47:i+="/";break;case 98:i+="\b";break;case 102:i+="\f";break;case 110:i+=` `;break;case 114:i+="\r";break;case 116:i+=" ";break;case 117:const t=I(4);t>=0?i+=String.fromCharCode(t):b=4;break;default:b=5;}T=e;continue}if(s>=0&&s<=31)if(r(s)){i+=n.substring(T,e),b=2;break}else b=6;e++;}return i}function w(){if(u="",b=0,p=e,o=A,B=O,e>=g)return p=g,k=17;let i=n.charCodeAt(e);if(J(i)){do e++,u+=String.fromCharCode(i),i=n.charCodeAt(e);while(J(i));return k=15}if(r(i))return e++,u+=String.fromCharCode(i),i===13&&n.charCodeAt(e)===10&&(e++,u+=` `),A++,O=e,k=14;switch(i){case 123:return e++,k=1;case 125:return e++,k=2;case 91:return e++,k=3;case 93:return e++,k=4;case 58:return e++,k=6;case 44:return e++,k=5;case 34:return e++,u=a(),k=10;case 47:const T=e-1;if(n.charCodeAt(e+1)===47){for(e+=2;e<g&&!r(n.charCodeAt(e));)e++;return u=n.substring(T,e),k=12}if(n.charCodeAt(e+1)===42){e+=2;const s=g-1;let c=false;for(;e<s;){const t=n.charCodeAt(e);if(t===42&&n.charCodeAt(e+1)===47){e+=2,c=true;break}e++,r(t)&&(t===13&&n.charCodeAt(e)===10&&e++,A++,O=e);}return c||(e++,b=1),u=n.substring(T,e),k=13}return u+=String.fromCharCode(i),e++,k=16;case 45:if(u+=String.fromCharCode(i),e++,e===g||!L(n.charCodeAt(e)))return k=16;case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return u+=F(),k=11;default:for(;e<g&&v(i);)e++,i=n.charCodeAt(e);if(p!==e){switch(u=n.substring(p,e),u){case "true":return k=8;case "false":return k=9;case "null":return k=7}return k=16}return u+=String.fromCharCode(i),e++,k=16}}function v(i){if(J(i)||r(i))return false;switch(i){case 125:case 93:case 123:case 91:case 34:case 58:case 44:case 47:return false}return true}function j(){let i;do i=w();while(i>=12&&i<=15);return i}return {setPosition:V,getPosition:()=>e,scan:l?j:w,getToken:()=>k,getTokenValue:()=>u,getTokenOffset:()=>p,getTokenLength:()=>e-p,getTokenStartLine:()=>o,getTokenStartCharacter:()=>p-B,getTokenError:()=>b}}function J(n){return n===32||n===9}function r(n){return n===10||n===13}function L(n){return n>=48&&n<=57}var Q;((function(n){n[n.lineFeed=10]="lineFeed",n[n.carriageReturn=13]="carriageReturn",n[n.space=32]="space",n[n._0=48]="_0",n[n._1=49]="_1",n[n._2=50]="_2",n[n._3=51]="_3",n[n._4=52]="_4",n[n._5=53]="_5",n[n._6=54]="_6",n[n._7=55]="_7",n[n._8=56]="_8",n[n._9=57]="_9",n[n.a=97]="a",n[n.b=98]="b",n[n.c=99]="c",n[n.d=100]="d",n[n.e=101]="e",n[n.f=102]="f",n[n.g=103]="g",n[n.h=104]="h",n[n.i=105]="i",n[n.j=106]="j",n[n.k=107]="k",n[n.l=108]="l",n[n.m=109]="m",n[n.n=110]="n",n[n.o=111]="o",n[n.p=112]="p",n[n.q=113]="q",n[n.r=114]="r",n[n.s=115]="s",n[n.t=116]="t",n[n.u=117]="u",n[n.v=118]="v",n[n.w=119]="w",n[n.x=120]="x",n[n.y=121]="y",n[n.z=122]="z",n[n.A=65]="A",n[n.B=66]="B",n[n.C=67]="C",n[n.D=68]="D",n[n.E=69]="E",n[n.F=70]="F",n[n.G=71]="G",n[n.H=72]="H",n[n.I=73]="I",n[n.J=74]="J",n[n.K=75]="K",n[n.L=76]="L",n[n.M=77]="M",n[n.N=78]="N",n[n.O=79]="O",n[n.P=80]="P",n[n.Q=81]="Q",n[n.R=82]="R",n[n.S=83]="S",n[n.T=84]="T",n[n.U=85]="U",n[n.V=86]="V",n[n.W=87]="W",n[n.X=88]="X",n[n.Y=89]="Y",n[n.Z=90]="Z",n[n.asterisk=42]="asterisk",n[n.backslash=92]="backslash",n[n.closeBrace=125]="closeBrace",n[n.closeBracket=93]="closeBracket",n[n.colon=58]="colon",n[n.comma=44]="comma",n[n.dot=46]="dot",n[n.doubleQuote=34]="doubleQuote",n[n.minus=45]="minus",n[n.openBrace=123]="openBrace",n[n.openBracket=91]="openBracket",n[n.plus=43]="plus",n[n.slash=47]="slash",n[n.formFeed=12]="formFeed",n[n.tab=9]="tab";}))(Q||(Q={})),new Array(20).fill(0).map((n,l)=>" ".repeat(l));const N=200;new Array(N).fill(0).map((n,l)=>` `+" ".repeat(l)),new Array(N).fill(0).map((n,l)=>"\r"+" ".repeat(l)),new Array(N).fill(0).map((n,l)=>`\r `+" ".repeat(l)),new Array(N).fill(0).map((n,l)=>` `+" ".repeat(l)),new Array(N).fill(0).map((n,l)=>"\r"+" ".repeat(l)),new Array(N).fill(0).map((n,l)=>`\r `+" ".repeat(l));var U;(function(n){n.DEFAULT={allowTrailingComma:false};})(U||(U={}));function S(n,l=[],g=U.DEFAULT){let e=null,u=[];const p=[];function k(o){Array.isArray(u)?u.push(o):e!==null&&(u[e]=o);}return P(n,{onObjectBegin:()=>{const o={};k(o),p.push(u),u=o,e=null;},onObjectProperty:o=>{e=o;},onObjectEnd:()=>{u=p.pop();},onArrayBegin:()=>{const o=[];k(o),p.push(u),u=o,e=null;},onArrayEnd:()=>{u=p.pop();},onLiteralValue:k,onError:(o,O,B)=>{l.push({error:o,offset:O,length:B});}},g),u[0]}function P(n,l,g=U.DEFAULT){const e=$(n,false),u=[];let p=0;function k(f){return f?()=>p===0&&f(e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter()):()=>true}function A(f){return f?m=>p===0&&f(m,e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter()):()=>true}function o(f){return f?m=>p===0&&f(m,e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter(),()=>u.slice()):()=>true}function O(f){return f?()=>{p>0?p++:f(e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter(),()=>u.slice())===false&&(p=1);}:()=>true}function B(f){return f?()=>{p>0&&p--,p===0&&f(e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter());}:()=>true}const b=O(l.onObjectBegin),I=o(l.onObjectProperty),V=B(l.onObjectEnd),F=O(l.onArrayBegin),a=B(l.onArrayEnd),w=o(l.onLiteralValue),v=A(l.onSeparator),j=k(l.onComment),i=A(l.onError),T=g&&g.disallowComments,s=g&&g.allowTrailingComma;function c(){for(;;){const f=e.scan();switch(e.getTokenError()){case 4:t(14);break;case 5:t(15);break;case 3:t(13);break;case 1:T||t(11);break;case 2:t(12);break;case 6:t(16);break}switch(f){case 12:case 13:T?t(10):j();break;case 16:t(1);break;case 15:case 14:break;default:return f}}}function t(f,m=[],y=[]){if(i(f),m.length+y.length>0){let _=e.getToken();for(;_!==17;){if(m.indexOf(_)!==-1){c();break}else if(y.indexOf(_)!==-1)break;_=c();}}}function D(f){const m=e.getTokenValue();return f?w(m):(I(m),u.push(m)),c(),true}function G(){switch(e.getToken()){case 11:const f=e.getTokenValue();let m=Number(f);isNaN(m)&&(t(2),m=0),w(m);break;case 7:w(null);break;case 8:w(true);break;case 9:w(false);break;default:return false}return c(),true}function M(){return e.getToken()!==10?(t(3,[],[2,5]),false):(D(false),e.getToken()===6?(v(":"),c(),E()||t(4,[],[2,5])):t(5,[],[2,5]),u.pop(),true)}function X(){b(),c();let f=false;for(;e.getToken()!==2&&e.getToken()!==17;){if(e.getToken()===5){if(f||t(4,[],[]),v(","),c(),e.getToken()===2&&s)break}else f&&t(6,[],[]);M()||t(4,[],[2,5]),f=true;}return V(),e.getToken()!==2?t(7,[2],[]):c(),true}function Y(){F(),c();let f=true,m=false;for(;e.getToken()!==4&&e.getToken()!==17;){if(e.getToken()===5){if(m||t(4,[],[]),v(","),c(),e.getToken()===4&&s)break}else m&&t(6,[],[]);f?(u.push(0),f=false):u[u.length-1]++,E()||t(4,[],[4,5]),m=true;}return a(),f||u.pop(),e.getToken()!==4?t(8,[4],[]):c(),true}function E(){switch(e.getToken()){case 3:return Y();case 1:return X();case 10:return D(true);default:return G()}}return c(),e.getToken()===17?g.allowEmptyContent?true:(t(4,[],[]),false):E()?(e.getToken()!==17&&t(9,[],[]),true):(t(4,[],[]),false)}var W;(function(n){n[n.None=0]="None",n[n.UnexpectedEndOfComment=1]="UnexpectedEndOfComment",n[n.UnexpectedEndOfString=2]="UnexpectedEndOfString",n[n.UnexpectedEndOfNumber=3]="UnexpectedEndOfNumber",n[n.InvalidUnicode=4]="InvalidUnicode",n[n.InvalidEscapeCharacter=5]="InvalidEscapeCharacter",n[n.InvalidCharacter=6]="InvalidCharacter";})(W||(W={}));var H;(function(n){n[n.OpenBraceToken=1]="OpenBraceToken",n[n.CloseBraceToken=2]="CloseBraceToken",n[n.OpenBracketToken=3]="OpenBracketToken",n[n.CloseBracketToken=4]="CloseBracketToken",n[n.CommaToken=5]="CommaToken",n[n.ColonToken=6]="ColonToken",n[n.NullKeyword=7]="NullKeyword",n[n.TrueKeyword=8]="TrueKeyword",n[n.FalseKeyword=9]="FalseKeyword",n[n.StringLiteral=10]="StringLiteral",n[n.NumericLiteral=11]="NumericLiteral",n[n.LineCommentTrivia=12]="LineCommentTrivia",n[n.BlockCommentTrivia=13]="BlockCommentTrivia",n[n.LineBreakTrivia=14]="LineBreakTrivia",n[n.Trivia=15]="Trivia",n[n.Unknown=16]="Unknown",n[n.EOF=17]="EOF";})(H||(H={}));const K=S;var q;(function(n){n[n.InvalidSymbol=1]="InvalidSymbol",n[n.InvalidNumberFormat=2]="InvalidNumberFormat",n[n.PropertyNameExpected=3]="PropertyNameExpected",n[n.ValueExpected=4]="ValueExpected",n[n.ColonExpected=5]="ColonExpected",n[n.CommaExpected=6]="CommaExpected",n[n.CloseBraceExpected=7]="CloseBraceExpected",n[n.CloseBracketExpected=8]="CloseBracketExpected",n[n.EndOfFileExpected=9]="EndOfFileExpected",n[n.InvalidCommentToken=10]="InvalidCommentToken",n[n.UnexpectedEndOfComment=11]="UnexpectedEndOfComment",n[n.UnexpectedEndOfString=12]="UnexpectedEndOfString",n[n.UnexpectedEndOfNumber=13]="UnexpectedEndOfNumber",n[n.InvalidUnicode=14]="InvalidUnicode",n[n.InvalidEscapeCharacter=15]="InvalidEscapeCharacter",n[n.InvalidCharacter=16]="InvalidCharacter";})(q||(q={}));function x(n,l){const g=JSON.parse(n,l?.reviver);return N$1(n,g,l),g}function h(n,l){const g=K(n,l?.errors,l);return N$1(n,g,l),g} const nodeBuiltins = [ "_http_agent", "_http_client", "_http_common", "_http_incoming", "_http_outgoing", "_http_server", "_stream_duplex", "_stream_passthrough", "_stream_readable", "_stream_transform", "_stream_wrap", "_stream_writable", "_tls_common", "_tls_wrap", "assert", "assert/strict", "async_hooks", "buffer", "child_process", "cluster", "console", "constants", "crypto", "dgram", "diagnostics_channel", "dns", "dns/promises", "domain", "events", "fs", "fs/promises", "http", "http2", "https", "inspector", "inspector/promises", "module", "net", "os", "path", "path/posix", "path/win32", "perf_hooks", "process", "punycode", "querystring", "readline", "readline/promises", "repl", "stream", "stream/consumers", "stream/promises", "stream/web", "string_decoder", "sys", "timers", "timers/promises", "tls", "trace_events", "tty", "url", "util", "util/types", "v8", "vm", "wasi", "worker_threads", "zlib" ]; const own$1 = {}.hasOwnProperty; const classRegExp = /^([A-Z][a-z\d]*)+$/; const kTypes = /* @__PURE__ */ new Set([ "string", "function", "number", "object", // Accept 'Function' and 'Object' as alternative to the lower cased version. "Function", "Object", "boolean", "bigint", "symbol" ]); const messages = /* @__PURE__ */ new Map(); const nodeInternalPrefix = "__node_internal_"; let userStackTraceLimit; function formatList(array, type = "and") { return array.length < 3 ? array.join(` ${type} `) : `${array.slice(0, -1).join(", ")}, ${type} ${array.at(-1)}`; } function createError(sym, value, constructor) { messages.set(sym, value); return makeNodeErrorWithCode(constructor, sym); } function makeNodeErrorWithCode(Base, key) { return function NodeError(...parameters) { const limit = Error.stackTraceLimit; if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; const error = new Base(); if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = limit; const message = getMessage(key, parameters, error); Object.defineProperties(error, { // Note: no need to implement `kIsNodeError` symbol, would be hard, // probably. message: { value: message, enumerable: false, writable: true, configurable: true }, toString: { /** @this {Error} */ value() { return `${this.name} [${key}]: ${this.message}`; }, enumerable: false, writable: true, configurable: true } }); captur