Replace bash mosaic-init with a modern 9-stage wizard: - SOUL.md identity, USER.md profile, TOOLS.md configuration - Runtime detection (Claude, Codex, OpenCode) + MCP setup - Skills catalog with categorized selection - Quick Start and Advanced modes - HeadlessPrompter for --non-interactive and CI usage - ConfigService abstraction layer for future DB migration - Bundled as single dist/mosaic-wizard.mjs via tsdown - mosaic init now prefers wizard when Node.js is available - 30 tests covering stages, templates, and integration Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
15690 lines
534 KiB
JavaScript
Executable File
15690 lines
534 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
||
import { createRequire } from "node:module";
|
||
import { execSync, spawnSync } from "node:child_process";
|
||
import { dirname, join, relative } from "node:path";
|
||
import { appendFileSync, copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
||
import p, { stdin, stdout } from "node:process";
|
||
import { stripVTControlCharacters } from "node:util";
|
||
import * as f from "node:readline";
|
||
import M from "node:readline";
|
||
import { WriteStream } from "node:tty";
|
||
import { homedir, platform } from "node:os";
|
||
|
||
//#region \0rolldown/runtime.js
|
||
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 __commonJSMin = (cb, mod) => () => (mod || cb((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(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(target, "default", {
|
||
value: mod,
|
||
enumerable: true
|
||
}) : target, mod));
|
||
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/commander@13.1.0/node_modules/commander/lib/error.js
|
||
var require_error = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
/**
|
||
* CommanderError class
|
||
*/
|
||
var CommanderError = class extends Error {
|
||
/**
|
||
* Constructs the CommanderError class
|
||
* @param {number} exitCode suggested exit code which could be used with process.exit
|
||
* @param {string} code an id string representing the error
|
||
* @param {string} message human-readable description of the error
|
||
*/
|
||
constructor(exitCode, code, message) {
|
||
super(message);
|
||
Error.captureStackTrace(this, this.constructor);
|
||
this.name = this.constructor.name;
|
||
this.code = code;
|
||
this.exitCode = exitCode;
|
||
this.nestedError = void 0;
|
||
}
|
||
};
|
||
/**
|
||
* InvalidArgumentError class
|
||
*/
|
||
var InvalidArgumentError = class extends CommanderError {
|
||
/**
|
||
* Constructs the InvalidArgumentError class
|
||
* @param {string} [message] explanation of why argument is invalid
|
||
*/
|
||
constructor(message) {
|
||
super(1, "commander.invalidArgument", message);
|
||
Error.captureStackTrace(this, this.constructor);
|
||
this.name = this.constructor.name;
|
||
}
|
||
};
|
||
exports.CommanderError = CommanderError;
|
||
exports.InvalidArgumentError = InvalidArgumentError;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/commander@13.1.0/node_modules/commander/lib/argument.js
|
||
var require_argument = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
const { InvalidArgumentError } = require_error();
|
||
var Argument = class {
|
||
/**
|
||
* Initialize a new command argument with the given name and description.
|
||
* The default is that the argument is required, and you can explicitly
|
||
* indicate this with <> around the name. Put [] around the name for an optional argument.
|
||
*
|
||
* @param {string} name
|
||
* @param {string} [description]
|
||
*/
|
||
constructor(name, description) {
|
||
this.description = description || "";
|
||
this.variadic = false;
|
||
this.parseArg = void 0;
|
||
this.defaultValue = void 0;
|
||
this.defaultValueDescription = void 0;
|
||
this.argChoices = void 0;
|
||
switch (name[0]) {
|
||
case "<":
|
||
this.required = true;
|
||
this._name = name.slice(1, -1);
|
||
break;
|
||
case "[":
|
||
this.required = false;
|
||
this._name = name.slice(1, -1);
|
||
break;
|
||
default:
|
||
this.required = true;
|
||
this._name = name;
|
||
break;
|
||
}
|
||
if (this._name.length > 3 && this._name.slice(-3) === "...") {
|
||
this.variadic = true;
|
||
this._name = this._name.slice(0, -3);
|
||
}
|
||
}
|
||
/**
|
||
* Return argument name.
|
||
*
|
||
* @return {string}
|
||
*/
|
||
name() {
|
||
return this._name;
|
||
}
|
||
/**
|
||
* @package
|
||
*/
|
||
_concatValue(value, previous) {
|
||
if (previous === this.defaultValue || !Array.isArray(previous)) return [value];
|
||
return previous.concat(value);
|
||
}
|
||
/**
|
||
* Set the default value, and optionally supply the description to be displayed in the help.
|
||
*
|
||
* @param {*} value
|
||
* @param {string} [description]
|
||
* @return {Argument}
|
||
*/
|
||
default(value, description) {
|
||
this.defaultValue = value;
|
||
this.defaultValueDescription = description;
|
||
return this;
|
||
}
|
||
/**
|
||
* Set the custom handler for processing CLI command arguments into argument values.
|
||
*
|
||
* @param {Function} [fn]
|
||
* @return {Argument}
|
||
*/
|
||
argParser(fn) {
|
||
this.parseArg = fn;
|
||
return this;
|
||
}
|
||
/**
|
||
* Only allow argument value to be one of choices.
|
||
*
|
||
* @param {string[]} values
|
||
* @return {Argument}
|
||
*/
|
||
choices(values) {
|
||
this.argChoices = values.slice();
|
||
this.parseArg = (arg, previous) => {
|
||
if (!this.argChoices.includes(arg)) throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
|
||
if (this.variadic) return this._concatValue(arg, previous);
|
||
return arg;
|
||
};
|
||
return this;
|
||
}
|
||
/**
|
||
* Make argument required.
|
||
*
|
||
* @returns {Argument}
|
||
*/
|
||
argRequired() {
|
||
this.required = true;
|
||
return this;
|
||
}
|
||
/**
|
||
* Make argument optional.
|
||
*
|
||
* @returns {Argument}
|
||
*/
|
||
argOptional() {
|
||
this.required = false;
|
||
return this;
|
||
}
|
||
};
|
||
/**
|
||
* Takes an argument and returns its human readable equivalent for help usage.
|
||
*
|
||
* @param {Argument} arg
|
||
* @return {string}
|
||
* @private
|
||
*/
|
||
function humanReadableArgName(arg) {
|
||
const nameOutput = arg.name() + (arg.variadic === true ? "..." : "");
|
||
return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]";
|
||
}
|
||
exports.Argument = Argument;
|
||
exports.humanReadableArgName = humanReadableArgName;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/commander@13.1.0/node_modules/commander/lib/help.js
|
||
var require_help = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
const { humanReadableArgName } = require_argument();
|
||
/**
|
||
* TypeScript import types for JSDoc, used by Visual Studio Code IntelliSense and `npm run typescript-checkJS`
|
||
* https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#import-types
|
||
* @typedef { import("./argument.js").Argument } Argument
|
||
* @typedef { import("./command.js").Command } Command
|
||
* @typedef { import("./option.js").Option } Option
|
||
*/
|
||
var Help = class {
|
||
constructor() {
|
||
this.helpWidth = void 0;
|
||
this.minWidthToWrap = 40;
|
||
this.sortSubcommands = false;
|
||
this.sortOptions = false;
|
||
this.showGlobalOptions = false;
|
||
}
|
||
/**
|
||
* prepareContext is called by Commander after applying overrides from `Command.configureHelp()`
|
||
* and just before calling `formatHelp()`.
|
||
*
|
||
* Commander just uses the helpWidth and the rest is provided for optional use by more complex subclasses.
|
||
*
|
||
* @param {{ error?: boolean, helpWidth?: number, outputHasColors?: boolean }} contextOptions
|
||
*/
|
||
prepareContext(contextOptions) {
|
||
this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80;
|
||
}
|
||
/**
|
||
* Get an array of the visible subcommands. Includes a placeholder for the implicit help command, if there is one.
|
||
*
|
||
* @param {Command} cmd
|
||
* @returns {Command[]}
|
||
*/
|
||
visibleCommands(cmd) {
|
||
const visibleCommands = cmd.commands.filter((cmd) => !cmd._hidden);
|
||
const helpCommand = cmd._getHelpCommand();
|
||
if (helpCommand && !helpCommand._hidden) visibleCommands.push(helpCommand);
|
||
if (this.sortSubcommands) visibleCommands.sort((a, b) => {
|
||
return a.name().localeCompare(b.name());
|
||
});
|
||
return visibleCommands;
|
||
}
|
||
/**
|
||
* Compare options for sort.
|
||
*
|
||
* @param {Option} a
|
||
* @param {Option} b
|
||
* @returns {number}
|
||
*/
|
||
compareOptions(a, b) {
|
||
const getSortKey = (option) => {
|
||
return option.short ? option.short.replace(/^-/, "") : option.long.replace(/^--/, "");
|
||
};
|
||
return getSortKey(a).localeCompare(getSortKey(b));
|
||
}
|
||
/**
|
||
* Get an array of the visible options. Includes a placeholder for the implicit help option, if there is one.
|
||
*
|
||
* @param {Command} cmd
|
||
* @returns {Option[]}
|
||
*/
|
||
visibleOptions(cmd) {
|
||
const visibleOptions = cmd.options.filter((option) => !option.hidden);
|
||
const helpOption = cmd._getHelpOption();
|
||
if (helpOption && !helpOption.hidden) {
|
||
const removeShort = helpOption.short && cmd._findOption(helpOption.short);
|
||
const removeLong = helpOption.long && cmd._findOption(helpOption.long);
|
||
if (!removeShort && !removeLong) visibleOptions.push(helpOption);
|
||
else if (helpOption.long && !removeLong) visibleOptions.push(cmd.createOption(helpOption.long, helpOption.description));
|
||
else if (helpOption.short && !removeShort) visibleOptions.push(cmd.createOption(helpOption.short, helpOption.description));
|
||
}
|
||
if (this.sortOptions) visibleOptions.sort(this.compareOptions);
|
||
return visibleOptions;
|
||
}
|
||
/**
|
||
* Get an array of the visible global options. (Not including help.)
|
||
*
|
||
* @param {Command} cmd
|
||
* @returns {Option[]}
|
||
*/
|
||
visibleGlobalOptions(cmd) {
|
||
if (!this.showGlobalOptions) return [];
|
||
const globalOptions = [];
|
||
for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) {
|
||
const visibleOptions = ancestorCmd.options.filter((option) => !option.hidden);
|
||
globalOptions.push(...visibleOptions);
|
||
}
|
||
if (this.sortOptions) globalOptions.sort(this.compareOptions);
|
||
return globalOptions;
|
||
}
|
||
/**
|
||
* Get an array of the arguments if any have a description.
|
||
*
|
||
* @param {Command} cmd
|
||
* @returns {Argument[]}
|
||
*/
|
||
visibleArguments(cmd) {
|
||
if (cmd._argsDescription) cmd.registeredArguments.forEach((argument) => {
|
||
argument.description = argument.description || cmd._argsDescription[argument.name()] || "";
|
||
});
|
||
if (cmd.registeredArguments.find((argument) => argument.description)) return cmd.registeredArguments;
|
||
return [];
|
||
}
|
||
/**
|
||
* Get the command term to show in the list of subcommands.
|
||
*
|
||
* @param {Command} cmd
|
||
* @returns {string}
|
||
*/
|
||
subcommandTerm(cmd) {
|
||
const args = cmd.registeredArguments.map((arg) => humanReadableArgName(arg)).join(" ");
|
||
return cmd._name + (cmd._aliases[0] ? "|" + cmd._aliases[0] : "") + (cmd.options.length ? " [options]" : "") + (args ? " " + args : "");
|
||
}
|
||
/**
|
||
* Get the option term to show in the list of options.
|
||
*
|
||
* @param {Option} option
|
||
* @returns {string}
|
||
*/
|
||
optionTerm(option) {
|
||
return option.flags;
|
||
}
|
||
/**
|
||
* Get the argument term to show in the list of arguments.
|
||
*
|
||
* @param {Argument} argument
|
||
* @returns {string}
|
||
*/
|
||
argumentTerm(argument) {
|
||
return argument.name();
|
||
}
|
||
/**
|
||
* Get the longest command term length.
|
||
*
|
||
* @param {Command} cmd
|
||
* @param {Help} helper
|
||
* @returns {number}
|
||
*/
|
||
longestSubcommandTermLength(cmd, helper) {
|
||
return helper.visibleCommands(cmd).reduce((max, command) => {
|
||
return Math.max(max, this.displayWidth(helper.styleSubcommandTerm(helper.subcommandTerm(command))));
|
||
}, 0);
|
||
}
|
||
/**
|
||
* Get the longest option term length.
|
||
*
|
||
* @param {Command} cmd
|
||
* @param {Help} helper
|
||
* @returns {number}
|
||
*/
|
||
longestOptionTermLength(cmd, helper) {
|
||
return helper.visibleOptions(cmd).reduce((max, option) => {
|
||
return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
|
||
}, 0);
|
||
}
|
||
/**
|
||
* Get the longest global option term length.
|
||
*
|
||
* @param {Command} cmd
|
||
* @param {Help} helper
|
||
* @returns {number}
|
||
*/
|
||
longestGlobalOptionTermLength(cmd, helper) {
|
||
return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
|
||
return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
|
||
}, 0);
|
||
}
|
||
/**
|
||
* Get the longest argument term length.
|
||
*
|
||
* @param {Command} cmd
|
||
* @param {Help} helper
|
||
* @returns {number}
|
||
*/
|
||
longestArgumentTermLength(cmd, helper) {
|
||
return helper.visibleArguments(cmd).reduce((max, argument) => {
|
||
return Math.max(max, this.displayWidth(helper.styleArgumentTerm(helper.argumentTerm(argument))));
|
||
}, 0);
|
||
}
|
||
/**
|
||
* Get the command usage to be displayed at the top of the built-in help.
|
||
*
|
||
* @param {Command} cmd
|
||
* @returns {string}
|
||
*/
|
||
commandUsage(cmd) {
|
||
let cmdName = cmd._name;
|
||
if (cmd._aliases[0]) cmdName = cmdName + "|" + cmd._aliases[0];
|
||
let ancestorCmdNames = "";
|
||
for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) ancestorCmdNames = ancestorCmd.name() + " " + ancestorCmdNames;
|
||
return ancestorCmdNames + cmdName + " " + cmd.usage();
|
||
}
|
||
/**
|
||
* Get the description for the command.
|
||
*
|
||
* @param {Command} cmd
|
||
* @returns {string}
|
||
*/
|
||
commandDescription(cmd) {
|
||
return cmd.description();
|
||
}
|
||
/**
|
||
* Get the subcommand summary to show in the list of subcommands.
|
||
* (Fallback to description for backwards compatibility.)
|
||
*
|
||
* @param {Command} cmd
|
||
* @returns {string}
|
||
*/
|
||
subcommandDescription(cmd) {
|
||
return cmd.summary() || cmd.description();
|
||
}
|
||
/**
|
||
* Get the option description to show in the list of options.
|
||
*
|
||
* @param {Option} option
|
||
* @return {string}
|
||
*/
|
||
optionDescription(option) {
|
||
const extraInfo = [];
|
||
if (option.argChoices) extraInfo.push(`choices: ${option.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`);
|
||
if (option.defaultValue !== void 0) {
|
||
if (option.required || option.optional || option.isBoolean() && typeof option.defaultValue === "boolean") extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`);
|
||
}
|
||
if (option.presetArg !== void 0 && option.optional) extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`);
|
||
if (option.envVar !== void 0) extraInfo.push(`env: ${option.envVar}`);
|
||
if (extraInfo.length > 0) return `${option.description} (${extraInfo.join(", ")})`;
|
||
return option.description;
|
||
}
|
||
/**
|
||
* Get the argument description to show in the list of arguments.
|
||
*
|
||
* @param {Argument} argument
|
||
* @return {string}
|
||
*/
|
||
argumentDescription(argument) {
|
||
const extraInfo = [];
|
||
if (argument.argChoices) extraInfo.push(`choices: ${argument.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`);
|
||
if (argument.defaultValue !== void 0) extraInfo.push(`default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`);
|
||
if (extraInfo.length > 0) {
|
||
const extraDescription = `(${extraInfo.join(", ")})`;
|
||
if (argument.description) return `${argument.description} ${extraDescription}`;
|
||
return extraDescription;
|
||
}
|
||
return argument.description;
|
||
}
|
||
/**
|
||
* Generate the built-in help text.
|
||
*
|
||
* @param {Command} cmd
|
||
* @param {Help} helper
|
||
* @returns {string}
|
||
*/
|
||
formatHelp(cmd, helper) {
|
||
const termWidth = helper.padWidth(cmd, helper);
|
||
const helpWidth = helper.helpWidth ?? 80;
|
||
function callFormatItem(term, description) {
|
||
return helper.formatItem(term, termWidth, description, helper);
|
||
}
|
||
let output = [`${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`, ""];
|
||
const commandDescription = helper.commandDescription(cmd);
|
||
if (commandDescription.length > 0) output = output.concat([helper.boxWrap(helper.styleCommandDescription(commandDescription), helpWidth), ""]);
|
||
const argumentList = helper.visibleArguments(cmd).map((argument) => {
|
||
return callFormatItem(helper.styleArgumentTerm(helper.argumentTerm(argument)), helper.styleArgumentDescription(helper.argumentDescription(argument)));
|
||
});
|
||
if (argumentList.length > 0) output = output.concat([
|
||
helper.styleTitle("Arguments:"),
|
||
...argumentList,
|
||
""
|
||
]);
|
||
const optionList = helper.visibleOptions(cmd).map((option) => {
|
||
return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
|
||
});
|
||
if (optionList.length > 0) output = output.concat([
|
||
helper.styleTitle("Options:"),
|
||
...optionList,
|
||
""
|
||
]);
|
||
if (helper.showGlobalOptions) {
|
||
const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
|
||
return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
|
||
});
|
||
if (globalOptionList.length > 0) output = output.concat([
|
||
helper.styleTitle("Global Options:"),
|
||
...globalOptionList,
|
||
""
|
||
]);
|
||
}
|
||
const commandList = helper.visibleCommands(cmd).map((cmd) => {
|
||
return callFormatItem(helper.styleSubcommandTerm(helper.subcommandTerm(cmd)), helper.styleSubcommandDescription(helper.subcommandDescription(cmd)));
|
||
});
|
||
if (commandList.length > 0) output = output.concat([
|
||
helper.styleTitle("Commands:"),
|
||
...commandList,
|
||
""
|
||
]);
|
||
return output.join("\n");
|
||
}
|
||
/**
|
||
* Return display width of string, ignoring ANSI escape sequences. Used in padding and wrapping calculations.
|
||
*
|
||
* @param {string} str
|
||
* @returns {number}
|
||
*/
|
||
displayWidth(str) {
|
||
return stripColor(str).length;
|
||
}
|
||
/**
|
||
* Style the title for displaying in the help. Called with 'Usage:', 'Options:', etc.
|
||
*
|
||
* @param {string} str
|
||
* @returns {string}
|
||
*/
|
||
styleTitle(str) {
|
||
return str;
|
||
}
|
||
styleUsage(str) {
|
||
return str.split(" ").map((word) => {
|
||
if (word === "[options]") return this.styleOptionText(word);
|
||
if (word === "[command]") return this.styleSubcommandText(word);
|
||
if (word[0] === "[" || word[0] === "<") return this.styleArgumentText(word);
|
||
return this.styleCommandText(word);
|
||
}).join(" ");
|
||
}
|
||
styleCommandDescription(str) {
|
||
return this.styleDescriptionText(str);
|
||
}
|
||
styleOptionDescription(str) {
|
||
return this.styleDescriptionText(str);
|
||
}
|
||
styleSubcommandDescription(str) {
|
||
return this.styleDescriptionText(str);
|
||
}
|
||
styleArgumentDescription(str) {
|
||
return this.styleDescriptionText(str);
|
||
}
|
||
styleDescriptionText(str) {
|
||
return str;
|
||
}
|
||
styleOptionTerm(str) {
|
||
return this.styleOptionText(str);
|
||
}
|
||
styleSubcommandTerm(str) {
|
||
return str.split(" ").map((word) => {
|
||
if (word === "[options]") return this.styleOptionText(word);
|
||
if (word[0] === "[" || word[0] === "<") return this.styleArgumentText(word);
|
||
return this.styleSubcommandText(word);
|
||
}).join(" ");
|
||
}
|
||
styleArgumentTerm(str) {
|
||
return this.styleArgumentText(str);
|
||
}
|
||
styleOptionText(str) {
|
||
return str;
|
||
}
|
||
styleArgumentText(str) {
|
||
return str;
|
||
}
|
||
styleSubcommandText(str) {
|
||
return str;
|
||
}
|
||
styleCommandText(str) {
|
||
return str;
|
||
}
|
||
/**
|
||
* Calculate the pad width from the maximum term length.
|
||
*
|
||
* @param {Command} cmd
|
||
* @param {Help} helper
|
||
* @returns {number}
|
||
*/
|
||
padWidth(cmd, helper) {
|
||
return Math.max(helper.longestOptionTermLength(cmd, helper), helper.longestGlobalOptionTermLength(cmd, helper), helper.longestSubcommandTermLength(cmd, helper), helper.longestArgumentTermLength(cmd, helper));
|
||
}
|
||
/**
|
||
* Detect manually wrapped and indented strings by checking for line break followed by whitespace.
|
||
*
|
||
* @param {string} str
|
||
* @returns {boolean}
|
||
*/
|
||
preformatted(str) {
|
||
return /\n[^\S\r\n]/.test(str);
|
||
}
|
||
/**
|
||
* Format the "item", which consists of a term and description. Pad the term and wrap the description, indenting the following lines.
|
||
*
|
||
* So "TTT", 5, "DDD DDDD DD DDD" might be formatted for this.helpWidth=17 like so:
|
||
* TTT DDD DDDD
|
||
* DD DDD
|
||
*
|
||
* @param {string} term
|
||
* @param {number} termWidth
|
||
* @param {string} description
|
||
* @param {Help} helper
|
||
* @returns {string}
|
||
*/
|
||
formatItem(term, termWidth, description, helper) {
|
||
const itemIndent = 2;
|
||
const itemIndentStr = " ".repeat(itemIndent);
|
||
if (!description) return itemIndentStr + term;
|
||
const paddedTerm = term.padEnd(termWidth + term.length - helper.displayWidth(term));
|
||
const spacerWidth = 2;
|
||
const remainingWidth = (this.helpWidth ?? 80) - termWidth - spacerWidth - itemIndent;
|
||
let formattedDescription;
|
||
if (remainingWidth < this.minWidthToWrap || helper.preformatted(description)) formattedDescription = description;
|
||
else formattedDescription = helper.boxWrap(description, remainingWidth).replace(/\n/g, "\n" + " ".repeat(termWidth + spacerWidth));
|
||
return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, `\n${itemIndentStr}`);
|
||
}
|
||
/**
|
||
* Wrap a string at whitespace, preserving existing line breaks.
|
||
* Wrapping is skipped if the width is less than `minWidthToWrap`.
|
||
*
|
||
* @param {string} str
|
||
* @param {number} width
|
||
* @returns {string}
|
||
*/
|
||
boxWrap(str, width) {
|
||
if (width < this.minWidthToWrap) return str;
|
||
const rawLines = str.split(/\r\n|\n/);
|
||
const chunkPattern = /[\s]*[^\s]+/g;
|
||
const wrappedLines = [];
|
||
rawLines.forEach((line) => {
|
||
const chunks = line.match(chunkPattern);
|
||
if (chunks === null) {
|
||
wrappedLines.push("");
|
||
return;
|
||
}
|
||
let sumChunks = [chunks.shift()];
|
||
let sumWidth = this.displayWidth(sumChunks[0]);
|
||
chunks.forEach((chunk) => {
|
||
const visibleWidth = this.displayWidth(chunk);
|
||
if (sumWidth + visibleWidth <= width) {
|
||
sumChunks.push(chunk);
|
||
sumWidth += visibleWidth;
|
||
return;
|
||
}
|
||
wrappedLines.push(sumChunks.join(""));
|
||
const nextChunk = chunk.trimStart();
|
||
sumChunks = [nextChunk];
|
||
sumWidth = this.displayWidth(nextChunk);
|
||
});
|
||
wrappedLines.push(sumChunks.join(""));
|
||
});
|
||
return wrappedLines.join("\n");
|
||
}
|
||
};
|
||
/**
|
||
* Strip style ANSI escape sequences from the string. In particular, SGR (Select Graphic Rendition) codes.
|
||
*
|
||
* @param {string} str
|
||
* @returns {string}
|
||
* @package
|
||
*/
|
||
function stripColor(str) {
|
||
return str.replace(/\x1b\[\d*(;\d*)*m/g, "");
|
||
}
|
||
exports.Help = Help;
|
||
exports.stripColor = stripColor;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/commander@13.1.0/node_modules/commander/lib/option.js
|
||
var require_option = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
const { InvalidArgumentError } = require_error();
|
||
var Option = class {
|
||
/**
|
||
* Initialize a new `Option` with the given `flags` and `description`.
|
||
*
|
||
* @param {string} flags
|
||
* @param {string} [description]
|
||
*/
|
||
constructor(flags, description) {
|
||
this.flags = flags;
|
||
this.description = description || "";
|
||
this.required = flags.includes("<");
|
||
this.optional = flags.includes("[");
|
||
this.variadic = /\w\.\.\.[>\]]$/.test(flags);
|
||
this.mandatory = false;
|
||
const optionFlags = splitOptionFlags(flags);
|
||
this.short = optionFlags.shortFlag;
|
||
this.long = optionFlags.longFlag;
|
||
this.negate = false;
|
||
if (this.long) this.negate = this.long.startsWith("--no-");
|
||
this.defaultValue = void 0;
|
||
this.defaultValueDescription = void 0;
|
||
this.presetArg = void 0;
|
||
this.envVar = void 0;
|
||
this.parseArg = void 0;
|
||
this.hidden = false;
|
||
this.argChoices = void 0;
|
||
this.conflictsWith = [];
|
||
this.implied = void 0;
|
||
}
|
||
/**
|
||
* Set the default value, and optionally supply the description to be displayed in the help.
|
||
*
|
||
* @param {*} value
|
||
* @param {string} [description]
|
||
* @return {Option}
|
||
*/
|
||
default(value, description) {
|
||
this.defaultValue = value;
|
||
this.defaultValueDescription = description;
|
||
return this;
|
||
}
|
||
/**
|
||
* Preset to use when option used without option-argument, especially optional but also boolean and negated.
|
||
* The custom processing (parseArg) is called.
|
||
*
|
||
* @example
|
||
* new Option('--color').default('GREYSCALE').preset('RGB');
|
||
* new Option('--donate [amount]').preset('20').argParser(parseFloat);
|
||
*
|
||
* @param {*} arg
|
||
* @return {Option}
|
||
*/
|
||
preset(arg) {
|
||
this.presetArg = arg;
|
||
return this;
|
||
}
|
||
/**
|
||
* Add option name(s) that conflict with this option.
|
||
* An error will be displayed if conflicting options are found during parsing.
|
||
*
|
||
* @example
|
||
* new Option('--rgb').conflicts('cmyk');
|
||
* new Option('--js').conflicts(['ts', 'jsx']);
|
||
*
|
||
* @param {(string | string[])} names
|
||
* @return {Option}
|
||
*/
|
||
conflicts(names) {
|
||
this.conflictsWith = this.conflictsWith.concat(names);
|
||
return this;
|
||
}
|
||
/**
|
||
* Specify implied option values for when this option is set and the implied options are not.
|
||
*
|
||
* The custom processing (parseArg) is not called on the implied values.
|
||
*
|
||
* @example
|
||
* program
|
||
* .addOption(new Option('--log', 'write logging information to file'))
|
||
* .addOption(new Option('--trace', 'log extra details').implies({ log: 'trace.txt' }));
|
||
*
|
||
* @param {object} impliedOptionValues
|
||
* @return {Option}
|
||
*/
|
||
implies(impliedOptionValues) {
|
||
let newImplied = impliedOptionValues;
|
||
if (typeof impliedOptionValues === "string") newImplied = { [impliedOptionValues]: true };
|
||
this.implied = Object.assign(this.implied || {}, newImplied);
|
||
return this;
|
||
}
|
||
/**
|
||
* Set environment variable to check for option value.
|
||
*
|
||
* An environment variable is only used if when processed the current option value is
|
||
* undefined, or the source of the current value is 'default' or 'config' or 'env'.
|
||
*
|
||
* @param {string} name
|
||
* @return {Option}
|
||
*/
|
||
env(name) {
|
||
this.envVar = name;
|
||
return this;
|
||
}
|
||
/**
|
||
* Set the custom handler for processing CLI option arguments into option values.
|
||
*
|
||
* @param {Function} [fn]
|
||
* @return {Option}
|
||
*/
|
||
argParser(fn) {
|
||
this.parseArg = fn;
|
||
return this;
|
||
}
|
||
/**
|
||
* Whether the option is mandatory and must have a value after parsing.
|
||
*
|
||
* @param {boolean} [mandatory=true]
|
||
* @return {Option}
|
||
*/
|
||
makeOptionMandatory(mandatory = true) {
|
||
this.mandatory = !!mandatory;
|
||
return this;
|
||
}
|
||
/**
|
||
* Hide option in help.
|
||
*
|
||
* @param {boolean} [hide=true]
|
||
* @return {Option}
|
||
*/
|
||
hideHelp(hide = true) {
|
||
this.hidden = !!hide;
|
||
return this;
|
||
}
|
||
/**
|
||
* @package
|
||
*/
|
||
_concatValue(value, previous) {
|
||
if (previous === this.defaultValue || !Array.isArray(previous)) return [value];
|
||
return previous.concat(value);
|
||
}
|
||
/**
|
||
* Only allow option value to be one of choices.
|
||
*
|
||
* @param {string[]} values
|
||
* @return {Option}
|
||
*/
|
||
choices(values) {
|
||
this.argChoices = values.slice();
|
||
this.parseArg = (arg, previous) => {
|
||
if (!this.argChoices.includes(arg)) throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
|
||
if (this.variadic) return this._concatValue(arg, previous);
|
||
return arg;
|
||
};
|
||
return this;
|
||
}
|
||
/**
|
||
* Return option name.
|
||
*
|
||
* @return {string}
|
||
*/
|
||
name() {
|
||
if (this.long) return this.long.replace(/^--/, "");
|
||
return this.short.replace(/^-/, "");
|
||
}
|
||
/**
|
||
* Return option name, in a camelcase format that can be used
|
||
* as an object attribute key.
|
||
*
|
||
* @return {string}
|
||
*/
|
||
attributeName() {
|
||
if (this.negate) return camelcase(this.name().replace(/^no-/, ""));
|
||
return camelcase(this.name());
|
||
}
|
||
/**
|
||
* Check if `arg` matches the short or long flag.
|
||
*
|
||
* @param {string} arg
|
||
* @return {boolean}
|
||
* @package
|
||
*/
|
||
is(arg) {
|
||
return this.short === arg || this.long === arg;
|
||
}
|
||
/**
|
||
* Return whether a boolean option.
|
||
*
|
||
* Options are one of boolean, negated, required argument, or optional argument.
|
||
*
|
||
* @return {boolean}
|
||
* @package
|
||
*/
|
||
isBoolean() {
|
||
return !this.required && !this.optional && !this.negate;
|
||
}
|
||
};
|
||
/**
|
||
* This class is to make it easier to work with dual options, without changing the existing
|
||
* implementation. We support separate dual options for separate positive and negative options,
|
||
* like `--build` and `--no-build`, which share a single option value. This works nicely for some
|
||
* use cases, but is tricky for others where we want separate behaviours despite
|
||
* the single shared option value.
|
||
*/
|
||
var DualOptions = class {
|
||
/**
|
||
* @param {Option[]} options
|
||
*/
|
||
constructor(options) {
|
||
this.positiveOptions = /* @__PURE__ */ new Map();
|
||
this.negativeOptions = /* @__PURE__ */ new Map();
|
||
this.dualOptions = /* @__PURE__ */ new Set();
|
||
options.forEach((option) => {
|
||
if (option.negate) this.negativeOptions.set(option.attributeName(), option);
|
||
else this.positiveOptions.set(option.attributeName(), option);
|
||
});
|
||
this.negativeOptions.forEach((value, key) => {
|
||
if (this.positiveOptions.has(key)) this.dualOptions.add(key);
|
||
});
|
||
}
|
||
/**
|
||
* Did the value come from the option, and not from possible matching dual option?
|
||
*
|
||
* @param {*} value
|
||
* @param {Option} option
|
||
* @returns {boolean}
|
||
*/
|
||
valueFromOption(value, option) {
|
||
const optionKey = option.attributeName();
|
||
if (!this.dualOptions.has(optionKey)) return true;
|
||
const preset = this.negativeOptions.get(optionKey).presetArg;
|
||
const negativeValue = preset !== void 0 ? preset : false;
|
||
return option.negate === (negativeValue === value);
|
||
}
|
||
};
|
||
/**
|
||
* Convert string from kebab-case to camelCase.
|
||
*
|
||
* @param {string} str
|
||
* @return {string}
|
||
* @private
|
||
*/
|
||
function camelcase(str) {
|
||
return str.split("-").reduce((str, word) => {
|
||
return str + word[0].toUpperCase() + word.slice(1);
|
||
});
|
||
}
|
||
/**
|
||
* Split the short and long flag out of something like '-m,--mixed <value>'
|
||
*
|
||
* @private
|
||
*/
|
||
function splitOptionFlags(flags) {
|
||
let shortFlag;
|
||
let longFlag;
|
||
const shortFlagExp = /^-[^-]$/;
|
||
const longFlagExp = /^--[^-]/;
|
||
const flagParts = flags.split(/[ |,]+/).concat("guard");
|
||
if (shortFlagExp.test(flagParts[0])) shortFlag = flagParts.shift();
|
||
if (longFlagExp.test(flagParts[0])) longFlag = flagParts.shift();
|
||
if (!shortFlag && shortFlagExp.test(flagParts[0])) shortFlag = flagParts.shift();
|
||
if (!shortFlag && longFlagExp.test(flagParts[0])) {
|
||
shortFlag = longFlag;
|
||
longFlag = flagParts.shift();
|
||
}
|
||
if (flagParts[0].startsWith("-")) {
|
||
const unsupportedFlag = flagParts[0];
|
||
const baseError = `option creation failed due to '${unsupportedFlag}' in option flags '${flags}'`;
|
||
if (/^-[^-][^-]/.test(unsupportedFlag)) throw new Error(`${baseError}
|
||
- a short flag is a single dash and a single character
|
||
- either use a single dash and a single character (for a short flag)
|
||
- or use a double dash for a long option (and can have two, like '--ws, --workspace')`);
|
||
if (shortFlagExp.test(unsupportedFlag)) throw new Error(`${baseError}
|
||
- too many short flags`);
|
||
if (longFlagExp.test(unsupportedFlag)) throw new Error(`${baseError}
|
||
- too many long flags`);
|
||
throw new Error(`${baseError}
|
||
- unrecognised flag format`);
|
||
}
|
||
if (shortFlag === void 0 && longFlag === void 0) throw new Error(`option creation failed due to no flags found in '${flags}'.`);
|
||
return {
|
||
shortFlag,
|
||
longFlag
|
||
};
|
||
}
|
||
exports.Option = Option;
|
||
exports.DualOptions = DualOptions;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/commander@13.1.0/node_modules/commander/lib/suggestSimilar.js
|
||
var require_suggestSimilar = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
const maxDistance = 3;
|
||
function editDistance(a, b) {
|
||
if (Math.abs(a.length - b.length) > maxDistance) return Math.max(a.length, b.length);
|
||
const d = [];
|
||
for (let i = 0; i <= a.length; i++) d[i] = [i];
|
||
for (let j = 0; j <= b.length; j++) d[0][j] = j;
|
||
for (let j = 1; j <= b.length; j++) for (let i = 1; i <= a.length; i++) {
|
||
let cost = 1;
|
||
if (a[i - 1] === b[j - 1]) cost = 0;
|
||
else cost = 1;
|
||
d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
|
||
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
|
||
}
|
||
return d[a.length][b.length];
|
||
}
|
||
/**
|
||
* Find close matches, restricted to same number of edits.
|
||
*
|
||
* @param {string} word
|
||
* @param {string[]} candidates
|
||
* @returns {string}
|
||
*/
|
||
function suggestSimilar(word, candidates) {
|
||
if (!candidates || candidates.length === 0) return "";
|
||
candidates = Array.from(new Set(candidates));
|
||
const searchingOptions = word.startsWith("--");
|
||
if (searchingOptions) {
|
||
word = word.slice(2);
|
||
candidates = candidates.map((candidate) => candidate.slice(2));
|
||
}
|
||
let similar = [];
|
||
let bestDistance = maxDistance;
|
||
const minSimilarity = .4;
|
||
candidates.forEach((candidate) => {
|
||
if (candidate.length <= 1) return;
|
||
const distance = editDistance(word, candidate);
|
||
const length = Math.max(word.length, candidate.length);
|
||
if ((length - distance) / length > minSimilarity) {
|
||
if (distance < bestDistance) {
|
||
bestDistance = distance;
|
||
similar = [candidate];
|
||
} else if (distance === bestDistance) similar.push(candidate);
|
||
}
|
||
});
|
||
similar.sort((a, b) => a.localeCompare(b));
|
||
if (searchingOptions) similar = similar.map((candidate) => `--${candidate}`);
|
||
if (similar.length > 1) return `\n(Did you mean one of ${similar.join(", ")}?)`;
|
||
if (similar.length === 1) return `\n(Did you mean ${similar[0]}?)`;
|
||
return "";
|
||
}
|
||
exports.suggestSimilar = suggestSimilar;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/commander@13.1.0/node_modules/commander/lib/command.js
|
||
var require_command = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
const EventEmitter = __require("node:events").EventEmitter;
|
||
const childProcess = __require("node:child_process");
|
||
const path = __require("node:path");
|
||
const fs = __require("node:fs");
|
||
const process$1 = __require("node:process");
|
||
const { Argument, humanReadableArgName } = require_argument();
|
||
const { CommanderError } = require_error();
|
||
const { Help, stripColor } = require_help();
|
||
const { Option, DualOptions } = require_option();
|
||
const { suggestSimilar } = require_suggestSimilar();
|
||
var Command = class Command extends EventEmitter {
|
||
/**
|
||
* Initialize a new `Command`.
|
||
*
|
||
* @param {string} [name]
|
||
*/
|
||
constructor(name) {
|
||
super();
|
||
/** @type {Command[]} */
|
||
this.commands = [];
|
||
/** @type {Option[]} */
|
||
this.options = [];
|
||
this.parent = null;
|
||
this._allowUnknownOption = false;
|
||
this._allowExcessArguments = false;
|
||
/** @type {Argument[]} */
|
||
this.registeredArguments = [];
|
||
this._args = this.registeredArguments;
|
||
/** @type {string[]} */
|
||
this.args = [];
|
||
this.rawArgs = [];
|
||
this.processedArgs = [];
|
||
this._scriptPath = null;
|
||
this._name = name || "";
|
||
this._optionValues = {};
|
||
this._optionValueSources = {};
|
||
this._storeOptionsAsProperties = false;
|
||
this._actionHandler = null;
|
||
this._executableHandler = false;
|
||
this._executableFile = null;
|
||
this._executableDir = null;
|
||
this._defaultCommandName = null;
|
||
this._exitCallback = null;
|
||
this._aliases = [];
|
||
this._combineFlagAndOptionalValue = true;
|
||
this._description = "";
|
||
this._summary = "";
|
||
this._argsDescription = void 0;
|
||
this._enablePositionalOptions = false;
|
||
this._passThroughOptions = false;
|
||
this._lifeCycleHooks = {};
|
||
/** @type {(boolean | string)} */
|
||
this._showHelpAfterError = false;
|
||
this._showSuggestionAfterError = true;
|
||
this._savedState = null;
|
||
this._outputConfiguration = {
|
||
writeOut: (str) => process$1.stdout.write(str),
|
||
writeErr: (str) => process$1.stderr.write(str),
|
||
outputError: (str, write) => write(str),
|
||
getOutHelpWidth: () => process$1.stdout.isTTY ? process$1.stdout.columns : void 0,
|
||
getErrHelpWidth: () => process$1.stderr.isTTY ? process$1.stderr.columns : void 0,
|
||
getOutHasColors: () => useColor() ?? (process$1.stdout.isTTY && process$1.stdout.hasColors?.()),
|
||
getErrHasColors: () => useColor() ?? (process$1.stderr.isTTY && process$1.stderr.hasColors?.()),
|
||
stripColor: (str) => stripColor(str)
|
||
};
|
||
this._hidden = false;
|
||
/** @type {(Option | null | undefined)} */
|
||
this._helpOption = void 0;
|
||
this._addImplicitHelpCommand = void 0;
|
||
/** @type {Command} */
|
||
this._helpCommand = void 0;
|
||
this._helpConfiguration = {};
|
||
}
|
||
/**
|
||
* Copy settings that are useful to have in common across root command and subcommands.
|
||
*
|
||
* (Used internally when adding a command using `.command()` so subcommands inherit parent settings.)
|
||
*
|
||
* @param {Command} sourceCommand
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
copyInheritedSettings(sourceCommand) {
|
||
this._outputConfiguration = sourceCommand._outputConfiguration;
|
||
this._helpOption = sourceCommand._helpOption;
|
||
this._helpCommand = sourceCommand._helpCommand;
|
||
this._helpConfiguration = sourceCommand._helpConfiguration;
|
||
this._exitCallback = sourceCommand._exitCallback;
|
||
this._storeOptionsAsProperties = sourceCommand._storeOptionsAsProperties;
|
||
this._combineFlagAndOptionalValue = sourceCommand._combineFlagAndOptionalValue;
|
||
this._allowExcessArguments = sourceCommand._allowExcessArguments;
|
||
this._enablePositionalOptions = sourceCommand._enablePositionalOptions;
|
||
this._showHelpAfterError = sourceCommand._showHelpAfterError;
|
||
this._showSuggestionAfterError = sourceCommand._showSuggestionAfterError;
|
||
return this;
|
||
}
|
||
/**
|
||
* @returns {Command[]}
|
||
* @private
|
||
*/
|
||
_getCommandAndAncestors() {
|
||
const result = [];
|
||
for (let command = this; command; command = command.parent) result.push(command);
|
||
return result;
|
||
}
|
||
/**
|
||
* Define a command.
|
||
*
|
||
* There are two styles of command: pay attention to where to put the description.
|
||
*
|
||
* @example
|
||
* // Command implemented using action handler (description is supplied separately to `.command`)
|
||
* program
|
||
* .command('clone <source> [destination]')
|
||
* .description('clone a repository into a newly created directory')
|
||
* .action((source, destination) => {
|
||
* console.log('clone command called');
|
||
* });
|
||
*
|
||
* // Command implemented using separate executable file (description is second parameter to `.command`)
|
||
* program
|
||
* .command('start <service>', 'start named service')
|
||
* .command('stop [service]', 'stop named service, or all if no name supplied');
|
||
*
|
||
* @param {string} nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`
|
||
* @param {(object | string)} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)
|
||
* @param {object} [execOpts] - configuration options (for executable)
|
||
* @return {Command} returns new command for action handler, or `this` for executable command
|
||
*/
|
||
command(nameAndArgs, actionOptsOrExecDesc, execOpts) {
|
||
let desc = actionOptsOrExecDesc;
|
||
let opts = execOpts;
|
||
if (typeof desc === "object" && desc !== null) {
|
||
opts = desc;
|
||
desc = null;
|
||
}
|
||
opts = opts || {};
|
||
const [, name, args] = nameAndArgs.match(/([^ ]+) *(.*)/);
|
||
const cmd = this.createCommand(name);
|
||
if (desc) {
|
||
cmd.description(desc);
|
||
cmd._executableHandler = true;
|
||
}
|
||
if (opts.isDefault) this._defaultCommandName = cmd._name;
|
||
cmd._hidden = !!(opts.noHelp || opts.hidden);
|
||
cmd._executableFile = opts.executableFile || null;
|
||
if (args) cmd.arguments(args);
|
||
this._registerCommand(cmd);
|
||
cmd.parent = this;
|
||
cmd.copyInheritedSettings(this);
|
||
if (desc) return this;
|
||
return cmd;
|
||
}
|
||
/**
|
||
* Factory routine to create a new unattached command.
|
||
*
|
||
* See .command() for creating an attached subcommand, which uses this routine to
|
||
* create the command. You can override createCommand to customise subcommands.
|
||
*
|
||
* @param {string} [name]
|
||
* @return {Command} new command
|
||
*/
|
||
createCommand(name) {
|
||
return new Command(name);
|
||
}
|
||
/**
|
||
* You can customise the help with a subclass of Help by overriding createHelp,
|
||
* or by overriding Help properties using configureHelp().
|
||
*
|
||
* @return {Help}
|
||
*/
|
||
createHelp() {
|
||
return Object.assign(new Help(), this.configureHelp());
|
||
}
|
||
/**
|
||
* You can customise the help by overriding Help properties using configureHelp(),
|
||
* or with a subclass of Help by overriding createHelp().
|
||
*
|
||
* @param {object} [configuration] - configuration options
|
||
* @return {(Command | object)} `this` command for chaining, or stored configuration
|
||
*/
|
||
configureHelp(configuration) {
|
||
if (configuration === void 0) return this._helpConfiguration;
|
||
this._helpConfiguration = configuration;
|
||
return this;
|
||
}
|
||
/**
|
||
* The default output goes to stdout and stderr. You can customise this for special
|
||
* applications. You can also customise the display of errors by overriding outputError.
|
||
*
|
||
* The configuration properties are all functions:
|
||
*
|
||
* // change how output being written, defaults to stdout and stderr
|
||
* writeOut(str)
|
||
* writeErr(str)
|
||
* // change how output being written for errors, defaults to writeErr
|
||
* outputError(str, write) // used for displaying errors and not used for displaying help
|
||
* // specify width for wrapping help
|
||
* getOutHelpWidth()
|
||
* getErrHelpWidth()
|
||
* // color support, currently only used with Help
|
||
* getOutHasColors()
|
||
* getErrHasColors()
|
||
* stripColor() // used to remove ANSI escape codes if output does not have colors
|
||
*
|
||
* @param {object} [configuration] - configuration options
|
||
* @return {(Command | object)} `this` command for chaining, or stored configuration
|
||
*/
|
||
configureOutput(configuration) {
|
||
if (configuration === void 0) return this._outputConfiguration;
|
||
Object.assign(this._outputConfiguration, configuration);
|
||
return this;
|
||
}
|
||
/**
|
||
* Display the help or a custom message after an error occurs.
|
||
*
|
||
* @param {(boolean|string)} [displayHelp]
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
showHelpAfterError(displayHelp = true) {
|
||
if (typeof displayHelp !== "string") displayHelp = !!displayHelp;
|
||
this._showHelpAfterError = displayHelp;
|
||
return this;
|
||
}
|
||
/**
|
||
* Display suggestion of similar commands for unknown commands, or options for unknown options.
|
||
*
|
||
* @param {boolean} [displaySuggestion]
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
showSuggestionAfterError(displaySuggestion = true) {
|
||
this._showSuggestionAfterError = !!displaySuggestion;
|
||
return this;
|
||
}
|
||
/**
|
||
* Add a prepared subcommand.
|
||
*
|
||
* See .command() for creating an attached subcommand which inherits settings from its parent.
|
||
*
|
||
* @param {Command} cmd - new subcommand
|
||
* @param {object} [opts] - configuration options
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
addCommand(cmd, opts) {
|
||
if (!cmd._name) throw new Error(`Command passed to .addCommand() must have a name
|
||
- specify the name in Command constructor or using .name()`);
|
||
opts = opts || {};
|
||
if (opts.isDefault) this._defaultCommandName = cmd._name;
|
||
if (opts.noHelp || opts.hidden) cmd._hidden = true;
|
||
this._registerCommand(cmd);
|
||
cmd.parent = this;
|
||
cmd._checkForBrokenPassThrough();
|
||
return this;
|
||
}
|
||
/**
|
||
* Factory routine to create a new unattached argument.
|
||
*
|
||
* See .argument() for creating an attached argument, which uses this routine to
|
||
* create the argument. You can override createArgument to return a custom argument.
|
||
*
|
||
* @param {string} name
|
||
* @param {string} [description]
|
||
* @return {Argument} new argument
|
||
*/
|
||
createArgument(name, description) {
|
||
return new Argument(name, description);
|
||
}
|
||
/**
|
||
* Define argument syntax for command.
|
||
*
|
||
* The default is that the argument is required, and you can explicitly
|
||
* indicate this with <> around the name. Put [] around the name for an optional argument.
|
||
*
|
||
* @example
|
||
* program.argument('<input-file>');
|
||
* program.argument('[output-file]');
|
||
*
|
||
* @param {string} name
|
||
* @param {string} [description]
|
||
* @param {(Function|*)} [fn] - custom argument processing function
|
||
* @param {*} [defaultValue]
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
argument(name, description, fn, defaultValue) {
|
||
const argument = this.createArgument(name, description);
|
||
if (typeof fn === "function") argument.default(defaultValue).argParser(fn);
|
||
else argument.default(fn);
|
||
this.addArgument(argument);
|
||
return this;
|
||
}
|
||
/**
|
||
* Define argument syntax for command, adding multiple at once (without descriptions).
|
||
*
|
||
* See also .argument().
|
||
*
|
||
* @example
|
||
* program.arguments('<cmd> [env]');
|
||
*
|
||
* @param {string} names
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
arguments(names) {
|
||
names.trim().split(/ +/).forEach((detail) => {
|
||
this.argument(detail);
|
||
});
|
||
return this;
|
||
}
|
||
/**
|
||
* Define argument syntax for command, adding a prepared argument.
|
||
*
|
||
* @param {Argument} argument
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
addArgument(argument) {
|
||
const previousArgument = this.registeredArguments.slice(-1)[0];
|
||
if (previousArgument && previousArgument.variadic) throw new Error(`only the last argument can be variadic '${previousArgument.name()}'`);
|
||
if (argument.required && argument.defaultValue !== void 0 && argument.parseArg === void 0) throw new Error(`a default value for a required argument is never used: '${argument.name()}'`);
|
||
this.registeredArguments.push(argument);
|
||
return this;
|
||
}
|
||
/**
|
||
* Customise or override default help command. By default a help command is automatically added if your command has subcommands.
|
||
*
|
||
* @example
|
||
* program.helpCommand('help [cmd]');
|
||
* program.helpCommand('help [cmd]', 'show help');
|
||
* program.helpCommand(false); // suppress default help command
|
||
* program.helpCommand(true); // add help command even if no subcommands
|
||
*
|
||
* @param {string|boolean} enableOrNameAndArgs - enable with custom name and/or arguments, or boolean to override whether added
|
||
* @param {string} [description] - custom description
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
helpCommand(enableOrNameAndArgs, description) {
|
||
if (typeof enableOrNameAndArgs === "boolean") {
|
||
this._addImplicitHelpCommand = enableOrNameAndArgs;
|
||
return this;
|
||
}
|
||
enableOrNameAndArgs = enableOrNameAndArgs ?? "help [command]";
|
||
const [, helpName, helpArgs] = enableOrNameAndArgs.match(/([^ ]+) *(.*)/);
|
||
const helpDescription = description ?? "display help for command";
|
||
const helpCommand = this.createCommand(helpName);
|
||
helpCommand.helpOption(false);
|
||
if (helpArgs) helpCommand.arguments(helpArgs);
|
||
if (helpDescription) helpCommand.description(helpDescription);
|
||
this._addImplicitHelpCommand = true;
|
||
this._helpCommand = helpCommand;
|
||
return this;
|
||
}
|
||
/**
|
||
* Add prepared custom help command.
|
||
*
|
||
* @param {(Command|string|boolean)} helpCommand - custom help command, or deprecated enableOrNameAndArgs as for `.helpCommand()`
|
||
* @param {string} [deprecatedDescription] - deprecated custom description used with custom name only
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
addHelpCommand(helpCommand, deprecatedDescription) {
|
||
if (typeof helpCommand !== "object") {
|
||
this.helpCommand(helpCommand, deprecatedDescription);
|
||
return this;
|
||
}
|
||
this._addImplicitHelpCommand = true;
|
||
this._helpCommand = helpCommand;
|
||
return this;
|
||
}
|
||
/**
|
||
* Lazy create help command.
|
||
*
|
||
* @return {(Command|null)}
|
||
* @package
|
||
*/
|
||
_getHelpCommand() {
|
||
if (this._addImplicitHelpCommand ?? (this.commands.length && !this._actionHandler && !this._findCommand("help"))) {
|
||
if (this._helpCommand === void 0) this.helpCommand(void 0, void 0);
|
||
return this._helpCommand;
|
||
}
|
||
return null;
|
||
}
|
||
/**
|
||
* Add hook for life cycle event.
|
||
*
|
||
* @param {string} event
|
||
* @param {Function} listener
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
hook(event, listener) {
|
||
const allowedValues = [
|
||
"preSubcommand",
|
||
"preAction",
|
||
"postAction"
|
||
];
|
||
if (!allowedValues.includes(event)) throw new Error(`Unexpected value for event passed to hook : '${event}'.
|
||
Expecting one of '${allowedValues.join("', '")}'`);
|
||
if (this._lifeCycleHooks[event]) this._lifeCycleHooks[event].push(listener);
|
||
else this._lifeCycleHooks[event] = [listener];
|
||
return this;
|
||
}
|
||
/**
|
||
* Register callback to use as replacement for calling process.exit.
|
||
*
|
||
* @param {Function} [fn] optional callback which will be passed a CommanderError, defaults to throwing
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
exitOverride(fn) {
|
||
if (fn) this._exitCallback = fn;
|
||
else this._exitCallback = (err) => {
|
||
if (err.code !== "commander.executeSubCommandAsync") throw err;
|
||
};
|
||
return this;
|
||
}
|
||
/**
|
||
* Call process.exit, and _exitCallback if defined.
|
||
*
|
||
* @param {number} exitCode exit code for using with process.exit
|
||
* @param {string} code an id string representing the error
|
||
* @param {string} message human-readable description of the error
|
||
* @return never
|
||
* @private
|
||
*/
|
||
_exit(exitCode, code, message) {
|
||
if (this._exitCallback) this._exitCallback(new CommanderError(exitCode, code, message));
|
||
process$1.exit(exitCode);
|
||
}
|
||
/**
|
||
* Register callback `fn` for the command.
|
||
*
|
||
* @example
|
||
* program
|
||
* .command('serve')
|
||
* .description('start service')
|
||
* .action(function() {
|
||
* // do work here
|
||
* });
|
||
*
|
||
* @param {Function} fn
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
action(fn) {
|
||
const listener = (args) => {
|
||
const expectedArgsCount = this.registeredArguments.length;
|
||
const actionArgs = args.slice(0, expectedArgsCount);
|
||
if (this._storeOptionsAsProperties) actionArgs[expectedArgsCount] = this;
|
||
else actionArgs[expectedArgsCount] = this.opts();
|
||
actionArgs.push(this);
|
||
return fn.apply(this, actionArgs);
|
||
};
|
||
this._actionHandler = listener;
|
||
return this;
|
||
}
|
||
/**
|
||
* Factory routine to create a new unattached option.
|
||
*
|
||
* See .option() for creating an attached option, which uses this routine to
|
||
* create the option. You can override createOption to return a custom option.
|
||
*
|
||
* @param {string} flags
|
||
* @param {string} [description]
|
||
* @return {Option} new option
|
||
*/
|
||
createOption(flags, description) {
|
||
return new Option(flags, description);
|
||
}
|
||
/**
|
||
* Wrap parseArgs to catch 'commander.invalidArgument'.
|
||
*
|
||
* @param {(Option | Argument)} target
|
||
* @param {string} value
|
||
* @param {*} previous
|
||
* @param {string} invalidArgumentMessage
|
||
* @private
|
||
*/
|
||
_callParseArg(target, value, previous, invalidArgumentMessage) {
|
||
try {
|
||
return target.parseArg(value, previous);
|
||
} catch (err) {
|
||
if (err.code === "commander.invalidArgument") {
|
||
const message = `${invalidArgumentMessage} ${err.message}`;
|
||
this.error(message, {
|
||
exitCode: err.exitCode,
|
||
code: err.code
|
||
});
|
||
}
|
||
throw err;
|
||
}
|
||
}
|
||
/**
|
||
* Check for option flag conflicts.
|
||
* Register option if no conflicts found, or throw on conflict.
|
||
*
|
||
* @param {Option} option
|
||
* @private
|
||
*/
|
||
_registerOption(option) {
|
||
const matchingOption = option.short && this._findOption(option.short) || option.long && this._findOption(option.long);
|
||
if (matchingOption) {
|
||
const matchingFlag = option.long && this._findOption(option.long) ? option.long : option.short;
|
||
throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'
|
||
- already used by option '${matchingOption.flags}'`);
|
||
}
|
||
this.options.push(option);
|
||
}
|
||
/**
|
||
* Check for command name and alias conflicts with existing commands.
|
||
* Register command if no conflicts found, or throw on conflict.
|
||
*
|
||
* @param {Command} command
|
||
* @private
|
||
*/
|
||
_registerCommand(command) {
|
||
const knownBy = (cmd) => {
|
||
return [cmd.name()].concat(cmd.aliases());
|
||
};
|
||
const alreadyUsed = knownBy(command).find((name) => this._findCommand(name));
|
||
if (alreadyUsed) {
|
||
const existingCmd = knownBy(this._findCommand(alreadyUsed)).join("|");
|
||
const newCmd = knownBy(command).join("|");
|
||
throw new Error(`cannot add command '${newCmd}' as already have command '${existingCmd}'`);
|
||
}
|
||
this.commands.push(command);
|
||
}
|
||
/**
|
||
* Add an option.
|
||
*
|
||
* @param {Option} option
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
addOption(option) {
|
||
this._registerOption(option);
|
||
const oname = option.name();
|
||
const name = option.attributeName();
|
||
if (option.negate) {
|
||
const positiveLongFlag = option.long.replace(/^--no-/, "--");
|
||
if (!this._findOption(positiveLongFlag)) this.setOptionValueWithSource(name, option.defaultValue === void 0 ? true : option.defaultValue, "default");
|
||
} else if (option.defaultValue !== void 0) this.setOptionValueWithSource(name, option.defaultValue, "default");
|
||
const handleOptionValue = (val, invalidValueMessage, valueSource) => {
|
||
if (val == null && option.presetArg !== void 0) val = option.presetArg;
|
||
const oldValue = this.getOptionValue(name);
|
||
if (val !== null && option.parseArg) val = this._callParseArg(option, val, oldValue, invalidValueMessage);
|
||
else if (val !== null && option.variadic) val = option._concatValue(val, oldValue);
|
||
if (val == null) if (option.negate) val = false;
|
||
else if (option.isBoolean() || option.optional) val = true;
|
||
else val = "";
|
||
this.setOptionValueWithSource(name, val, valueSource);
|
||
};
|
||
this.on("option:" + oname, (val) => {
|
||
handleOptionValue(val, `error: option '${option.flags}' argument '${val}' is invalid.`, "cli");
|
||
});
|
||
if (option.envVar) this.on("optionEnv:" + oname, (val) => {
|
||
handleOptionValue(val, `error: option '${option.flags}' value '${val}' from env '${option.envVar}' is invalid.`, "env");
|
||
});
|
||
return this;
|
||
}
|
||
/**
|
||
* Internal implementation shared by .option() and .requiredOption()
|
||
*
|
||
* @return {Command} `this` command for chaining
|
||
* @private
|
||
*/
|
||
_optionEx(config, flags, description, fn, defaultValue) {
|
||
if (typeof flags === "object" && flags instanceof Option) throw new Error("To add an Option object use addOption() instead of option() or requiredOption()");
|
||
const option = this.createOption(flags, description);
|
||
option.makeOptionMandatory(!!config.mandatory);
|
||
if (typeof fn === "function") option.default(defaultValue).argParser(fn);
|
||
else if (fn instanceof RegExp) {
|
||
const regex = fn;
|
||
fn = (val, def) => {
|
||
const m = regex.exec(val);
|
||
return m ? m[0] : def;
|
||
};
|
||
option.default(defaultValue).argParser(fn);
|
||
} else option.default(fn);
|
||
return this.addOption(option);
|
||
}
|
||
/**
|
||
* Define option with `flags`, `description`, and optional argument parsing function or `defaultValue` or both.
|
||
*
|
||
* The `flags` string contains the short and/or long flags, separated by comma, a pipe or space. A required
|
||
* option-argument is indicated by `<>` and an optional option-argument by `[]`.
|
||
*
|
||
* See the README for more details, and see also addOption() and requiredOption().
|
||
*
|
||
* @example
|
||
* program
|
||
* .option('-p, --pepper', 'add pepper')
|
||
* .option('--pt, --pizza-type <TYPE>', 'type of pizza') // required option-argument
|
||
* .option('-c, --cheese [CHEESE]', 'add extra cheese', 'mozzarella') // optional option-argument with default
|
||
* .option('-t, --tip <VALUE>', 'add tip to purchase cost', parseFloat) // custom parse function
|
||
*
|
||
* @param {string} flags
|
||
* @param {string} [description]
|
||
* @param {(Function|*)} [parseArg] - custom option processing function or default value
|
||
* @param {*} [defaultValue]
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
option(flags, description, parseArg, defaultValue) {
|
||
return this._optionEx({}, flags, description, parseArg, defaultValue);
|
||
}
|
||
/**
|
||
* Add a required option which must have a value after parsing. This usually means
|
||
* the option must be specified on the command line. (Otherwise the same as .option().)
|
||
*
|
||
* The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.
|
||
*
|
||
* @param {string} flags
|
||
* @param {string} [description]
|
||
* @param {(Function|*)} [parseArg] - custom option processing function or default value
|
||
* @param {*} [defaultValue]
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
requiredOption(flags, description, parseArg, defaultValue) {
|
||
return this._optionEx({ mandatory: true }, flags, description, parseArg, defaultValue);
|
||
}
|
||
/**
|
||
* Alter parsing of short flags with optional values.
|
||
*
|
||
* @example
|
||
* // for `.option('-f,--flag [value]'):
|
||
* program.combineFlagAndOptionalValue(true); // `-f80` is treated like `--flag=80`, this is the default behaviour
|
||
* program.combineFlagAndOptionalValue(false) // `-fb` is treated like `-f -b`
|
||
*
|
||
* @param {boolean} [combine] - if `true` or omitted, an optional value can be specified directly after the flag.
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
combineFlagAndOptionalValue(combine = true) {
|
||
this._combineFlagAndOptionalValue = !!combine;
|
||
return this;
|
||
}
|
||
/**
|
||
* Allow unknown options on the command line.
|
||
*
|
||
* @param {boolean} [allowUnknown] - if `true` or omitted, no error will be thrown for unknown options.
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
allowUnknownOption(allowUnknown = true) {
|
||
this._allowUnknownOption = !!allowUnknown;
|
||
return this;
|
||
}
|
||
/**
|
||
* Allow excess command-arguments on the command line. Pass false to make excess arguments an error.
|
||
*
|
||
* @param {boolean} [allowExcess] - if `true` or omitted, no error will be thrown for excess arguments.
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
allowExcessArguments(allowExcess = true) {
|
||
this._allowExcessArguments = !!allowExcess;
|
||
return this;
|
||
}
|
||
/**
|
||
* Enable positional options. Positional means global options are specified before subcommands which lets
|
||
* subcommands reuse the same option names, and also enables subcommands to turn on passThroughOptions.
|
||
* The default behaviour is non-positional and global options may appear anywhere on the command line.
|
||
*
|
||
* @param {boolean} [positional]
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
enablePositionalOptions(positional = true) {
|
||
this._enablePositionalOptions = !!positional;
|
||
return this;
|
||
}
|
||
/**
|
||
* Pass through options that come after command-arguments rather than treat them as command-options,
|
||
* so actual command-options come before command-arguments. Turning this on for a subcommand requires
|
||
* positional options to have been enabled on the program (parent commands).
|
||
* The default behaviour is non-positional and options may appear before or after command-arguments.
|
||
*
|
||
* @param {boolean} [passThrough] for unknown options.
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
passThroughOptions(passThrough = true) {
|
||
this._passThroughOptions = !!passThrough;
|
||
this._checkForBrokenPassThrough();
|
||
return this;
|
||
}
|
||
/**
|
||
* @private
|
||
*/
|
||
_checkForBrokenPassThrough() {
|
||
if (this.parent && this._passThroughOptions && !this.parent._enablePositionalOptions) throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`);
|
||
}
|
||
/**
|
||
* Whether to store option values as properties on command object,
|
||
* or store separately (specify false). In both cases the option values can be accessed using .opts().
|
||
*
|
||
* @param {boolean} [storeAsProperties=true]
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
storeOptionsAsProperties(storeAsProperties = true) {
|
||
if (this.options.length) throw new Error("call .storeOptionsAsProperties() before adding options");
|
||
if (Object.keys(this._optionValues).length) throw new Error("call .storeOptionsAsProperties() before setting option values");
|
||
this._storeOptionsAsProperties = !!storeAsProperties;
|
||
return this;
|
||
}
|
||
/**
|
||
* Retrieve option value.
|
||
*
|
||
* @param {string} key
|
||
* @return {object} value
|
||
*/
|
||
getOptionValue(key) {
|
||
if (this._storeOptionsAsProperties) return this[key];
|
||
return this._optionValues[key];
|
||
}
|
||
/**
|
||
* Store option value.
|
||
*
|
||
* @param {string} key
|
||
* @param {object} value
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
setOptionValue(key, value) {
|
||
return this.setOptionValueWithSource(key, value, void 0);
|
||
}
|
||
/**
|
||
* Store option value and where the value came from.
|
||
*
|
||
* @param {string} key
|
||
* @param {object} value
|
||
* @param {string} source - expected values are default/config/env/cli/implied
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
setOptionValueWithSource(key, value, source) {
|
||
if (this._storeOptionsAsProperties) this[key] = value;
|
||
else this._optionValues[key] = value;
|
||
this._optionValueSources[key] = source;
|
||
return this;
|
||
}
|
||
/**
|
||
* Get source of option value.
|
||
* Expected values are default | config | env | cli | implied
|
||
*
|
||
* @param {string} key
|
||
* @return {string}
|
||
*/
|
||
getOptionValueSource(key) {
|
||
return this._optionValueSources[key];
|
||
}
|
||
/**
|
||
* Get source of option value. See also .optsWithGlobals().
|
||
* Expected values are default | config | env | cli | implied
|
||
*
|
||
* @param {string} key
|
||
* @return {string}
|
||
*/
|
||
getOptionValueSourceWithGlobals(key) {
|
||
let source;
|
||
this._getCommandAndAncestors().forEach((cmd) => {
|
||
if (cmd.getOptionValueSource(key) !== void 0) source = cmd.getOptionValueSource(key);
|
||
});
|
||
return source;
|
||
}
|
||
/**
|
||
* Get user arguments from implied or explicit arguments.
|
||
* Side-effects: set _scriptPath if args included script. Used for default program name, and subcommand searches.
|
||
*
|
||
* @private
|
||
*/
|
||
_prepareUserArgs(argv, parseOptions) {
|
||
if (argv !== void 0 && !Array.isArray(argv)) throw new Error("first parameter to parse must be array or undefined");
|
||
parseOptions = parseOptions || {};
|
||
if (argv === void 0 && parseOptions.from === void 0) {
|
||
if (process$1.versions?.electron) parseOptions.from = "electron";
|
||
const execArgv = process$1.execArgv ?? [];
|
||
if (execArgv.includes("-e") || execArgv.includes("--eval") || execArgv.includes("-p") || execArgv.includes("--print")) parseOptions.from = "eval";
|
||
}
|
||
if (argv === void 0) argv = process$1.argv;
|
||
this.rawArgs = argv.slice();
|
||
let userArgs;
|
||
switch (parseOptions.from) {
|
||
case void 0:
|
||
case "node":
|
||
this._scriptPath = argv[1];
|
||
userArgs = argv.slice(2);
|
||
break;
|
||
case "electron":
|
||
if (process$1.defaultApp) {
|
||
this._scriptPath = argv[1];
|
||
userArgs = argv.slice(2);
|
||
} else userArgs = argv.slice(1);
|
||
break;
|
||
case "user":
|
||
userArgs = argv.slice(0);
|
||
break;
|
||
case "eval":
|
||
userArgs = argv.slice(1);
|
||
break;
|
||
default: throw new Error(`unexpected parse option { from: '${parseOptions.from}' }`);
|
||
}
|
||
if (!this._name && this._scriptPath) this.nameFromFilename(this._scriptPath);
|
||
this._name = this._name || "program";
|
||
return userArgs;
|
||
}
|
||
/**
|
||
* Parse `argv`, setting options and invoking commands when defined.
|
||
*
|
||
* Use parseAsync instead of parse if any of your action handlers are async.
|
||
*
|
||
* Call with no parameters to parse `process.argv`. Detects Electron and special node options like `node --eval`. Easy mode!
|
||
*
|
||
* Or call with an array of strings to parse, and optionally where the user arguments start by specifying where the arguments are `from`:
|
||
* - `'node'`: default, `argv[0]` is the application and `argv[1]` is the script being run, with user arguments after that
|
||
* - `'electron'`: `argv[0]` is the application and `argv[1]` varies depending on whether the electron application is packaged
|
||
* - `'user'`: just user arguments
|
||
*
|
||
* @example
|
||
* program.parse(); // parse process.argv and auto-detect electron and special node flags
|
||
* program.parse(process.argv); // assume argv[0] is app and argv[1] is script
|
||
* program.parse(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
|
||
*
|
||
* @param {string[]} [argv] - optional, defaults to process.argv
|
||
* @param {object} [parseOptions] - optionally specify style of options with from: node/user/electron
|
||
* @param {string} [parseOptions.from] - where the args are from: 'node', 'user', 'electron'
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
parse(argv, parseOptions) {
|
||
this._prepareForParse();
|
||
const userArgs = this._prepareUserArgs(argv, parseOptions);
|
||
this._parseCommand([], userArgs);
|
||
return this;
|
||
}
|
||
/**
|
||
* Parse `argv`, setting options and invoking commands when defined.
|
||
*
|
||
* Call with no parameters to parse `process.argv`. Detects Electron and special node options like `node --eval`. Easy mode!
|
||
*
|
||
* Or call with an array of strings to parse, and optionally where the user arguments start by specifying where the arguments are `from`:
|
||
* - `'node'`: default, `argv[0]` is the application and `argv[1]` is the script being run, with user arguments after that
|
||
* - `'electron'`: `argv[0]` is the application and `argv[1]` varies depending on whether the electron application is packaged
|
||
* - `'user'`: just user arguments
|
||
*
|
||
* @example
|
||
* await program.parseAsync(); // parse process.argv and auto-detect electron and special node flags
|
||
* await program.parseAsync(process.argv); // assume argv[0] is app and argv[1] is script
|
||
* await program.parseAsync(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
|
||
*
|
||
* @param {string[]} [argv]
|
||
* @param {object} [parseOptions]
|
||
* @param {string} parseOptions.from - where the args are from: 'node', 'user', 'electron'
|
||
* @return {Promise}
|
||
*/
|
||
async parseAsync(argv, parseOptions) {
|
||
this._prepareForParse();
|
||
const userArgs = this._prepareUserArgs(argv, parseOptions);
|
||
await this._parseCommand([], userArgs);
|
||
return this;
|
||
}
|
||
_prepareForParse() {
|
||
if (this._savedState === null) this.saveStateBeforeParse();
|
||
else this.restoreStateBeforeParse();
|
||
}
|
||
/**
|
||
* Called the first time parse is called to save state and allow a restore before subsequent calls to parse.
|
||
* Not usually called directly, but available for subclasses to save their custom state.
|
||
*
|
||
* This is called in a lazy way. Only commands used in parsing chain will have state saved.
|
||
*/
|
||
saveStateBeforeParse() {
|
||
this._savedState = {
|
||
_name: this._name,
|
||
_optionValues: { ...this._optionValues },
|
||
_optionValueSources: { ...this._optionValueSources }
|
||
};
|
||
}
|
||
/**
|
||
* Restore state before parse for calls after the first.
|
||
* Not usually called directly, but available for subclasses to save their custom state.
|
||
*
|
||
* This is called in a lazy way. Only commands used in parsing chain will have state restored.
|
||
*/
|
||
restoreStateBeforeParse() {
|
||
if (this._storeOptionsAsProperties) throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
|
||
- either make a new Command for each call to parse, or stop storing options as properties`);
|
||
this._name = this._savedState._name;
|
||
this._scriptPath = null;
|
||
this.rawArgs = [];
|
||
this._optionValues = { ...this._savedState._optionValues };
|
||
this._optionValueSources = { ...this._savedState._optionValueSources };
|
||
this.args = [];
|
||
this.processedArgs = [];
|
||
}
|
||
/**
|
||
* Throw if expected executable is missing. Add lots of help for author.
|
||
*
|
||
* @param {string} executableFile
|
||
* @param {string} executableDir
|
||
* @param {string} subcommandName
|
||
*/
|
||
_checkForMissingExecutable(executableFile, executableDir, subcommandName) {
|
||
if (fs.existsSync(executableFile)) return;
|
||
const executableMissing = `'${executableFile}' does not exist
|
||
- if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
|
||
- if the default executable name is not suitable, use the executableFile option to supply a custom name or path
|
||
- ${executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory"}`;
|
||
throw new Error(executableMissing);
|
||
}
|
||
/**
|
||
* Execute a sub-command executable.
|
||
*
|
||
* @private
|
||
*/
|
||
_executeSubCommand(subcommand, args) {
|
||
args = args.slice();
|
||
let launchWithNode = false;
|
||
const sourceExt = [
|
||
".js",
|
||
".ts",
|
||
".tsx",
|
||
".mjs",
|
||
".cjs"
|
||
];
|
||
function findFile(baseDir, baseName) {
|
||
const localBin = path.resolve(baseDir, baseName);
|
||
if (fs.existsSync(localBin)) return localBin;
|
||
if (sourceExt.includes(path.extname(baseName))) return void 0;
|
||
const foundExt = sourceExt.find((ext) => fs.existsSync(`${localBin}${ext}`));
|
||
if (foundExt) return `${localBin}${foundExt}`;
|
||
}
|
||
this._checkForMissingMandatoryOptions();
|
||
this._checkForConflictingOptions();
|
||
let executableFile = subcommand._executableFile || `${this._name}-${subcommand._name}`;
|
||
let executableDir = this._executableDir || "";
|
||
if (this._scriptPath) {
|
||
let resolvedScriptPath;
|
||
try {
|
||
resolvedScriptPath = fs.realpathSync(this._scriptPath);
|
||
} catch {
|
||
resolvedScriptPath = this._scriptPath;
|
||
}
|
||
executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir);
|
||
}
|
||
if (executableDir) {
|
||
let localFile = findFile(executableDir, executableFile);
|
||
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
||
const legacyName = path.basename(this._scriptPath, path.extname(this._scriptPath));
|
||
if (legacyName !== this._name) localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
|
||
}
|
||
executableFile = localFile || executableFile;
|
||
}
|
||
launchWithNode = sourceExt.includes(path.extname(executableFile));
|
||
let proc;
|
||
if (process$1.platform !== "win32") if (launchWithNode) {
|
||
args.unshift(executableFile);
|
||
args = incrementNodeInspectorPort(process$1.execArgv).concat(args);
|
||
proc = childProcess.spawn(process$1.argv[0], args, { stdio: "inherit" });
|
||
} else proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
|
||
else {
|
||
this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
|
||
args.unshift(executableFile);
|
||
args = incrementNodeInspectorPort(process$1.execArgv).concat(args);
|
||
proc = childProcess.spawn(process$1.execPath, args, { stdio: "inherit" });
|
||
}
|
||
if (!proc.killed) [
|
||
"SIGUSR1",
|
||
"SIGUSR2",
|
||
"SIGTERM",
|
||
"SIGINT",
|
||
"SIGHUP"
|
||
].forEach((signal) => {
|
||
process$1.on(signal, () => {
|
||
if (proc.killed === false && proc.exitCode === null) proc.kill(signal);
|
||
});
|
||
});
|
||
const exitCallback = this._exitCallback;
|
||
proc.on("close", (code) => {
|
||
code = code ?? 1;
|
||
if (!exitCallback) process$1.exit(code);
|
||
else exitCallback(new CommanderError(code, "commander.executeSubCommandAsync", "(close)"));
|
||
});
|
||
proc.on("error", (err) => {
|
||
if (err.code === "ENOENT") this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
|
||
else if (err.code === "EACCES") throw new Error(`'${executableFile}' not executable`);
|
||
if (!exitCallback) process$1.exit(1);
|
||
else {
|
||
const wrappedError = new CommanderError(1, "commander.executeSubCommandAsync", "(error)");
|
||
wrappedError.nestedError = err;
|
||
exitCallback(wrappedError);
|
||
}
|
||
});
|
||
this.runningCommand = proc;
|
||
}
|
||
/**
|
||
* @private
|
||
*/
|
||
_dispatchSubcommand(commandName, operands, unknown) {
|
||
const subCommand = this._findCommand(commandName);
|
||
if (!subCommand) this.help({ error: true });
|
||
subCommand._prepareForParse();
|
||
let promiseChain;
|
||
promiseChain = this._chainOrCallSubCommandHook(promiseChain, subCommand, "preSubcommand");
|
||
promiseChain = this._chainOrCall(promiseChain, () => {
|
||
if (subCommand._executableHandler) this._executeSubCommand(subCommand, operands.concat(unknown));
|
||
else return subCommand._parseCommand(operands, unknown);
|
||
});
|
||
return promiseChain;
|
||
}
|
||
/**
|
||
* Invoke help directly if possible, or dispatch if necessary.
|
||
* e.g. help foo
|
||
*
|
||
* @private
|
||
*/
|
||
_dispatchHelpCommand(subcommandName) {
|
||
if (!subcommandName) this.help();
|
||
const subCommand = this._findCommand(subcommandName);
|
||
if (subCommand && !subCommand._executableHandler) subCommand.help();
|
||
return this._dispatchSubcommand(subcommandName, [], [this._getHelpOption()?.long ?? this._getHelpOption()?.short ?? "--help"]);
|
||
}
|
||
/**
|
||
* Check this.args against expected this.registeredArguments.
|
||
*
|
||
* @private
|
||
*/
|
||
_checkNumberOfArguments() {
|
||
this.registeredArguments.forEach((arg, i) => {
|
||
if (arg.required && this.args[i] == null) this.missingArgument(arg.name());
|
||
});
|
||
if (this.registeredArguments.length > 0 && this.registeredArguments[this.registeredArguments.length - 1].variadic) return;
|
||
if (this.args.length > this.registeredArguments.length) this._excessArguments(this.args);
|
||
}
|
||
/**
|
||
* Process this.args using this.registeredArguments and save as this.processedArgs!
|
||
*
|
||
* @private
|
||
*/
|
||
_processArguments() {
|
||
const myParseArg = (argument, value, previous) => {
|
||
let parsedValue = value;
|
||
if (value !== null && argument.parseArg) {
|
||
const invalidValueMessage = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'.`;
|
||
parsedValue = this._callParseArg(argument, value, previous, invalidValueMessage);
|
||
}
|
||
return parsedValue;
|
||
};
|
||
this._checkNumberOfArguments();
|
||
const processedArgs = [];
|
||
this.registeredArguments.forEach((declaredArg, index) => {
|
||
let value = declaredArg.defaultValue;
|
||
if (declaredArg.variadic) {
|
||
if (index < this.args.length) {
|
||
value = this.args.slice(index);
|
||
if (declaredArg.parseArg) value = value.reduce((processed, v) => {
|
||
return myParseArg(declaredArg, v, processed);
|
||
}, declaredArg.defaultValue);
|
||
} else if (value === void 0) value = [];
|
||
} else if (index < this.args.length) {
|
||
value = this.args[index];
|
||
if (declaredArg.parseArg) value = myParseArg(declaredArg, value, declaredArg.defaultValue);
|
||
}
|
||
processedArgs[index] = value;
|
||
});
|
||
this.processedArgs = processedArgs;
|
||
}
|
||
/**
|
||
* Once we have a promise we chain, but call synchronously until then.
|
||
*
|
||
* @param {(Promise|undefined)} promise
|
||
* @param {Function} fn
|
||
* @return {(Promise|undefined)}
|
||
* @private
|
||
*/
|
||
_chainOrCall(promise, fn) {
|
||
if (promise && promise.then && typeof promise.then === "function") return promise.then(() => fn());
|
||
return fn();
|
||
}
|
||
/**
|
||
*
|
||
* @param {(Promise|undefined)} promise
|
||
* @param {string} event
|
||
* @return {(Promise|undefined)}
|
||
* @private
|
||
*/
|
||
_chainOrCallHooks(promise, event) {
|
||
let result = promise;
|
||
const hooks = [];
|
||
this._getCommandAndAncestors().reverse().filter((cmd) => cmd._lifeCycleHooks[event] !== void 0).forEach((hookedCommand) => {
|
||
hookedCommand._lifeCycleHooks[event].forEach((callback) => {
|
||
hooks.push({
|
||
hookedCommand,
|
||
callback
|
||
});
|
||
});
|
||
});
|
||
if (event === "postAction") hooks.reverse();
|
||
hooks.forEach((hookDetail) => {
|
||
result = this._chainOrCall(result, () => {
|
||
return hookDetail.callback(hookDetail.hookedCommand, this);
|
||
});
|
||
});
|
||
return result;
|
||
}
|
||
/**
|
||
*
|
||
* @param {(Promise|undefined)} promise
|
||
* @param {Command} subCommand
|
||
* @param {string} event
|
||
* @return {(Promise|undefined)}
|
||
* @private
|
||
*/
|
||
_chainOrCallSubCommandHook(promise, subCommand, event) {
|
||
let result = promise;
|
||
if (this._lifeCycleHooks[event] !== void 0) this._lifeCycleHooks[event].forEach((hook) => {
|
||
result = this._chainOrCall(result, () => {
|
||
return hook(this, subCommand);
|
||
});
|
||
});
|
||
return result;
|
||
}
|
||
/**
|
||
* Process arguments in context of this command.
|
||
* Returns action result, in case it is a promise.
|
||
*
|
||
* @private
|
||
*/
|
||
_parseCommand(operands, unknown) {
|
||
const parsed = this.parseOptions(unknown);
|
||
this._parseOptionsEnv();
|
||
this._parseOptionsImplied();
|
||
operands = operands.concat(parsed.operands);
|
||
unknown = parsed.unknown;
|
||
this.args = operands.concat(unknown);
|
||
if (operands && this._findCommand(operands[0])) return this._dispatchSubcommand(operands[0], operands.slice(1), unknown);
|
||
if (this._getHelpCommand() && operands[0] === this._getHelpCommand().name()) return this._dispatchHelpCommand(operands[1]);
|
||
if (this._defaultCommandName) {
|
||
this._outputHelpIfRequested(unknown);
|
||
return this._dispatchSubcommand(this._defaultCommandName, operands, unknown);
|
||
}
|
||
if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) this.help({ error: true });
|
||
this._outputHelpIfRequested(parsed.unknown);
|
||
this._checkForMissingMandatoryOptions();
|
||
this._checkForConflictingOptions();
|
||
const checkForUnknownOptions = () => {
|
||
if (parsed.unknown.length > 0) this.unknownOption(parsed.unknown[0]);
|
||
};
|
||
const commandEvent = `command:${this.name()}`;
|
||
if (this._actionHandler) {
|
||
checkForUnknownOptions();
|
||
this._processArguments();
|
||
let promiseChain;
|
||
promiseChain = this._chainOrCallHooks(promiseChain, "preAction");
|
||
promiseChain = this._chainOrCall(promiseChain, () => this._actionHandler(this.processedArgs));
|
||
if (this.parent) promiseChain = this._chainOrCall(promiseChain, () => {
|
||
this.parent.emit(commandEvent, operands, unknown);
|
||
});
|
||
promiseChain = this._chainOrCallHooks(promiseChain, "postAction");
|
||
return promiseChain;
|
||
}
|
||
if (this.parent && this.parent.listenerCount(commandEvent)) {
|
||
checkForUnknownOptions();
|
||
this._processArguments();
|
||
this.parent.emit(commandEvent, operands, unknown);
|
||
} else if (operands.length) {
|
||
if (this._findCommand("*")) return this._dispatchSubcommand("*", operands, unknown);
|
||
if (this.listenerCount("command:*")) this.emit("command:*", operands, unknown);
|
||
else if (this.commands.length) this.unknownCommand();
|
||
else {
|
||
checkForUnknownOptions();
|
||
this._processArguments();
|
||
}
|
||
} else if (this.commands.length) {
|
||
checkForUnknownOptions();
|
||
this.help({ error: true });
|
||
} else {
|
||
checkForUnknownOptions();
|
||
this._processArguments();
|
||
}
|
||
}
|
||
/**
|
||
* Find matching command.
|
||
*
|
||
* @private
|
||
* @return {Command | undefined}
|
||
*/
|
||
_findCommand(name) {
|
||
if (!name) return void 0;
|
||
return this.commands.find((cmd) => cmd._name === name || cmd._aliases.includes(name));
|
||
}
|
||
/**
|
||
* Return an option matching `arg` if any.
|
||
*
|
||
* @param {string} arg
|
||
* @return {Option}
|
||
* @package
|
||
*/
|
||
_findOption(arg) {
|
||
return this.options.find((option) => option.is(arg));
|
||
}
|
||
/**
|
||
* Display an error message if a mandatory option does not have a value.
|
||
* Called after checking for help flags in leaf subcommand.
|
||
*
|
||
* @private
|
||
*/
|
||
_checkForMissingMandatoryOptions() {
|
||
this._getCommandAndAncestors().forEach((cmd) => {
|
||
cmd.options.forEach((anOption) => {
|
||
if (anOption.mandatory && cmd.getOptionValue(anOption.attributeName()) === void 0) cmd.missingMandatoryOptionValue(anOption);
|
||
});
|
||
});
|
||
}
|
||
/**
|
||
* Display an error message if conflicting options are used together in this.
|
||
*
|
||
* @private
|
||
*/
|
||
_checkForConflictingLocalOptions() {
|
||
const definedNonDefaultOptions = this.options.filter((option) => {
|
||
const optionKey = option.attributeName();
|
||
if (this.getOptionValue(optionKey) === void 0) return false;
|
||
return this.getOptionValueSource(optionKey) !== "default";
|
||
});
|
||
definedNonDefaultOptions.filter((option) => option.conflictsWith.length > 0).forEach((option) => {
|
||
const conflictingAndDefined = definedNonDefaultOptions.find((defined) => option.conflictsWith.includes(defined.attributeName()));
|
||
if (conflictingAndDefined) this._conflictingOption(option, conflictingAndDefined);
|
||
});
|
||
}
|
||
/**
|
||
* Display an error message if conflicting options are used together.
|
||
* Called after checking for help flags in leaf subcommand.
|
||
*
|
||
* @private
|
||
*/
|
||
_checkForConflictingOptions() {
|
||
this._getCommandAndAncestors().forEach((cmd) => {
|
||
cmd._checkForConflictingLocalOptions();
|
||
});
|
||
}
|
||
/**
|
||
* Parse options from `argv` removing known options,
|
||
* and return argv split into operands and unknown arguments.
|
||
*
|
||
* Side effects: modifies command by storing options. Does not reset state if called again.
|
||
*
|
||
* Examples:
|
||
*
|
||
* argv => operands, unknown
|
||
* --known kkk op => [op], []
|
||
* op --known kkk => [op], []
|
||
* sub --unknown uuu op => [sub], [--unknown uuu op]
|
||
* sub -- --unknown uuu op => [sub --unknown uuu op], []
|
||
*
|
||
* @param {string[]} argv
|
||
* @return {{operands: string[], unknown: string[]}}
|
||
*/
|
||
parseOptions(argv) {
|
||
const operands = [];
|
||
const unknown = [];
|
||
let dest = operands;
|
||
const args = argv.slice();
|
||
function maybeOption(arg) {
|
||
return arg.length > 1 && arg[0] === "-";
|
||
}
|
||
let activeVariadicOption = null;
|
||
while (args.length) {
|
||
const arg = args.shift();
|
||
if (arg === "--") {
|
||
if (dest === unknown) dest.push(arg);
|
||
dest.push(...args);
|
||
break;
|
||
}
|
||
if (activeVariadicOption && !maybeOption(arg)) {
|
||
this.emit(`option:${activeVariadicOption.name()}`, arg);
|
||
continue;
|
||
}
|
||
activeVariadicOption = null;
|
||
if (maybeOption(arg)) {
|
||
const option = this._findOption(arg);
|
||
if (option) {
|
||
if (option.required) {
|
||
const value = args.shift();
|
||
if (value === void 0) this.optionMissingArgument(option);
|
||
this.emit(`option:${option.name()}`, value);
|
||
} else if (option.optional) {
|
||
let value = null;
|
||
if (args.length > 0 && !maybeOption(args[0])) value = args.shift();
|
||
this.emit(`option:${option.name()}`, value);
|
||
} else this.emit(`option:${option.name()}`);
|
||
activeVariadicOption = option.variadic ? option : null;
|
||
continue;
|
||
}
|
||
}
|
||
if (arg.length > 2 && arg[0] === "-" && arg[1] !== "-") {
|
||
const option = this._findOption(`-${arg[1]}`);
|
||
if (option) {
|
||
if (option.required || option.optional && this._combineFlagAndOptionalValue) this.emit(`option:${option.name()}`, arg.slice(2));
|
||
else {
|
||
this.emit(`option:${option.name()}`);
|
||
args.unshift(`-${arg.slice(2)}`);
|
||
}
|
||
continue;
|
||
}
|
||
}
|
||
if (/^--[^=]+=/.test(arg)) {
|
||
const index = arg.indexOf("=");
|
||
const option = this._findOption(arg.slice(0, index));
|
||
if (option && (option.required || option.optional)) {
|
||
this.emit(`option:${option.name()}`, arg.slice(index + 1));
|
||
continue;
|
||
}
|
||
}
|
||
if (maybeOption(arg)) dest = unknown;
|
||
if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
|
||
if (this._findCommand(arg)) {
|
||
operands.push(arg);
|
||
if (args.length > 0) unknown.push(...args);
|
||
break;
|
||
} else if (this._getHelpCommand() && arg === this._getHelpCommand().name()) {
|
||
operands.push(arg);
|
||
if (args.length > 0) operands.push(...args);
|
||
break;
|
||
} else if (this._defaultCommandName) {
|
||
unknown.push(arg);
|
||
if (args.length > 0) unknown.push(...args);
|
||
break;
|
||
}
|
||
}
|
||
if (this._passThroughOptions) {
|
||
dest.push(arg);
|
||
if (args.length > 0) dest.push(...args);
|
||
break;
|
||
}
|
||
dest.push(arg);
|
||
}
|
||
return {
|
||
operands,
|
||
unknown
|
||
};
|
||
}
|
||
/**
|
||
* Return an object containing local option values as key-value pairs.
|
||
*
|
||
* @return {object}
|
||
*/
|
||
opts() {
|
||
if (this._storeOptionsAsProperties) {
|
||
const result = {};
|
||
const len = this.options.length;
|
||
for (let i = 0; i < len; i++) {
|
||
const key = this.options[i].attributeName();
|
||
result[key] = key === this._versionOptionName ? this._version : this[key];
|
||
}
|
||
return result;
|
||
}
|
||
return this._optionValues;
|
||
}
|
||
/**
|
||
* Return an object containing merged local and global option values as key-value pairs.
|
||
*
|
||
* @return {object}
|
||
*/
|
||
optsWithGlobals() {
|
||
return this._getCommandAndAncestors().reduce((combinedOptions, cmd) => Object.assign(combinedOptions, cmd.opts()), {});
|
||
}
|
||
/**
|
||
* Display error message and exit (or call exitOverride).
|
||
*
|
||
* @param {string} message
|
||
* @param {object} [errorOptions]
|
||
* @param {string} [errorOptions.code] - an id string representing the error
|
||
* @param {number} [errorOptions.exitCode] - used with process.exit
|
||
*/
|
||
error(message, errorOptions) {
|
||
this._outputConfiguration.outputError(`${message}\n`, this._outputConfiguration.writeErr);
|
||
if (typeof this._showHelpAfterError === "string") this._outputConfiguration.writeErr(`${this._showHelpAfterError}\n`);
|
||
else if (this._showHelpAfterError) {
|
||
this._outputConfiguration.writeErr("\n");
|
||
this.outputHelp({ error: true });
|
||
}
|
||
const config = errorOptions || {};
|
||
const exitCode = config.exitCode || 1;
|
||
const code = config.code || "commander.error";
|
||
this._exit(exitCode, code, message);
|
||
}
|
||
/**
|
||
* Apply any option related environment variables, if option does
|
||
* not have a value from cli or client code.
|
||
*
|
||
* @private
|
||
*/
|
||
_parseOptionsEnv() {
|
||
this.options.forEach((option) => {
|
||
if (option.envVar && option.envVar in process$1.env) {
|
||
const optionKey = option.attributeName();
|
||
if (this.getOptionValue(optionKey) === void 0 || [
|
||
"default",
|
||
"config",
|
||
"env"
|
||
].includes(this.getOptionValueSource(optionKey))) if (option.required || option.optional) this.emit(`optionEnv:${option.name()}`, process$1.env[option.envVar]);
|
||
else this.emit(`optionEnv:${option.name()}`);
|
||
}
|
||
});
|
||
}
|
||
/**
|
||
* Apply any implied option values, if option is undefined or default value.
|
||
*
|
||
* @private
|
||
*/
|
||
_parseOptionsImplied() {
|
||
const dualHelper = new DualOptions(this.options);
|
||
const hasCustomOptionValue = (optionKey) => {
|
||
return this.getOptionValue(optionKey) !== void 0 && !["default", "implied"].includes(this.getOptionValueSource(optionKey));
|
||
};
|
||
this.options.filter((option) => option.implied !== void 0 && hasCustomOptionValue(option.attributeName()) && dualHelper.valueFromOption(this.getOptionValue(option.attributeName()), option)).forEach((option) => {
|
||
Object.keys(option.implied).filter((impliedKey) => !hasCustomOptionValue(impliedKey)).forEach((impliedKey) => {
|
||
this.setOptionValueWithSource(impliedKey, option.implied[impliedKey], "implied");
|
||
});
|
||
});
|
||
}
|
||
/**
|
||
* Argument `name` is missing.
|
||
*
|
||
* @param {string} name
|
||
* @private
|
||
*/
|
||
missingArgument(name) {
|
||
const message = `error: missing required argument '${name}'`;
|
||
this.error(message, { code: "commander.missingArgument" });
|
||
}
|
||
/**
|
||
* `Option` is missing an argument.
|
||
*
|
||
* @param {Option} option
|
||
* @private
|
||
*/
|
||
optionMissingArgument(option) {
|
||
const message = `error: option '${option.flags}' argument missing`;
|
||
this.error(message, { code: "commander.optionMissingArgument" });
|
||
}
|
||
/**
|
||
* `Option` does not have a value, and is a mandatory option.
|
||
*
|
||
* @param {Option} option
|
||
* @private
|
||
*/
|
||
missingMandatoryOptionValue(option) {
|
||
const message = `error: required option '${option.flags}' not specified`;
|
||
this.error(message, { code: "commander.missingMandatoryOptionValue" });
|
||
}
|
||
/**
|
||
* `Option` conflicts with another option.
|
||
*
|
||
* @param {Option} option
|
||
* @param {Option} conflictingOption
|
||
* @private
|
||
*/
|
||
_conflictingOption(option, conflictingOption) {
|
||
const findBestOptionFromValue = (option) => {
|
||
const optionKey = option.attributeName();
|
||
const optionValue = this.getOptionValue(optionKey);
|
||
const negativeOption = this.options.find((target) => target.negate && optionKey === target.attributeName());
|
||
const positiveOption = this.options.find((target) => !target.negate && optionKey === target.attributeName());
|
||
if (negativeOption && (negativeOption.presetArg === void 0 && optionValue === false || negativeOption.presetArg !== void 0 && optionValue === negativeOption.presetArg)) return negativeOption;
|
||
return positiveOption || option;
|
||
};
|
||
const getErrorMessage = (option) => {
|
||
const bestOption = findBestOptionFromValue(option);
|
||
const optionKey = bestOption.attributeName();
|
||
if (this.getOptionValueSource(optionKey) === "env") return `environment variable '${bestOption.envVar}'`;
|
||
return `option '${bestOption.flags}'`;
|
||
};
|
||
const message = `error: ${getErrorMessage(option)} cannot be used with ${getErrorMessage(conflictingOption)}`;
|
||
this.error(message, { code: "commander.conflictingOption" });
|
||
}
|
||
/**
|
||
* Unknown option `flag`.
|
||
*
|
||
* @param {string} flag
|
||
* @private
|
||
*/
|
||
unknownOption(flag) {
|
||
if (this._allowUnknownOption) return;
|
||
let suggestion = "";
|
||
if (flag.startsWith("--") && this._showSuggestionAfterError) {
|
||
let candidateFlags = [];
|
||
let command = this;
|
||
do {
|
||
const moreFlags = command.createHelp().visibleOptions(command).filter((option) => option.long).map((option) => option.long);
|
||
candidateFlags = candidateFlags.concat(moreFlags);
|
||
command = command.parent;
|
||
} while (command && !command._enablePositionalOptions);
|
||
suggestion = suggestSimilar(flag, candidateFlags);
|
||
}
|
||
const message = `error: unknown option '${flag}'${suggestion}`;
|
||
this.error(message, { code: "commander.unknownOption" });
|
||
}
|
||
/**
|
||
* Excess arguments, more than expected.
|
||
*
|
||
* @param {string[]} receivedArgs
|
||
* @private
|
||
*/
|
||
_excessArguments(receivedArgs) {
|
||
if (this._allowExcessArguments) return;
|
||
const expected = this.registeredArguments.length;
|
||
const s = expected === 1 ? "" : "s";
|
||
const message = `error: too many arguments${this.parent ? ` for '${this.name()}'` : ""}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;
|
||
this.error(message, { code: "commander.excessArguments" });
|
||
}
|
||
/**
|
||
* Unknown command.
|
||
*
|
||
* @private
|
||
*/
|
||
unknownCommand() {
|
||
const unknownName = this.args[0];
|
||
let suggestion = "";
|
||
if (this._showSuggestionAfterError) {
|
||
const candidateNames = [];
|
||
this.createHelp().visibleCommands(this).forEach((command) => {
|
||
candidateNames.push(command.name());
|
||
if (command.alias()) candidateNames.push(command.alias());
|
||
});
|
||
suggestion = suggestSimilar(unknownName, candidateNames);
|
||
}
|
||
const message = `error: unknown command '${unknownName}'${suggestion}`;
|
||
this.error(message, { code: "commander.unknownCommand" });
|
||
}
|
||
/**
|
||
* Get or set the program version.
|
||
*
|
||
* This method auto-registers the "-V, --version" option which will print the version number.
|
||
*
|
||
* You can optionally supply the flags and description to override the defaults.
|
||
*
|
||
* @param {string} [str]
|
||
* @param {string} [flags]
|
||
* @param {string} [description]
|
||
* @return {(this | string | undefined)} `this` command for chaining, or version string if no arguments
|
||
*/
|
||
version(str, flags, description) {
|
||
if (str === void 0) return this._version;
|
||
this._version = str;
|
||
flags = flags || "-V, --version";
|
||
description = description || "output the version number";
|
||
const versionOption = this.createOption(flags, description);
|
||
this._versionOptionName = versionOption.attributeName();
|
||
this._registerOption(versionOption);
|
||
this.on("option:" + versionOption.name(), () => {
|
||
this._outputConfiguration.writeOut(`${str}\n`);
|
||
this._exit(0, "commander.version", str);
|
||
});
|
||
return this;
|
||
}
|
||
/**
|
||
* Set the description.
|
||
*
|
||
* @param {string} [str]
|
||
* @param {object} [argsDescription]
|
||
* @return {(string|Command)}
|
||
*/
|
||
description(str, argsDescription) {
|
||
if (str === void 0 && argsDescription === void 0) return this._description;
|
||
this._description = str;
|
||
if (argsDescription) this._argsDescription = argsDescription;
|
||
return this;
|
||
}
|
||
/**
|
||
* Set the summary. Used when listed as subcommand of parent.
|
||
*
|
||
* @param {string} [str]
|
||
* @return {(string|Command)}
|
||
*/
|
||
summary(str) {
|
||
if (str === void 0) return this._summary;
|
||
this._summary = str;
|
||
return this;
|
||
}
|
||
/**
|
||
* Set an alias for the command.
|
||
*
|
||
* You may call more than once to add multiple aliases. Only the first alias is shown in the auto-generated help.
|
||
*
|
||
* @param {string} [alias]
|
||
* @return {(string|Command)}
|
||
*/
|
||
alias(alias) {
|
||
if (alias === void 0) return this._aliases[0];
|
||
/** @type {Command} */
|
||
let command = this;
|
||
if (this.commands.length !== 0 && this.commands[this.commands.length - 1]._executableHandler) command = this.commands[this.commands.length - 1];
|
||
if (alias === command._name) throw new Error("Command alias can't be the same as its name");
|
||
const matchingCommand = this.parent?._findCommand(alias);
|
||
if (matchingCommand) {
|
||
const existingCmd = [matchingCommand.name()].concat(matchingCommand.aliases()).join("|");
|
||
throw new Error(`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`);
|
||
}
|
||
command._aliases.push(alias);
|
||
return this;
|
||
}
|
||
/**
|
||
* Set aliases for the command.
|
||
*
|
||
* Only the first alias is shown in the auto-generated help.
|
||
*
|
||
* @param {string[]} [aliases]
|
||
* @return {(string[]|Command)}
|
||
*/
|
||
aliases(aliases) {
|
||
if (aliases === void 0) return this._aliases;
|
||
aliases.forEach((alias) => this.alias(alias));
|
||
return this;
|
||
}
|
||
/**
|
||
* Set / get the command usage `str`.
|
||
*
|
||
* @param {string} [str]
|
||
* @return {(string|Command)}
|
||
*/
|
||
usage(str) {
|
||
if (str === void 0) {
|
||
if (this._usage) return this._usage;
|
||
const args = this.registeredArguments.map((arg) => {
|
||
return humanReadableArgName(arg);
|
||
});
|
||
return [].concat(this.options.length || this._helpOption !== null ? "[options]" : [], this.commands.length ? "[command]" : [], this.registeredArguments.length ? args : []).join(" ");
|
||
}
|
||
this._usage = str;
|
||
return this;
|
||
}
|
||
/**
|
||
* Get or set the name of the command.
|
||
*
|
||
* @param {string} [str]
|
||
* @return {(string|Command)}
|
||
*/
|
||
name(str) {
|
||
if (str === void 0) return this._name;
|
||
this._name = str;
|
||
return this;
|
||
}
|
||
/**
|
||
* Set the name of the command from script filename, such as process.argv[1],
|
||
* or require.main.filename, or __filename.
|
||
*
|
||
* (Used internally and public although not documented in README.)
|
||
*
|
||
* @example
|
||
* program.nameFromFilename(require.main.filename);
|
||
*
|
||
* @param {string} filename
|
||
* @return {Command}
|
||
*/
|
||
nameFromFilename(filename) {
|
||
this._name = path.basename(filename, path.extname(filename));
|
||
return this;
|
||
}
|
||
/**
|
||
* Get or set the directory for searching for executable subcommands of this command.
|
||
*
|
||
* @example
|
||
* program.executableDir(__dirname);
|
||
* // or
|
||
* program.executableDir('subcommands');
|
||
*
|
||
* @param {string} [path]
|
||
* @return {(string|null|Command)}
|
||
*/
|
||
executableDir(path) {
|
||
if (path === void 0) return this._executableDir;
|
||
this._executableDir = path;
|
||
return this;
|
||
}
|
||
/**
|
||
* Return program help documentation.
|
||
*
|
||
* @param {{ error: boolean }} [contextOptions] - pass {error:true} to wrap for stderr instead of stdout
|
||
* @return {string}
|
||
*/
|
||
helpInformation(contextOptions) {
|
||
const helper = this.createHelp();
|
||
const context = this._getOutputContext(contextOptions);
|
||
helper.prepareContext({
|
||
error: context.error,
|
||
helpWidth: context.helpWidth,
|
||
outputHasColors: context.hasColors
|
||
});
|
||
const text = helper.formatHelp(this, helper);
|
||
if (context.hasColors) return text;
|
||
return this._outputConfiguration.stripColor(text);
|
||
}
|
||
/**
|
||
* @typedef HelpContext
|
||
* @type {object}
|
||
* @property {boolean} error
|
||
* @property {number} helpWidth
|
||
* @property {boolean} hasColors
|
||
* @property {function} write - includes stripColor if needed
|
||
*
|
||
* @returns {HelpContext}
|
||
* @private
|
||
*/
|
||
_getOutputContext(contextOptions) {
|
||
contextOptions = contextOptions || {};
|
||
const error = !!contextOptions.error;
|
||
let baseWrite;
|
||
let hasColors;
|
||
let helpWidth;
|
||
if (error) {
|
||
baseWrite = (str) => this._outputConfiguration.writeErr(str);
|
||
hasColors = this._outputConfiguration.getErrHasColors();
|
||
helpWidth = this._outputConfiguration.getErrHelpWidth();
|
||
} else {
|
||
baseWrite = (str) => this._outputConfiguration.writeOut(str);
|
||
hasColors = this._outputConfiguration.getOutHasColors();
|
||
helpWidth = this._outputConfiguration.getOutHelpWidth();
|
||
}
|
||
const write = (str) => {
|
||
if (!hasColors) str = this._outputConfiguration.stripColor(str);
|
||
return baseWrite(str);
|
||
};
|
||
return {
|
||
error,
|
||
write,
|
||
hasColors,
|
||
helpWidth
|
||
};
|
||
}
|
||
/**
|
||
* Output help information for this command.
|
||
*
|
||
* Outputs built-in help, and custom text added using `.addHelpText()`.
|
||
*
|
||
* @param {{ error: boolean } | Function} [contextOptions] - pass {error:true} to write to stderr instead of stdout
|
||
*/
|
||
outputHelp(contextOptions) {
|
||
let deprecatedCallback;
|
||
if (typeof contextOptions === "function") {
|
||
deprecatedCallback = contextOptions;
|
||
contextOptions = void 0;
|
||
}
|
||
const outputContext = this._getOutputContext(contextOptions);
|
||
/** @type {HelpTextEventContext} */
|
||
const eventContext = {
|
||
error: outputContext.error,
|
||
write: outputContext.write,
|
||
command: this
|
||
};
|
||
this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", eventContext));
|
||
this.emit("beforeHelp", eventContext);
|
||
let helpInformation = this.helpInformation({ error: outputContext.error });
|
||
if (deprecatedCallback) {
|
||
helpInformation = deprecatedCallback(helpInformation);
|
||
if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) throw new Error("outputHelp callback must return a string or a Buffer");
|
||
}
|
||
outputContext.write(helpInformation);
|
||
if (this._getHelpOption()?.long) this.emit(this._getHelpOption().long);
|
||
this.emit("afterHelp", eventContext);
|
||
this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", eventContext));
|
||
}
|
||
/**
|
||
* You can pass in flags and a description to customise the built-in help option.
|
||
* Pass in false to disable the built-in help option.
|
||
*
|
||
* @example
|
||
* program.helpOption('-?, --help' 'show help'); // customise
|
||
* program.helpOption(false); // disable
|
||
*
|
||
* @param {(string | boolean)} flags
|
||
* @param {string} [description]
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
helpOption(flags, description) {
|
||
if (typeof flags === "boolean") {
|
||
// istanbul ignore if
|
||
if (flags) this._helpOption = this._helpOption ?? void 0;
|
||
else this._helpOption = null;
|
||
return this;
|
||
}
|
||
flags = flags ?? "-h, --help";
|
||
description = description ?? "display help for command";
|
||
this._helpOption = this.createOption(flags, description);
|
||
return this;
|
||
}
|
||
/**
|
||
* Lazy create help option.
|
||
* Returns null if has been disabled with .helpOption(false).
|
||
*
|
||
* @returns {(Option | null)} the help option
|
||
* @package
|
||
*/
|
||
_getHelpOption() {
|
||
if (this._helpOption === void 0) this.helpOption(void 0, void 0);
|
||
return this._helpOption;
|
||
}
|
||
/**
|
||
* Supply your own option to use for the built-in help option.
|
||
* This is an alternative to using helpOption() to customise the flags and description etc.
|
||
*
|
||
* @param {Option} option
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
addHelpOption(option) {
|
||
this._helpOption = option;
|
||
return this;
|
||
}
|
||
/**
|
||
* Output help information and exit.
|
||
*
|
||
* Outputs built-in help, and custom text added using `.addHelpText()`.
|
||
*
|
||
* @param {{ error: boolean }} [contextOptions] - pass {error:true} to write to stderr instead of stdout
|
||
*/
|
||
help(contextOptions) {
|
||
this.outputHelp(contextOptions);
|
||
let exitCode = Number(process$1.exitCode ?? 0);
|
||
if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) exitCode = 1;
|
||
this._exit(exitCode, "commander.help", "(outputHelp)");
|
||
}
|
||
/**
|
||
* // Do a little typing to coordinate emit and listener for the help text events.
|
||
* @typedef HelpTextEventContext
|
||
* @type {object}
|
||
* @property {boolean} error
|
||
* @property {Command} command
|
||
* @property {function} write
|
||
*/
|
||
/**
|
||
* Add additional text to be displayed with the built-in help.
|
||
*
|
||
* Position is 'before' or 'after' to affect just this command,
|
||
* and 'beforeAll' or 'afterAll' to affect this command and all its subcommands.
|
||
*
|
||
* @param {string} position - before or after built-in help
|
||
* @param {(string | Function)} text - string to add, or a function returning a string
|
||
* @return {Command} `this` command for chaining
|
||
*/
|
||
addHelpText(position, text) {
|
||
const allowedValues = [
|
||
"beforeAll",
|
||
"before",
|
||
"after",
|
||
"afterAll"
|
||
];
|
||
if (!allowedValues.includes(position)) throw new Error(`Unexpected value for position to addHelpText.
|
||
Expecting one of '${allowedValues.join("', '")}'`);
|
||
const helpEvent = `${position}Help`;
|
||
this.on(helpEvent, (context) => {
|
||
let helpStr;
|
||
if (typeof text === "function") helpStr = text({
|
||
error: context.error,
|
||
command: context.command
|
||
});
|
||
else helpStr = text;
|
||
if (helpStr) context.write(`${helpStr}\n`);
|
||
});
|
||
return this;
|
||
}
|
||
/**
|
||
* Output help information if help flags specified
|
||
*
|
||
* @param {Array} args - array of options to search for help flags
|
||
* @private
|
||
*/
|
||
_outputHelpIfRequested(args) {
|
||
const helpOption = this._getHelpOption();
|
||
if (helpOption && args.find((arg) => helpOption.is(arg))) {
|
||
this.outputHelp();
|
||
this._exit(0, "commander.helpDisplayed", "(outputHelp)");
|
||
}
|
||
}
|
||
};
|
||
/**
|
||
* Scan arguments and increment port number for inspect calls (to avoid conflicts when spawning new command).
|
||
*
|
||
* @param {string[]} args - array of arguments from node.execArgv
|
||
* @returns {string[]}
|
||
* @private
|
||
*/
|
||
function incrementNodeInspectorPort(args) {
|
||
return args.map((arg) => {
|
||
if (!arg.startsWith("--inspect")) return arg;
|
||
let debugOption;
|
||
let debugHost = "127.0.0.1";
|
||
let debugPort = "9229";
|
||
let match;
|
||
if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) debugOption = match[1];
|
||
else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
|
||
debugOption = match[1];
|
||
if (/^\d+$/.test(match[3])) debugPort = match[3];
|
||
else debugHost = match[3];
|
||
} else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
|
||
debugOption = match[1];
|
||
debugHost = match[3];
|
||
debugPort = match[4];
|
||
}
|
||
if (debugOption && debugPort !== "0") return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
|
||
return arg;
|
||
});
|
||
}
|
||
/**
|
||
* @returns {boolean | undefined}
|
||
* @package
|
||
*/
|
||
function useColor() {
|
||
if (process$1.env.NO_COLOR || process$1.env.FORCE_COLOR === "0" || process$1.env.FORCE_COLOR === "false") return false;
|
||
if (process$1.env.FORCE_COLOR || process$1.env.CLICOLOR_FORCE !== void 0) return true;
|
||
}
|
||
exports.Command = Command;
|
||
exports.useColor = useColor;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/commander@13.1.0/node_modules/commander/index.js
|
||
var require_commander = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
const { Argument } = require_argument();
|
||
const { Command } = require_command();
|
||
const { CommanderError, InvalidArgumentError } = require_error();
|
||
const { Help } = require_help();
|
||
const { Option } = require_option();
|
||
exports.program = new Command();
|
||
exports.createCommand = (name) => new Command(name);
|
||
exports.createOption = (flags, description) => new Option(flags, description);
|
||
exports.createArgument = (name, description) => new Argument(name, description);
|
||
/**
|
||
* Expose classes
|
||
*/
|
||
exports.Command = Command;
|
||
exports.Option = Option;
|
||
exports.Argument = Argument;
|
||
exports.Help = Help;
|
||
exports.CommanderError = CommanderError;
|
||
exports.InvalidArgumentError = InvalidArgumentError;
|
||
exports.InvalidOptionArgumentError = InvalidArgumentError;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/commander@13.1.0/node_modules/commander/esm.mjs
|
||
var import_commander = /* @__PURE__ */ __toESM(require_commander(), 1);
|
||
const { program: program$1, createCommand, createArgument, createOption, CommanderError, InvalidArgumentError, InvalidOptionArgumentError, Command, Argument, Option, Help } = import_commander.default;
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/sisteransi@1.0.5/node_modules/sisteransi/src/index.js
|
||
var require_src = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
||
const ESC = "\x1B";
|
||
const CSI = `${ESC}[`;
|
||
const beep = "\x07";
|
||
const cursor = {
|
||
to(x, y) {
|
||
if (!y) return `${CSI}${x + 1}G`;
|
||
return `${CSI}${y + 1};${x + 1}H`;
|
||
},
|
||
move(x, y) {
|
||
let ret = "";
|
||
if (x < 0) ret += `${CSI}${-x}D`;
|
||
else if (x > 0) ret += `${CSI}${x}C`;
|
||
if (y < 0) ret += `${CSI}${-y}A`;
|
||
else if (y > 0) ret += `${CSI}${y}B`;
|
||
return ret;
|
||
},
|
||
up: (count = 1) => `${CSI}${count}A`,
|
||
down: (count = 1) => `${CSI}${count}B`,
|
||
forward: (count = 1) => `${CSI}${count}C`,
|
||
backward: (count = 1) => `${CSI}${count}D`,
|
||
nextLine: (count = 1) => `${CSI}E`.repeat(count),
|
||
prevLine: (count = 1) => `${CSI}F`.repeat(count),
|
||
left: `${CSI}G`,
|
||
hide: `${CSI}?25l`,
|
||
show: `${CSI}?25h`,
|
||
save: `${ESC}7`,
|
||
restore: `${ESC}8`
|
||
};
|
||
const scroll = {
|
||
up: (count = 1) => `${CSI}S`.repeat(count),
|
||
down: (count = 1) => `${CSI}T`.repeat(count)
|
||
};
|
||
const erase = {
|
||
screen: `${CSI}2J`,
|
||
up: (count = 1) => `${CSI}1J`.repeat(count),
|
||
down: (count = 1) => `${CSI}J`.repeat(count),
|
||
line: `${CSI}2K`,
|
||
lineEnd: `${CSI}K`,
|
||
lineStart: `${CSI}1K`,
|
||
lines(count) {
|
||
let clear = "";
|
||
for (let i = 0; i < count; i++) clear += this.line + (i < count - 1 ? cursor.up() : "");
|
||
if (count) clear += cursor.left;
|
||
return clear;
|
||
}
|
||
};
|
||
module.exports = {
|
||
cursor,
|
||
scroll,
|
||
erase,
|
||
beep
|
||
};
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js
|
||
var require_picocolors = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
||
let p = process || {}, argv = p.argv || [], env = p.env || {};
|
||
let isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
||
let formatter = (open, close, replace = open) => (input) => {
|
||
let string = "" + input, index = string.indexOf(close, open.length);
|
||
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
||
};
|
||
let replaceClose = (string, close, replace, index) => {
|
||
let result = "", cursor = 0;
|
||
do {
|
||
result += string.substring(cursor, index) + replace;
|
||
cursor = index + close.length;
|
||
index = string.indexOf(close, cursor);
|
||
} while (~index);
|
||
return result + string.substring(cursor);
|
||
};
|
||
let createColors = (enabled = isColorSupported) => {
|
||
let f = enabled ? formatter : () => String;
|
||
return {
|
||
isColorSupported: enabled,
|
||
reset: f("\x1B[0m", "\x1B[0m"),
|
||
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
||
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
||
italic: f("\x1B[3m", "\x1B[23m"),
|
||
underline: f("\x1B[4m", "\x1B[24m"),
|
||
inverse: f("\x1B[7m", "\x1B[27m"),
|
||
hidden: f("\x1B[8m", "\x1B[28m"),
|
||
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
||
black: f("\x1B[30m", "\x1B[39m"),
|
||
red: f("\x1B[31m", "\x1B[39m"),
|
||
green: f("\x1B[32m", "\x1B[39m"),
|
||
yellow: f("\x1B[33m", "\x1B[39m"),
|
||
blue: f("\x1B[34m", "\x1B[39m"),
|
||
magenta: f("\x1B[35m", "\x1B[39m"),
|
||
cyan: f("\x1B[36m", "\x1B[39m"),
|
||
white: f("\x1B[37m", "\x1B[39m"),
|
||
gray: f("\x1B[90m", "\x1B[39m"),
|
||
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
||
bgRed: f("\x1B[41m", "\x1B[49m"),
|
||
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
||
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
||
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
||
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
||
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
||
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
||
blackBright: f("\x1B[90m", "\x1B[39m"),
|
||
redBright: f("\x1B[91m", "\x1B[39m"),
|
||
greenBright: f("\x1B[92m", "\x1B[39m"),
|
||
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
||
blueBright: f("\x1B[94m", "\x1B[39m"),
|
||
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
||
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
||
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
||
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
||
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
||
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
||
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
||
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
||
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
||
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
||
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
||
};
|
||
};
|
||
module.exports = createColors();
|
||
module.exports.createColors = createColors;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/@clack+core@0.4.1/node_modules/@clack/core/dist/index.mjs
|
||
var import_src = require_src();
|
||
var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors(), 1);
|
||
function J({ onlyFirst: t = !1 } = {}) {
|
||
const F = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
|
||
return new RegExp(F, t ? void 0 : "g");
|
||
}
|
||
const Q = J();
|
||
function T(t) {
|
||
if (typeof t != "string") throw new TypeError(`Expected a \`string\`, got \`${typeof t}\``);
|
||
return t.replace(Q, "");
|
||
}
|
||
function O(t) {
|
||
return t && t.__esModule && Object.prototype.hasOwnProperty.call(t, "default") ? t.default : t;
|
||
}
|
||
var P = { exports: {} };
|
||
(function(t) {
|
||
var u = {};
|
||
t.exports = u, u.eastAsianWidth = function(e) {
|
||
var s = e.charCodeAt(0), i = e.length == 2 ? e.charCodeAt(1) : 0, D = s;
|
||
return 55296 <= s && s <= 56319 && 56320 <= i && i <= 57343 && (s &= 1023, i &= 1023, D = s << 10 | i, D += 65536), D == 12288 || 65281 <= D && D <= 65376 || 65504 <= D && D <= 65510 ? "F" : D == 8361 || 65377 <= D && D <= 65470 || 65474 <= D && D <= 65479 || 65482 <= D && D <= 65487 || 65490 <= D && D <= 65495 || 65498 <= D && D <= 65500 || 65512 <= D && D <= 65518 ? "H" : 4352 <= D && D <= 4447 || 4515 <= D && D <= 4519 || 4602 <= D && D <= 4607 || 9001 <= D && D <= 9002 || 11904 <= D && D <= 11929 || 11931 <= D && D <= 12019 || 12032 <= D && D <= 12245 || 12272 <= D && D <= 12283 || 12289 <= D && D <= 12350 || 12353 <= D && D <= 12438 || 12441 <= D && D <= 12543 || 12549 <= D && D <= 12589 || 12593 <= D && D <= 12686 || 12688 <= D && D <= 12730 || 12736 <= D && D <= 12771 || 12784 <= D && D <= 12830 || 12832 <= D && D <= 12871 || 12880 <= D && D <= 13054 || 13056 <= D && D <= 19903 || 19968 <= D && D <= 42124 || 42128 <= D && D <= 42182 || 43360 <= D && D <= 43388 || 44032 <= D && D <= 55203 || 55216 <= D && D <= 55238 || 55243 <= D && D <= 55291 || 63744 <= D && D <= 64255 || 65040 <= D && D <= 65049 || 65072 <= D && D <= 65106 || 65108 <= D && D <= 65126 || 65128 <= D && D <= 65131 || 110592 <= D && D <= 110593 || 127488 <= D && D <= 127490 || 127504 <= D && D <= 127546 || 127552 <= D && D <= 127560 || 127568 <= D && D <= 127569 || 131072 <= D && D <= 194367 || 177984 <= D && D <= 196605 || 196608 <= D && D <= 262141 ? "W" : 32 <= D && D <= 126 || 162 <= D && D <= 163 || 165 <= D && D <= 166 || D == 172 || D == 175 || 10214 <= D && D <= 10221 || 10629 <= D && D <= 10630 ? "Na" : D == 161 || D == 164 || 167 <= D && D <= 168 || D == 170 || 173 <= D && D <= 174 || 176 <= D && D <= 180 || 182 <= D && D <= 186 || 188 <= D && D <= 191 || D == 198 || D == 208 || 215 <= D && D <= 216 || 222 <= D && D <= 225 || D == 230 || 232 <= D && D <= 234 || 236 <= D && D <= 237 || D == 240 || 242 <= D && D <= 243 || 247 <= D && D <= 250 || D == 252 || D == 254 || D == 257 || D == 273 || D == 275 || D == 283 || 294 <= D && D <= 295 || D == 299 || 305 <= D && D <= 307 || D == 312 || 319 <= D && D <= 322 || D == 324 || 328 <= D && D <= 331 || D == 333 || 338 <= D && D <= 339 || 358 <= D && D <= 359 || D == 363 || D == 462 || D == 464 || D == 466 || D == 468 || D == 470 || D == 472 || D == 474 || D == 476 || D == 593 || D == 609 || D == 708 || D == 711 || 713 <= D && D <= 715 || D == 717 || D == 720 || 728 <= D && D <= 731 || D == 733 || D == 735 || 768 <= D && D <= 879 || 913 <= D && D <= 929 || 931 <= D && D <= 937 || 945 <= D && D <= 961 || 963 <= D && D <= 969 || D == 1025 || 1040 <= D && D <= 1103 || D == 1105 || D == 8208 || 8211 <= D && D <= 8214 || 8216 <= D && D <= 8217 || 8220 <= D && D <= 8221 || 8224 <= D && D <= 8226 || 8228 <= D && D <= 8231 || D == 8240 || 8242 <= D && D <= 8243 || D == 8245 || D == 8251 || D == 8254 || D == 8308 || D == 8319 || 8321 <= D && D <= 8324 || D == 8364 || D == 8451 || D == 8453 || D == 8457 || D == 8467 || D == 8470 || 8481 <= D && D <= 8482 || D == 8486 || D == 8491 || 8531 <= D && D <= 8532 || 8539 <= D && D <= 8542 || 8544 <= D && D <= 8555 || 8560 <= D && D <= 8569 || D == 8585 || 8592 <= D && D <= 8601 || 8632 <= D && D <= 8633 || D == 8658 || D == 8660 || D == 8679 || D == 8704 || 8706 <= D && D <= 8707 || 8711 <= D && D <= 8712 || D == 8715 || D == 8719 || D == 8721 || D == 8725 || D == 8730 || 8733 <= D && D <= 8736 || D == 8739 || D == 8741 || 8743 <= D && D <= 8748 || D == 8750 || 8756 <= D && D <= 8759 || 8764 <= D && D <= 8765 || D == 8776 || D == 8780 || D == 8786 || 8800 <= D && D <= 8801 || 8804 <= D && D <= 8807 || 8810 <= D && D <= 8811 || 8814 <= D && D <= 8815 || 8834 <= D && D <= 8835 || 8838 <= D && D <= 8839 || D == 8853 || D == 8857 || D == 8869 || D == 8895 || D == 8978 || 9312 <= D && D <= 9449 || 9451 <= D && D <= 9547 || 9552 <= D && D <= 9587 || 9600 <= D && D <= 9615 || 9618 <= D && D <= 9621 || 9632 <= D && D <= 9633 || 9635 <= D && D <= 9641 || 9650 <= D && D <= 9651 || 9654 <= D && D <= 9655 || 9660 <= D && D <= 9661 || 9664 <= D && D <= 9665 || 9670 <= D && D <= 9672 || D == 9675 || 9678 <= D && D <= 9681 || 9698 <= D && D <= 9701 || D == 9711 || 9733 <= D && D <= 9734 || D == 9737 || 9742 <= D && D <= 9743 || 9748 <= D && D <= 9749 || D == 9756 || D == 9758 || D == 9792 || D == 9794 || 9824 <= D && D <= 9825 || 9827 <= D && D <= 9829 || 9831 <= D && D <= 9834 || 9836 <= D && D <= 9837 || D == 9839 || 9886 <= D && D <= 9887 || 9918 <= D && D <= 9919 || 9924 <= D && D <= 9933 || 9935 <= D && D <= 9953 || D == 9955 || 9960 <= D && D <= 9983 || D == 10045 || D == 10071 || 10102 <= D && D <= 10111 || 11093 <= D && D <= 11097 || 12872 <= D && D <= 12879 || 57344 <= D && D <= 63743 || 65024 <= D && D <= 65039 || D == 65533 || 127232 <= D && D <= 127242 || 127248 <= D && D <= 127277 || 127280 <= D && D <= 127337 || 127344 <= D && D <= 127386 || 917760 <= D && D <= 917999 || 983040 <= D && D <= 1048573 || 1048576 <= D && D <= 1114109 ? "A" : "N";
|
||
}, u.characterLength = function(e) {
|
||
var s = this.eastAsianWidth(e);
|
||
return s == "F" || s == "W" || s == "A" ? 2 : 1;
|
||
};
|
||
function F(e) {
|
||
return e.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
|
||
}
|
||
u.length = function(e) {
|
||
for (var s = F(e), i = 0, D = 0; D < s.length; D++) i = i + this.characterLength(s[D]);
|
||
return i;
|
||
}, u.slice = function(e, s, i) {
|
||
textLen = u.length(e), s = s || 0, i = i || 1, s < 0 && (s = textLen + s), i < 0 && (i = textLen + i);
|
||
for (var D = "", C = 0, o = F(e), E = 0; E < o.length; E++) {
|
||
var a = o[E], n = u.length(a);
|
||
if (C >= s - (n == 2 ? 1 : 0)) if (C + n <= i) D += a;
|
||
else break;
|
||
C += n;
|
||
}
|
||
return D;
|
||
};
|
||
})(P);
|
||
var X$1 = P.exports;
|
||
const DD = O(X$1);
|
||
var uD = function() {
|
||
return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
|
||
};
|
||
const FD = O(uD);
|
||
function A$1(t, u = {}) {
|
||
if (typeof t != "string" || t.length === 0 || (u = {
|
||
ambiguousIsNarrow: !0,
|
||
...u
|
||
}, t = T(t), t.length === 0)) return 0;
|
||
t = t.replace(FD(), " ");
|
||
const F = u.ambiguousIsNarrow ? 1 : 2;
|
||
let e = 0;
|
||
for (const s of t) {
|
||
const i = s.codePointAt(0);
|
||
if (i <= 31 || i >= 127 && i <= 159 || i >= 768 && i <= 879) continue;
|
||
switch (DD.eastAsianWidth(s)) {
|
||
case "F":
|
||
case "W":
|
||
e += 2;
|
||
break;
|
||
case "A":
|
||
e += F;
|
||
break;
|
||
default: e += 1;
|
||
}
|
||
}
|
||
return e;
|
||
}
|
||
const m$1 = 10, L$1 = (t = 0) => (u) => `\x1B[${u + t}m`, N$1 = (t = 0) => (u) => `\x1B[${38 + t};5;${u}m`, I = (t = 0) => (u, F, e) => `\x1B[${38 + t};2;${u};${F};${e}m`, r = {
|
||
modifier: {
|
||
reset: [0, 0],
|
||
bold: [1, 22],
|
||
dim: [2, 22],
|
||
italic: [3, 23],
|
||
underline: [4, 24],
|
||
overline: [53, 55],
|
||
inverse: [7, 27],
|
||
hidden: [8, 28],
|
||
strikethrough: [9, 29]
|
||
},
|
||
color: {
|
||
black: [30, 39],
|
||
red: [31, 39],
|
||
green: [32, 39],
|
||
yellow: [33, 39],
|
||
blue: [34, 39],
|
||
magenta: [35, 39],
|
||
cyan: [36, 39],
|
||
white: [37, 39],
|
||
blackBright: [90, 39],
|
||
gray: [90, 39],
|
||
grey: [90, 39],
|
||
redBright: [91, 39],
|
||
greenBright: [92, 39],
|
||
yellowBright: [93, 39],
|
||
blueBright: [94, 39],
|
||
magentaBright: [95, 39],
|
||
cyanBright: [96, 39],
|
||
whiteBright: [97, 39]
|
||
},
|
||
bgColor: {
|
||
bgBlack: [40, 49],
|
||
bgRed: [41, 49],
|
||
bgGreen: [42, 49],
|
||
bgYellow: [43, 49],
|
||
bgBlue: [44, 49],
|
||
bgMagenta: [45, 49],
|
||
bgCyan: [46, 49],
|
||
bgWhite: [47, 49],
|
||
bgBlackBright: [100, 49],
|
||
bgGray: [100, 49],
|
||
bgGrey: [100, 49],
|
||
bgRedBright: [101, 49],
|
||
bgGreenBright: [102, 49],
|
||
bgYellowBright: [103, 49],
|
||
bgBlueBright: [104, 49],
|
||
bgMagentaBright: [105, 49],
|
||
bgCyanBright: [106, 49],
|
||
bgWhiteBright: [107, 49]
|
||
}
|
||
};
|
||
Object.keys(r.modifier);
|
||
const tD = Object.keys(r.color), eD = Object.keys(r.bgColor);
|
||
[...tD, ...eD];
|
||
function sD() {
|
||
const t = /* @__PURE__ */ new Map();
|
||
for (const [u, F] of Object.entries(r)) {
|
||
for (const [e, s] of Object.entries(F)) r[e] = {
|
||
open: `\x1B[${s[0]}m`,
|
||
close: `\x1B[${s[1]}m`
|
||
}, F[e] = r[e], t.set(s[0], s[1]);
|
||
Object.defineProperty(r, u, {
|
||
value: F,
|
||
enumerable: !1
|
||
});
|
||
}
|
||
return Object.defineProperty(r, "codes", {
|
||
value: t,
|
||
enumerable: !1
|
||
}), r.color.close = "\x1B[39m", r.bgColor.close = "\x1B[49m", r.color.ansi = L$1(), r.color.ansi256 = N$1(), r.color.ansi16m = I(), r.bgColor.ansi = L$1(m$1), r.bgColor.ansi256 = N$1(m$1), r.bgColor.ansi16m = I(m$1), Object.defineProperties(r, {
|
||
rgbToAnsi256: {
|
||
value: (u, F, e) => u === F && F === e ? u < 8 ? 16 : u > 248 ? 231 : Math.round((u - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(u / 255 * 5) + 6 * Math.round(F / 255 * 5) + Math.round(e / 255 * 5),
|
||
enumerable: !1
|
||
},
|
||
hexToRgb: {
|
||
value: (u) => {
|
||
const F = /[a-f\d]{6}|[a-f\d]{3}/i.exec(u.toString(16));
|
||
if (!F) return [
|
||
0,
|
||
0,
|
||
0
|
||
];
|
||
let [e] = F;
|
||
e.length === 3 && (e = [...e].map((i) => i + i).join(""));
|
||
const s = Number.parseInt(e, 16);
|
||
return [
|
||
s >> 16 & 255,
|
||
s >> 8 & 255,
|
||
s & 255
|
||
];
|
||
},
|
||
enumerable: !1
|
||
},
|
||
hexToAnsi256: {
|
||
value: (u) => r.rgbToAnsi256(...r.hexToRgb(u)),
|
||
enumerable: !1
|
||
},
|
||
ansi256ToAnsi: {
|
||
value: (u) => {
|
||
if (u < 8) return 30 + u;
|
||
if (u < 16) return 90 + (u - 8);
|
||
let F, e, s;
|
||
if (u >= 232) F = ((u - 232) * 10 + 8) / 255, e = F, s = F;
|
||
else {
|
||
u -= 16;
|
||
const C = u % 36;
|
||
F = Math.floor(u / 36) / 5, e = Math.floor(C / 6) / 5, s = C % 6 / 5;
|
||
}
|
||
const i = Math.max(F, e, s) * 2;
|
||
if (i === 0) return 30;
|
||
let D = 30 + (Math.round(s) << 2 | Math.round(e) << 1 | Math.round(F));
|
||
return i === 2 && (D += 60), D;
|
||
},
|
||
enumerable: !1
|
||
},
|
||
rgbToAnsi: {
|
||
value: (u, F, e) => r.ansi256ToAnsi(r.rgbToAnsi256(u, F, e)),
|
||
enumerable: !1
|
||
},
|
||
hexToAnsi: {
|
||
value: (u) => r.ansi256ToAnsi(r.hexToAnsi256(u)),
|
||
enumerable: !1
|
||
}
|
||
}), r;
|
||
}
|
||
const iD = sD(), v$1 = new Set(["\x1B", ""]), CD = 39, w = "\x07", W = "[", rD = "]", R$1 = "m", y$1 = `${rD}8;;`, V$1 = (t) => `${v$1.values().next().value}${W}${t}${R$1}`, z = (t) => `${v$1.values().next().value}${y$1}${t}${w}`, ED = (t) => t.split(" ").map((u) => A$1(u)), _ = (t, u, F) => {
|
||
const e = [...u];
|
||
let s = !1, i = !1, D = A$1(T(t[t.length - 1]));
|
||
for (const [C, o] of e.entries()) {
|
||
const E = A$1(o);
|
||
if (D + E <= F ? t[t.length - 1] += o : (t.push(o), D = 0), v$1.has(o) && (s = !0, i = e.slice(C + 1).join("").startsWith(y$1)), s) {
|
||
i ? o === w && (s = !1, i = !1) : o === R$1 && (s = !1);
|
||
continue;
|
||
}
|
||
D += E, D === F && C < e.length - 1 && (t.push(""), D = 0);
|
||
}
|
||
!D && t[t.length - 1].length > 0 && t.length > 1 && (t[t.length - 2] += t.pop());
|
||
}, nD = (t) => {
|
||
const u = t.split(" ");
|
||
let F = u.length;
|
||
for (; F > 0 && !(A$1(u[F - 1]) > 0);) F--;
|
||
return F === u.length ? t : u.slice(0, F).join(" ") + u.slice(F).join("");
|
||
}, oD = (t, u, F = {}) => {
|
||
if (F.trim !== !1 && t.trim() === "") return "";
|
||
let e = "", s, i;
|
||
const D = ED(t);
|
||
let C = [""];
|
||
for (const [E, a] of t.split(" ").entries()) {
|
||
F.trim !== !1 && (C[C.length - 1] = C[C.length - 1].trimStart());
|
||
let n = A$1(C[C.length - 1]);
|
||
if (E !== 0 && (n >= u && (F.wordWrap === !1 || F.trim === !1) && (C.push(""), n = 0), (n > 0 || F.trim === !1) && (C[C.length - 1] += " ", n++)), F.hard && D[E] > u) {
|
||
const B = u - n, p = 1 + Math.floor((D[E] - B - 1) / u);
|
||
Math.floor((D[E] - 1) / u) < p && C.push(""), _(C, a, u);
|
||
continue;
|
||
}
|
||
if (n + D[E] > u && n > 0 && D[E] > 0) {
|
||
if (F.wordWrap === !1 && n < u) {
|
||
_(C, a, u);
|
||
continue;
|
||
}
|
||
C.push("");
|
||
}
|
||
if (n + D[E] > u && F.wordWrap === !1) {
|
||
_(C, a, u);
|
||
continue;
|
||
}
|
||
C[C.length - 1] += a;
|
||
}
|
||
F.trim !== !1 && (C = C.map((E) => nD(E)));
|
||
const o = [...C.join(`
|
||
`)];
|
||
for (const [E, a] of o.entries()) {
|
||
if (e += a, v$1.has(a)) {
|
||
const { groups: B } = new RegExp(`(?:\\${W}(?<code>\\d+)m|\\${y$1}(?<uri>.*)${w})`).exec(o.slice(E).join("")) || { groups: {} };
|
||
if (B.code !== void 0) {
|
||
const p = Number.parseFloat(B.code);
|
||
s = p === CD ? void 0 : p;
|
||
} else B.uri !== void 0 && (i = B.uri.length === 0 ? void 0 : B.uri);
|
||
}
|
||
const n = iD.codes.get(Number(s));
|
||
o[E + 1] === `
|
||
` ? (i && (e += z("")), s && n && (e += V$1(n))) : a === `
|
||
` && (s && n && (e += V$1(s)), i && (e += z(i)));
|
||
}
|
||
return e;
|
||
};
|
||
function G$1(t, u, F) {
|
||
return String(t).normalize().replace(/\r\n/g, `
|
||
`).split(`
|
||
`).map((e) => oD(e, u, F)).join(`
|
||
`);
|
||
}
|
||
const c = {
|
||
actions: new Set([
|
||
"up",
|
||
"down",
|
||
"left",
|
||
"right",
|
||
"space",
|
||
"enter",
|
||
"cancel"
|
||
]),
|
||
aliases: new Map([
|
||
["k", "up"],
|
||
["j", "down"],
|
||
["h", "left"],
|
||
["l", "right"],
|
||
["", "cancel"],
|
||
["escape", "cancel"]
|
||
])
|
||
};
|
||
function k$1(t, u) {
|
||
if (typeof t == "string") return c.aliases.get(t) === u;
|
||
for (const F of t) if (F !== void 0 && k$1(F, u)) return !0;
|
||
return !1;
|
||
}
|
||
function lD(t, u) {
|
||
if (t === u) return;
|
||
const F = t.split(`
|
||
`), e = u.split(`
|
||
`), s = [];
|
||
for (let i = 0; i < Math.max(F.length, e.length); i++) F[i] !== e[i] && s.push(i);
|
||
return s;
|
||
}
|
||
const xD = globalThis.process.platform.startsWith("win"), S$1 = Symbol("clack:cancel");
|
||
function BD(t) {
|
||
return t === S$1;
|
||
}
|
||
function d(t, u) {
|
||
const F = t;
|
||
F.isTTY && F.setRawMode(u);
|
||
}
|
||
function cD({ input: t = stdin, output: u = stdout, overwrite: F = !0, hideCursor: e = !0 } = {}) {
|
||
const s = f.createInterface({
|
||
input: t,
|
||
output: u,
|
||
prompt: "",
|
||
tabSize: 1
|
||
});
|
||
f.emitKeypressEvents(t, s), t.isTTY && t.setRawMode(!0);
|
||
const i = (D, { name: C, sequence: o }) => {
|
||
if (k$1([
|
||
String(D),
|
||
C,
|
||
o
|
||
], "cancel")) {
|
||
e && u.write(import_src.cursor.show), process.exit(0);
|
||
return;
|
||
}
|
||
if (!F) return;
|
||
const a = C === "return" ? 0 : -1, n = C === "return" ? -1 : 0;
|
||
f.moveCursor(u, a, n, () => {
|
||
f.clearLine(u, 1, () => {
|
||
t.once("keypress", i);
|
||
});
|
||
});
|
||
};
|
||
return e && u.write(import_src.cursor.hide), t.once("keypress", i), () => {
|
||
t.off("keypress", i), e && u.write(import_src.cursor.show), t.isTTY && !xD && t.setRawMode(!1), s.terminal = !1, s.close();
|
||
};
|
||
}
|
||
var AD = Object.defineProperty, pD = (t, u, F) => u in t ? AD(t, u, {
|
||
enumerable: !0,
|
||
configurable: !0,
|
||
writable: !0,
|
||
value: F
|
||
}) : t[u] = F, h = (t, u, F) => (pD(t, typeof u != "symbol" ? u + "" : u, F), F);
|
||
var x = class {
|
||
constructor(u, F = !0) {
|
||
h(this, "input"), h(this, "output"), h(this, "_abortSignal"), h(this, "rl"), h(this, "opts"), h(this, "_render"), h(this, "_track", !1), h(this, "_prevFrame", ""), h(this, "_subscribers", /* @__PURE__ */ new Map()), h(this, "_cursor", 0), h(this, "state", "initial"), h(this, "error", ""), h(this, "value");
|
||
const { input: e = stdin, output: s = stdout, render: i, signal: D, ...C } = u;
|
||
this.opts = C, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = i.bind(this), this._track = F, this._abortSignal = D, this.input = e, this.output = s;
|
||
}
|
||
unsubscribe() {
|
||
this._subscribers.clear();
|
||
}
|
||
setSubscriber(u, F) {
|
||
const e = this._subscribers.get(u) ?? [];
|
||
e.push(F), this._subscribers.set(u, e);
|
||
}
|
||
on(u, F) {
|
||
this.setSubscriber(u, { cb: F });
|
||
}
|
||
once(u, F) {
|
||
this.setSubscriber(u, {
|
||
cb: F,
|
||
once: !0
|
||
});
|
||
}
|
||
emit(u, ...F) {
|
||
const e = this._subscribers.get(u) ?? [], s = [];
|
||
for (const i of e) i.cb(...F), i.once && s.push(() => e.splice(e.indexOf(i), 1));
|
||
for (const i of s) i();
|
||
}
|
||
prompt() {
|
||
return new Promise((u, F) => {
|
||
if (this._abortSignal) {
|
||
if (this._abortSignal.aborted) return this.state = "cancel", this.close(), u(S$1);
|
||
this._abortSignal.addEventListener("abort", () => {
|
||
this.state = "cancel", this.close();
|
||
}, { once: !0 });
|
||
}
|
||
const e = new WriteStream(0);
|
||
e._write = (s, i, D) => {
|
||
this._track && (this.value = this.rl?.line.replace(/\t/g, ""), this._cursor = this.rl?.cursor ?? 0, this.emit("value", this.value)), D();
|
||
}, this.input.pipe(e), this.rl = M.createInterface({
|
||
input: this.input,
|
||
output: e,
|
||
tabSize: 2,
|
||
prompt: "",
|
||
escapeCodeTimeout: 50
|
||
}), M.emitKeypressEvents(this.input, this.rl), this.rl.prompt(), this.opts.initialValue !== void 0 && this._track && this.rl.write(this.opts.initialValue), this.input.on("keypress", this.onKeypress), d(this.input, !0), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
|
||
this.output.write(import_src.cursor.show), this.output.off("resize", this.render), d(this.input, !1), u(this.value);
|
||
}), this.once("cancel", () => {
|
||
this.output.write(import_src.cursor.show), this.output.off("resize", this.render), d(this.input, !1), u(S$1);
|
||
});
|
||
});
|
||
}
|
||
onKeypress(u, F) {
|
||
if (this.state === "error" && (this.state = "active"), F?.name && (!this._track && c.aliases.has(F.name) && this.emit("cursor", c.aliases.get(F.name)), c.actions.has(F.name) && this.emit("cursor", F.name)), u && (u.toLowerCase() === "y" || u.toLowerCase() === "n") && this.emit("confirm", u.toLowerCase() === "y"), u === " " && this.opts.placeholder && (this.value || (this.rl?.write(this.opts.placeholder), this.emit("value", this.opts.placeholder))), u && this.emit("key", u.toLowerCase()), F?.name === "return") {
|
||
if (this.opts.validate) {
|
||
const e = this.opts.validate(this.value);
|
||
e && (this.error = e instanceof Error ? e.message : e, this.state = "error", this.rl?.write(this.value));
|
||
}
|
||
this.state !== "error" && (this.state = "submit");
|
||
}
|
||
k$1([
|
||
u,
|
||
F?.name,
|
||
F?.sequence
|
||
], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
|
||
}
|
||
close() {
|
||
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
||
`), d(this.input, !1), this.rl?.close(), this.rl = void 0, this.emit(`${this.state}`, this.value), this.unsubscribe();
|
||
}
|
||
restoreCursor() {
|
||
const u = G$1(this._prevFrame, process.stdout.columns, { hard: !0 }).split(`
|
||
`).length - 1;
|
||
this.output.write(import_src.cursor.move(-999, u * -1));
|
||
}
|
||
render() {
|
||
const u = G$1(this._render(this) ?? "", process.stdout.columns, { hard: !0 });
|
||
if (u !== this._prevFrame) {
|
||
if (this.state === "initial") this.output.write(import_src.cursor.hide);
|
||
else {
|
||
const F = lD(this._prevFrame, u);
|
||
if (this.restoreCursor(), F && F?.length === 1) {
|
||
const e = F[0];
|
||
this.output.write(import_src.cursor.move(0, e)), this.output.write(import_src.erase.lines(1));
|
||
const s = u.split(`
|
||
`);
|
||
this.output.write(s[e]), this._prevFrame = u, this.output.write(import_src.cursor.move(0, s.length - e - 1));
|
||
return;
|
||
}
|
||
if (F && F?.length > 1) {
|
||
const e = F[0];
|
||
this.output.write(import_src.cursor.move(0, e)), this.output.write(import_src.erase.down());
|
||
const s = u.split(`
|
||
`).slice(e);
|
||
this.output.write(s.join(`
|
||
`)), this._prevFrame = u;
|
||
return;
|
||
}
|
||
this.output.write(import_src.erase.down());
|
||
}
|
||
this.output.write(u), this.state === "initial" && (this.state = "active"), this._prevFrame = u;
|
||
}
|
||
}
|
||
};
|
||
var fD = class extends x {
|
||
get cursor() {
|
||
return this.value ? 0 : 1;
|
||
}
|
||
get _value() {
|
||
return this.cursor === 0;
|
||
}
|
||
constructor(u) {
|
||
super(u, !1), this.value = !!u.initialValue, this.on("value", () => {
|
||
this.value = this._value;
|
||
}), this.on("confirm", (F) => {
|
||
this.output.write(import_src.cursor.move(0, -1)), this.value = F, this.state = "submit", this.close();
|
||
}), this.on("cursor", () => {
|
||
this.value = !this.value;
|
||
});
|
||
}
|
||
};
|
||
var gD = Object.defineProperty, vD = (t, u, F) => u in t ? gD(t, u, {
|
||
enumerable: !0,
|
||
configurable: !0,
|
||
writable: !0,
|
||
value: F
|
||
}) : t[u] = F, K = (t, u, F) => (vD(t, typeof u != "symbol" ? u + "" : u, F), F);
|
||
let dD = class extends x {
|
||
constructor(u) {
|
||
super(u, !1), K(this, "options"), K(this, "cursor", 0);
|
||
const { options: F } = u;
|
||
this.options = Object.entries(F).flatMap(([e, s]) => [{
|
||
value: e,
|
||
group: !0,
|
||
label: e
|
||
}, ...s.map((i) => ({
|
||
...i,
|
||
group: e
|
||
}))]), this.value = [...u.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: e }) => e === u.cursorAt), 0), this.on("cursor", (e) => {
|
||
switch (e) {
|
||
case "left":
|
||
case "up":
|
||
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
||
break;
|
||
case "down":
|
||
case "right":
|
||
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
||
break;
|
||
case "space":
|
||
this.toggleValue();
|
||
break;
|
||
}
|
||
});
|
||
}
|
||
getGroupItems(u) {
|
||
return this.options.filter((F) => F.group === u);
|
||
}
|
||
isGroupSelected(u) {
|
||
return this.getGroupItems(u).every((F) => this.value.includes(F.value));
|
||
}
|
||
toggleValue() {
|
||
const u = this.options[this.cursor];
|
||
if (u.group === !0) {
|
||
const F = u.value, e = this.getGroupItems(F);
|
||
this.isGroupSelected(F) ? this.value = this.value.filter((s) => e.findIndex((i) => i.value === s) === -1) : this.value = [...this.value, ...e.map((s) => s.value)], this.value = Array.from(new Set(this.value));
|
||
} else this.value = this.value.includes(u.value) ? this.value.filter((e) => e !== u.value) : [...this.value, u.value];
|
||
}
|
||
};
|
||
var bD = Object.defineProperty, mD = (t, u, F) => u in t ? bD(t, u, {
|
||
enumerable: !0,
|
||
configurable: !0,
|
||
writable: !0,
|
||
value: F
|
||
}) : t[u] = F, Y = (t, u, F) => (mD(t, typeof u != "symbol" ? u + "" : u, F), F);
|
||
let wD = class extends x {
|
||
constructor(u) {
|
||
super(u, !1), Y(this, "options"), Y(this, "cursor", 0), this.options = u.options, this.value = [...u.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: F }) => F === u.cursorAt), 0), this.on("key", (F) => {
|
||
F === "a" && this.toggleAll();
|
||
}), this.on("cursor", (F) => {
|
||
switch (F) {
|
||
case "left":
|
||
case "up":
|
||
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
||
break;
|
||
case "down":
|
||
case "right":
|
||
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
||
break;
|
||
case "space":
|
||
this.toggleValue();
|
||
break;
|
||
}
|
||
});
|
||
}
|
||
get _value() {
|
||
return this.options[this.cursor].value;
|
||
}
|
||
toggleAll() {
|
||
this.value = this.value.length === this.options.length ? [] : this.options.map((F) => F.value);
|
||
}
|
||
toggleValue() {
|
||
this.value = this.value.includes(this._value) ? this.value.filter((F) => F !== this._value) : [...this.value, this._value];
|
||
}
|
||
};
|
||
var yD = Object.defineProperty, _D = (t, u, F) => u in t ? yD(t, u, {
|
||
enumerable: !0,
|
||
configurable: !0,
|
||
writable: !0,
|
||
value: F
|
||
}) : t[u] = F, Z$1 = (t, u, F) => (_D(t, typeof u != "symbol" ? u + "" : u, F), F);
|
||
var kD = class extends x {
|
||
constructor({ mask: u, ...F }) {
|
||
super(F), Z$1(this, "valueWithCursor", ""), Z$1(this, "_mask", "•"), this._mask = u ?? "•", this.on("finalize", () => {
|
||
this.valueWithCursor = this.masked;
|
||
}), this.on("value", () => {
|
||
if (this.cursor >= this.value.length) this.valueWithCursor = `${this.masked}${import_picocolors.default.inverse(import_picocolors.default.hidden("_"))}`;
|
||
else {
|
||
const e = this.masked.slice(0, this.cursor), s = this.masked.slice(this.cursor);
|
||
this.valueWithCursor = `${e}${import_picocolors.default.inverse(s[0])}${s.slice(1)}`;
|
||
}
|
||
});
|
||
}
|
||
get cursor() {
|
||
return this._cursor;
|
||
}
|
||
get masked() {
|
||
return this.value.replaceAll(/./g, this._mask);
|
||
}
|
||
};
|
||
var SD = Object.defineProperty, $D = (t, u, F) => u in t ? SD(t, u, {
|
||
enumerable: !0,
|
||
configurable: !0,
|
||
writable: !0,
|
||
value: F
|
||
}) : t[u] = F, q = (t, u, F) => ($D(t, typeof u != "symbol" ? u + "" : u, F), F);
|
||
var jD = class extends x {
|
||
constructor(u) {
|
||
super(u, !1), q(this, "options"), q(this, "cursor", 0), this.options = u.options, this.cursor = this.options.findIndex(({ value: F }) => F === u.initialValue), this.cursor === -1 && (this.cursor = 0), this.changeValue(), this.on("cursor", (F) => {
|
||
switch (F) {
|
||
case "left":
|
||
case "up":
|
||
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
||
break;
|
||
case "down":
|
||
case "right":
|
||
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
||
break;
|
||
}
|
||
this.changeValue();
|
||
});
|
||
}
|
||
get _value() {
|
||
return this.options[this.cursor];
|
||
}
|
||
changeValue() {
|
||
this.value = this._value.value;
|
||
}
|
||
};
|
||
var MD = Object.defineProperty, TD = (t, u, F) => u in t ? MD(t, u, {
|
||
enumerable: !0,
|
||
configurable: !0,
|
||
writable: !0,
|
||
value: F
|
||
}) : t[u] = F, H$1 = (t, u, F) => (TD(t, typeof u != "symbol" ? u + "" : u, F), F);
|
||
var OD = class extends x {
|
||
constructor(u) {
|
||
super(u, !1), H$1(this, "options"), H$1(this, "cursor", 0), this.options = u.options;
|
||
const F = this.options.map(({ value: [e] }) => e?.toLowerCase());
|
||
this.cursor = Math.max(F.indexOf(u.initialValue), 0), this.on("key", (e) => {
|
||
if (!F.includes(e)) return;
|
||
const s = this.options.find(({ value: [i] }) => i?.toLowerCase() === e);
|
||
s && (this.value = s.value, this.state = "submit", this.emit("submit"));
|
||
});
|
||
}
|
||
};
|
||
var PD = class extends x {
|
||
get valueWithCursor() {
|
||
if (this.state === "submit") return this.value;
|
||
if (this.cursor >= this.value.length) return `${this.value}\u2588`;
|
||
const u = this.value.slice(0, this.cursor), [F, ...e] = this.value.slice(this.cursor);
|
||
return `${u}${import_picocolors.default.inverse(F)}${e.join("")}`;
|
||
}
|
||
get cursor() {
|
||
return this._cursor;
|
||
}
|
||
constructor(u) {
|
||
super(u), this.on("finalize", () => {
|
||
this.value || (this.value = u.defaultValue);
|
||
});
|
||
}
|
||
};
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/@clack+prompts@0.9.1/node_modules/@clack/prompts/dist/index.mjs
|
||
function X() {
|
||
return p.platform !== "win32" ? p.env.TERM !== "linux" : !!p.env.CI || !!p.env.WT_SESSION || !!p.env.TERMINUS_SUBLIME || p.env.ConEmuTask === "{cmd::Cmder}" || p.env.TERM_PROGRAM === "Terminus-Sublime" || p.env.TERM_PROGRAM === "vscode" || p.env.TERM === "xterm-256color" || p.env.TERM === "alacritty" || p.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
||
}
|
||
const E = X(), u = (s, n) => E ? s : n, ee = u("◆", "*"), A = u("■", "x"), B = u("▲", "x"), S = u("◇", "o"), te = u("┌", "T"), a = u("│", "|"), m = u("└", "—"), j = u("●", ">"), R = u("○", " "), V = u("◻", "[•]"), M$1 = u("◼", "[+]"), G = u("◻", "[ ]"), se = u("▪", "•"), N = u("─", "-"), re = u("╮", "+"), ie = u("├", "+"), ne = u("╯", "+"), ae = u("●", "•"), oe = u("◆", "*"), ce = u("▲", "!"), le = u("■", "x"), y = (s) => {
|
||
switch (s) {
|
||
case "initial":
|
||
case "active": return import_picocolors.default.cyan(ee);
|
||
case "cancel": return import_picocolors.default.red(A);
|
||
case "error": return import_picocolors.default.yellow(B);
|
||
case "submit": return import_picocolors.default.green(S);
|
||
}
|
||
}, k = (s) => {
|
||
const { cursor: n, options: t, style: i } = s, r = s.maxItems ?? Number.POSITIVE_INFINITY, c = Math.max(process.stdout.rows - 4, 0), o = Math.min(c, Math.max(r, 5));
|
||
let l = 0;
|
||
n >= l + o - 3 ? l = Math.max(Math.min(n - o + 3, t.length - o), 0) : n < l + 2 && (l = Math.max(n - 2, 0));
|
||
const $ = o < t.length && l > 0, d = o < t.length && l + o < t.length;
|
||
return t.slice(l, l + o).map((w, b, C) => {
|
||
const I = b === 0 && $, x = b === C.length - 1 && d;
|
||
return I || x ? import_picocolors.default.dim("...") : i(w, b + l === n);
|
||
});
|
||
}, ue = (s) => new PD({
|
||
validate: s.validate,
|
||
placeholder: s.placeholder,
|
||
defaultValue: s.defaultValue,
|
||
initialValue: s.initialValue,
|
||
render() {
|
||
const n = `${import_picocolors.default.gray(a)}
|
||
${y(this.state)} ${s.message}
|
||
`, t = s.placeholder ? import_picocolors.default.inverse(s.placeholder[0]) + import_picocolors.default.dim(s.placeholder.slice(1)) : import_picocolors.default.inverse(import_picocolors.default.hidden("_")), i = this.value ? this.valueWithCursor : t;
|
||
switch (this.state) {
|
||
case "error": return `${n.trim()}
|
||
${import_picocolors.default.yellow(a)} ${i}
|
||
${import_picocolors.default.yellow(m)} ${import_picocolors.default.yellow(this.error)}
|
||
`;
|
||
case "submit": return `${n}${import_picocolors.default.gray(a)} ${import_picocolors.default.dim(this.value || s.placeholder)}`;
|
||
case "cancel": return `${n}${import_picocolors.default.gray(a)} ${import_picocolors.default.strikethrough(import_picocolors.default.dim(this.value ?? ""))}${this.value?.trim() ? `
|
||
${import_picocolors.default.gray(a)}` : ""}`;
|
||
default: return `${n}${import_picocolors.default.cyan(a)} ${i}
|
||
${import_picocolors.default.cyan(m)}
|
||
`;
|
||
}
|
||
}
|
||
}).prompt(), $e = (s) => new kD({
|
||
validate: s.validate,
|
||
mask: s.mask ?? se,
|
||
render() {
|
||
const n = `${import_picocolors.default.gray(a)}
|
||
${y(this.state)} ${s.message}
|
||
`, t = this.valueWithCursor, i = this.masked;
|
||
switch (this.state) {
|
||
case "error": return `${n.trim()}
|
||
${import_picocolors.default.yellow(a)} ${i}
|
||
${import_picocolors.default.yellow(m)} ${import_picocolors.default.yellow(this.error)}
|
||
`;
|
||
case "submit": return `${n}${import_picocolors.default.gray(a)} ${import_picocolors.default.dim(i)}`;
|
||
case "cancel": return `${n}${import_picocolors.default.gray(a)} ${import_picocolors.default.strikethrough(import_picocolors.default.dim(i ?? ""))}${i ? `
|
||
${import_picocolors.default.gray(a)}` : ""}`;
|
||
default: return `${n}${import_picocolors.default.cyan(a)} ${t}
|
||
${import_picocolors.default.cyan(m)}
|
||
`;
|
||
}
|
||
}
|
||
}).prompt(), me = (s) => {
|
||
const n = s.active ?? "Yes", t = s.inactive ?? "No";
|
||
return new fD({
|
||
active: n,
|
||
inactive: t,
|
||
initialValue: s.initialValue ?? !0,
|
||
render() {
|
||
const i = `${import_picocolors.default.gray(a)}
|
||
${y(this.state)} ${s.message}
|
||
`, r = this.value ? n : t;
|
||
switch (this.state) {
|
||
case "submit": return `${i}${import_picocolors.default.gray(a)} ${import_picocolors.default.dim(r)}`;
|
||
case "cancel": return `${i}${import_picocolors.default.gray(a)} ${import_picocolors.default.strikethrough(import_picocolors.default.dim(r))}
|
||
${import_picocolors.default.gray(a)}`;
|
||
default: return `${i}${import_picocolors.default.cyan(a)} ${this.value ? `${import_picocolors.default.green(j)} ${n}` : `${import_picocolors.default.dim(R)} ${import_picocolors.default.dim(n)}`} ${import_picocolors.default.dim("/")} ${this.value ? `${import_picocolors.default.dim(R)} ${import_picocolors.default.dim(t)}` : `${import_picocolors.default.green(j)} ${t}`}
|
||
${import_picocolors.default.cyan(m)}
|
||
`;
|
||
}
|
||
}
|
||
}).prompt();
|
||
}, de = (s) => {
|
||
const n = (t, i) => {
|
||
const r = t.label ?? String(t.value);
|
||
switch (i) {
|
||
case "selected": return `${import_picocolors.default.dim(r)}`;
|
||
case "active": return `${import_picocolors.default.green(j)} ${r} ${t.hint ? import_picocolors.default.dim(`(${t.hint})`) : ""}`;
|
||
case "cancelled": return `${import_picocolors.default.strikethrough(import_picocolors.default.dim(r))}`;
|
||
default: return `${import_picocolors.default.dim(R)} ${import_picocolors.default.dim(r)}`;
|
||
}
|
||
};
|
||
return new jD({
|
||
options: s.options,
|
||
initialValue: s.initialValue,
|
||
render() {
|
||
const t = `${import_picocolors.default.gray(a)}
|
||
${y(this.state)} ${s.message}
|
||
`;
|
||
switch (this.state) {
|
||
case "submit": return `${t}${import_picocolors.default.gray(a)} ${n(this.options[this.cursor], "selected")}`;
|
||
case "cancel": return `${t}${import_picocolors.default.gray(a)} ${n(this.options[this.cursor], "cancelled")}
|
||
${import_picocolors.default.gray(a)}`;
|
||
default: return `${t}${import_picocolors.default.cyan(a)} ${k({
|
||
cursor: this.cursor,
|
||
options: this.options,
|
||
maxItems: s.maxItems,
|
||
style: (i, r) => n(i, r ? "active" : "inactive")
|
||
}).join(`
|
||
${import_picocolors.default.cyan(a)} `)}
|
||
${import_picocolors.default.cyan(m)}
|
||
`;
|
||
}
|
||
}
|
||
}).prompt();
|
||
}, he = (s) => {
|
||
const n = (t, i = "inactive") => {
|
||
const r = t.label ?? String(t.value);
|
||
return i === "selected" ? `${import_picocolors.default.dim(r)}` : i === "cancelled" ? `${import_picocolors.default.strikethrough(import_picocolors.default.dim(r))}` : i === "active" ? `${import_picocolors.default.bgCyan(import_picocolors.default.gray(` ${t.value} `))} ${r} ${t.hint ? import_picocolors.default.dim(`(${t.hint})`) : ""}` : `${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(` ${t.value} `)))} ${r} ${t.hint ? import_picocolors.default.dim(`(${t.hint})`) : ""}`;
|
||
};
|
||
return new OD({
|
||
options: s.options,
|
||
initialValue: s.initialValue,
|
||
render() {
|
||
const t = `${import_picocolors.default.gray(a)}
|
||
${y(this.state)} ${s.message}
|
||
`;
|
||
switch (this.state) {
|
||
case "submit": return `${t}${import_picocolors.default.gray(a)} ${n(this.options.find((i) => i.value === this.value) ?? s.options[0], "selected")}`;
|
||
case "cancel": return `${t}${import_picocolors.default.gray(a)} ${n(this.options[0], "cancelled")}
|
||
${import_picocolors.default.gray(a)}`;
|
||
default: return `${t}${import_picocolors.default.cyan(a)} ${this.options.map((i, r) => n(i, r === this.cursor ? "active" : "inactive")).join(`
|
||
${import_picocolors.default.cyan(a)} `)}
|
||
${import_picocolors.default.cyan(m)}
|
||
`;
|
||
}
|
||
}
|
||
}).prompt();
|
||
}, pe = (s) => {
|
||
const n = (t, i) => {
|
||
const r = t.label ?? String(t.value);
|
||
return i === "active" ? `${import_picocolors.default.cyan(V)} ${r} ${t.hint ? import_picocolors.default.dim(`(${t.hint})`) : ""}` : i === "selected" ? `${import_picocolors.default.green(M$1)} ${import_picocolors.default.dim(r)}` : i === "cancelled" ? `${import_picocolors.default.strikethrough(import_picocolors.default.dim(r))}` : i === "active-selected" ? `${import_picocolors.default.green(M$1)} ${r} ${t.hint ? import_picocolors.default.dim(`(${t.hint})`) : ""}` : i === "submitted" ? `${import_picocolors.default.dim(r)}` : `${import_picocolors.default.dim(G)} ${import_picocolors.default.dim(r)}`;
|
||
};
|
||
return new wD({
|
||
options: s.options,
|
||
initialValues: s.initialValues,
|
||
required: s.required ?? !0,
|
||
cursorAt: s.cursorAt,
|
||
validate(t) {
|
||
if (this.required && t.length === 0) return `Please select at least one option.
|
||
${import_picocolors.default.reset(import_picocolors.default.dim(`Press ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" space ")))} to select, ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" enter ")))} to submit`))}`;
|
||
},
|
||
render() {
|
||
const t = `${import_picocolors.default.gray(a)}
|
||
${y(this.state)} ${s.message}
|
||
`, i = (r, c) => {
|
||
const o = this.value.includes(r.value);
|
||
return c && o ? n(r, "active-selected") : o ? n(r, "selected") : n(r, c ? "active" : "inactive");
|
||
};
|
||
switch (this.state) {
|
||
case "submit": return `${t}${import_picocolors.default.gray(a)} ${this.options.filter(({ value: r }) => this.value.includes(r)).map((r) => n(r, "submitted")).join(import_picocolors.default.dim(", ")) || import_picocolors.default.dim("none")}`;
|
||
case "cancel": {
|
||
const r = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors.default.dim(", "));
|
||
return `${t}${import_picocolors.default.gray(a)} ${r.trim() ? `${r}
|
||
${import_picocolors.default.gray(a)}` : ""}`;
|
||
}
|
||
case "error": {
|
||
const r = this.error.split(`
|
||
`).map((c, o) => o === 0 ? `${import_picocolors.default.yellow(m)} ${import_picocolors.default.yellow(c)}` : ` ${c}`).join(`
|
||
`);
|
||
return `${t + import_picocolors.default.yellow(a)} ${k({
|
||
options: this.options,
|
||
cursor: this.cursor,
|
||
maxItems: s.maxItems,
|
||
style: i
|
||
}).join(`
|
||
${import_picocolors.default.yellow(a)} `)}
|
||
${r}
|
||
`;
|
||
}
|
||
default: return `${t}${import_picocolors.default.cyan(a)} ${k({
|
||
options: this.options,
|
||
cursor: this.cursor,
|
||
maxItems: s.maxItems,
|
||
style: i
|
||
}).join(`
|
||
${import_picocolors.default.cyan(a)} `)}
|
||
${import_picocolors.default.cyan(m)}
|
||
`;
|
||
}
|
||
}
|
||
}).prompt();
|
||
}, ge = (s) => {
|
||
const n = (t, i, r = []) => {
|
||
const c = t.label ?? String(t.value), o = typeof t.group == "string", l = o && (r[r.indexOf(t) + 1] ?? { group: !0 }), $ = o && l.group === !0, d = o ? `${$ ? m : a} ` : "";
|
||
return i === "active" ? `${import_picocolors.default.dim(d)}${import_picocolors.default.cyan(V)} ${c} ${t.hint ? import_picocolors.default.dim(`(${t.hint})`) : ""}` : i === "group-active" ? `${d}${import_picocolors.default.cyan(V)} ${import_picocolors.default.dim(c)}` : i === "group-active-selected" ? `${d}${import_picocolors.default.green(M$1)} ${import_picocolors.default.dim(c)}` : i === "selected" ? `${import_picocolors.default.dim(d)}${import_picocolors.default.green(M$1)} ${import_picocolors.default.dim(c)}` : i === "cancelled" ? `${import_picocolors.default.strikethrough(import_picocolors.default.dim(c))}` : i === "active-selected" ? `${import_picocolors.default.dim(d)}${import_picocolors.default.green(M$1)} ${c} ${t.hint ? import_picocolors.default.dim(`(${t.hint})`) : ""}` : i === "submitted" ? `${import_picocolors.default.dim(c)}` : `${import_picocolors.default.dim(d)}${import_picocolors.default.dim(G)} ${import_picocolors.default.dim(c)}`;
|
||
};
|
||
return new dD({
|
||
options: s.options,
|
||
initialValues: s.initialValues,
|
||
required: s.required ?? !0,
|
||
cursorAt: s.cursorAt,
|
||
validate(t) {
|
||
if (this.required && t.length === 0) return `Please select at least one option.
|
||
${import_picocolors.default.reset(import_picocolors.default.dim(`Press ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" space ")))} to select, ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" enter ")))} to submit`))}`;
|
||
},
|
||
render() {
|
||
const t = `${import_picocolors.default.gray(a)}
|
||
${y(this.state)} ${s.message}
|
||
`;
|
||
switch (this.state) {
|
||
case "submit": return `${t}${import_picocolors.default.gray(a)} ${this.options.filter(({ value: i }) => this.value.includes(i)).map((i) => n(i, "submitted")).join(import_picocolors.default.dim(", "))}`;
|
||
case "cancel": {
|
||
const i = this.options.filter(({ value: r }) => this.value.includes(r)).map((r) => n(r, "cancelled")).join(import_picocolors.default.dim(", "));
|
||
return `${t}${import_picocolors.default.gray(a)} ${i.trim() ? `${i}
|
||
${import_picocolors.default.gray(a)}` : ""}`;
|
||
}
|
||
case "error": {
|
||
const i = this.error.split(`
|
||
`).map((r, c) => c === 0 ? `${import_picocolors.default.yellow(m)} ${import_picocolors.default.yellow(r)}` : ` ${r}`).join(`
|
||
`);
|
||
return `${t}${import_picocolors.default.yellow(a)} ${this.options.map((r, c, o) => {
|
||
const l = this.value.includes(r.value) || r.group === !0 && this.isGroupSelected(`${r.value}`), $ = c === this.cursor;
|
||
return !$ && typeof r.group == "string" && this.options[this.cursor].value === r.group ? n(r, l ? "group-active-selected" : "group-active", o) : $ && l ? n(r, "active-selected", o) : l ? n(r, "selected", o) : n(r, $ ? "active" : "inactive", o);
|
||
}).join(`
|
||
${import_picocolors.default.yellow(a)} `)}
|
||
${i}
|
||
`;
|
||
}
|
||
default: return `${t}${import_picocolors.default.cyan(a)} ${this.options.map((i, r, c) => {
|
||
const o = this.value.includes(i.value) || i.group === !0 && this.isGroupSelected(`${i.value}`), l = r === this.cursor;
|
||
return !l && typeof i.group == "string" && this.options[this.cursor].value === i.group ? n(i, o ? "group-active-selected" : "group-active", c) : l && o ? n(i, "active-selected", c) : o ? n(i, "selected", c) : n(i, l ? "active" : "inactive", c);
|
||
}).join(`
|
||
${import_picocolors.default.cyan(a)} `)}
|
||
${import_picocolors.default.cyan(m)}
|
||
`;
|
||
}
|
||
}
|
||
}).prompt();
|
||
}, ye = (s = "", n = "") => {
|
||
const t = `
|
||
${s}
|
||
`.split(`
|
||
`), i = stripVTControlCharacters(n).length, r = Math.max(t.reduce((o, l) => {
|
||
const $ = stripVTControlCharacters(l);
|
||
return $.length > o ? $.length : o;
|
||
}, 0), i) + 2, c = t.map((o) => `${import_picocolors.default.gray(a)} ${import_picocolors.default.dim(o)}${" ".repeat(r - stripVTControlCharacters(o).length)}${import_picocolors.default.gray(a)}`).join(`
|
||
`);
|
||
process.stdout.write(`${import_picocolors.default.gray(a)}
|
||
${import_picocolors.default.green(S)} ${import_picocolors.default.reset(n)} ${import_picocolors.default.gray(N.repeat(Math.max(r - i - 1, 1)) + re)}
|
||
${c}
|
||
${import_picocolors.default.gray(ie + N.repeat(r + 2) + ne)}
|
||
`);
|
||
}, ve = (s = "") => {
|
||
process.stdout.write(`${import_picocolors.default.gray(m)} ${import_picocolors.default.red(s)}
|
||
|
||
`);
|
||
}, we = (s = "") => {
|
||
process.stdout.write(`${import_picocolors.default.gray(te)} ${s}
|
||
`);
|
||
}, fe = (s = "") => {
|
||
process.stdout.write(`${import_picocolors.default.gray(a)}
|
||
${import_picocolors.default.gray(m)} ${s}
|
||
|
||
`);
|
||
}, v = {
|
||
message: (s = "", { symbol: n = import_picocolors.default.gray(a) } = {}) => {
|
||
const t = [`${import_picocolors.default.gray(a)}`];
|
||
if (s) {
|
||
const [i, ...r] = s.split(`
|
||
`);
|
||
t.push(`${n} ${i}`, ...r.map((c) => `${import_picocolors.default.gray(a)} ${c}`));
|
||
}
|
||
process.stdout.write(`${t.join(`
|
||
`)}
|
||
`);
|
||
},
|
||
info: (s) => {
|
||
v.message(s, { symbol: import_picocolors.default.blue(ae) });
|
||
},
|
||
success: (s) => {
|
||
v.message(s, { symbol: import_picocolors.default.green(oe) });
|
||
},
|
||
step: (s) => {
|
||
v.message(s, { symbol: import_picocolors.default.green(S) });
|
||
},
|
||
warn: (s) => {
|
||
v.message(s, { symbol: import_picocolors.default.yellow(ce) });
|
||
},
|
||
warning: (s) => {
|
||
v.warn(s);
|
||
},
|
||
error: (s) => {
|
||
v.message(s, { symbol: import_picocolors.default.red(le) });
|
||
}
|
||
}, L = () => {
|
||
const s = E ? [
|
||
"◒",
|
||
"◐",
|
||
"◓",
|
||
"◑"
|
||
] : [
|
||
"•",
|
||
"o",
|
||
"O",
|
||
"0"
|
||
], n = E ? 80 : 120, t = process.env.CI === "true";
|
||
let i, r, c = !1, o = "", l;
|
||
const $ = (h) => {
|
||
c && P(h > 1 ? "Something went wrong" : "Canceled", h);
|
||
}, d = () => $(2), w = () => $(1), b = () => {
|
||
process.on("uncaughtExceptionMonitor", d), process.on("unhandledRejection", d), process.on("SIGINT", w), process.on("SIGTERM", w), process.on("exit", $);
|
||
}, C = () => {
|
||
process.removeListener("uncaughtExceptionMonitor", d), process.removeListener("unhandledRejection", d), process.removeListener("SIGINT", w), process.removeListener("SIGTERM", w), process.removeListener("exit", $);
|
||
}, I = () => {
|
||
if (l === void 0) return;
|
||
t && process.stdout.write(`
|
||
`);
|
||
const h = l.split(`
|
||
`);
|
||
process.stdout.write(import_src.cursor.move(-999, h.length - 1)), process.stdout.write(import_src.erase.down(h.length));
|
||
}, x = (h) => h.replace(/\.+$/, ""), O = (h = "") => {
|
||
c = !0, i = cD(), o = x(h), process.stdout.write(`${import_picocolors.default.gray(a)}
|
||
`);
|
||
let g = 0, f = 0;
|
||
b(), r = setInterval(() => {
|
||
if (t && o === l) return;
|
||
I(), l = o;
|
||
const W = import_picocolors.default.magenta(s[g]), _ = t ? "..." : ".".repeat(Math.floor(f)).slice(0, 3);
|
||
process.stdout.write(`${W} ${o}${_}`), g = g + 1 < s.length ? g + 1 : 0, f = f < s.length ? f + .125 : 0;
|
||
}, n);
|
||
}, P = (h = "", g = 0) => {
|
||
c = !1, clearInterval(r), I();
|
||
const f = g === 0 ? import_picocolors.default.green(S) : g === 1 ? import_picocolors.default.red(A) : import_picocolors.default.red(B);
|
||
o = x(h ?? o), process.stdout.write(`${f} ${o}
|
||
`), C(), i();
|
||
};
|
||
return {
|
||
start: O,
|
||
stop: P,
|
||
message: (h = "") => {
|
||
o = x(h ?? o);
|
||
}
|
||
};
|
||
}, be = async (s, n) => {
|
||
const t = {}, i = Object.keys(s);
|
||
for (const r of i) {
|
||
const c = s[r], o = await c({ results: t })?.catch((l) => {
|
||
throw l;
|
||
});
|
||
if (typeof n?.onCancel == "function" && BD(o)) {
|
||
t[r] = "canceled", n.onCancel({ results: t });
|
||
continue;
|
||
}
|
||
t[r] = o;
|
||
}
|
||
return t;
|
||
}, xe = async (s) => {
|
||
for (const n of s) {
|
||
if (n.enabled === !1) continue;
|
||
const t = L();
|
||
t.start(n.title);
|
||
const i = await n.task(t.message);
|
||
t.stop(i || n.title);
|
||
}
|
||
};
|
||
|
||
//#endregion
|
||
//#region src/errors.ts
|
||
var WizardCancelledError = class extends Error {
|
||
name = "WizardCancelledError";
|
||
constructor() {
|
||
super("Wizard cancelled by user");
|
||
}
|
||
};
|
||
|
||
//#endregion
|
||
//#region src/prompter/clack-prompter.ts
|
||
function guardCancel(value) {
|
||
if (BD(value)) throw new WizardCancelledError();
|
||
return value;
|
||
}
|
||
var ClackPrompter = class {
|
||
intro(message) {
|
||
we(message);
|
||
}
|
||
outro(message) {
|
||
fe(message);
|
||
}
|
||
note(message, title) {
|
||
ye(message, title);
|
||
}
|
||
log(message) {
|
||
v.info(message);
|
||
}
|
||
warn(message) {
|
||
v.warn(message);
|
||
}
|
||
async text(opts) {
|
||
const validate = opts.validate ? (v) => {
|
||
const r = opts.validate(v);
|
||
return r === void 0 ? void 0 : r;
|
||
} : void 0;
|
||
return guardCancel(await ue({
|
||
message: opts.message,
|
||
placeholder: opts.placeholder,
|
||
defaultValue: opts.defaultValue,
|
||
validate
|
||
}));
|
||
}
|
||
async confirm(opts) {
|
||
return guardCancel(await me({
|
||
message: opts.message,
|
||
initialValue: opts.initialValue
|
||
}));
|
||
}
|
||
async select(opts) {
|
||
const clackOptions = opts.options.map((o) => ({
|
||
value: o.value,
|
||
label: o.label,
|
||
hint: o.hint
|
||
}));
|
||
return guardCancel(await de({
|
||
message: opts.message,
|
||
options: clackOptions,
|
||
initialValue: opts.initialValue
|
||
}));
|
||
}
|
||
async multiselect(opts) {
|
||
const clackOptions = opts.options.map((o) => ({
|
||
value: o.value,
|
||
label: o.label,
|
||
hint: o.hint
|
||
}));
|
||
return guardCancel(await pe({
|
||
message: opts.message,
|
||
options: clackOptions,
|
||
required: opts.required,
|
||
initialValues: opts.options.filter((o) => o.selected).map((o) => o.value)
|
||
}));
|
||
}
|
||
async groupMultiselect(opts) {
|
||
const grouped = {};
|
||
for (const [group, items] of Object.entries(opts.options)) grouped[group] = items.map((o) => ({
|
||
value: o.value,
|
||
label: o.label,
|
||
hint: o.hint
|
||
}));
|
||
return guardCancel(await ge({
|
||
message: opts.message,
|
||
options: grouped,
|
||
required: opts.required
|
||
}));
|
||
}
|
||
spinner() {
|
||
const s = L();
|
||
let started = false;
|
||
return {
|
||
update(message) {
|
||
if (!started) {
|
||
s.start(message);
|
||
started = true;
|
||
} else s.message(message);
|
||
},
|
||
stop(message) {
|
||
if (started) {
|
||
s.stop(message);
|
||
started = false;
|
||
}
|
||
}
|
||
};
|
||
}
|
||
separator() {
|
||
v.info("");
|
||
}
|
||
};
|
||
|
||
//#endregion
|
||
//#region src/prompter/headless-prompter.ts
|
||
var HeadlessPrompter = class {
|
||
answers;
|
||
logs = [];
|
||
constructor(answers = {}) {
|
||
this.answers = new Map(Object.entries(answers));
|
||
}
|
||
intro(message) {
|
||
this.logs.push(`[intro] ${message}`);
|
||
}
|
||
outro(message) {
|
||
this.logs.push(`[outro] ${message}`);
|
||
}
|
||
note(message, title) {
|
||
this.logs.push(`[note] ${title ?? ""}: ${message}`);
|
||
}
|
||
log(message) {
|
||
this.logs.push(`[log] ${message}`);
|
||
}
|
||
warn(message) {
|
||
this.logs.push(`[warn] ${message}`);
|
||
}
|
||
async text(opts) {
|
||
const answer = this.answers.get(opts.message);
|
||
const value = typeof answer === "string" ? answer : opts.defaultValue !== void 0 ? opts.defaultValue : void 0;
|
||
if (value === void 0) throw new Error(`HeadlessPrompter: no answer for "${opts.message}"`);
|
||
if (opts.validate) {
|
||
const error = opts.validate(value);
|
||
if (error) throw new Error(`HeadlessPrompter validation failed for "${opts.message}": ${error}`);
|
||
}
|
||
return value;
|
||
}
|
||
async confirm(opts) {
|
||
const answer = this.answers.get(opts.message);
|
||
if (typeof answer === "boolean") return answer;
|
||
return opts.initialValue ?? true;
|
||
}
|
||
async select(opts) {
|
||
const answer = this.answers.get(opts.message);
|
||
if (answer !== void 0) {
|
||
const match = opts.options.find((o) => String(o.value) === String(answer));
|
||
if (match) return match.value;
|
||
}
|
||
if (opts.initialValue !== void 0) return opts.initialValue;
|
||
if (opts.options.length === 0) throw new Error(`HeadlessPrompter: no options for "${opts.message}"`);
|
||
return opts.options[0].value;
|
||
}
|
||
async multiselect(opts) {
|
||
const answer = this.answers.get(opts.message);
|
||
if (Array.isArray(answer)) return opts.options.filter((o) => answer.includes(String(o.value))).map((o) => o.value);
|
||
return opts.options.filter((o) => o.selected).map((o) => o.value);
|
||
}
|
||
async groupMultiselect(opts) {
|
||
const answer = this.answers.get(opts.message);
|
||
if (Array.isArray(answer)) return Object.values(opts.options).flat().filter((o) => answer.includes(String(o.value))).map((o) => o.value);
|
||
return Object.values(opts.options).flat().filter((o) => o.selected).map((o) => o.value);
|
||
}
|
||
spinner() {
|
||
return {
|
||
update(_message) {},
|
||
stop(_message) {}
|
||
};
|
||
}
|
||
separator() {}
|
||
getLogs() {
|
||
return [...this.logs];
|
||
}
|
||
};
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js
|
||
var util;
|
||
(function(util) {
|
||
util.assertEqual = (_) => {};
|
||
function assertIs(_arg) {}
|
||
util.assertIs = assertIs;
|
||
function assertNever(_x) {
|
||
throw new Error();
|
||
}
|
||
util.assertNever = assertNever;
|
||
util.arrayToEnum = (items) => {
|
||
const obj = {};
|
||
for (const item of items) obj[item] = item;
|
||
return obj;
|
||
};
|
||
util.getValidEnumValues = (obj) => {
|
||
const validKeys = util.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
|
||
const filtered = {};
|
||
for (const k of validKeys) filtered[k] = obj[k];
|
||
return util.objectValues(filtered);
|
||
};
|
||
util.objectValues = (obj) => {
|
||
return util.objectKeys(obj).map(function(e) {
|
||
return obj[e];
|
||
});
|
||
};
|
||
util.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object) => {
|
||
const keys = [];
|
||
for (const key in object) if (Object.prototype.hasOwnProperty.call(object, key)) keys.push(key);
|
||
return keys;
|
||
};
|
||
util.find = (arr, checker) => {
|
||
for (const item of arr) if (checker(item)) return item;
|
||
};
|
||
util.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val;
|
||
function joinValues(array, separator = " | ") {
|
||
return array.map((val) => typeof val === "string" ? `'${val}'` : val).join(separator);
|
||
}
|
||
util.joinValues = joinValues;
|
||
util.jsonStringifyReplacer = (_, value) => {
|
||
if (typeof value === "bigint") return value.toString();
|
||
return value;
|
||
};
|
||
})(util || (util = {}));
|
||
var objectUtil;
|
||
(function(objectUtil) {
|
||
objectUtil.mergeShapes = (first, second) => {
|
||
return {
|
||
...first,
|
||
...second
|
||
};
|
||
};
|
||
})(objectUtil || (objectUtil = {}));
|
||
const ZodParsedType = util.arrayToEnum([
|
||
"string",
|
||
"nan",
|
||
"number",
|
||
"integer",
|
||
"float",
|
||
"boolean",
|
||
"date",
|
||
"bigint",
|
||
"symbol",
|
||
"function",
|
||
"undefined",
|
||
"null",
|
||
"array",
|
||
"object",
|
||
"unknown",
|
||
"promise",
|
||
"void",
|
||
"never",
|
||
"map",
|
||
"set"
|
||
]);
|
||
const getParsedType = (data) => {
|
||
switch (typeof data) {
|
||
case "undefined": return ZodParsedType.undefined;
|
||
case "string": return ZodParsedType.string;
|
||
case "number": return Number.isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;
|
||
case "boolean": return ZodParsedType.boolean;
|
||
case "function": return ZodParsedType.function;
|
||
case "bigint": return ZodParsedType.bigint;
|
||
case "symbol": return ZodParsedType.symbol;
|
||
case "object":
|
||
if (Array.isArray(data)) return ZodParsedType.array;
|
||
if (data === null) return ZodParsedType.null;
|
||
if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") return ZodParsedType.promise;
|
||
if (typeof Map !== "undefined" && data instanceof Map) return ZodParsedType.map;
|
||
if (typeof Set !== "undefined" && data instanceof Set) return ZodParsedType.set;
|
||
if (typeof Date !== "undefined" && data instanceof Date) return ZodParsedType.date;
|
||
return ZodParsedType.object;
|
||
default: return ZodParsedType.unknown;
|
||
}
|
||
};
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js
|
||
const ZodIssueCode = util.arrayToEnum([
|
||
"invalid_type",
|
||
"invalid_literal",
|
||
"custom",
|
||
"invalid_union",
|
||
"invalid_union_discriminator",
|
||
"invalid_enum_value",
|
||
"unrecognized_keys",
|
||
"invalid_arguments",
|
||
"invalid_return_type",
|
||
"invalid_date",
|
||
"invalid_string",
|
||
"too_small",
|
||
"too_big",
|
||
"invalid_intersection_types",
|
||
"not_multiple_of",
|
||
"not_finite"
|
||
]);
|
||
var ZodError = class ZodError extends Error {
|
||
get errors() {
|
||
return this.issues;
|
||
}
|
||
constructor(issues) {
|
||
super();
|
||
this.issues = [];
|
||
this.addIssue = (sub) => {
|
||
this.issues = [...this.issues, sub];
|
||
};
|
||
this.addIssues = (subs = []) => {
|
||
this.issues = [...this.issues, ...subs];
|
||
};
|
||
const actualProto = new.target.prototype;
|
||
if (Object.setPrototypeOf) Object.setPrototypeOf(this, actualProto);
|
||
else this.__proto__ = actualProto;
|
||
this.name = "ZodError";
|
||
this.issues = issues;
|
||
}
|
||
format(_mapper) {
|
||
const mapper = _mapper || function(issue) {
|
||
return issue.message;
|
||
};
|
||
const fieldErrors = { _errors: [] };
|
||
const processError = (error) => {
|
||
for (const issue of error.issues) if (issue.code === "invalid_union") issue.unionErrors.map(processError);
|
||
else if (issue.code === "invalid_return_type") processError(issue.returnTypeError);
|
||
else if (issue.code === "invalid_arguments") processError(issue.argumentsError);
|
||
else if (issue.path.length === 0) fieldErrors._errors.push(mapper(issue));
|
||
else {
|
||
let curr = fieldErrors;
|
||
let i = 0;
|
||
while (i < issue.path.length) {
|
||
const el = issue.path[i];
|
||
if (!(i === issue.path.length - 1)) curr[el] = curr[el] || { _errors: [] };
|
||
else {
|
||
curr[el] = curr[el] || { _errors: [] };
|
||
curr[el]._errors.push(mapper(issue));
|
||
}
|
||
curr = curr[el];
|
||
i++;
|
||
}
|
||
}
|
||
};
|
||
processError(this);
|
||
return fieldErrors;
|
||
}
|
||
static assert(value) {
|
||
if (!(value instanceof ZodError)) throw new Error(`Not a ZodError: ${value}`);
|
||
}
|
||
toString() {
|
||
return this.message;
|
||
}
|
||
get message() {
|
||
return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
|
||
}
|
||
get isEmpty() {
|
||
return this.issues.length === 0;
|
||
}
|
||
flatten(mapper = (issue) => issue.message) {
|
||
const fieldErrors = {};
|
||
const formErrors = [];
|
||
for (const sub of this.issues) if (sub.path.length > 0) {
|
||
const firstEl = sub.path[0];
|
||
fieldErrors[firstEl] = fieldErrors[firstEl] || [];
|
||
fieldErrors[firstEl].push(mapper(sub));
|
||
} else formErrors.push(mapper(sub));
|
||
return {
|
||
formErrors,
|
||
fieldErrors
|
||
};
|
||
}
|
||
get formErrors() {
|
||
return this.flatten();
|
||
}
|
||
};
|
||
ZodError.create = (issues) => {
|
||
return new ZodError(issues);
|
||
};
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js
|
||
const errorMap = (issue, _ctx) => {
|
||
let message;
|
||
switch (issue.code) {
|
||
case ZodIssueCode.invalid_type:
|
||
if (issue.received === ZodParsedType.undefined) message = "Required";
|
||
else message = `Expected ${issue.expected}, received ${issue.received}`;
|
||
break;
|
||
case ZodIssueCode.invalid_literal:
|
||
message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`;
|
||
break;
|
||
case ZodIssueCode.unrecognized_keys:
|
||
message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`;
|
||
break;
|
||
case ZodIssueCode.invalid_union:
|
||
message = `Invalid input`;
|
||
break;
|
||
case ZodIssueCode.invalid_union_discriminator:
|
||
message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;
|
||
break;
|
||
case ZodIssueCode.invalid_enum_value:
|
||
message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`;
|
||
break;
|
||
case ZodIssueCode.invalid_arguments:
|
||
message = `Invalid function arguments`;
|
||
break;
|
||
case ZodIssueCode.invalid_return_type:
|
||
message = `Invalid function return type`;
|
||
break;
|
||
case ZodIssueCode.invalid_date:
|
||
message = `Invalid date`;
|
||
break;
|
||
case ZodIssueCode.invalid_string:
|
||
if (typeof issue.validation === "object") if ("includes" in issue.validation) {
|
||
message = `Invalid input: must include "${issue.validation.includes}"`;
|
||
if (typeof issue.validation.position === "number") message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;
|
||
} else if ("startsWith" in issue.validation) message = `Invalid input: must start with "${issue.validation.startsWith}"`;
|
||
else if ("endsWith" in issue.validation) message = `Invalid input: must end with "${issue.validation.endsWith}"`;
|
||
else util.assertNever(issue.validation);
|
||
else if (issue.validation !== "regex") message = `Invalid ${issue.validation}`;
|
||
else message = "Invalid";
|
||
break;
|
||
case ZodIssueCode.too_small:
|
||
if (issue.type === "array") message = `Array must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;
|
||
else if (issue.type === "string") message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
|
||
else if (issue.type === "number") message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
|
||
else if (issue.type === "bigint") message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
|
||
else if (issue.type === "date") message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;
|
||
else message = "Invalid input";
|
||
break;
|
||
case ZodIssueCode.too_big:
|
||
if (issue.type === "array") message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;
|
||
else if (issue.type === "string") message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
|
||
else if (issue.type === "number") message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
|
||
else if (issue.type === "bigint") message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
|
||
else if (issue.type === "date") message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`;
|
||
else message = "Invalid input";
|
||
break;
|
||
case ZodIssueCode.custom:
|
||
message = `Invalid input`;
|
||
break;
|
||
case ZodIssueCode.invalid_intersection_types:
|
||
message = `Intersection results could not be merged`;
|
||
break;
|
||
case ZodIssueCode.not_multiple_of:
|
||
message = `Number must be a multiple of ${issue.multipleOf}`;
|
||
break;
|
||
case ZodIssueCode.not_finite:
|
||
message = "Number must be finite";
|
||
break;
|
||
default:
|
||
message = _ctx.defaultError;
|
||
util.assertNever(issue);
|
||
}
|
||
return { message };
|
||
};
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js
|
||
let overrideErrorMap = errorMap;
|
||
function getErrorMap() {
|
||
return overrideErrorMap;
|
||
}
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
|
||
const makeIssue = (params) => {
|
||
const { data, path, errorMaps, issueData } = params;
|
||
const fullPath = [...path, ...issueData.path || []];
|
||
const fullIssue = {
|
||
...issueData,
|
||
path: fullPath
|
||
};
|
||
if (issueData.message !== void 0) return {
|
||
...issueData,
|
||
path: fullPath,
|
||
message: issueData.message
|
||
};
|
||
let errorMessage = "";
|
||
const maps = errorMaps.filter((m) => !!m).slice().reverse();
|
||
for (const map of maps) errorMessage = map(fullIssue, {
|
||
data,
|
||
defaultError: errorMessage
|
||
}).message;
|
||
return {
|
||
...issueData,
|
||
path: fullPath,
|
||
message: errorMessage
|
||
};
|
||
};
|
||
function addIssueToContext(ctx, issueData) {
|
||
const overrideMap = getErrorMap();
|
||
const issue = makeIssue({
|
||
issueData,
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
errorMaps: [
|
||
ctx.common.contextualErrorMap,
|
||
ctx.schemaErrorMap,
|
||
overrideMap,
|
||
overrideMap === errorMap ? void 0 : errorMap
|
||
].filter((x) => !!x)
|
||
});
|
||
ctx.common.issues.push(issue);
|
||
}
|
||
var ParseStatus = class ParseStatus {
|
||
constructor() {
|
||
this.value = "valid";
|
||
}
|
||
dirty() {
|
||
if (this.value === "valid") this.value = "dirty";
|
||
}
|
||
abort() {
|
||
if (this.value !== "aborted") this.value = "aborted";
|
||
}
|
||
static mergeArray(status, results) {
|
||
const arrayValue = [];
|
||
for (const s of results) {
|
||
if (s.status === "aborted") return INVALID;
|
||
if (s.status === "dirty") status.dirty();
|
||
arrayValue.push(s.value);
|
||
}
|
||
return {
|
||
status: status.value,
|
||
value: arrayValue
|
||
};
|
||
}
|
||
static async mergeObjectAsync(status, pairs) {
|
||
const syncPairs = [];
|
||
for (const pair of pairs) {
|
||
const key = await pair.key;
|
||
const value = await pair.value;
|
||
syncPairs.push({
|
||
key,
|
||
value
|
||
});
|
||
}
|
||
return ParseStatus.mergeObjectSync(status, syncPairs);
|
||
}
|
||
static mergeObjectSync(status, pairs) {
|
||
const finalObject = {};
|
||
for (const pair of pairs) {
|
||
const { key, value } = pair;
|
||
if (key.status === "aborted") return INVALID;
|
||
if (value.status === "aborted") return INVALID;
|
||
if (key.status === "dirty") status.dirty();
|
||
if (value.status === "dirty") status.dirty();
|
||
if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) finalObject[key.value] = value.value;
|
||
}
|
||
return {
|
||
status: status.value,
|
||
value: finalObject
|
||
};
|
||
}
|
||
};
|
||
const INVALID = Object.freeze({ status: "aborted" });
|
||
const DIRTY = (value) => ({
|
||
status: "dirty",
|
||
value
|
||
});
|
||
const OK = (value) => ({
|
||
status: "valid",
|
||
value
|
||
});
|
||
const isAborted = (x) => x.status === "aborted";
|
||
const isDirty = (x) => x.status === "dirty";
|
||
const isValid = (x) => x.status === "valid";
|
||
const isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
|
||
var errorUtil;
|
||
(function(errorUtil) {
|
||
errorUtil.errToObj = (message) => typeof message === "string" ? { message } : message || {};
|
||
errorUtil.toString = (message) => typeof message === "string" ? message : message?.message;
|
||
})(errorUtil || (errorUtil = {}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
|
||
var ParseInputLazyPath = class {
|
||
constructor(parent, value, path, key) {
|
||
this._cachedPath = [];
|
||
this.parent = parent;
|
||
this.data = value;
|
||
this._path = path;
|
||
this._key = key;
|
||
}
|
||
get path() {
|
||
if (!this._cachedPath.length) if (Array.isArray(this._key)) this._cachedPath.push(...this._path, ...this._key);
|
||
else this._cachedPath.push(...this._path, this._key);
|
||
return this._cachedPath;
|
||
}
|
||
};
|
||
const handleResult = (ctx, result) => {
|
||
if (isValid(result)) return {
|
||
success: true,
|
||
data: result.value
|
||
};
|
||
else {
|
||
if (!ctx.common.issues.length) throw new Error("Validation failed but no issues detected.");
|
||
return {
|
||
success: false,
|
||
get error() {
|
||
if (this._error) return this._error;
|
||
this._error = new ZodError(ctx.common.issues);
|
||
return this._error;
|
||
}
|
||
};
|
||
}
|
||
};
|
||
function processCreateParams(params) {
|
||
if (!params) return {};
|
||
const { errorMap, invalid_type_error, required_error, description } = params;
|
||
if (errorMap && (invalid_type_error || required_error)) throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);
|
||
if (errorMap) return {
|
||
errorMap,
|
||
description
|
||
};
|
||
const customMap = (iss, ctx) => {
|
||
const { message } = params;
|
||
if (iss.code === "invalid_enum_value") return { message: message ?? ctx.defaultError };
|
||
if (typeof ctx.data === "undefined") return { message: message ?? required_error ?? ctx.defaultError };
|
||
if (iss.code !== "invalid_type") return { message: ctx.defaultError };
|
||
return { message: message ?? invalid_type_error ?? ctx.defaultError };
|
||
};
|
||
return {
|
||
errorMap: customMap,
|
||
description
|
||
};
|
||
}
|
||
var ZodType = class {
|
||
get description() {
|
||
return this._def.description;
|
||
}
|
||
_getType(input) {
|
||
return getParsedType(input.data);
|
||
}
|
||
_getOrReturnCtx(input, ctx) {
|
||
return ctx || {
|
||
common: input.parent.common,
|
||
data: input.data,
|
||
parsedType: getParsedType(input.data),
|
||
schemaErrorMap: this._def.errorMap,
|
||
path: input.path,
|
||
parent: input.parent
|
||
};
|
||
}
|
||
_processInputParams(input) {
|
||
return {
|
||
status: new ParseStatus(),
|
||
ctx: {
|
||
common: input.parent.common,
|
||
data: input.data,
|
||
parsedType: getParsedType(input.data),
|
||
schemaErrorMap: this._def.errorMap,
|
||
path: input.path,
|
||
parent: input.parent
|
||
}
|
||
};
|
||
}
|
||
_parseSync(input) {
|
||
const result = this._parse(input);
|
||
if (isAsync(result)) throw new Error("Synchronous parse encountered promise.");
|
||
return result;
|
||
}
|
||
_parseAsync(input) {
|
||
const result = this._parse(input);
|
||
return Promise.resolve(result);
|
||
}
|
||
parse(data, params) {
|
||
const result = this.safeParse(data, params);
|
||
if (result.success) return result.data;
|
||
throw result.error;
|
||
}
|
||
safeParse(data, params) {
|
||
const ctx = {
|
||
common: {
|
||
issues: [],
|
||
async: params?.async ?? false,
|
||
contextualErrorMap: params?.errorMap
|
||
},
|
||
path: params?.path || [],
|
||
schemaErrorMap: this._def.errorMap,
|
||
parent: null,
|
||
data,
|
||
parsedType: getParsedType(data)
|
||
};
|
||
return handleResult(ctx, this._parseSync({
|
||
data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
}));
|
||
}
|
||
"~validate"(data) {
|
||
const ctx = {
|
||
common: {
|
||
issues: [],
|
||
async: !!this["~standard"].async
|
||
},
|
||
path: [],
|
||
schemaErrorMap: this._def.errorMap,
|
||
parent: null,
|
||
data,
|
||
parsedType: getParsedType(data)
|
||
};
|
||
if (!this["~standard"].async) try {
|
||
const result = this._parseSync({
|
||
data,
|
||
path: [],
|
||
parent: ctx
|
||
});
|
||
return isValid(result) ? { value: result.value } : { issues: ctx.common.issues };
|
||
} catch (err) {
|
||
if (err?.message?.toLowerCase()?.includes("encountered")) this["~standard"].async = true;
|
||
ctx.common = {
|
||
issues: [],
|
||
async: true
|
||
};
|
||
}
|
||
return this._parseAsync({
|
||
data,
|
||
path: [],
|
||
parent: ctx
|
||
}).then((result) => isValid(result) ? { value: result.value } : { issues: ctx.common.issues });
|
||
}
|
||
async parseAsync(data, params) {
|
||
const result = await this.safeParseAsync(data, params);
|
||
if (result.success) return result.data;
|
||
throw result.error;
|
||
}
|
||
async safeParseAsync(data, params) {
|
||
const ctx = {
|
||
common: {
|
||
issues: [],
|
||
contextualErrorMap: params?.errorMap,
|
||
async: true
|
||
},
|
||
path: params?.path || [],
|
||
schemaErrorMap: this._def.errorMap,
|
||
parent: null,
|
||
data,
|
||
parsedType: getParsedType(data)
|
||
};
|
||
const maybeAsyncResult = this._parse({
|
||
data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
return handleResult(ctx, await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult)));
|
||
}
|
||
refine(check, message) {
|
||
const getIssueProperties = (val) => {
|
||
if (typeof message === "string" || typeof message === "undefined") return { message };
|
||
else if (typeof message === "function") return message(val);
|
||
else return message;
|
||
};
|
||
return this._refinement((val, ctx) => {
|
||
const result = check(val);
|
||
const setError = () => ctx.addIssue({
|
||
code: ZodIssueCode.custom,
|
||
...getIssueProperties(val)
|
||
});
|
||
if (typeof Promise !== "undefined" && result instanceof Promise) return result.then((data) => {
|
||
if (!data) {
|
||
setError();
|
||
return false;
|
||
} else return true;
|
||
});
|
||
if (!result) {
|
||
setError();
|
||
return false;
|
||
} else return true;
|
||
});
|
||
}
|
||
refinement(check, refinementData) {
|
||
return this._refinement((val, ctx) => {
|
||
if (!check(val)) {
|
||
ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData);
|
||
return false;
|
||
} else return true;
|
||
});
|
||
}
|
||
_refinement(refinement) {
|
||
return new ZodEffects({
|
||
schema: this,
|
||
typeName: ZodFirstPartyTypeKind.ZodEffects,
|
||
effect: {
|
||
type: "refinement",
|
||
refinement
|
||
}
|
||
});
|
||
}
|
||
superRefine(refinement) {
|
||
return this._refinement(refinement);
|
||
}
|
||
constructor(def) {
|
||
/** Alias of safeParseAsync */
|
||
this.spa = this.safeParseAsync;
|
||
this._def = def;
|
||
this.parse = this.parse.bind(this);
|
||
this.safeParse = this.safeParse.bind(this);
|
||
this.parseAsync = this.parseAsync.bind(this);
|
||
this.safeParseAsync = this.safeParseAsync.bind(this);
|
||
this.spa = this.spa.bind(this);
|
||
this.refine = this.refine.bind(this);
|
||
this.refinement = this.refinement.bind(this);
|
||
this.superRefine = this.superRefine.bind(this);
|
||
this.optional = this.optional.bind(this);
|
||
this.nullable = this.nullable.bind(this);
|
||
this.nullish = this.nullish.bind(this);
|
||
this.array = this.array.bind(this);
|
||
this.promise = this.promise.bind(this);
|
||
this.or = this.or.bind(this);
|
||
this.and = this.and.bind(this);
|
||
this.transform = this.transform.bind(this);
|
||
this.brand = this.brand.bind(this);
|
||
this.default = this.default.bind(this);
|
||
this.catch = this.catch.bind(this);
|
||
this.describe = this.describe.bind(this);
|
||
this.pipe = this.pipe.bind(this);
|
||
this.readonly = this.readonly.bind(this);
|
||
this.isNullable = this.isNullable.bind(this);
|
||
this.isOptional = this.isOptional.bind(this);
|
||
this["~standard"] = {
|
||
version: 1,
|
||
vendor: "zod",
|
||
validate: (data) => this["~validate"](data)
|
||
};
|
||
}
|
||
optional() {
|
||
return ZodOptional.create(this, this._def);
|
||
}
|
||
nullable() {
|
||
return ZodNullable.create(this, this._def);
|
||
}
|
||
nullish() {
|
||
return this.nullable().optional();
|
||
}
|
||
array() {
|
||
return ZodArray.create(this);
|
||
}
|
||
promise() {
|
||
return ZodPromise.create(this, this._def);
|
||
}
|
||
or(option) {
|
||
return ZodUnion.create([this, option], this._def);
|
||
}
|
||
and(incoming) {
|
||
return ZodIntersection.create(this, incoming, this._def);
|
||
}
|
||
transform(transform) {
|
||
return new ZodEffects({
|
||
...processCreateParams(this._def),
|
||
schema: this,
|
||
typeName: ZodFirstPartyTypeKind.ZodEffects,
|
||
effect: {
|
||
type: "transform",
|
||
transform
|
||
}
|
||
});
|
||
}
|
||
default(def) {
|
||
const defaultValueFunc = typeof def === "function" ? def : () => def;
|
||
return new ZodDefault({
|
||
...processCreateParams(this._def),
|
||
innerType: this,
|
||
defaultValue: defaultValueFunc,
|
||
typeName: ZodFirstPartyTypeKind.ZodDefault
|
||
});
|
||
}
|
||
brand() {
|
||
return new ZodBranded({
|
||
typeName: ZodFirstPartyTypeKind.ZodBranded,
|
||
type: this,
|
||
...processCreateParams(this._def)
|
||
});
|
||
}
|
||
catch(def) {
|
||
const catchValueFunc = typeof def === "function" ? def : () => def;
|
||
return new ZodCatch({
|
||
...processCreateParams(this._def),
|
||
innerType: this,
|
||
catchValue: catchValueFunc,
|
||
typeName: ZodFirstPartyTypeKind.ZodCatch
|
||
});
|
||
}
|
||
describe(description) {
|
||
const This = this.constructor;
|
||
return new This({
|
||
...this._def,
|
||
description
|
||
});
|
||
}
|
||
pipe(target) {
|
||
return ZodPipeline.create(this, target);
|
||
}
|
||
readonly() {
|
||
return ZodReadonly.create(this);
|
||
}
|
||
isOptional() {
|
||
return this.safeParse(void 0).success;
|
||
}
|
||
isNullable() {
|
||
return this.safeParse(null).success;
|
||
}
|
||
};
|
||
const cuidRegex = /^c[^\s-]{8,}$/i;
|
||
const cuid2Regex = /^[0-9a-z]+$/;
|
||
const ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i;
|
||
const uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i;
|
||
const nanoidRegex = /^[a-z0-9_-]{21}$/i;
|
||
const jwtRegex = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/;
|
||
const durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/;
|
||
const emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;
|
||
const _emojiRegex = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
|
||
let emojiRegex;
|
||
const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
|
||
const ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/;
|
||
const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
|
||
const ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
|
||
const base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
|
||
const base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/;
|
||
const dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`;
|
||
const dateRegex = new RegExp(`^${dateRegexSource}$`);
|
||
function timeRegexSource(args) {
|
||
let secondsRegexSource = `[0-5]\\d`;
|
||
if (args.precision) secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`;
|
||
else if (args.precision == null) secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`;
|
||
const secondsQuantifier = args.precision ? "+" : "?";
|
||
return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`;
|
||
}
|
||
function timeRegex(args) {
|
||
return new RegExp(`^${timeRegexSource(args)}$`);
|
||
}
|
||
function datetimeRegex(args) {
|
||
let regex = `${dateRegexSource}T${timeRegexSource(args)}`;
|
||
const opts = [];
|
||
opts.push(args.local ? `Z?` : `Z`);
|
||
if (args.offset) opts.push(`([+-]\\d{2}:?\\d{2})`);
|
||
regex = `${regex}(${opts.join("|")})`;
|
||
return new RegExp(`^${regex}$`);
|
||
}
|
||
function isValidIP(ip, version) {
|
||
if ((version === "v4" || !version) && ipv4Regex.test(ip)) return true;
|
||
if ((version === "v6" || !version) && ipv6Regex.test(ip)) return true;
|
||
return false;
|
||
}
|
||
function isValidJWT(jwt, alg) {
|
||
if (!jwtRegex.test(jwt)) return false;
|
||
try {
|
||
const [header] = jwt.split(".");
|
||
if (!header) return false;
|
||
const base64 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "=");
|
||
const decoded = JSON.parse(atob(base64));
|
||
if (typeof decoded !== "object" || decoded === null) return false;
|
||
if ("typ" in decoded && decoded?.typ !== "JWT") return false;
|
||
if (!decoded.alg) return false;
|
||
if (alg && decoded.alg !== alg) return false;
|
||
return true;
|
||
} catch {
|
||
return false;
|
||
}
|
||
}
|
||
function isValidCidr(ip, version) {
|
||
if ((version === "v4" || !version) && ipv4CidrRegex.test(ip)) return true;
|
||
if ((version === "v6" || !version) && ipv6CidrRegex.test(ip)) return true;
|
||
return false;
|
||
}
|
||
var ZodString = class ZodString extends ZodType {
|
||
_parse(input) {
|
||
if (this._def.coerce) input.data = String(input.data);
|
||
if (this._getType(input) !== ZodParsedType.string) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.string,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
const status = new ParseStatus();
|
||
let ctx = void 0;
|
||
for (const check of this._def.checks) if (check.kind === "min") {
|
||
if (input.data.length < check.value) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_small,
|
||
minimum: check.value,
|
||
type: "string",
|
||
inclusive: true,
|
||
exact: false,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "max") {
|
||
if (input.data.length > check.value) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_big,
|
||
maximum: check.value,
|
||
type: "string",
|
||
inclusive: true,
|
||
exact: false,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "length") {
|
||
const tooBig = input.data.length > check.value;
|
||
const tooSmall = input.data.length < check.value;
|
||
if (tooBig || tooSmall) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
if (tooBig) addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_big,
|
||
maximum: check.value,
|
||
type: "string",
|
||
inclusive: true,
|
||
exact: true,
|
||
message: check.message
|
||
});
|
||
else if (tooSmall) addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_small,
|
||
minimum: check.value,
|
||
type: "string",
|
||
inclusive: true,
|
||
exact: true,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "email") {
|
||
if (!emailRegex.test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "email",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "emoji") {
|
||
if (!emojiRegex) emojiRegex = new RegExp(_emojiRegex, "u");
|
||
if (!emojiRegex.test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "emoji",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "uuid") {
|
||
if (!uuidRegex.test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "uuid",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "nanoid") {
|
||
if (!nanoidRegex.test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "nanoid",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "cuid") {
|
||
if (!cuidRegex.test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "cuid",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "cuid2") {
|
||
if (!cuid2Regex.test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "cuid2",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "ulid") {
|
||
if (!ulidRegex.test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "ulid",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "url") try {
|
||
new URL(input.data);
|
||
} catch {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "url",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
else if (check.kind === "regex") {
|
||
check.regex.lastIndex = 0;
|
||
if (!check.regex.test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "regex",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "trim") input.data = input.data.trim();
|
||
else if (check.kind === "includes") {
|
||
if (!input.data.includes(check.value, check.position)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_string,
|
||
validation: {
|
||
includes: check.value,
|
||
position: check.position
|
||
},
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "toLowerCase") input.data = input.data.toLowerCase();
|
||
else if (check.kind === "toUpperCase") input.data = input.data.toUpperCase();
|
||
else if (check.kind === "startsWith") {
|
||
if (!input.data.startsWith(check.value)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_string,
|
||
validation: { startsWith: check.value },
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "endsWith") {
|
||
if (!input.data.endsWith(check.value)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_string,
|
||
validation: { endsWith: check.value },
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "datetime") {
|
||
if (!datetimeRegex(check).test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_string,
|
||
validation: "datetime",
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "date") {
|
||
if (!dateRegex.test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_string,
|
||
validation: "date",
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "time") {
|
||
if (!timeRegex(check).test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_string,
|
||
validation: "time",
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "duration") {
|
||
if (!durationRegex.test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "duration",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "ip") {
|
||
if (!isValidIP(input.data, check.version)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "ip",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "jwt") {
|
||
if (!isValidJWT(input.data, check.alg)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "jwt",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "cidr") {
|
||
if (!isValidCidr(input.data, check.version)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "cidr",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "base64") {
|
||
if (!base64Regex.test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "base64",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "base64url") {
|
||
if (!base64urlRegex.test(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
validation: "base64url",
|
||
code: ZodIssueCode.invalid_string,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else util.assertNever(check);
|
||
return {
|
||
status: status.value,
|
||
value: input.data
|
||
};
|
||
}
|
||
_regex(regex, validation, message) {
|
||
return this.refinement((data) => regex.test(data), {
|
||
validation,
|
||
code: ZodIssueCode.invalid_string,
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
_addCheck(check) {
|
||
return new ZodString({
|
||
...this._def,
|
||
checks: [...this._def.checks, check]
|
||
});
|
||
}
|
||
email(message) {
|
||
return this._addCheck({
|
||
kind: "email",
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
url(message) {
|
||
return this._addCheck({
|
||
kind: "url",
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
emoji(message) {
|
||
return this._addCheck({
|
||
kind: "emoji",
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
uuid(message) {
|
||
return this._addCheck({
|
||
kind: "uuid",
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
nanoid(message) {
|
||
return this._addCheck({
|
||
kind: "nanoid",
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
cuid(message) {
|
||
return this._addCheck({
|
||
kind: "cuid",
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
cuid2(message) {
|
||
return this._addCheck({
|
||
kind: "cuid2",
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
ulid(message) {
|
||
return this._addCheck({
|
||
kind: "ulid",
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
base64(message) {
|
||
return this._addCheck({
|
||
kind: "base64",
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
base64url(message) {
|
||
return this._addCheck({
|
||
kind: "base64url",
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
jwt(options) {
|
||
return this._addCheck({
|
||
kind: "jwt",
|
||
...errorUtil.errToObj(options)
|
||
});
|
||
}
|
||
ip(options) {
|
||
return this._addCheck({
|
||
kind: "ip",
|
||
...errorUtil.errToObj(options)
|
||
});
|
||
}
|
||
cidr(options) {
|
||
return this._addCheck({
|
||
kind: "cidr",
|
||
...errorUtil.errToObj(options)
|
||
});
|
||
}
|
||
datetime(options) {
|
||
if (typeof options === "string") return this._addCheck({
|
||
kind: "datetime",
|
||
precision: null,
|
||
offset: false,
|
||
local: false,
|
||
message: options
|
||
});
|
||
return this._addCheck({
|
||
kind: "datetime",
|
||
precision: typeof options?.precision === "undefined" ? null : options?.precision,
|
||
offset: options?.offset ?? false,
|
||
local: options?.local ?? false,
|
||
...errorUtil.errToObj(options?.message)
|
||
});
|
||
}
|
||
date(message) {
|
||
return this._addCheck({
|
||
kind: "date",
|
||
message
|
||
});
|
||
}
|
||
time(options) {
|
||
if (typeof options === "string") return this._addCheck({
|
||
kind: "time",
|
||
precision: null,
|
||
message: options
|
||
});
|
||
return this._addCheck({
|
||
kind: "time",
|
||
precision: typeof options?.precision === "undefined" ? null : options?.precision,
|
||
...errorUtil.errToObj(options?.message)
|
||
});
|
||
}
|
||
duration(message) {
|
||
return this._addCheck({
|
||
kind: "duration",
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
regex(regex, message) {
|
||
return this._addCheck({
|
||
kind: "regex",
|
||
regex,
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
includes(value, options) {
|
||
return this._addCheck({
|
||
kind: "includes",
|
||
value,
|
||
position: options?.position,
|
||
...errorUtil.errToObj(options?.message)
|
||
});
|
||
}
|
||
startsWith(value, message) {
|
||
return this._addCheck({
|
||
kind: "startsWith",
|
||
value,
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
endsWith(value, message) {
|
||
return this._addCheck({
|
||
kind: "endsWith",
|
||
value,
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
min(minLength, message) {
|
||
return this._addCheck({
|
||
kind: "min",
|
||
value: minLength,
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
max(maxLength, message) {
|
||
return this._addCheck({
|
||
kind: "max",
|
||
value: maxLength,
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
length(len, message) {
|
||
return this._addCheck({
|
||
kind: "length",
|
||
value: len,
|
||
...errorUtil.errToObj(message)
|
||
});
|
||
}
|
||
/**
|
||
* Equivalent to `.min(1)`
|
||
*/
|
||
nonempty(message) {
|
||
return this.min(1, errorUtil.errToObj(message));
|
||
}
|
||
trim() {
|
||
return new ZodString({
|
||
...this._def,
|
||
checks: [...this._def.checks, { kind: "trim" }]
|
||
});
|
||
}
|
||
toLowerCase() {
|
||
return new ZodString({
|
||
...this._def,
|
||
checks: [...this._def.checks, { kind: "toLowerCase" }]
|
||
});
|
||
}
|
||
toUpperCase() {
|
||
return new ZodString({
|
||
...this._def,
|
||
checks: [...this._def.checks, { kind: "toUpperCase" }]
|
||
});
|
||
}
|
||
get isDatetime() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "datetime");
|
||
}
|
||
get isDate() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "date");
|
||
}
|
||
get isTime() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "time");
|
||
}
|
||
get isDuration() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "duration");
|
||
}
|
||
get isEmail() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "email");
|
||
}
|
||
get isURL() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "url");
|
||
}
|
||
get isEmoji() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "emoji");
|
||
}
|
||
get isUUID() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "uuid");
|
||
}
|
||
get isNANOID() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "nanoid");
|
||
}
|
||
get isCUID() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "cuid");
|
||
}
|
||
get isCUID2() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "cuid2");
|
||
}
|
||
get isULID() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "ulid");
|
||
}
|
||
get isIP() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "ip");
|
||
}
|
||
get isCIDR() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "cidr");
|
||
}
|
||
get isBase64() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "base64");
|
||
}
|
||
get isBase64url() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "base64url");
|
||
}
|
||
get minLength() {
|
||
let min = null;
|
||
for (const ch of this._def.checks) if (ch.kind === "min") {
|
||
if (min === null || ch.value > min) min = ch.value;
|
||
}
|
||
return min;
|
||
}
|
||
get maxLength() {
|
||
let max = null;
|
||
for (const ch of this._def.checks) if (ch.kind === "max") {
|
||
if (max === null || ch.value < max) max = ch.value;
|
||
}
|
||
return max;
|
||
}
|
||
};
|
||
ZodString.create = (params) => {
|
||
return new ZodString({
|
||
checks: [],
|
||
typeName: ZodFirstPartyTypeKind.ZodString,
|
||
coerce: params?.coerce ?? false,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
function floatSafeRemainder(val, step) {
|
||
const valDecCount = (val.toString().split(".")[1] || "").length;
|
||
const stepDecCount = (step.toString().split(".")[1] || "").length;
|
||
const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;
|
||
return Number.parseInt(val.toFixed(decCount).replace(".", "")) % Number.parseInt(step.toFixed(decCount).replace(".", "")) / 10 ** decCount;
|
||
}
|
||
var ZodNumber = class ZodNumber extends ZodType {
|
||
constructor() {
|
||
super(...arguments);
|
||
this.min = this.gte;
|
||
this.max = this.lte;
|
||
this.step = this.multipleOf;
|
||
}
|
||
_parse(input) {
|
||
if (this._def.coerce) input.data = Number(input.data);
|
||
if (this._getType(input) !== ZodParsedType.number) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.number,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
let ctx = void 0;
|
||
const status = new ParseStatus();
|
||
for (const check of this._def.checks) if (check.kind === "int") {
|
||
if (!util.isInteger(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: "integer",
|
||
received: "float",
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "min") {
|
||
if (check.inclusive ? input.data < check.value : input.data <= check.value) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_small,
|
||
minimum: check.value,
|
||
type: "number",
|
||
inclusive: check.inclusive,
|
||
exact: false,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "max") {
|
||
if (check.inclusive ? input.data > check.value : input.data >= check.value) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_big,
|
||
maximum: check.value,
|
||
type: "number",
|
||
inclusive: check.inclusive,
|
||
exact: false,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "multipleOf") {
|
||
if (floatSafeRemainder(input.data, check.value) !== 0) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.not_multiple_of,
|
||
multipleOf: check.value,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "finite") {
|
||
if (!Number.isFinite(input.data)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.not_finite,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else util.assertNever(check);
|
||
return {
|
||
status: status.value,
|
||
value: input.data
|
||
};
|
||
}
|
||
gte(value, message) {
|
||
return this.setLimit("min", value, true, errorUtil.toString(message));
|
||
}
|
||
gt(value, message) {
|
||
return this.setLimit("min", value, false, errorUtil.toString(message));
|
||
}
|
||
lte(value, message) {
|
||
return this.setLimit("max", value, true, errorUtil.toString(message));
|
||
}
|
||
lt(value, message) {
|
||
return this.setLimit("max", value, false, errorUtil.toString(message));
|
||
}
|
||
setLimit(kind, value, inclusive, message) {
|
||
return new ZodNumber({
|
||
...this._def,
|
||
checks: [...this._def.checks, {
|
||
kind,
|
||
value,
|
||
inclusive,
|
||
message: errorUtil.toString(message)
|
||
}]
|
||
});
|
||
}
|
||
_addCheck(check) {
|
||
return new ZodNumber({
|
||
...this._def,
|
||
checks: [...this._def.checks, check]
|
||
});
|
||
}
|
||
int(message) {
|
||
return this._addCheck({
|
||
kind: "int",
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
positive(message) {
|
||
return this._addCheck({
|
||
kind: "min",
|
||
value: 0,
|
||
inclusive: false,
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
negative(message) {
|
||
return this._addCheck({
|
||
kind: "max",
|
||
value: 0,
|
||
inclusive: false,
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
nonpositive(message) {
|
||
return this._addCheck({
|
||
kind: "max",
|
||
value: 0,
|
||
inclusive: true,
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
nonnegative(message) {
|
||
return this._addCheck({
|
||
kind: "min",
|
||
value: 0,
|
||
inclusive: true,
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
multipleOf(value, message) {
|
||
return this._addCheck({
|
||
kind: "multipleOf",
|
||
value,
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
finite(message) {
|
||
return this._addCheck({
|
||
kind: "finite",
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
safe(message) {
|
||
return this._addCheck({
|
||
kind: "min",
|
||
inclusive: true,
|
||
value: Number.MIN_SAFE_INTEGER,
|
||
message: errorUtil.toString(message)
|
||
})._addCheck({
|
||
kind: "max",
|
||
inclusive: true,
|
||
value: Number.MAX_SAFE_INTEGER,
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
get minValue() {
|
||
let min = null;
|
||
for (const ch of this._def.checks) if (ch.kind === "min") {
|
||
if (min === null || ch.value > min) min = ch.value;
|
||
}
|
||
return min;
|
||
}
|
||
get maxValue() {
|
||
let max = null;
|
||
for (const ch of this._def.checks) if (ch.kind === "max") {
|
||
if (max === null || ch.value < max) max = ch.value;
|
||
}
|
||
return max;
|
||
}
|
||
get isInt() {
|
||
return !!this._def.checks.find((ch) => ch.kind === "int" || ch.kind === "multipleOf" && util.isInteger(ch.value));
|
||
}
|
||
get isFinite() {
|
||
let max = null;
|
||
let min = null;
|
||
for (const ch of this._def.checks) if (ch.kind === "finite" || ch.kind === "int" || ch.kind === "multipleOf") return true;
|
||
else if (ch.kind === "min") {
|
||
if (min === null || ch.value > min) min = ch.value;
|
||
} else if (ch.kind === "max") {
|
||
if (max === null || ch.value < max) max = ch.value;
|
||
}
|
||
return Number.isFinite(min) && Number.isFinite(max);
|
||
}
|
||
};
|
||
ZodNumber.create = (params) => {
|
||
return new ZodNumber({
|
||
checks: [],
|
||
typeName: ZodFirstPartyTypeKind.ZodNumber,
|
||
coerce: params?.coerce || false,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodBigInt = class ZodBigInt extends ZodType {
|
||
constructor() {
|
||
super(...arguments);
|
||
this.min = this.gte;
|
||
this.max = this.lte;
|
||
}
|
||
_parse(input) {
|
||
if (this._def.coerce) try {
|
||
input.data = BigInt(input.data);
|
||
} catch {
|
||
return this._getInvalidInput(input);
|
||
}
|
||
if (this._getType(input) !== ZodParsedType.bigint) return this._getInvalidInput(input);
|
||
let ctx = void 0;
|
||
const status = new ParseStatus();
|
||
for (const check of this._def.checks) if (check.kind === "min") {
|
||
if (check.inclusive ? input.data < check.value : input.data <= check.value) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_small,
|
||
type: "bigint",
|
||
minimum: check.value,
|
||
inclusive: check.inclusive,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "max") {
|
||
if (check.inclusive ? input.data > check.value : input.data >= check.value) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_big,
|
||
type: "bigint",
|
||
maximum: check.value,
|
||
inclusive: check.inclusive,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "multipleOf") {
|
||
if (input.data % check.value !== BigInt(0)) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.not_multiple_of,
|
||
multipleOf: check.value,
|
||
message: check.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else util.assertNever(check);
|
||
return {
|
||
status: status.value,
|
||
value: input.data
|
||
};
|
||
}
|
||
_getInvalidInput(input) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.bigint,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
gte(value, message) {
|
||
return this.setLimit("min", value, true, errorUtil.toString(message));
|
||
}
|
||
gt(value, message) {
|
||
return this.setLimit("min", value, false, errorUtil.toString(message));
|
||
}
|
||
lte(value, message) {
|
||
return this.setLimit("max", value, true, errorUtil.toString(message));
|
||
}
|
||
lt(value, message) {
|
||
return this.setLimit("max", value, false, errorUtil.toString(message));
|
||
}
|
||
setLimit(kind, value, inclusive, message) {
|
||
return new ZodBigInt({
|
||
...this._def,
|
||
checks: [...this._def.checks, {
|
||
kind,
|
||
value,
|
||
inclusive,
|
||
message: errorUtil.toString(message)
|
||
}]
|
||
});
|
||
}
|
||
_addCheck(check) {
|
||
return new ZodBigInt({
|
||
...this._def,
|
||
checks: [...this._def.checks, check]
|
||
});
|
||
}
|
||
positive(message) {
|
||
return this._addCheck({
|
||
kind: "min",
|
||
value: BigInt(0),
|
||
inclusive: false,
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
negative(message) {
|
||
return this._addCheck({
|
||
kind: "max",
|
||
value: BigInt(0),
|
||
inclusive: false,
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
nonpositive(message) {
|
||
return this._addCheck({
|
||
kind: "max",
|
||
value: BigInt(0),
|
||
inclusive: true,
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
nonnegative(message) {
|
||
return this._addCheck({
|
||
kind: "min",
|
||
value: BigInt(0),
|
||
inclusive: true,
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
multipleOf(value, message) {
|
||
return this._addCheck({
|
||
kind: "multipleOf",
|
||
value,
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
get minValue() {
|
||
let min = null;
|
||
for (const ch of this._def.checks) if (ch.kind === "min") {
|
||
if (min === null || ch.value > min) min = ch.value;
|
||
}
|
||
return min;
|
||
}
|
||
get maxValue() {
|
||
let max = null;
|
||
for (const ch of this._def.checks) if (ch.kind === "max") {
|
||
if (max === null || ch.value < max) max = ch.value;
|
||
}
|
||
return max;
|
||
}
|
||
};
|
||
ZodBigInt.create = (params) => {
|
||
return new ZodBigInt({
|
||
checks: [],
|
||
typeName: ZodFirstPartyTypeKind.ZodBigInt,
|
||
coerce: params?.coerce ?? false,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodBoolean = class extends ZodType {
|
||
_parse(input) {
|
||
if (this._def.coerce) input.data = Boolean(input.data);
|
||
if (this._getType(input) !== ZodParsedType.boolean) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.boolean,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
return OK(input.data);
|
||
}
|
||
};
|
||
ZodBoolean.create = (params) => {
|
||
return new ZodBoolean({
|
||
typeName: ZodFirstPartyTypeKind.ZodBoolean,
|
||
coerce: params?.coerce || false,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodDate = class ZodDate extends ZodType {
|
||
_parse(input) {
|
||
if (this._def.coerce) input.data = new Date(input.data);
|
||
if (this._getType(input) !== ZodParsedType.date) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.date,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
if (Number.isNaN(input.data.getTime())) {
|
||
addIssueToContext(this._getOrReturnCtx(input), { code: ZodIssueCode.invalid_date });
|
||
return INVALID;
|
||
}
|
||
const status = new ParseStatus();
|
||
let ctx = void 0;
|
||
for (const check of this._def.checks) if (check.kind === "min") {
|
||
if (input.data.getTime() < check.value) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_small,
|
||
message: check.message,
|
||
inclusive: true,
|
||
exact: false,
|
||
minimum: check.value,
|
||
type: "date"
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (check.kind === "max") {
|
||
if (input.data.getTime() > check.value) {
|
||
ctx = this._getOrReturnCtx(input, ctx);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_big,
|
||
message: check.message,
|
||
inclusive: true,
|
||
exact: false,
|
||
maximum: check.value,
|
||
type: "date"
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else util.assertNever(check);
|
||
return {
|
||
status: status.value,
|
||
value: new Date(input.data.getTime())
|
||
};
|
||
}
|
||
_addCheck(check) {
|
||
return new ZodDate({
|
||
...this._def,
|
||
checks: [...this._def.checks, check]
|
||
});
|
||
}
|
||
min(minDate, message) {
|
||
return this._addCheck({
|
||
kind: "min",
|
||
value: minDate.getTime(),
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
max(maxDate, message) {
|
||
return this._addCheck({
|
||
kind: "max",
|
||
value: maxDate.getTime(),
|
||
message: errorUtil.toString(message)
|
||
});
|
||
}
|
||
get minDate() {
|
||
let min = null;
|
||
for (const ch of this._def.checks) if (ch.kind === "min") {
|
||
if (min === null || ch.value > min) min = ch.value;
|
||
}
|
||
return min != null ? new Date(min) : null;
|
||
}
|
||
get maxDate() {
|
||
let max = null;
|
||
for (const ch of this._def.checks) if (ch.kind === "max") {
|
||
if (max === null || ch.value < max) max = ch.value;
|
||
}
|
||
return max != null ? new Date(max) : null;
|
||
}
|
||
};
|
||
ZodDate.create = (params) => {
|
||
return new ZodDate({
|
||
checks: [],
|
||
coerce: params?.coerce || false,
|
||
typeName: ZodFirstPartyTypeKind.ZodDate,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodSymbol = class extends ZodType {
|
||
_parse(input) {
|
||
if (this._getType(input) !== ZodParsedType.symbol) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.symbol,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
return OK(input.data);
|
||
}
|
||
};
|
||
ZodSymbol.create = (params) => {
|
||
return new ZodSymbol({
|
||
typeName: ZodFirstPartyTypeKind.ZodSymbol,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodUndefined = class extends ZodType {
|
||
_parse(input) {
|
||
if (this._getType(input) !== ZodParsedType.undefined) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.undefined,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
return OK(input.data);
|
||
}
|
||
};
|
||
ZodUndefined.create = (params) => {
|
||
return new ZodUndefined({
|
||
typeName: ZodFirstPartyTypeKind.ZodUndefined,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodNull = class extends ZodType {
|
||
_parse(input) {
|
||
if (this._getType(input) !== ZodParsedType.null) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.null,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
return OK(input.data);
|
||
}
|
||
};
|
||
ZodNull.create = (params) => {
|
||
return new ZodNull({
|
||
typeName: ZodFirstPartyTypeKind.ZodNull,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodAny = class extends ZodType {
|
||
constructor() {
|
||
super(...arguments);
|
||
this._any = true;
|
||
}
|
||
_parse(input) {
|
||
return OK(input.data);
|
||
}
|
||
};
|
||
ZodAny.create = (params) => {
|
||
return new ZodAny({
|
||
typeName: ZodFirstPartyTypeKind.ZodAny,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodUnknown = class extends ZodType {
|
||
constructor() {
|
||
super(...arguments);
|
||
this._unknown = true;
|
||
}
|
||
_parse(input) {
|
||
return OK(input.data);
|
||
}
|
||
};
|
||
ZodUnknown.create = (params) => {
|
||
return new ZodUnknown({
|
||
typeName: ZodFirstPartyTypeKind.ZodUnknown,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodNever = class extends ZodType {
|
||
_parse(input) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.never,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
};
|
||
ZodNever.create = (params) => {
|
||
return new ZodNever({
|
||
typeName: ZodFirstPartyTypeKind.ZodNever,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodVoid = class extends ZodType {
|
||
_parse(input) {
|
||
if (this._getType(input) !== ZodParsedType.undefined) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.void,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
return OK(input.data);
|
||
}
|
||
};
|
||
ZodVoid.create = (params) => {
|
||
return new ZodVoid({
|
||
typeName: ZodFirstPartyTypeKind.ZodVoid,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodArray = class ZodArray extends ZodType {
|
||
_parse(input) {
|
||
const { ctx, status } = this._processInputParams(input);
|
||
const def = this._def;
|
||
if (ctx.parsedType !== ZodParsedType.array) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.array,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
if (def.exactLength !== null) {
|
||
const tooBig = ctx.data.length > def.exactLength.value;
|
||
const tooSmall = ctx.data.length < def.exactLength.value;
|
||
if (tooBig || tooSmall) {
|
||
addIssueToContext(ctx, {
|
||
code: tooBig ? ZodIssueCode.too_big : ZodIssueCode.too_small,
|
||
minimum: tooSmall ? def.exactLength.value : void 0,
|
||
maximum: tooBig ? def.exactLength.value : void 0,
|
||
type: "array",
|
||
inclusive: true,
|
||
exact: true,
|
||
message: def.exactLength.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
}
|
||
if (def.minLength !== null) {
|
||
if (ctx.data.length < def.minLength.value) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_small,
|
||
minimum: def.minLength.value,
|
||
type: "array",
|
||
inclusive: true,
|
||
exact: false,
|
||
message: def.minLength.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
}
|
||
if (def.maxLength !== null) {
|
||
if (ctx.data.length > def.maxLength.value) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_big,
|
||
maximum: def.maxLength.value,
|
||
type: "array",
|
||
inclusive: true,
|
||
exact: false,
|
||
message: def.maxLength.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
}
|
||
if (ctx.common.async) return Promise.all([...ctx.data].map((item, i) => {
|
||
return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));
|
||
})).then((result) => {
|
||
return ParseStatus.mergeArray(status, result);
|
||
});
|
||
const result = [...ctx.data].map((item, i) => {
|
||
return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));
|
||
});
|
||
return ParseStatus.mergeArray(status, result);
|
||
}
|
||
get element() {
|
||
return this._def.type;
|
||
}
|
||
min(minLength, message) {
|
||
return new ZodArray({
|
||
...this._def,
|
||
minLength: {
|
||
value: minLength,
|
||
message: errorUtil.toString(message)
|
||
}
|
||
});
|
||
}
|
||
max(maxLength, message) {
|
||
return new ZodArray({
|
||
...this._def,
|
||
maxLength: {
|
||
value: maxLength,
|
||
message: errorUtil.toString(message)
|
||
}
|
||
});
|
||
}
|
||
length(len, message) {
|
||
return new ZodArray({
|
||
...this._def,
|
||
exactLength: {
|
||
value: len,
|
||
message: errorUtil.toString(message)
|
||
}
|
||
});
|
||
}
|
||
nonempty(message) {
|
||
return this.min(1, message);
|
||
}
|
||
};
|
||
ZodArray.create = (schema, params) => {
|
||
return new ZodArray({
|
||
type: schema,
|
||
minLength: null,
|
||
maxLength: null,
|
||
exactLength: null,
|
||
typeName: ZodFirstPartyTypeKind.ZodArray,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
function deepPartialify(schema) {
|
||
if (schema instanceof ZodObject) {
|
||
const newShape = {};
|
||
for (const key in schema.shape) {
|
||
const fieldSchema = schema.shape[key];
|
||
newShape[key] = ZodOptional.create(deepPartialify(fieldSchema));
|
||
}
|
||
return new ZodObject({
|
||
...schema._def,
|
||
shape: () => newShape
|
||
});
|
||
} else if (schema instanceof ZodArray) return new ZodArray({
|
||
...schema._def,
|
||
type: deepPartialify(schema.element)
|
||
});
|
||
else if (schema instanceof ZodOptional) return ZodOptional.create(deepPartialify(schema.unwrap()));
|
||
else if (schema instanceof ZodNullable) return ZodNullable.create(deepPartialify(schema.unwrap()));
|
||
else if (schema instanceof ZodTuple) return ZodTuple.create(schema.items.map((item) => deepPartialify(item)));
|
||
else return schema;
|
||
}
|
||
var ZodObject = class ZodObject extends ZodType {
|
||
constructor() {
|
||
super(...arguments);
|
||
this._cached = null;
|
||
/**
|
||
* @deprecated In most cases, this is no longer needed - unknown properties are now silently stripped.
|
||
* If you want to pass through unknown properties, use `.passthrough()` instead.
|
||
*/
|
||
this.nonstrict = this.passthrough;
|
||
/**
|
||
* @deprecated Use `.extend` instead
|
||
* */
|
||
this.augment = this.extend;
|
||
}
|
||
_getCached() {
|
||
if (this._cached !== null) return this._cached;
|
||
const shape = this._def.shape();
|
||
this._cached = {
|
||
shape,
|
||
keys: util.objectKeys(shape)
|
||
};
|
||
return this._cached;
|
||
}
|
||
_parse(input) {
|
||
if (this._getType(input) !== ZodParsedType.object) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.object,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
const { status, ctx } = this._processInputParams(input);
|
||
const { shape, keys: shapeKeys } = this._getCached();
|
||
const extraKeys = [];
|
||
if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
|
||
for (const key in ctx.data) if (!shapeKeys.includes(key)) extraKeys.push(key);
|
||
}
|
||
const pairs = [];
|
||
for (const key of shapeKeys) {
|
||
const keyValidator = shape[key];
|
||
const value = ctx.data[key];
|
||
pairs.push({
|
||
key: {
|
||
status: "valid",
|
||
value: key
|
||
},
|
||
value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)),
|
||
alwaysSet: key in ctx.data
|
||
});
|
||
}
|
||
if (this._def.catchall instanceof ZodNever) {
|
||
const unknownKeys = this._def.unknownKeys;
|
||
if (unknownKeys === "passthrough") for (const key of extraKeys) pairs.push({
|
||
key: {
|
||
status: "valid",
|
||
value: key
|
||
},
|
||
value: {
|
||
status: "valid",
|
||
value: ctx.data[key]
|
||
}
|
||
});
|
||
else if (unknownKeys === "strict") {
|
||
if (extraKeys.length > 0) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.unrecognized_keys,
|
||
keys: extraKeys
|
||
});
|
||
status.dirty();
|
||
}
|
||
} else if (unknownKeys === "strip") {} else throw new Error(`Internal ZodObject error: invalid unknownKeys value.`);
|
||
} else {
|
||
const catchall = this._def.catchall;
|
||
for (const key of extraKeys) {
|
||
const value = ctx.data[key];
|
||
pairs.push({
|
||
key: {
|
||
status: "valid",
|
||
value: key
|
||
},
|
||
value: catchall._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)),
|
||
alwaysSet: key in ctx.data
|
||
});
|
||
}
|
||
}
|
||
if (ctx.common.async) return Promise.resolve().then(async () => {
|
||
const syncPairs = [];
|
||
for (const pair of pairs) {
|
||
const key = await pair.key;
|
||
const value = await pair.value;
|
||
syncPairs.push({
|
||
key,
|
||
value,
|
||
alwaysSet: pair.alwaysSet
|
||
});
|
||
}
|
||
return syncPairs;
|
||
}).then((syncPairs) => {
|
||
return ParseStatus.mergeObjectSync(status, syncPairs);
|
||
});
|
||
else return ParseStatus.mergeObjectSync(status, pairs);
|
||
}
|
||
get shape() {
|
||
return this._def.shape();
|
||
}
|
||
strict(message) {
|
||
errorUtil.errToObj;
|
||
return new ZodObject({
|
||
...this._def,
|
||
unknownKeys: "strict",
|
||
...message !== void 0 ? { errorMap: (issue, ctx) => {
|
||
const defaultError = this._def.errorMap?.(issue, ctx).message ?? ctx.defaultError;
|
||
if (issue.code === "unrecognized_keys") return { message: errorUtil.errToObj(message).message ?? defaultError };
|
||
return { message: defaultError };
|
||
} } : {}
|
||
});
|
||
}
|
||
strip() {
|
||
return new ZodObject({
|
||
...this._def,
|
||
unknownKeys: "strip"
|
||
});
|
||
}
|
||
passthrough() {
|
||
return new ZodObject({
|
||
...this._def,
|
||
unknownKeys: "passthrough"
|
||
});
|
||
}
|
||
extend(augmentation) {
|
||
return new ZodObject({
|
||
...this._def,
|
||
shape: () => ({
|
||
...this._def.shape(),
|
||
...augmentation
|
||
})
|
||
});
|
||
}
|
||
/**
|
||
* Prior to zod@1.0.12 there was a bug in the
|
||
* inferred type of merged objects. Please
|
||
* upgrade if you are experiencing issues.
|
||
*/
|
||
merge(merging) {
|
||
return new ZodObject({
|
||
unknownKeys: merging._def.unknownKeys,
|
||
catchall: merging._def.catchall,
|
||
shape: () => ({
|
||
...this._def.shape(),
|
||
...merging._def.shape()
|
||
}),
|
||
typeName: ZodFirstPartyTypeKind.ZodObject
|
||
});
|
||
}
|
||
setKey(key, schema) {
|
||
return this.augment({ [key]: schema });
|
||
}
|
||
catchall(index) {
|
||
return new ZodObject({
|
||
...this._def,
|
||
catchall: index
|
||
});
|
||
}
|
||
pick(mask) {
|
||
const shape = {};
|
||
for (const key of util.objectKeys(mask)) if (mask[key] && this.shape[key]) shape[key] = this.shape[key];
|
||
return new ZodObject({
|
||
...this._def,
|
||
shape: () => shape
|
||
});
|
||
}
|
||
omit(mask) {
|
||
const shape = {};
|
||
for (const key of util.objectKeys(this.shape)) if (!mask[key]) shape[key] = this.shape[key];
|
||
return new ZodObject({
|
||
...this._def,
|
||
shape: () => shape
|
||
});
|
||
}
|
||
/**
|
||
* @deprecated
|
||
*/
|
||
deepPartial() {
|
||
return deepPartialify(this);
|
||
}
|
||
partial(mask) {
|
||
const newShape = {};
|
||
for (const key of util.objectKeys(this.shape)) {
|
||
const fieldSchema = this.shape[key];
|
||
if (mask && !mask[key]) newShape[key] = fieldSchema;
|
||
else newShape[key] = fieldSchema.optional();
|
||
}
|
||
return new ZodObject({
|
||
...this._def,
|
||
shape: () => newShape
|
||
});
|
||
}
|
||
required(mask) {
|
||
const newShape = {};
|
||
for (const key of util.objectKeys(this.shape)) if (mask && !mask[key]) newShape[key] = this.shape[key];
|
||
else {
|
||
let newField = this.shape[key];
|
||
while (newField instanceof ZodOptional) newField = newField._def.innerType;
|
||
newShape[key] = newField;
|
||
}
|
||
return new ZodObject({
|
||
...this._def,
|
||
shape: () => newShape
|
||
});
|
||
}
|
||
keyof() {
|
||
return createZodEnum(util.objectKeys(this.shape));
|
||
}
|
||
};
|
||
ZodObject.create = (shape, params) => {
|
||
return new ZodObject({
|
||
shape: () => shape,
|
||
unknownKeys: "strip",
|
||
catchall: ZodNever.create(),
|
||
typeName: ZodFirstPartyTypeKind.ZodObject,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
ZodObject.strictCreate = (shape, params) => {
|
||
return new ZodObject({
|
||
shape: () => shape,
|
||
unknownKeys: "strict",
|
||
catchall: ZodNever.create(),
|
||
typeName: ZodFirstPartyTypeKind.ZodObject,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
ZodObject.lazycreate = (shape, params) => {
|
||
return new ZodObject({
|
||
shape,
|
||
unknownKeys: "strip",
|
||
catchall: ZodNever.create(),
|
||
typeName: ZodFirstPartyTypeKind.ZodObject,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodUnion = class extends ZodType {
|
||
_parse(input) {
|
||
const { ctx } = this._processInputParams(input);
|
||
const options = this._def.options;
|
||
function handleResults(results) {
|
||
for (const result of results) if (result.result.status === "valid") return result.result;
|
||
for (const result of results) if (result.result.status === "dirty") {
|
||
ctx.common.issues.push(...result.ctx.common.issues);
|
||
return result.result;
|
||
}
|
||
const unionErrors = results.map((result) => new ZodError(result.ctx.common.issues));
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_union,
|
||
unionErrors
|
||
});
|
||
return INVALID;
|
||
}
|
||
if (ctx.common.async) return Promise.all(options.map(async (option) => {
|
||
const childCtx = {
|
||
...ctx,
|
||
common: {
|
||
...ctx.common,
|
||
issues: []
|
||
},
|
||
parent: null
|
||
};
|
||
return {
|
||
result: await option._parseAsync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: childCtx
|
||
}),
|
||
ctx: childCtx
|
||
};
|
||
})).then(handleResults);
|
||
else {
|
||
let dirty = void 0;
|
||
const issues = [];
|
||
for (const option of options) {
|
||
const childCtx = {
|
||
...ctx,
|
||
common: {
|
||
...ctx.common,
|
||
issues: []
|
||
},
|
||
parent: null
|
||
};
|
||
const result = option._parseSync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: childCtx
|
||
});
|
||
if (result.status === "valid") return result;
|
||
else if (result.status === "dirty" && !dirty) dirty = {
|
||
result,
|
||
ctx: childCtx
|
||
};
|
||
if (childCtx.common.issues.length) issues.push(childCtx.common.issues);
|
||
}
|
||
if (dirty) {
|
||
ctx.common.issues.push(...dirty.ctx.common.issues);
|
||
return dirty.result;
|
||
}
|
||
const unionErrors = issues.map((issues) => new ZodError(issues));
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_union,
|
||
unionErrors
|
||
});
|
||
return INVALID;
|
||
}
|
||
}
|
||
get options() {
|
||
return this._def.options;
|
||
}
|
||
};
|
||
ZodUnion.create = (types, params) => {
|
||
return new ZodUnion({
|
||
options: types,
|
||
typeName: ZodFirstPartyTypeKind.ZodUnion,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
const getDiscriminator = (type) => {
|
||
if (type instanceof ZodLazy) return getDiscriminator(type.schema);
|
||
else if (type instanceof ZodEffects) return getDiscriminator(type.innerType());
|
||
else if (type instanceof ZodLiteral) return [type.value];
|
||
else if (type instanceof ZodEnum) return type.options;
|
||
else if (type instanceof ZodNativeEnum) return util.objectValues(type.enum);
|
||
else if (type instanceof ZodDefault) return getDiscriminator(type._def.innerType);
|
||
else if (type instanceof ZodUndefined) return [void 0];
|
||
else if (type instanceof ZodNull) return [null];
|
||
else if (type instanceof ZodOptional) return [void 0, ...getDiscriminator(type.unwrap())];
|
||
else if (type instanceof ZodNullable) return [null, ...getDiscriminator(type.unwrap())];
|
||
else if (type instanceof ZodBranded) return getDiscriminator(type.unwrap());
|
||
else if (type instanceof ZodReadonly) return getDiscriminator(type.unwrap());
|
||
else if (type instanceof ZodCatch) return getDiscriminator(type._def.innerType);
|
||
else return [];
|
||
};
|
||
var ZodDiscriminatedUnion = class ZodDiscriminatedUnion extends ZodType {
|
||
_parse(input) {
|
||
const { ctx } = this._processInputParams(input);
|
||
if (ctx.parsedType !== ZodParsedType.object) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.object,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
const discriminator = this.discriminator;
|
||
const discriminatorValue = ctx.data[discriminator];
|
||
const option = this.optionsMap.get(discriminatorValue);
|
||
if (!option) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_union_discriminator,
|
||
options: Array.from(this.optionsMap.keys()),
|
||
path: [discriminator]
|
||
});
|
||
return INVALID;
|
||
}
|
||
if (ctx.common.async) return option._parseAsync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
else return option._parseSync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
}
|
||
get discriminator() {
|
||
return this._def.discriminator;
|
||
}
|
||
get options() {
|
||
return this._def.options;
|
||
}
|
||
get optionsMap() {
|
||
return this._def.optionsMap;
|
||
}
|
||
/**
|
||
* The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor.
|
||
* However, it only allows a union of objects, all of which need to share a discriminator property. This property must
|
||
* have a different value for each object in the union.
|
||
* @param discriminator the name of the discriminator property
|
||
* @param types an array of object schemas
|
||
* @param params
|
||
*/
|
||
static create(discriminator, options, params) {
|
||
const optionsMap = /* @__PURE__ */ new Map();
|
||
for (const type of options) {
|
||
const discriminatorValues = getDiscriminator(type.shape[discriminator]);
|
||
if (!discriminatorValues.length) throw new Error(`A discriminator value for key \`${discriminator}\` could not be extracted from all schema options`);
|
||
for (const value of discriminatorValues) {
|
||
if (optionsMap.has(value)) throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`);
|
||
optionsMap.set(value, type);
|
||
}
|
||
}
|
||
return new ZodDiscriminatedUnion({
|
||
typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion,
|
||
discriminator,
|
||
options,
|
||
optionsMap,
|
||
...processCreateParams(params)
|
||
});
|
||
}
|
||
};
|
||
function mergeValues(a, b) {
|
||
const aType = getParsedType(a);
|
||
const bType = getParsedType(b);
|
||
if (a === b) return {
|
||
valid: true,
|
||
data: a
|
||
};
|
||
else if (aType === ZodParsedType.object && bType === ZodParsedType.object) {
|
||
const bKeys = util.objectKeys(b);
|
||
const sharedKeys = util.objectKeys(a).filter((key) => bKeys.indexOf(key) !== -1);
|
||
const newObj = {
|
||
...a,
|
||
...b
|
||
};
|
||
for (const key of sharedKeys) {
|
||
const sharedValue = mergeValues(a[key], b[key]);
|
||
if (!sharedValue.valid) return { valid: false };
|
||
newObj[key] = sharedValue.data;
|
||
}
|
||
return {
|
||
valid: true,
|
||
data: newObj
|
||
};
|
||
} else if (aType === ZodParsedType.array && bType === ZodParsedType.array) {
|
||
if (a.length !== b.length) return { valid: false };
|
||
const newArray = [];
|
||
for (let index = 0; index < a.length; index++) {
|
||
const itemA = a[index];
|
||
const itemB = b[index];
|
||
const sharedValue = mergeValues(itemA, itemB);
|
||
if (!sharedValue.valid) return { valid: false };
|
||
newArray.push(sharedValue.data);
|
||
}
|
||
return {
|
||
valid: true,
|
||
data: newArray
|
||
};
|
||
} else if (aType === ZodParsedType.date && bType === ZodParsedType.date && +a === +b) return {
|
||
valid: true,
|
||
data: a
|
||
};
|
||
else return { valid: false };
|
||
}
|
||
var ZodIntersection = class extends ZodType {
|
||
_parse(input) {
|
||
const { status, ctx } = this._processInputParams(input);
|
||
const handleParsed = (parsedLeft, parsedRight) => {
|
||
if (isAborted(parsedLeft) || isAborted(parsedRight)) return INVALID;
|
||
const merged = mergeValues(parsedLeft.value, parsedRight.value);
|
||
if (!merged.valid) {
|
||
addIssueToContext(ctx, { code: ZodIssueCode.invalid_intersection_types });
|
||
return INVALID;
|
||
}
|
||
if (isDirty(parsedLeft) || isDirty(parsedRight)) status.dirty();
|
||
return {
|
||
status: status.value,
|
||
value: merged.data
|
||
};
|
||
};
|
||
if (ctx.common.async) return Promise.all([this._def.left._parseAsync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
}), this._def.right._parseAsync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
})]).then(([left, right]) => handleParsed(left, right));
|
||
else return handleParsed(this._def.left._parseSync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
}), this._def.right._parseSync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
}));
|
||
}
|
||
};
|
||
ZodIntersection.create = (left, right, params) => {
|
||
return new ZodIntersection({
|
||
left,
|
||
right,
|
||
typeName: ZodFirstPartyTypeKind.ZodIntersection,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodTuple = class ZodTuple extends ZodType {
|
||
_parse(input) {
|
||
const { status, ctx } = this._processInputParams(input);
|
||
if (ctx.parsedType !== ZodParsedType.array) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.array,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
if (ctx.data.length < this._def.items.length) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_small,
|
||
minimum: this._def.items.length,
|
||
inclusive: true,
|
||
exact: false,
|
||
type: "array"
|
||
});
|
||
return INVALID;
|
||
}
|
||
if (!this._def.rest && ctx.data.length > this._def.items.length) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_big,
|
||
maximum: this._def.items.length,
|
||
inclusive: true,
|
||
exact: false,
|
||
type: "array"
|
||
});
|
||
status.dirty();
|
||
}
|
||
const items = [...ctx.data].map((item, itemIndex) => {
|
||
const schema = this._def.items[itemIndex] || this._def.rest;
|
||
if (!schema) return null;
|
||
return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex));
|
||
}).filter((x) => !!x);
|
||
if (ctx.common.async) return Promise.all(items).then((results) => {
|
||
return ParseStatus.mergeArray(status, results);
|
||
});
|
||
else return ParseStatus.mergeArray(status, items);
|
||
}
|
||
get items() {
|
||
return this._def.items;
|
||
}
|
||
rest(rest) {
|
||
return new ZodTuple({
|
||
...this._def,
|
||
rest
|
||
});
|
||
}
|
||
};
|
||
ZodTuple.create = (schemas, params) => {
|
||
if (!Array.isArray(schemas)) throw new Error("You must pass an array of schemas to z.tuple([ ... ])");
|
||
return new ZodTuple({
|
||
items: schemas,
|
||
typeName: ZodFirstPartyTypeKind.ZodTuple,
|
||
rest: null,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodRecord = class ZodRecord extends ZodType {
|
||
get keySchema() {
|
||
return this._def.keyType;
|
||
}
|
||
get valueSchema() {
|
||
return this._def.valueType;
|
||
}
|
||
_parse(input) {
|
||
const { status, ctx } = this._processInputParams(input);
|
||
if (ctx.parsedType !== ZodParsedType.object) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.object,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
const pairs = [];
|
||
const keyType = this._def.keyType;
|
||
const valueType = this._def.valueType;
|
||
for (const key in ctx.data) pairs.push({
|
||
key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)),
|
||
value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)),
|
||
alwaysSet: key in ctx.data
|
||
});
|
||
if (ctx.common.async) return ParseStatus.mergeObjectAsync(status, pairs);
|
||
else return ParseStatus.mergeObjectSync(status, pairs);
|
||
}
|
||
get element() {
|
||
return this._def.valueType;
|
||
}
|
||
static create(first, second, third) {
|
||
if (second instanceof ZodType) return new ZodRecord({
|
||
keyType: first,
|
||
valueType: second,
|
||
typeName: ZodFirstPartyTypeKind.ZodRecord,
|
||
...processCreateParams(third)
|
||
});
|
||
return new ZodRecord({
|
||
keyType: ZodString.create(),
|
||
valueType: first,
|
||
typeName: ZodFirstPartyTypeKind.ZodRecord,
|
||
...processCreateParams(second)
|
||
});
|
||
}
|
||
};
|
||
var ZodMap = class extends ZodType {
|
||
get keySchema() {
|
||
return this._def.keyType;
|
||
}
|
||
get valueSchema() {
|
||
return this._def.valueType;
|
||
}
|
||
_parse(input) {
|
||
const { status, ctx } = this._processInputParams(input);
|
||
if (ctx.parsedType !== ZodParsedType.map) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.map,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
const keyType = this._def.keyType;
|
||
const valueType = this._def.valueType;
|
||
const pairs = [...ctx.data.entries()].map(([key, value], index) => {
|
||
return {
|
||
key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, "key"])),
|
||
value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, "value"]))
|
||
};
|
||
});
|
||
if (ctx.common.async) {
|
||
const finalMap = /* @__PURE__ */ new Map();
|
||
return Promise.resolve().then(async () => {
|
||
for (const pair of pairs) {
|
||
const key = await pair.key;
|
||
const value = await pair.value;
|
||
if (key.status === "aborted" || value.status === "aborted") return INVALID;
|
||
if (key.status === "dirty" || value.status === "dirty") status.dirty();
|
||
finalMap.set(key.value, value.value);
|
||
}
|
||
return {
|
||
status: status.value,
|
||
value: finalMap
|
||
};
|
||
});
|
||
} else {
|
||
const finalMap = /* @__PURE__ */ new Map();
|
||
for (const pair of pairs) {
|
||
const key = pair.key;
|
||
const value = pair.value;
|
||
if (key.status === "aborted" || value.status === "aborted") return INVALID;
|
||
if (key.status === "dirty" || value.status === "dirty") status.dirty();
|
||
finalMap.set(key.value, value.value);
|
||
}
|
||
return {
|
||
status: status.value,
|
||
value: finalMap
|
||
};
|
||
}
|
||
}
|
||
};
|
||
ZodMap.create = (keyType, valueType, params) => {
|
||
return new ZodMap({
|
||
valueType,
|
||
keyType,
|
||
typeName: ZodFirstPartyTypeKind.ZodMap,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodSet = class ZodSet extends ZodType {
|
||
_parse(input) {
|
||
const { status, ctx } = this._processInputParams(input);
|
||
if (ctx.parsedType !== ZodParsedType.set) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.set,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
const def = this._def;
|
||
if (def.minSize !== null) {
|
||
if (ctx.data.size < def.minSize.value) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_small,
|
||
minimum: def.minSize.value,
|
||
type: "set",
|
||
inclusive: true,
|
||
exact: false,
|
||
message: def.minSize.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
}
|
||
if (def.maxSize !== null) {
|
||
if (ctx.data.size > def.maxSize.value) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.too_big,
|
||
maximum: def.maxSize.value,
|
||
type: "set",
|
||
inclusive: true,
|
||
exact: false,
|
||
message: def.maxSize.message
|
||
});
|
||
status.dirty();
|
||
}
|
||
}
|
||
const valueType = this._def.valueType;
|
||
function finalizeSet(elements) {
|
||
const parsedSet = /* @__PURE__ */ new Set();
|
||
for (const element of elements) {
|
||
if (element.status === "aborted") return INVALID;
|
||
if (element.status === "dirty") status.dirty();
|
||
parsedSet.add(element.value);
|
||
}
|
||
return {
|
||
status: status.value,
|
||
value: parsedSet
|
||
};
|
||
}
|
||
const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)));
|
||
if (ctx.common.async) return Promise.all(elements).then((elements) => finalizeSet(elements));
|
||
else return finalizeSet(elements);
|
||
}
|
||
min(minSize, message) {
|
||
return new ZodSet({
|
||
...this._def,
|
||
minSize: {
|
||
value: minSize,
|
||
message: errorUtil.toString(message)
|
||
}
|
||
});
|
||
}
|
||
max(maxSize, message) {
|
||
return new ZodSet({
|
||
...this._def,
|
||
maxSize: {
|
||
value: maxSize,
|
||
message: errorUtil.toString(message)
|
||
}
|
||
});
|
||
}
|
||
size(size, message) {
|
||
return this.min(size, message).max(size, message);
|
||
}
|
||
nonempty(message) {
|
||
return this.min(1, message);
|
||
}
|
||
};
|
||
ZodSet.create = (valueType, params) => {
|
||
return new ZodSet({
|
||
valueType,
|
||
minSize: null,
|
||
maxSize: null,
|
||
typeName: ZodFirstPartyTypeKind.ZodSet,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodFunction = class ZodFunction extends ZodType {
|
||
constructor() {
|
||
super(...arguments);
|
||
this.validate = this.implement;
|
||
}
|
||
_parse(input) {
|
||
const { ctx } = this._processInputParams(input);
|
||
if (ctx.parsedType !== ZodParsedType.function) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.function,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
function makeArgsIssue(args, error) {
|
||
return makeIssue({
|
||
data: args,
|
||
path: ctx.path,
|
||
errorMaps: [
|
||
ctx.common.contextualErrorMap,
|
||
ctx.schemaErrorMap,
|
||
getErrorMap(),
|
||
errorMap
|
||
].filter((x) => !!x),
|
||
issueData: {
|
||
code: ZodIssueCode.invalid_arguments,
|
||
argumentsError: error
|
||
}
|
||
});
|
||
}
|
||
function makeReturnsIssue(returns, error) {
|
||
return makeIssue({
|
||
data: returns,
|
||
path: ctx.path,
|
||
errorMaps: [
|
||
ctx.common.contextualErrorMap,
|
||
ctx.schemaErrorMap,
|
||
getErrorMap(),
|
||
errorMap
|
||
].filter((x) => !!x),
|
||
issueData: {
|
||
code: ZodIssueCode.invalid_return_type,
|
||
returnTypeError: error
|
||
}
|
||
});
|
||
}
|
||
const params = { errorMap: ctx.common.contextualErrorMap };
|
||
const fn = ctx.data;
|
||
if (this._def.returns instanceof ZodPromise) {
|
||
const me = this;
|
||
return OK(async function(...args) {
|
||
const error = new ZodError([]);
|
||
const parsedArgs = await me._def.args.parseAsync(args, params).catch((e) => {
|
||
error.addIssue(makeArgsIssue(args, e));
|
||
throw error;
|
||
});
|
||
const result = await Reflect.apply(fn, this, parsedArgs);
|
||
return await me._def.returns._def.type.parseAsync(result, params).catch((e) => {
|
||
error.addIssue(makeReturnsIssue(result, e));
|
||
throw error;
|
||
});
|
||
});
|
||
} else {
|
||
const me = this;
|
||
return OK(function(...args) {
|
||
const parsedArgs = me._def.args.safeParse(args, params);
|
||
if (!parsedArgs.success) throw new ZodError([makeArgsIssue(args, parsedArgs.error)]);
|
||
const result = Reflect.apply(fn, this, parsedArgs.data);
|
||
const parsedReturns = me._def.returns.safeParse(result, params);
|
||
if (!parsedReturns.success) throw new ZodError([makeReturnsIssue(result, parsedReturns.error)]);
|
||
return parsedReturns.data;
|
||
});
|
||
}
|
||
}
|
||
parameters() {
|
||
return this._def.args;
|
||
}
|
||
returnType() {
|
||
return this._def.returns;
|
||
}
|
||
args(...items) {
|
||
return new ZodFunction({
|
||
...this._def,
|
||
args: ZodTuple.create(items).rest(ZodUnknown.create())
|
||
});
|
||
}
|
||
returns(returnType) {
|
||
return new ZodFunction({
|
||
...this._def,
|
||
returns: returnType
|
||
});
|
||
}
|
||
implement(func) {
|
||
return this.parse(func);
|
||
}
|
||
strictImplement(func) {
|
||
return this.parse(func);
|
||
}
|
||
static create(args, returns, params) {
|
||
return new ZodFunction({
|
||
args: args ? args : ZodTuple.create([]).rest(ZodUnknown.create()),
|
||
returns: returns || ZodUnknown.create(),
|
||
typeName: ZodFirstPartyTypeKind.ZodFunction,
|
||
...processCreateParams(params)
|
||
});
|
||
}
|
||
};
|
||
var ZodLazy = class extends ZodType {
|
||
get schema() {
|
||
return this._def.getter();
|
||
}
|
||
_parse(input) {
|
||
const { ctx } = this._processInputParams(input);
|
||
return this._def.getter()._parse({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
}
|
||
};
|
||
ZodLazy.create = (getter, params) => {
|
||
return new ZodLazy({
|
||
getter,
|
||
typeName: ZodFirstPartyTypeKind.ZodLazy,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodLiteral = class extends ZodType {
|
||
_parse(input) {
|
||
if (input.data !== this._def.value) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
addIssueToContext(ctx, {
|
||
received: ctx.data,
|
||
code: ZodIssueCode.invalid_literal,
|
||
expected: this._def.value
|
||
});
|
||
return INVALID;
|
||
}
|
||
return {
|
||
status: "valid",
|
||
value: input.data
|
||
};
|
||
}
|
||
get value() {
|
||
return this._def.value;
|
||
}
|
||
};
|
||
ZodLiteral.create = (value, params) => {
|
||
return new ZodLiteral({
|
||
value,
|
||
typeName: ZodFirstPartyTypeKind.ZodLiteral,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
function createZodEnum(values, params) {
|
||
return new ZodEnum({
|
||
values,
|
||
typeName: ZodFirstPartyTypeKind.ZodEnum,
|
||
...processCreateParams(params)
|
||
});
|
||
}
|
||
var ZodEnum = class ZodEnum extends ZodType {
|
||
_parse(input) {
|
||
if (typeof input.data !== "string") {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
const expectedValues = this._def.values;
|
||
addIssueToContext(ctx, {
|
||
expected: util.joinValues(expectedValues),
|
||
received: ctx.parsedType,
|
||
code: ZodIssueCode.invalid_type
|
||
});
|
||
return INVALID;
|
||
}
|
||
if (!this._cache) this._cache = new Set(this._def.values);
|
||
if (!this._cache.has(input.data)) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
const expectedValues = this._def.values;
|
||
addIssueToContext(ctx, {
|
||
received: ctx.data,
|
||
code: ZodIssueCode.invalid_enum_value,
|
||
options: expectedValues
|
||
});
|
||
return INVALID;
|
||
}
|
||
return OK(input.data);
|
||
}
|
||
get options() {
|
||
return this._def.values;
|
||
}
|
||
get enum() {
|
||
const enumValues = {};
|
||
for (const val of this._def.values) enumValues[val] = val;
|
||
return enumValues;
|
||
}
|
||
get Values() {
|
||
const enumValues = {};
|
||
for (const val of this._def.values) enumValues[val] = val;
|
||
return enumValues;
|
||
}
|
||
get Enum() {
|
||
const enumValues = {};
|
||
for (const val of this._def.values) enumValues[val] = val;
|
||
return enumValues;
|
||
}
|
||
extract(values, newDef = this._def) {
|
||
return ZodEnum.create(values, {
|
||
...this._def,
|
||
...newDef
|
||
});
|
||
}
|
||
exclude(values, newDef = this._def) {
|
||
return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)), {
|
||
...this._def,
|
||
...newDef
|
||
});
|
||
}
|
||
};
|
||
ZodEnum.create = createZodEnum;
|
||
var ZodNativeEnum = class extends ZodType {
|
||
_parse(input) {
|
||
const nativeEnumValues = util.getValidEnumValues(this._def.values);
|
||
const ctx = this._getOrReturnCtx(input);
|
||
if (ctx.parsedType !== ZodParsedType.string && ctx.parsedType !== ZodParsedType.number) {
|
||
const expectedValues = util.objectValues(nativeEnumValues);
|
||
addIssueToContext(ctx, {
|
||
expected: util.joinValues(expectedValues),
|
||
received: ctx.parsedType,
|
||
code: ZodIssueCode.invalid_type
|
||
});
|
||
return INVALID;
|
||
}
|
||
if (!this._cache) this._cache = new Set(util.getValidEnumValues(this._def.values));
|
||
if (!this._cache.has(input.data)) {
|
||
const expectedValues = util.objectValues(nativeEnumValues);
|
||
addIssueToContext(ctx, {
|
||
received: ctx.data,
|
||
code: ZodIssueCode.invalid_enum_value,
|
||
options: expectedValues
|
||
});
|
||
return INVALID;
|
||
}
|
||
return OK(input.data);
|
||
}
|
||
get enum() {
|
||
return this._def.values;
|
||
}
|
||
};
|
||
ZodNativeEnum.create = (values, params) => {
|
||
return new ZodNativeEnum({
|
||
values,
|
||
typeName: ZodFirstPartyTypeKind.ZodNativeEnum,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodPromise = class extends ZodType {
|
||
unwrap() {
|
||
return this._def.type;
|
||
}
|
||
_parse(input) {
|
||
const { ctx } = this._processInputParams(input);
|
||
if (ctx.parsedType !== ZodParsedType.promise && ctx.common.async === false) {
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.promise,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
return OK((ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data)).then((data) => {
|
||
return this._def.type.parseAsync(data, {
|
||
path: ctx.path,
|
||
errorMap: ctx.common.contextualErrorMap
|
||
});
|
||
}));
|
||
}
|
||
};
|
||
ZodPromise.create = (schema, params) => {
|
||
return new ZodPromise({
|
||
type: schema,
|
||
typeName: ZodFirstPartyTypeKind.ZodPromise,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodEffects = class extends ZodType {
|
||
innerType() {
|
||
return this._def.schema;
|
||
}
|
||
sourceType() {
|
||
return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects ? this._def.schema.sourceType() : this._def.schema;
|
||
}
|
||
_parse(input) {
|
||
const { status, ctx } = this._processInputParams(input);
|
||
const effect = this._def.effect || null;
|
||
const checkCtx = {
|
||
addIssue: (arg) => {
|
||
addIssueToContext(ctx, arg);
|
||
if (arg.fatal) status.abort();
|
||
else status.dirty();
|
||
},
|
||
get path() {
|
||
return ctx.path;
|
||
}
|
||
};
|
||
checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);
|
||
if (effect.type === "preprocess") {
|
||
const processed = effect.transform(ctx.data, checkCtx);
|
||
if (ctx.common.async) return Promise.resolve(processed).then(async (processed) => {
|
||
if (status.value === "aborted") return INVALID;
|
||
const result = await this._def.schema._parseAsync({
|
||
data: processed,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
if (result.status === "aborted") return INVALID;
|
||
if (result.status === "dirty") return DIRTY(result.value);
|
||
if (status.value === "dirty") return DIRTY(result.value);
|
||
return result;
|
||
});
|
||
else {
|
||
if (status.value === "aborted") return INVALID;
|
||
const result = this._def.schema._parseSync({
|
||
data: processed,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
if (result.status === "aborted") return INVALID;
|
||
if (result.status === "dirty") return DIRTY(result.value);
|
||
if (status.value === "dirty") return DIRTY(result.value);
|
||
return result;
|
||
}
|
||
}
|
||
if (effect.type === "refinement") {
|
||
const executeRefinement = (acc) => {
|
||
const result = effect.refinement(acc, checkCtx);
|
||
if (ctx.common.async) return Promise.resolve(result);
|
||
if (result instanceof Promise) throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");
|
||
return acc;
|
||
};
|
||
if (ctx.common.async === false) {
|
||
const inner = this._def.schema._parseSync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
if (inner.status === "aborted") return INVALID;
|
||
if (inner.status === "dirty") status.dirty();
|
||
executeRefinement(inner.value);
|
||
return {
|
||
status: status.value,
|
||
value: inner.value
|
||
};
|
||
} else return this._def.schema._parseAsync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
}).then((inner) => {
|
||
if (inner.status === "aborted") return INVALID;
|
||
if (inner.status === "dirty") status.dirty();
|
||
return executeRefinement(inner.value).then(() => {
|
||
return {
|
||
status: status.value,
|
||
value: inner.value
|
||
};
|
||
});
|
||
});
|
||
}
|
||
if (effect.type === "transform") if (ctx.common.async === false) {
|
||
const base = this._def.schema._parseSync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
if (!isValid(base)) return INVALID;
|
||
const result = effect.transform(base.value, checkCtx);
|
||
if (result instanceof Promise) throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
|
||
return {
|
||
status: status.value,
|
||
value: result
|
||
};
|
||
} else return this._def.schema._parseAsync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
}).then((base) => {
|
||
if (!isValid(base)) return INVALID;
|
||
return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
|
||
status: status.value,
|
||
value: result
|
||
}));
|
||
});
|
||
util.assertNever(effect);
|
||
}
|
||
};
|
||
ZodEffects.create = (schema, effect, params) => {
|
||
return new ZodEffects({
|
||
schema,
|
||
typeName: ZodFirstPartyTypeKind.ZodEffects,
|
||
effect,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
ZodEffects.createWithPreprocess = (preprocess, schema, params) => {
|
||
return new ZodEffects({
|
||
schema,
|
||
effect: {
|
||
type: "preprocess",
|
||
transform: preprocess
|
||
},
|
||
typeName: ZodFirstPartyTypeKind.ZodEffects,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodOptional = class extends ZodType {
|
||
_parse(input) {
|
||
if (this._getType(input) === ZodParsedType.undefined) return OK(void 0);
|
||
return this._def.innerType._parse(input);
|
||
}
|
||
unwrap() {
|
||
return this._def.innerType;
|
||
}
|
||
};
|
||
ZodOptional.create = (type, params) => {
|
||
return new ZodOptional({
|
||
innerType: type,
|
||
typeName: ZodFirstPartyTypeKind.ZodOptional,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodNullable = class extends ZodType {
|
||
_parse(input) {
|
||
if (this._getType(input) === ZodParsedType.null) return OK(null);
|
||
return this._def.innerType._parse(input);
|
||
}
|
||
unwrap() {
|
||
return this._def.innerType;
|
||
}
|
||
};
|
||
ZodNullable.create = (type, params) => {
|
||
return new ZodNullable({
|
||
innerType: type,
|
||
typeName: ZodFirstPartyTypeKind.ZodNullable,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodDefault = class extends ZodType {
|
||
_parse(input) {
|
||
const { ctx } = this._processInputParams(input);
|
||
let data = ctx.data;
|
||
if (ctx.parsedType === ZodParsedType.undefined) data = this._def.defaultValue();
|
||
return this._def.innerType._parse({
|
||
data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
}
|
||
removeDefault() {
|
||
return this._def.innerType;
|
||
}
|
||
};
|
||
ZodDefault.create = (type, params) => {
|
||
return new ZodDefault({
|
||
innerType: type,
|
||
typeName: ZodFirstPartyTypeKind.ZodDefault,
|
||
defaultValue: typeof params.default === "function" ? params.default : () => params.default,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodCatch = class extends ZodType {
|
||
_parse(input) {
|
||
const { ctx } = this._processInputParams(input);
|
||
const newCtx = {
|
||
...ctx,
|
||
common: {
|
||
...ctx.common,
|
||
issues: []
|
||
}
|
||
};
|
||
const result = this._def.innerType._parse({
|
||
data: newCtx.data,
|
||
path: newCtx.path,
|
||
parent: { ...newCtx }
|
||
});
|
||
if (isAsync(result)) return result.then((result) => {
|
||
return {
|
||
status: "valid",
|
||
value: result.status === "valid" ? result.value : this._def.catchValue({
|
||
get error() {
|
||
return new ZodError(newCtx.common.issues);
|
||
},
|
||
input: newCtx.data
|
||
})
|
||
};
|
||
});
|
||
else return {
|
||
status: "valid",
|
||
value: result.status === "valid" ? result.value : this._def.catchValue({
|
||
get error() {
|
||
return new ZodError(newCtx.common.issues);
|
||
},
|
||
input: newCtx.data
|
||
})
|
||
};
|
||
}
|
||
removeCatch() {
|
||
return this._def.innerType;
|
||
}
|
||
};
|
||
ZodCatch.create = (type, params) => {
|
||
return new ZodCatch({
|
||
innerType: type,
|
||
typeName: ZodFirstPartyTypeKind.ZodCatch,
|
||
catchValue: typeof params.catch === "function" ? params.catch : () => params.catch,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodNaN = class extends ZodType {
|
||
_parse(input) {
|
||
if (this._getType(input) !== ZodParsedType.nan) {
|
||
const ctx = this._getOrReturnCtx(input);
|
||
addIssueToContext(ctx, {
|
||
code: ZodIssueCode.invalid_type,
|
||
expected: ZodParsedType.nan,
|
||
received: ctx.parsedType
|
||
});
|
||
return INVALID;
|
||
}
|
||
return {
|
||
status: "valid",
|
||
value: input.data
|
||
};
|
||
}
|
||
};
|
||
ZodNaN.create = (params) => {
|
||
return new ZodNaN({
|
||
typeName: ZodFirstPartyTypeKind.ZodNaN,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
var ZodBranded = class extends ZodType {
|
||
_parse(input) {
|
||
const { ctx } = this._processInputParams(input);
|
||
const data = ctx.data;
|
||
return this._def.type._parse({
|
||
data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
}
|
||
unwrap() {
|
||
return this._def.type;
|
||
}
|
||
};
|
||
var ZodPipeline = class ZodPipeline extends ZodType {
|
||
_parse(input) {
|
||
const { status, ctx } = this._processInputParams(input);
|
||
if (ctx.common.async) {
|
||
const handleAsync = async () => {
|
||
const inResult = await this._def.in._parseAsync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
if (inResult.status === "aborted") return INVALID;
|
||
if (inResult.status === "dirty") {
|
||
status.dirty();
|
||
return DIRTY(inResult.value);
|
||
} else return this._def.out._parseAsync({
|
||
data: inResult.value,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
};
|
||
return handleAsync();
|
||
} else {
|
||
const inResult = this._def.in._parseSync({
|
||
data: ctx.data,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
if (inResult.status === "aborted") return INVALID;
|
||
if (inResult.status === "dirty") {
|
||
status.dirty();
|
||
return {
|
||
status: "dirty",
|
||
value: inResult.value
|
||
};
|
||
} else return this._def.out._parseSync({
|
||
data: inResult.value,
|
||
path: ctx.path,
|
||
parent: ctx
|
||
});
|
||
}
|
||
}
|
||
static create(a, b) {
|
||
return new ZodPipeline({
|
||
in: a,
|
||
out: b,
|
||
typeName: ZodFirstPartyTypeKind.ZodPipeline
|
||
});
|
||
}
|
||
};
|
||
var ZodReadonly = class extends ZodType {
|
||
_parse(input) {
|
||
const result = this._def.innerType._parse(input);
|
||
const freeze = (data) => {
|
||
if (isValid(data)) data.value = Object.freeze(data.value);
|
||
return data;
|
||
};
|
||
return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result);
|
||
}
|
||
unwrap() {
|
||
return this._def.innerType;
|
||
}
|
||
};
|
||
ZodReadonly.create = (type, params) => {
|
||
return new ZodReadonly({
|
||
innerType: type,
|
||
typeName: ZodFirstPartyTypeKind.ZodReadonly,
|
||
...processCreateParams(params)
|
||
});
|
||
};
|
||
const late = { object: ZodObject.lazycreate };
|
||
var ZodFirstPartyTypeKind;
|
||
(function(ZodFirstPartyTypeKind) {
|
||
ZodFirstPartyTypeKind["ZodString"] = "ZodString";
|
||
ZodFirstPartyTypeKind["ZodNumber"] = "ZodNumber";
|
||
ZodFirstPartyTypeKind["ZodNaN"] = "ZodNaN";
|
||
ZodFirstPartyTypeKind["ZodBigInt"] = "ZodBigInt";
|
||
ZodFirstPartyTypeKind["ZodBoolean"] = "ZodBoolean";
|
||
ZodFirstPartyTypeKind["ZodDate"] = "ZodDate";
|
||
ZodFirstPartyTypeKind["ZodSymbol"] = "ZodSymbol";
|
||
ZodFirstPartyTypeKind["ZodUndefined"] = "ZodUndefined";
|
||
ZodFirstPartyTypeKind["ZodNull"] = "ZodNull";
|
||
ZodFirstPartyTypeKind["ZodAny"] = "ZodAny";
|
||
ZodFirstPartyTypeKind["ZodUnknown"] = "ZodUnknown";
|
||
ZodFirstPartyTypeKind["ZodNever"] = "ZodNever";
|
||
ZodFirstPartyTypeKind["ZodVoid"] = "ZodVoid";
|
||
ZodFirstPartyTypeKind["ZodArray"] = "ZodArray";
|
||
ZodFirstPartyTypeKind["ZodObject"] = "ZodObject";
|
||
ZodFirstPartyTypeKind["ZodUnion"] = "ZodUnion";
|
||
ZodFirstPartyTypeKind["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion";
|
||
ZodFirstPartyTypeKind["ZodIntersection"] = "ZodIntersection";
|
||
ZodFirstPartyTypeKind["ZodTuple"] = "ZodTuple";
|
||
ZodFirstPartyTypeKind["ZodRecord"] = "ZodRecord";
|
||
ZodFirstPartyTypeKind["ZodMap"] = "ZodMap";
|
||
ZodFirstPartyTypeKind["ZodSet"] = "ZodSet";
|
||
ZodFirstPartyTypeKind["ZodFunction"] = "ZodFunction";
|
||
ZodFirstPartyTypeKind["ZodLazy"] = "ZodLazy";
|
||
ZodFirstPartyTypeKind["ZodLiteral"] = "ZodLiteral";
|
||
ZodFirstPartyTypeKind["ZodEnum"] = "ZodEnum";
|
||
ZodFirstPartyTypeKind["ZodEffects"] = "ZodEffects";
|
||
ZodFirstPartyTypeKind["ZodNativeEnum"] = "ZodNativeEnum";
|
||
ZodFirstPartyTypeKind["ZodOptional"] = "ZodOptional";
|
||
ZodFirstPartyTypeKind["ZodNullable"] = "ZodNullable";
|
||
ZodFirstPartyTypeKind["ZodDefault"] = "ZodDefault";
|
||
ZodFirstPartyTypeKind["ZodCatch"] = "ZodCatch";
|
||
ZodFirstPartyTypeKind["ZodPromise"] = "ZodPromise";
|
||
ZodFirstPartyTypeKind["ZodBranded"] = "ZodBranded";
|
||
ZodFirstPartyTypeKind["ZodPipeline"] = "ZodPipeline";
|
||
ZodFirstPartyTypeKind["ZodReadonly"] = "ZodReadonly";
|
||
})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
|
||
const stringType = ZodString.create;
|
||
const numberType = ZodNumber.create;
|
||
const nanType = ZodNaN.create;
|
||
const bigIntType = ZodBigInt.create;
|
||
const booleanType = ZodBoolean.create;
|
||
const dateType = ZodDate.create;
|
||
const symbolType = ZodSymbol.create;
|
||
const undefinedType = ZodUndefined.create;
|
||
const nullType = ZodNull.create;
|
||
const anyType = ZodAny.create;
|
||
const unknownType = ZodUnknown.create;
|
||
const neverType = ZodNever.create;
|
||
const voidType = ZodVoid.create;
|
||
const arrayType = ZodArray.create;
|
||
const objectType = ZodObject.create;
|
||
const strictObjectType = ZodObject.strictCreate;
|
||
const unionType = ZodUnion.create;
|
||
const discriminatedUnionType = ZodDiscriminatedUnion.create;
|
||
const intersectionType = ZodIntersection.create;
|
||
const tupleType = ZodTuple.create;
|
||
const recordType = ZodRecord.create;
|
||
const mapType = ZodMap.create;
|
||
const setType = ZodSet.create;
|
||
const functionType = ZodFunction.create;
|
||
const lazyType = ZodLazy.create;
|
||
const literalType = ZodLiteral.create;
|
||
const enumType = ZodEnum.create;
|
||
const nativeEnumType = ZodNativeEnum.create;
|
||
const promiseType = ZodPromise.create;
|
||
const effectsType = ZodEffects.create;
|
||
const optionalType = ZodOptional.create;
|
||
const nullableType = ZodNullable.create;
|
||
const preprocessType = ZodEffects.createWithPreprocess;
|
||
const pipelineType = ZodPipeline.create;
|
||
|
||
//#endregion
|
||
//#region src/config/schemas.ts
|
||
const communicationStyleSchema = enumType([
|
||
"direct",
|
||
"friendly",
|
||
"formal"
|
||
]).default("direct");
|
||
const soulSchema = objectType({
|
||
agentName: stringType().min(1).max(50).default("Assistant"),
|
||
roleDescription: stringType().default("execution partner and visibility engine"),
|
||
communicationStyle: communicationStyleSchema,
|
||
accessibility: stringType().default("none"),
|
||
customGuardrails: stringType().default("")
|
||
}).partial();
|
||
const gitProviderSchema = objectType({
|
||
name: stringType().min(1),
|
||
url: stringType().min(1),
|
||
cli: stringType().min(1),
|
||
purpose: stringType().min(1)
|
||
});
|
||
const userSchema = objectType({
|
||
userName: stringType().default(""),
|
||
pronouns: stringType().default("They/Them"),
|
||
timezone: stringType().default("UTC"),
|
||
background: stringType().default("(not configured)"),
|
||
accessibilitySection: stringType().default("(No specific accommodations configured. Edit this section to add any.)"),
|
||
communicationPrefs: stringType().default(""),
|
||
personalBoundaries: stringType().default("(Edit this section to add any personal boundaries.)"),
|
||
projectsTable: stringType().default("")
|
||
}).partial();
|
||
const toolsSchema = objectType({
|
||
gitProviders: arrayType(gitProviderSchema).default([]),
|
||
credentialsLocation: stringType().default("none"),
|
||
customToolsSection: stringType().default("")
|
||
}).partial();
|
||
|
||
//#endregion
|
||
//#region src/template/engine.ts
|
||
/**
|
||
* Replaces {{PLACEHOLDER}} tokens with provided values.
|
||
* Does NOT expand ${ENV_VAR} syntax — those pass through for shell resolution.
|
||
*/
|
||
function renderTemplate(template, vars, options = {}) {
|
||
return template.replace(/\{\{([A-Z_][A-Z0-9_]*)\}\}/g, (match, varName) => {
|
||
if (varName in vars) return vars[varName];
|
||
if (options.strict) throw new Error(`Template variable not provided: {{${varName}}}`);
|
||
return "";
|
||
});
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/constants.ts
|
||
const VERSION = "0.2.0";
|
||
const DEFAULT_MOSAIC_HOME = join(homedir(), ".config", "mosaic");
|
||
const DEFAULTS = {
|
||
agentName: "Assistant",
|
||
roleDescription: "execution partner and visibility engine",
|
||
communicationStyle: "direct",
|
||
pronouns: "They/Them",
|
||
timezone: "UTC",
|
||
background: "(not configured)",
|
||
accessibilitySection: "(No specific accommodations configured. Edit this section to add any.)",
|
||
personalBoundaries: "(Edit this section to add any personal boundaries.)",
|
||
projectsTable: `| Project | Stack | Registry |
|
||
|---------|-------|----------|
|
||
| (none configured) | | |`,
|
||
credentialsLocation: "none",
|
||
customToolsSection: `## Custom Tools
|
||
|
||
(Add any machine-specific tools, scripts, or workflows here.)`,
|
||
gitProvidersTable: `| Instance | URL | CLI | Purpose |
|
||
|----------|-----|-----|---------|
|
||
| (add your git providers here) | | | |`
|
||
};
|
||
const RECOMMENDED_SKILLS = new Set([
|
||
"brainstorming",
|
||
"code-review-excellence",
|
||
"lint",
|
||
"systematic-debugging",
|
||
"verification-before-completion",
|
||
"writing-plans",
|
||
"executing-plans",
|
||
"architecture-patterns"
|
||
]);
|
||
|
||
//#endregion
|
||
//#region src/template/builders.ts
|
||
/**
|
||
* Build behavioral principles text based on communication style.
|
||
* Replicates mosaic-init lines 177-204 exactly.
|
||
*/
|
||
function buildBehavioralPrinciples(style, accessibility) {
|
||
let principles;
|
||
switch (style) {
|
||
case "direct":
|
||
principles = `1. Clarity over performance theater.
|
||
2. Practical execution over abstract planning.
|
||
3. Truthfulness over confidence: state uncertainty explicitly.
|
||
4. Visible state over hidden assumptions.
|
||
5. Accessibility-aware — see \`~/.config/mosaic/USER.md\` for user-specific accommodations.`;
|
||
break;
|
||
case "friendly":
|
||
principles = `1. Be helpful and approachable while staying efficient.
|
||
2. Provide context and explain reasoning when helpful.
|
||
3. Truthfulness over confidence: state uncertainty explicitly.
|
||
4. Visible state over hidden assumptions.
|
||
5. Accessibility-aware — see \`~/.config/mosaic/USER.md\` for user-specific accommodations.`;
|
||
break;
|
||
case "formal":
|
||
principles = `1. Maintain professional, structured communication.
|
||
2. Provide thorough analysis with explicit tradeoffs.
|
||
3. Truthfulness over confidence: state uncertainty explicitly.
|
||
4. Document decisions and rationale clearly.
|
||
5. Accessibility-aware — see \`~/.config/mosaic/USER.md\` for user-specific accommodations.`;
|
||
break;
|
||
}
|
||
if (accessibility && accessibility !== "none" && accessibility.length > 0) principles += `\n6. ${accessibility}.`;
|
||
return principles;
|
||
}
|
||
/**
|
||
* Build communication style text based on style choice.
|
||
* Replicates mosaic-init lines 208-227 exactly.
|
||
*/
|
||
function buildCommunicationStyleText(style) {
|
||
switch (style) {
|
||
case "direct": return `- Be direct, concise, and concrete.
|
||
- Avoid fluff, hype, and anthropomorphic roleplay.
|
||
- Do not simulate certainty when facts are missing.
|
||
- Prefer actionable next steps and explicit tradeoffs.`;
|
||
case "friendly": return `- Be warm and conversational while staying focused.
|
||
- Explain your reasoning when it helps the user.
|
||
- Do not simulate certainty when facts are missing.
|
||
- Prefer actionable next steps with clear context.`;
|
||
case "formal": return `- Use professional, structured language.
|
||
- Provide thorough explanations with supporting detail.
|
||
- Do not simulate certainty when facts are missing.
|
||
- Present options with explicit tradeoffs and recommendations.`;
|
||
}
|
||
}
|
||
/**
|
||
* Build communication preferences for USER.md based on style.
|
||
* Replicates mosaic-init lines 299-316 exactly.
|
||
*/
|
||
function buildCommunicationPrefs(style) {
|
||
switch (style) {
|
||
case "direct": return `- Direct and concise
|
||
- No sycophancy
|
||
- Executive summaries and tables for overview`;
|
||
case "friendly": return `- Warm and conversational
|
||
- Explain reasoning when helpful
|
||
- Balance thoroughness with brevity`;
|
||
case "formal": return `- Professional and structured
|
||
- Thorough explanations with supporting detail
|
||
- Formal tone with explicit recommendations`;
|
||
}
|
||
}
|
||
/**
|
||
* Build git providers markdown table from provider list.
|
||
* Replicates mosaic-init lines 362-384.
|
||
*/
|
||
function buildGitProvidersTable(providers) {
|
||
if (!providers || providers.length === 0) return DEFAULTS.gitProvidersTable;
|
||
return `| Instance | URL | CLI | Purpose |
|
||
|----------|-----|-----|---------|
|
||
${providers.map((p) => `| ${p.name} | ${p.url} | \`${p.cli}\` | ${p.purpose} |`).join("\n")}`;
|
||
}
|
||
function buildSoulTemplateVars(config) {
|
||
const style = config.communicationStyle ?? "direct";
|
||
const guardrails = config.customGuardrails ? `- ${config.customGuardrails}` : "";
|
||
return {
|
||
AGENT_NAME: config.agentName ?? DEFAULTS.agentName,
|
||
ROLE_DESCRIPTION: config.roleDescription ?? DEFAULTS.roleDescription,
|
||
BEHAVIORAL_PRINCIPLES: buildBehavioralPrinciples(style, config.accessibility),
|
||
COMMUNICATION_STYLE: buildCommunicationStyleText(style),
|
||
CUSTOM_GUARDRAILS: guardrails
|
||
};
|
||
}
|
||
function buildUserTemplateVars(config) {
|
||
return {
|
||
USER_NAME: config.userName ?? "",
|
||
PRONOUNS: config.pronouns ?? DEFAULTS.pronouns,
|
||
TIMEZONE: config.timezone ?? DEFAULTS.timezone,
|
||
BACKGROUND: config.background ?? DEFAULTS.background,
|
||
ACCESSIBILITY_SECTION: config.accessibilitySection ?? DEFAULTS.accessibilitySection,
|
||
COMMUNICATION_PREFS: config.communicationPrefs ?? buildCommunicationPrefs("direct"),
|
||
PERSONAL_BOUNDARIES: config.personalBoundaries ?? DEFAULTS.personalBoundaries,
|
||
PROJECTS_TABLE: config.projectsTable ?? DEFAULTS.projectsTable
|
||
};
|
||
}
|
||
function buildToolsTemplateVars(config) {
|
||
return {
|
||
GIT_PROVIDERS_TABLE: buildGitProvidersTable(config.gitProviders),
|
||
CREDENTIALS_LOCATION: config.credentialsLocation ?? DEFAULTS.credentialsLocation,
|
||
CUSTOM_TOOLS_SECTION: config.customToolsSection ?? DEFAULTS.customToolsSection
|
||
};
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/platform/file-ops.ts
|
||
const MAX_BACKUPS = 3;
|
||
/**
|
||
* Atomic write: write to temp file, then rename.
|
||
* Creates parent directories as needed.
|
||
*/
|
||
function atomicWrite(filePath, content) {
|
||
mkdirSync(dirname(filePath), { recursive: true });
|
||
const tmpPath = `${filePath}.tmp-${process.pid}`;
|
||
writeFileSync(tmpPath, content, "utf-8");
|
||
renameSync(tmpPath, filePath);
|
||
}
|
||
/**
|
||
* Create a backup of a file before overwriting.
|
||
* Rotates backups to keep at most MAX_BACKUPS.
|
||
*/
|
||
function backupFile(filePath) {
|
||
if (!existsSync(filePath)) return null;
|
||
const backupPath = `${filePath}.bak-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").replace("T", "-").slice(0, 19)}`;
|
||
copyFileSync(filePath, backupPath);
|
||
rotateBackups(filePath);
|
||
return backupPath;
|
||
}
|
||
function rotateBackups(filePath) {
|
||
const dir = dirname(filePath);
|
||
const prefix = `${filePath.split("/").pop()}.bak-`;
|
||
try {
|
||
const backups = readdirSync(dir).filter((f) => f.startsWith(prefix)).sort().reverse();
|
||
for (let i = MAX_BACKUPS; i < backups.length; i++) unlinkSync(join(dir, backups[i]));
|
||
} catch {}
|
||
}
|
||
/**
|
||
* Sync a source directory to a target, with optional preserve paths.
|
||
* Replaces the rsync/cp logic from install.sh.
|
||
*/
|
||
function syncDirectory(source, target, options = {}) {
|
||
const preserveSet = new Set(options.preserve ?? []);
|
||
function copyRecursive(src, dest, relBase) {
|
||
if (!existsSync(src)) return;
|
||
if (statSync(src).isDirectory()) {
|
||
const relPath = relative(relBase, src);
|
||
if (options.excludeGit && relPath === ".git") return;
|
||
if (preserveSet.has(relPath) && existsSync(dest)) return;
|
||
mkdirSync(dest, { recursive: true });
|
||
for (const entry of readdirSync(src)) copyRecursive(join(src, entry), join(dest, entry), relBase);
|
||
} else {
|
||
const relPath = relative(relBase, src);
|
||
if (preserveSet.has(relPath) && existsSync(dest)) return;
|
||
mkdirSync(dirname(dest), { recursive: true });
|
||
copyFileSync(src, dest);
|
||
}
|
||
}
|
||
copyRecursive(source, target, source);
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/config/file-adapter.ts
|
||
/**
|
||
* Parse a SoulConfig from an existing SOUL.md file.
|
||
*/
|
||
function parseSoulFromMarkdown(content) {
|
||
const config = {};
|
||
const nameMatch = content.match(/You are \*\*(.+?)\*\*/);
|
||
if (nameMatch) config.agentName = nameMatch[1];
|
||
const roleMatch = content.match(/Role identity: (.+)/);
|
||
if (roleMatch) config.roleDescription = roleMatch[1];
|
||
if (content.includes("Be direct, concise")) config.communicationStyle = "direct";
|
||
else if (content.includes("Be warm and conversational")) config.communicationStyle = "friendly";
|
||
else if (content.includes("Use professional, structured")) config.communicationStyle = "formal";
|
||
return config;
|
||
}
|
||
/**
|
||
* Parse a UserConfig from an existing USER.md file.
|
||
*/
|
||
function parseUserFromMarkdown(content) {
|
||
const config = {};
|
||
const nameMatch = content.match(/\*\*Name:\*\* (.+)/);
|
||
if (nameMatch) config.userName = nameMatch[1];
|
||
const pronounsMatch = content.match(/\*\*Pronouns:\*\* (.+)/);
|
||
if (pronounsMatch) config.pronouns = pronounsMatch[1];
|
||
const tzMatch = content.match(/\*\*Timezone:\*\* (.+)/);
|
||
if (tzMatch) config.timezone = tzMatch[1];
|
||
return config;
|
||
}
|
||
/**
|
||
* Parse a ToolsConfig from an existing TOOLS.md file.
|
||
*/
|
||
function parseToolsFromMarkdown(content) {
|
||
const config = {};
|
||
const credsMatch = content.match(/\*\*Location:\*\* (.+)/);
|
||
if (credsMatch) config.credentialsLocation = credsMatch[1];
|
||
return config;
|
||
}
|
||
var FileConfigAdapter = class {
|
||
constructor(mosaicHome, sourceDir) {
|
||
this.mosaicHome = mosaicHome;
|
||
this.sourceDir = sourceDir;
|
||
}
|
||
async readSoul() {
|
||
const path = join(this.mosaicHome, "SOUL.md");
|
||
if (!existsSync(path)) return {};
|
||
return parseSoulFromMarkdown(readFileSync(path, "utf-8"));
|
||
}
|
||
async readUser() {
|
||
const path = join(this.mosaicHome, "USER.md");
|
||
if (!existsSync(path)) return {};
|
||
return parseUserFromMarkdown(readFileSync(path, "utf-8"));
|
||
}
|
||
async readTools() {
|
||
const path = join(this.mosaicHome, "TOOLS.md");
|
||
if (!existsSync(path)) return {};
|
||
return parseToolsFromMarkdown(readFileSync(path, "utf-8"));
|
||
}
|
||
async writeSoul(config) {
|
||
const validated = soulSchema.parse(config);
|
||
const templatePath = this.findTemplate("SOUL.md.template");
|
||
if (!templatePath) return;
|
||
const output = renderTemplate(readFileSync(templatePath, "utf-8"), buildSoulTemplateVars(validated));
|
||
const outPath = join(this.mosaicHome, "SOUL.md");
|
||
backupFile(outPath);
|
||
atomicWrite(outPath, output);
|
||
}
|
||
async writeUser(config) {
|
||
const validated = userSchema.parse(config);
|
||
const templatePath = this.findTemplate("USER.md.template");
|
||
if (!templatePath) return;
|
||
const output = renderTemplate(readFileSync(templatePath, "utf-8"), buildUserTemplateVars(validated));
|
||
const outPath = join(this.mosaicHome, "USER.md");
|
||
backupFile(outPath);
|
||
atomicWrite(outPath, output);
|
||
}
|
||
async writeTools(config) {
|
||
const validated = toolsSchema.parse(config);
|
||
const templatePath = this.findTemplate("TOOLS.md.template");
|
||
if (!templatePath) return;
|
||
const output = renderTemplate(readFileSync(templatePath, "utf-8"), buildToolsTemplateVars(validated));
|
||
const outPath = join(this.mosaicHome, "TOOLS.md");
|
||
backupFile(outPath);
|
||
atomicWrite(outPath, output);
|
||
}
|
||
async syncFramework(action) {
|
||
const preservePaths = action === "keep" || action === "reconfigure" ? [
|
||
"SOUL.md",
|
||
"USER.md",
|
||
"TOOLS.md",
|
||
"memory"
|
||
] : [];
|
||
syncDirectory(this.sourceDir, this.mosaicHome, {
|
||
preserve: preservePaths,
|
||
excludeGit: true
|
||
});
|
||
}
|
||
/**
|
||
* Look for template in source dir first, then mosaic home.
|
||
*/
|
||
findTemplate(name) {
|
||
const candidates = [join(this.sourceDir, "templates", name), join(this.mosaicHome, "templates", name)];
|
||
for (const path of candidates) if (existsSync(path)) return path;
|
||
return null;
|
||
}
|
||
};
|
||
|
||
//#endregion
|
||
//#region src/config/config-service.ts
|
||
function createConfigService(mosaicHome, sourceDir) {
|
||
return new FileConfigAdapter(mosaicHome, sourceDir);
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/stages/welcome.ts
|
||
async function welcomeStage(p, _state) {
|
||
p.intro(`Mosaic Installation Wizard v${VERSION}`);
|
||
p.note("Mosaic is an agent framework that gives AI coding assistants\na persistent identity, shared skills, and structured workflows.\n\nIt works with Claude Code, Codex, and OpenCode.\n\nAll config is stored locally in ~/.config/mosaic/.\nNo data is sent anywhere. No accounts required.", "What is Mosaic?");
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/stages/detect-install.ts
|
||
function detectExistingInstall(mosaicHome) {
|
||
if (!existsSync(mosaicHome)) return false;
|
||
return existsSync(join(mosaicHome, "bin/mosaic")) || existsSync(join(mosaicHome, "AGENTS.md")) || existsSync(join(mosaicHome, "SOUL.md"));
|
||
}
|
||
function detectExistingIdentity(mosaicHome) {
|
||
const soulPath = join(mosaicHome, "SOUL.md");
|
||
const hasSoul = existsSync(soulPath);
|
||
let agentName;
|
||
if (hasSoul) try {
|
||
agentName = readFileSync(soulPath, "utf-8").match(/You are \*\*(.+?)\*\*/)?.[1];
|
||
} catch {}
|
||
return {
|
||
hasSoul,
|
||
hasUser: existsSync(join(mosaicHome, "USER.md")),
|
||
hasTools: existsSync(join(mosaicHome, "TOOLS.md")),
|
||
agentName
|
||
};
|
||
}
|
||
async function detectInstallStage(p, state, config) {
|
||
if (!detectExistingInstall(state.mosaicHome)) {
|
||
state.installAction = "fresh";
|
||
return;
|
||
}
|
||
const identity = detectExistingIdentity(state.mosaicHome);
|
||
const identitySummary = identity.agentName ? `Agent: ${identity.agentName}` : "No identity configured";
|
||
p.note(`Found existing Mosaic installation at:\n${state.mosaicHome}\n\n${identitySummary}\nSOUL.md: ${identity.hasSoul ? "yes" : "no"}\nUSER.md: ${identity.hasUser ? "yes" : "no"}\nTOOLS.md: ${identity.hasTools ? "yes" : "no"}`, "Existing Installation Detected");
|
||
state.installAction = await p.select({
|
||
message: "What would you like to do?",
|
||
options: [
|
||
{
|
||
value: "keep",
|
||
label: "Keep identity, update framework",
|
||
hint: "Preserves SOUL.md, USER.md, TOOLS.md, memory/"
|
||
},
|
||
{
|
||
value: "reconfigure",
|
||
label: "Reconfigure identity",
|
||
hint: "Re-run identity setup, update framework"
|
||
},
|
||
{
|
||
value: "reset",
|
||
label: "Fresh install",
|
||
hint: "Replace everything"
|
||
}
|
||
]
|
||
});
|
||
if (state.installAction === "keep") {
|
||
state.soul = await config.readSoul();
|
||
state.user = await config.readUser();
|
||
state.tools = await config.readTools();
|
||
}
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/stages/mode-select.ts
|
||
async function modeSelectStage(p, state) {
|
||
state.mode = await p.select({
|
||
message: "Installation mode",
|
||
options: [{
|
||
value: "quick",
|
||
label: "Quick Start",
|
||
hint: "Sensible defaults, minimal questions (~2 min)"
|
||
}, {
|
||
value: "advanced",
|
||
label: "Advanced",
|
||
hint: "Full customization of identity, runtimes, and skills"
|
||
}]
|
||
});
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/stages/soul-setup.ts
|
||
async function soulSetupStage(p, state) {
|
||
if (state.installAction === "keep") return;
|
||
p.separator();
|
||
p.note("Your agent identity defines how AI assistants behave,\ntheir principles, and communication style.\nThis creates SOUL.md.", "Agent Identity");
|
||
if (!state.soul.agentName) state.soul.agentName = await p.text({
|
||
message: "What name should agents use?",
|
||
placeholder: "e.g., Jarvis, Assistant, Mosaic",
|
||
defaultValue: DEFAULTS.agentName,
|
||
validate: (v) => {
|
||
if (v.length === 0) return "Name cannot be empty";
|
||
if (v.length > 50) return "Name must be under 50 characters";
|
||
}
|
||
});
|
||
if (state.mode === "advanced") {
|
||
if (!state.soul.roleDescription) state.soul.roleDescription = await p.text({
|
||
message: "Agent role description",
|
||
placeholder: "e.g., execution partner and visibility engine",
|
||
defaultValue: DEFAULTS.roleDescription
|
||
});
|
||
} else state.soul.roleDescription ??= DEFAULTS.roleDescription;
|
||
if (!state.soul.communicationStyle) state.soul.communicationStyle = await p.select({
|
||
message: "Communication style",
|
||
options: [
|
||
{
|
||
value: "direct",
|
||
label: "Direct",
|
||
hint: "Concise, no fluff, actionable"
|
||
},
|
||
{
|
||
value: "friendly",
|
||
label: "Friendly",
|
||
hint: "Warm but efficient, conversational"
|
||
},
|
||
{
|
||
value: "formal",
|
||
label: "Formal",
|
||
hint: "Professional, structured, thorough"
|
||
}
|
||
],
|
||
initialValue: "direct"
|
||
});
|
||
if (state.mode === "advanced") {
|
||
if (!state.soul.accessibility) state.soul.accessibility = await p.text({
|
||
message: "Accessibility preferences",
|
||
placeholder: "e.g., ADHD-friendly chunking, dyslexia-aware formatting, or 'none'",
|
||
defaultValue: "none"
|
||
});
|
||
if (!state.soul.customGuardrails) state.soul.customGuardrails = await p.text({
|
||
message: "Custom guardrails (optional)",
|
||
placeholder: "e.g., Never auto-commit to main",
|
||
defaultValue: ""
|
||
});
|
||
}
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/stages/user-setup.ts
|
||
async function userSetupStage(p, state) {
|
||
if (state.installAction === "keep") return;
|
||
p.separator();
|
||
p.note("Your user profile helps agents understand your context,\naccessibility needs, and communication preferences.\nThis creates USER.md.", "User Profile");
|
||
if (!state.user.userName) state.user.userName = await p.text({
|
||
message: "Your name",
|
||
placeholder: "How agents should address you",
|
||
defaultValue: ""
|
||
});
|
||
if (!state.user.pronouns) state.user.pronouns = await p.text({
|
||
message: "Your pronouns",
|
||
placeholder: "e.g., He/Him, She/Her, They/Them",
|
||
defaultValue: DEFAULTS.pronouns
|
||
});
|
||
let detectedTz;
|
||
try {
|
||
detectedTz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||
} catch {
|
||
detectedTz = DEFAULTS.timezone;
|
||
}
|
||
if (!state.user.timezone) state.user.timezone = await p.text({
|
||
message: "Your timezone",
|
||
placeholder: `e.g., ${detectedTz}`,
|
||
defaultValue: detectedTz
|
||
});
|
||
if (state.mode === "advanced") {
|
||
state.user.background = await p.text({
|
||
message: "Professional background (brief)",
|
||
placeholder: "e.g., Full-stack developer, 10 years TypeScript/React",
|
||
defaultValue: DEFAULTS.background
|
||
});
|
||
state.user.accessibilitySection = await p.text({
|
||
message: "Neurodivergence / accessibility accommodations",
|
||
placeholder: "e.g., ADHD-friendly chunking, or press Enter to skip",
|
||
defaultValue: DEFAULTS.accessibilitySection
|
||
});
|
||
state.user.personalBoundaries = await p.text({
|
||
message: "Personal boundaries for agents",
|
||
placeholder: "e.g., No unsolicited career advice, or press Enter to skip",
|
||
defaultValue: DEFAULTS.personalBoundaries
|
||
});
|
||
} else {
|
||
state.user.background = DEFAULTS.background;
|
||
state.user.accessibilitySection = DEFAULTS.accessibilitySection;
|
||
state.user.personalBoundaries = DEFAULTS.personalBoundaries;
|
||
}
|
||
state.user.communicationPrefs = buildCommunicationPrefs(state.soul.communicationStyle ?? "direct");
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/stages/tools-setup.ts
|
||
async function toolsSetupStage(p, state) {
|
||
if (state.installAction === "keep") return;
|
||
if (state.mode === "quick") {
|
||
state.tools.gitProviders = [];
|
||
state.tools.credentialsLocation = DEFAULTS.credentialsLocation;
|
||
state.tools.customToolsSection = DEFAULTS.customToolsSection;
|
||
return;
|
||
}
|
||
p.separator();
|
||
p.note("Tool configuration tells agents about your git providers,\ncredential locations, and custom tools.\nThis creates TOOLS.md.", "Tool Reference");
|
||
const addProviders = await p.confirm({
|
||
message: "Configure git providers?",
|
||
initialValue: false
|
||
});
|
||
state.tools.gitProviders = [];
|
||
if (addProviders) {
|
||
let addMore = true;
|
||
while (addMore) {
|
||
const name = await p.text({
|
||
message: "Provider name",
|
||
placeholder: "e.g., Gitea, GitHub"
|
||
});
|
||
const url = await p.text({
|
||
message: "Provider URL",
|
||
placeholder: "e.g., https://github.com"
|
||
});
|
||
const cli = await p.select({
|
||
message: "CLI tool",
|
||
options: [
|
||
{
|
||
value: "gh",
|
||
label: "gh (GitHub CLI)"
|
||
},
|
||
{
|
||
value: "tea",
|
||
label: "tea (Gitea CLI)"
|
||
},
|
||
{
|
||
value: "glab",
|
||
label: "glab (GitLab CLI)"
|
||
}
|
||
]
|
||
});
|
||
const purpose = await p.text({
|
||
message: "Purpose",
|
||
placeholder: "e.g., Primary code hosting",
|
||
defaultValue: "Code hosting"
|
||
});
|
||
state.tools.gitProviders.push({
|
||
name,
|
||
url,
|
||
cli,
|
||
purpose
|
||
});
|
||
addMore = await p.confirm({
|
||
message: "Add another provider?",
|
||
initialValue: false
|
||
});
|
||
}
|
||
}
|
||
state.tools.credentialsLocation = await p.text({
|
||
message: "Credential file path",
|
||
placeholder: "e.g., ~/.secrets/credentials.env, or 'none'",
|
||
defaultValue: DEFAULTS.credentialsLocation
|
||
});
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/runtime/detector.ts
|
||
const RUNTIME_DEFS = {
|
||
claude: {
|
||
label: "Claude Code",
|
||
command: "claude",
|
||
versionFlag: "--version",
|
||
installHint: "npm install -g @anthropic-ai/claude-code"
|
||
},
|
||
codex: {
|
||
label: "Codex",
|
||
command: "codex",
|
||
versionFlag: "--version",
|
||
installHint: "npm install -g @openai/codex"
|
||
},
|
||
opencode: {
|
||
label: "OpenCode",
|
||
command: "opencode",
|
||
versionFlag: "version",
|
||
installHint: "See https://opencode.ai for install instructions"
|
||
}
|
||
};
|
||
function detectRuntime(name) {
|
||
const def = RUNTIME_DEFS[name];
|
||
const whichCmd = platform() === "win32" ? `where ${def.command} 2>nul` : `which ${def.command} 2>/dev/null`;
|
||
try {
|
||
const path = execSync(whichCmd, {
|
||
encoding: "utf-8",
|
||
timeout: 5e3
|
||
}).trim().split("\n")[0];
|
||
let version;
|
||
try {
|
||
version = execSync(`${def.command} ${def.versionFlag} 2>/dev/null`, {
|
||
encoding: "utf-8",
|
||
timeout: 5e3
|
||
}).trim();
|
||
} catch {}
|
||
return {
|
||
name,
|
||
label: def.label,
|
||
installed: true,
|
||
path,
|
||
version,
|
||
installHint: def.installHint
|
||
};
|
||
} catch {
|
||
return {
|
||
name,
|
||
label: def.label,
|
||
installed: false,
|
||
installHint: def.installHint
|
||
};
|
||
}
|
||
}
|
||
function getInstallInstructions(name) {
|
||
return RUNTIME_DEFS[name].installHint;
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/runtime/installer.ts
|
||
function formatInstallInstructions(name) {
|
||
const hint = getInstallInstructions(name);
|
||
return `To install ${{
|
||
claude: "Claude Code",
|
||
codex: "Codex",
|
||
opencode: "OpenCode"
|
||
}[name]}:\n ${hint}`;
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/runtime/mcp-config.ts
|
||
const MCP_ENTRY = {
|
||
command: "npx",
|
||
args: ["-y", "@modelcontextprotocol/server-sequential-thinking"]
|
||
};
|
||
function configureMcpForRuntime(runtime) {
|
||
switch (runtime) {
|
||
case "claude": return configureClaudeMcp();
|
||
case "codex": return configureCodexMcp();
|
||
case "opencode": return configureOpenCodeMcp();
|
||
}
|
||
}
|
||
function ensureDir(filePath) {
|
||
mkdirSync(dirname(filePath), { recursive: true });
|
||
}
|
||
function configureClaudeMcp() {
|
||
const settingsPath = join(homedir(), ".claude", "settings.json");
|
||
ensureDir(settingsPath);
|
||
let data = {};
|
||
if (existsSync(settingsPath)) try {
|
||
data = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
||
} catch {}
|
||
if (!data.mcpServers || typeof data.mcpServers !== "object" || Array.isArray(data.mcpServers)) data.mcpServers = {};
|
||
data.mcpServers["sequential-thinking"] = MCP_ENTRY;
|
||
writeFileSync(settingsPath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
||
}
|
||
function configureCodexMcp() {
|
||
const configPath = join(homedir(), ".codex", "config.toml");
|
||
ensureDir(configPath);
|
||
let content = "";
|
||
if (existsSync(configPath)) {
|
||
content = readFileSync(configPath, "utf-8");
|
||
content = content.replace(/\[mcp_servers\.(sequential-thinking|sequential_thinking)\][\s\S]*?(?=\n\[|$)/g, "").trim();
|
||
}
|
||
content += "\n\n[mcp_servers.sequential-thinking]\ncommand = \"npx\"\nargs = [\"-y\", \"@modelcontextprotocol/server-sequential-thinking\"]\n";
|
||
writeFileSync(configPath, content, "utf-8");
|
||
}
|
||
function configureOpenCodeMcp() {
|
||
const configPath = join(homedir(), ".config", "opencode", "config.json");
|
||
ensureDir(configPath);
|
||
let data = {};
|
||
if (existsSync(configPath)) try {
|
||
data = JSON.parse(readFileSync(configPath, "utf-8"));
|
||
} catch {}
|
||
if (!data.mcp || typeof data.mcp !== "object" || Array.isArray(data.mcp)) data.mcp = {};
|
||
data.mcp["sequential-thinking"] = {
|
||
type: "local",
|
||
command: [
|
||
"npx",
|
||
"-y",
|
||
"@modelcontextprotocol/server-sequential-thinking"
|
||
],
|
||
enabled: true
|
||
};
|
||
writeFileSync(configPath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/stages/runtime-setup.ts
|
||
const RUNTIME_NAMES = [
|
||
"claude",
|
||
"codex",
|
||
"opencode"
|
||
];
|
||
async function runtimeSetupStage(p, state) {
|
||
p.separator();
|
||
const spin = p.spinner();
|
||
spin.update("Detecting installed runtimes...");
|
||
const runtimes = RUNTIME_NAMES.map(detectRuntime);
|
||
spin.stop("Runtime detection complete");
|
||
const detected = runtimes.filter((r) => r.installed);
|
||
const notDetected = runtimes.filter((r) => !r.installed);
|
||
if (detected.length > 0) {
|
||
const summary = detected.map((r) => ` ${r.label}: ${r.version ?? "installed"} (${r.path})`).join("\n");
|
||
p.note(summary, "Detected Runtimes");
|
||
} else p.warn("No runtimes detected. Install at least one to use Mosaic.");
|
||
state.runtimes.detected = detected.map((r) => r.name);
|
||
if (state.mode === "advanced" && notDetected.length > 0) {
|
||
if (await p.confirm({
|
||
message: `${notDetected.length} runtime(s) not found. Show install instructions?`,
|
||
initialValue: false
|
||
})) for (const rt of notDetected) p.note(formatInstallInstructions(rt.name), `Install ${rt.label}`);
|
||
}
|
||
if (detected.length > 0) {
|
||
const spin2 = p.spinner();
|
||
spin2.update("Configuring sequential-thinking MCP...");
|
||
try {
|
||
for (const rt of detected) configureMcpForRuntime(rt.name);
|
||
spin2.stop("MCP sequential-thinking configured");
|
||
state.runtimes.mcpConfigured = true;
|
||
} catch (err) {
|
||
spin2.stop("MCP configuration failed (non-fatal)");
|
||
p.warn(`MCP setup failed: ${err instanceof Error ? err.message : String(err)}. Run 'mosaic seq fix' later.`);
|
||
}
|
||
}
|
||
}
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/nodes/identity.js
|
||
var require_identity = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
const ALIAS = Symbol.for("yaml.alias");
|
||
const DOC = Symbol.for("yaml.document");
|
||
const MAP = Symbol.for("yaml.map");
|
||
const PAIR = Symbol.for("yaml.pair");
|
||
const SCALAR = Symbol.for("yaml.scalar");
|
||
const SEQ = Symbol.for("yaml.seq");
|
||
const NODE_TYPE = Symbol.for("yaml.node.type");
|
||
const isAlias = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === ALIAS;
|
||
const isDocument = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === DOC;
|
||
const isMap = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === MAP;
|
||
const isPair = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === PAIR;
|
||
const isScalar = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === SCALAR;
|
||
const isSeq = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === SEQ;
|
||
function isCollection(node) {
|
||
if (node && typeof node === "object") switch (node[NODE_TYPE]) {
|
||
case MAP:
|
||
case SEQ: return true;
|
||
}
|
||
return false;
|
||
}
|
||
function isNode(node) {
|
||
if (node && typeof node === "object") switch (node[NODE_TYPE]) {
|
||
case ALIAS:
|
||
case MAP:
|
||
case SCALAR:
|
||
case SEQ: return true;
|
||
}
|
||
return false;
|
||
}
|
||
const hasAnchor = (node) => (isScalar(node) || isCollection(node)) && !!node.anchor;
|
||
exports.ALIAS = ALIAS;
|
||
exports.DOC = DOC;
|
||
exports.MAP = MAP;
|
||
exports.NODE_TYPE = NODE_TYPE;
|
||
exports.PAIR = PAIR;
|
||
exports.SCALAR = SCALAR;
|
||
exports.SEQ = SEQ;
|
||
exports.hasAnchor = hasAnchor;
|
||
exports.isAlias = isAlias;
|
||
exports.isCollection = isCollection;
|
||
exports.isDocument = isDocument;
|
||
exports.isMap = isMap;
|
||
exports.isNode = isNode;
|
||
exports.isPair = isPair;
|
||
exports.isScalar = isScalar;
|
||
exports.isSeq = isSeq;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/visit.js
|
||
var require_visit = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
const BREAK = Symbol("break visit");
|
||
const SKIP = Symbol("skip children");
|
||
const REMOVE = Symbol("remove node");
|
||
/**
|
||
* Apply a visitor to an AST node or document.
|
||
*
|
||
* Walks through the tree (depth-first) starting from `node`, calling a
|
||
* `visitor` function with three arguments:
|
||
* - `key`: For sequence values and map `Pair`, the node's index in the
|
||
* collection. Within a `Pair`, `'key'` or `'value'`, correspondingly.
|
||
* `null` for the root node.
|
||
* - `node`: The current node.
|
||
* - `path`: The ancestry of the current node.
|
||
*
|
||
* The return value of the visitor may be used to control the traversal:
|
||
* - `undefined` (default): Do nothing and continue
|
||
* - `visit.SKIP`: Do not visit the children of this node, continue with next
|
||
* sibling
|
||
* - `visit.BREAK`: Terminate traversal completely
|
||
* - `visit.REMOVE`: Remove the current node, then continue with the next one
|
||
* - `Node`: Replace the current node, then continue by visiting it
|
||
* - `number`: While iterating the items of a sequence or map, set the index
|
||
* of the next step. This is useful especially if the index of the current
|
||
* node has changed.
|
||
*
|
||
* If `visitor` is a single function, it will be called with all values
|
||
* encountered in the tree, including e.g. `null` values. Alternatively,
|
||
* separate visitor functions may be defined for each `Map`, `Pair`, `Seq`,
|
||
* `Alias` and `Scalar` node. To define the same visitor function for more than
|
||
* one node type, use the `Collection` (map and seq), `Value` (map, seq & scalar)
|
||
* and `Node` (alias, map, seq & scalar) targets. Of all these, only the most
|
||
* specific defined one will be used for each node.
|
||
*/
|
||
function visit(node, visitor) {
|
||
const visitor_ = initVisitor(visitor);
|
||
if (identity.isDocument(node)) {
|
||
if (visit_(null, node.contents, visitor_, Object.freeze([node])) === REMOVE) node.contents = null;
|
||
} else visit_(null, node, visitor_, Object.freeze([]));
|
||
}
|
||
/** Terminate visit traversal completely */
|
||
visit.BREAK = BREAK;
|
||
/** Do not visit the children of the current node */
|
||
visit.SKIP = SKIP;
|
||
/** Remove the current node */
|
||
visit.REMOVE = REMOVE;
|
||
function visit_(key, node, visitor, path) {
|
||
const ctrl = callVisitor(key, node, visitor, path);
|
||
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
||
replaceNode(key, path, ctrl);
|
||
return visit_(key, ctrl, visitor, path);
|
||
}
|
||
if (typeof ctrl !== "symbol") {
|
||
if (identity.isCollection(node)) {
|
||
path = Object.freeze(path.concat(node));
|
||
for (let i = 0; i < node.items.length; ++i) {
|
||
const ci = visit_(i, node.items[i], visitor, path);
|
||
if (typeof ci === "number") i = ci - 1;
|
||
else if (ci === BREAK) return BREAK;
|
||
else if (ci === REMOVE) {
|
||
node.items.splice(i, 1);
|
||
i -= 1;
|
||
}
|
||
}
|
||
} else if (identity.isPair(node)) {
|
||
path = Object.freeze(path.concat(node));
|
||
const ck = visit_("key", node.key, visitor, path);
|
||
if (ck === BREAK) return BREAK;
|
||
else if (ck === REMOVE) node.key = null;
|
||
const cv = visit_("value", node.value, visitor, path);
|
||
if (cv === BREAK) return BREAK;
|
||
else if (cv === REMOVE) node.value = null;
|
||
}
|
||
}
|
||
return ctrl;
|
||
}
|
||
/**
|
||
* Apply an async visitor to an AST node or document.
|
||
*
|
||
* Walks through the tree (depth-first) starting from `node`, calling a
|
||
* `visitor` function with three arguments:
|
||
* - `key`: For sequence values and map `Pair`, the node's index in the
|
||
* collection. Within a `Pair`, `'key'` or `'value'`, correspondingly.
|
||
* `null` for the root node.
|
||
* - `node`: The current node.
|
||
* - `path`: The ancestry of the current node.
|
||
*
|
||
* The return value of the visitor may be used to control the traversal:
|
||
* - `Promise`: Must resolve to one of the following values
|
||
* - `undefined` (default): Do nothing and continue
|
||
* - `visit.SKIP`: Do not visit the children of this node, continue with next
|
||
* sibling
|
||
* - `visit.BREAK`: Terminate traversal completely
|
||
* - `visit.REMOVE`: Remove the current node, then continue with the next one
|
||
* - `Node`: Replace the current node, then continue by visiting it
|
||
* - `number`: While iterating the items of a sequence or map, set the index
|
||
* of the next step. This is useful especially if the index of the current
|
||
* node has changed.
|
||
*
|
||
* If `visitor` is a single function, it will be called with all values
|
||
* encountered in the tree, including e.g. `null` values. Alternatively,
|
||
* separate visitor functions may be defined for each `Map`, `Pair`, `Seq`,
|
||
* `Alias` and `Scalar` node. To define the same visitor function for more than
|
||
* one node type, use the `Collection` (map and seq), `Value` (map, seq & scalar)
|
||
* and `Node` (alias, map, seq & scalar) targets. Of all these, only the most
|
||
* specific defined one will be used for each node.
|
||
*/
|
||
async function visitAsync(node, visitor) {
|
||
const visitor_ = initVisitor(visitor);
|
||
if (identity.isDocument(node)) {
|
||
if (await visitAsync_(null, node.contents, visitor_, Object.freeze([node])) === REMOVE) node.contents = null;
|
||
} else await visitAsync_(null, node, visitor_, Object.freeze([]));
|
||
}
|
||
/** Terminate visit traversal completely */
|
||
visitAsync.BREAK = BREAK;
|
||
/** Do not visit the children of the current node */
|
||
visitAsync.SKIP = SKIP;
|
||
/** Remove the current node */
|
||
visitAsync.REMOVE = REMOVE;
|
||
async function visitAsync_(key, node, visitor, path) {
|
||
const ctrl = await callVisitor(key, node, visitor, path);
|
||
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
||
replaceNode(key, path, ctrl);
|
||
return visitAsync_(key, ctrl, visitor, path);
|
||
}
|
||
if (typeof ctrl !== "symbol") {
|
||
if (identity.isCollection(node)) {
|
||
path = Object.freeze(path.concat(node));
|
||
for (let i = 0; i < node.items.length; ++i) {
|
||
const ci = await visitAsync_(i, node.items[i], visitor, path);
|
||
if (typeof ci === "number") i = ci - 1;
|
||
else if (ci === BREAK) return BREAK;
|
||
else if (ci === REMOVE) {
|
||
node.items.splice(i, 1);
|
||
i -= 1;
|
||
}
|
||
}
|
||
} else if (identity.isPair(node)) {
|
||
path = Object.freeze(path.concat(node));
|
||
const ck = await visitAsync_("key", node.key, visitor, path);
|
||
if (ck === BREAK) return BREAK;
|
||
else if (ck === REMOVE) node.key = null;
|
||
const cv = await visitAsync_("value", node.value, visitor, path);
|
||
if (cv === BREAK) return BREAK;
|
||
else if (cv === REMOVE) node.value = null;
|
||
}
|
||
}
|
||
return ctrl;
|
||
}
|
||
function initVisitor(visitor) {
|
||
if (typeof visitor === "object" && (visitor.Collection || visitor.Node || visitor.Value)) return Object.assign({
|
||
Alias: visitor.Node,
|
||
Map: visitor.Node,
|
||
Scalar: visitor.Node,
|
||
Seq: visitor.Node
|
||
}, visitor.Value && {
|
||
Map: visitor.Value,
|
||
Scalar: visitor.Value,
|
||
Seq: visitor.Value
|
||
}, visitor.Collection && {
|
||
Map: visitor.Collection,
|
||
Seq: visitor.Collection
|
||
}, visitor);
|
||
return visitor;
|
||
}
|
||
function callVisitor(key, node, visitor, path) {
|
||
if (typeof visitor === "function") return visitor(key, node, path);
|
||
if (identity.isMap(node)) return visitor.Map?.(key, node, path);
|
||
if (identity.isSeq(node)) return visitor.Seq?.(key, node, path);
|
||
if (identity.isPair(node)) return visitor.Pair?.(key, node, path);
|
||
if (identity.isScalar(node)) return visitor.Scalar?.(key, node, path);
|
||
if (identity.isAlias(node)) return visitor.Alias?.(key, node, path);
|
||
}
|
||
function replaceNode(key, path, node) {
|
||
const parent = path[path.length - 1];
|
||
if (identity.isCollection(parent)) parent.items[key] = node;
|
||
else if (identity.isPair(parent)) if (key === "key") parent.key = node;
|
||
else parent.value = node;
|
||
else if (identity.isDocument(parent)) parent.contents = node;
|
||
else {
|
||
const pt = identity.isAlias(parent) ? "alias" : "scalar";
|
||
throw new Error(`Cannot replace node with ${pt} parent`);
|
||
}
|
||
}
|
||
exports.visit = visit;
|
||
exports.visitAsync = visitAsync;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/doc/directives.js
|
||
var require_directives = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var visit = require_visit();
|
||
const escapeChars = {
|
||
"!": "%21",
|
||
",": "%2C",
|
||
"[": "%5B",
|
||
"]": "%5D",
|
||
"{": "%7B",
|
||
"}": "%7D"
|
||
};
|
||
const escapeTagName = (tn) => tn.replace(/[!,[\]{}]/g, (ch) => escapeChars[ch]);
|
||
var Directives = class Directives {
|
||
constructor(yaml, tags) {
|
||
/**
|
||
* The directives-end/doc-start marker `---`. If `null`, a marker may still be
|
||
* included in the document's stringified representation.
|
||
*/
|
||
this.docStart = null;
|
||
/** The doc-end marker `...`. */
|
||
this.docEnd = false;
|
||
this.yaml = Object.assign({}, Directives.defaultYaml, yaml);
|
||
this.tags = Object.assign({}, Directives.defaultTags, tags);
|
||
}
|
||
clone() {
|
||
const copy = new Directives(this.yaml, this.tags);
|
||
copy.docStart = this.docStart;
|
||
return copy;
|
||
}
|
||
/**
|
||
* During parsing, get a Directives instance for the current document and
|
||
* update the stream state according to the current version's spec.
|
||
*/
|
||
atDocument() {
|
||
const res = new Directives(this.yaml, this.tags);
|
||
switch (this.yaml.version) {
|
||
case "1.1":
|
||
this.atNextDocument = true;
|
||
break;
|
||
case "1.2":
|
||
this.atNextDocument = false;
|
||
this.yaml = {
|
||
explicit: Directives.defaultYaml.explicit,
|
||
version: "1.2"
|
||
};
|
||
this.tags = Object.assign({}, Directives.defaultTags);
|
||
break;
|
||
}
|
||
return res;
|
||
}
|
||
/**
|
||
* @param onError - May be called even if the action was successful
|
||
* @returns `true` on success
|
||
*/
|
||
add(line, onError) {
|
||
if (this.atNextDocument) {
|
||
this.yaml = {
|
||
explicit: Directives.defaultYaml.explicit,
|
||
version: "1.1"
|
||
};
|
||
this.tags = Object.assign({}, Directives.defaultTags);
|
||
this.atNextDocument = false;
|
||
}
|
||
const parts = line.trim().split(/[ \t]+/);
|
||
const name = parts.shift();
|
||
switch (name) {
|
||
case "%TAG": {
|
||
if (parts.length !== 2) {
|
||
onError(0, "%TAG directive should contain exactly two parts");
|
||
if (parts.length < 2) return false;
|
||
}
|
||
const [handle, prefix] = parts;
|
||
this.tags[handle] = prefix;
|
||
return true;
|
||
}
|
||
case "%YAML": {
|
||
this.yaml.explicit = true;
|
||
if (parts.length !== 1) {
|
||
onError(0, "%YAML directive should contain exactly one part");
|
||
return false;
|
||
}
|
||
const [version] = parts;
|
||
if (version === "1.1" || version === "1.2") {
|
||
this.yaml.version = version;
|
||
return true;
|
||
} else {
|
||
const isValid = /^\d+\.\d+$/.test(version);
|
||
onError(6, `Unsupported YAML version ${version}`, isValid);
|
||
return false;
|
||
}
|
||
}
|
||
default:
|
||
onError(0, `Unknown directive ${name}`, true);
|
||
return false;
|
||
}
|
||
}
|
||
/**
|
||
* Resolves a tag, matching handles to those defined in %TAG directives.
|
||
*
|
||
* @returns Resolved tag, which may also be the non-specific tag `'!'` or a
|
||
* `'!local'` tag, or `null` if unresolvable.
|
||
*/
|
||
tagName(source, onError) {
|
||
if (source === "!") return "!";
|
||
if (source[0] !== "!") {
|
||
onError(`Not a valid tag: ${source}`);
|
||
return null;
|
||
}
|
||
if (source[1] === "<") {
|
||
const verbatim = source.slice(2, -1);
|
||
if (verbatim === "!" || verbatim === "!!") {
|
||
onError(`Verbatim tags aren't resolved, so ${source} is invalid.`);
|
||
return null;
|
||
}
|
||
if (source[source.length - 1] !== ">") onError("Verbatim tags must end with a >");
|
||
return verbatim;
|
||
}
|
||
const [, handle, suffix] = source.match(/^(.*!)([^!]*)$/s);
|
||
if (!suffix) onError(`The ${source} tag has no suffix`);
|
||
const prefix = this.tags[handle];
|
||
if (prefix) try {
|
||
return prefix + decodeURIComponent(suffix);
|
||
} catch (error) {
|
||
onError(String(error));
|
||
return null;
|
||
}
|
||
if (handle === "!") return source;
|
||
onError(`Could not resolve tag: ${source}`);
|
||
return null;
|
||
}
|
||
/**
|
||
* Given a fully resolved tag, returns its printable string form,
|
||
* taking into account current tag prefixes and defaults.
|
||
*/
|
||
tagString(tag) {
|
||
for (const [handle, prefix] of Object.entries(this.tags)) if (tag.startsWith(prefix)) return handle + escapeTagName(tag.substring(prefix.length));
|
||
return tag[0] === "!" ? tag : `!<${tag}>`;
|
||
}
|
||
toString(doc) {
|
||
const lines = this.yaml.explicit ? [`%YAML ${this.yaml.version || "1.2"}`] : [];
|
||
const tagEntries = Object.entries(this.tags);
|
||
let tagNames;
|
||
if (doc && tagEntries.length > 0 && identity.isNode(doc.contents)) {
|
||
const tags = {};
|
||
visit.visit(doc.contents, (_key, node) => {
|
||
if (identity.isNode(node) && node.tag) tags[node.tag] = true;
|
||
});
|
||
tagNames = Object.keys(tags);
|
||
} else tagNames = [];
|
||
for (const [handle, prefix] of tagEntries) {
|
||
if (handle === "!!" && prefix === "tag:yaml.org,2002:") continue;
|
||
if (!doc || tagNames.some((tn) => tn.startsWith(prefix))) lines.push(`%TAG ${handle} ${prefix}`);
|
||
}
|
||
return lines.join("\n");
|
||
}
|
||
};
|
||
Directives.defaultYaml = {
|
||
explicit: false,
|
||
version: "1.2"
|
||
};
|
||
Directives.defaultTags = { "!!": "tag:yaml.org,2002:" };
|
||
exports.Directives = Directives;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/doc/anchors.js
|
||
var require_anchors = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var visit = require_visit();
|
||
/**
|
||
* Verify that the input string is a valid anchor.
|
||
*
|
||
* Will throw on errors.
|
||
*/
|
||
function anchorIsValid(anchor) {
|
||
if (/[\x00-\x19\s,[\]{}]/.test(anchor)) {
|
||
const msg = `Anchor must not contain whitespace or control characters: ${JSON.stringify(anchor)}`;
|
||
throw new Error(msg);
|
||
}
|
||
return true;
|
||
}
|
||
function anchorNames(root) {
|
||
const anchors = /* @__PURE__ */ new Set();
|
||
visit.visit(root, { Value(_key, node) {
|
||
if (node.anchor) anchors.add(node.anchor);
|
||
} });
|
||
return anchors;
|
||
}
|
||
/** Find a new anchor name with the given `prefix` and a one-indexed suffix. */
|
||
function findNewAnchor(prefix, exclude) {
|
||
for (let i = 1;; ++i) {
|
||
const name = `${prefix}${i}`;
|
||
if (!exclude.has(name)) return name;
|
||
}
|
||
}
|
||
function createNodeAnchors(doc, prefix) {
|
||
const aliasObjects = [];
|
||
const sourceObjects = /* @__PURE__ */ new Map();
|
||
let prevAnchors = null;
|
||
return {
|
||
onAnchor: (source) => {
|
||
aliasObjects.push(source);
|
||
prevAnchors ?? (prevAnchors = anchorNames(doc));
|
||
const anchor = findNewAnchor(prefix, prevAnchors);
|
||
prevAnchors.add(anchor);
|
||
return anchor;
|
||
},
|
||
setAnchors: () => {
|
||
for (const source of aliasObjects) {
|
||
const ref = sourceObjects.get(source);
|
||
if (typeof ref === "object" && ref.anchor && (identity.isScalar(ref.node) || identity.isCollection(ref.node))) ref.node.anchor = ref.anchor;
|
||
else {
|
||
const error = /* @__PURE__ */ new Error("Failed to resolve repeated object (this should not happen)");
|
||
error.source = source;
|
||
throw error;
|
||
}
|
||
}
|
||
},
|
||
sourceObjects
|
||
};
|
||
}
|
||
exports.anchorIsValid = anchorIsValid;
|
||
exports.anchorNames = anchorNames;
|
||
exports.createNodeAnchors = createNodeAnchors;
|
||
exports.findNewAnchor = findNewAnchor;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/doc/applyReviver.js
|
||
var require_applyReviver = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
/**
|
||
* Applies the JSON.parse reviver algorithm as defined in the ECMA-262 spec,
|
||
* in section 24.5.1.1 "Runtime Semantics: InternalizeJSONProperty" of the
|
||
* 2021 edition: https://tc39.es/ecma262/#sec-json.parse
|
||
*
|
||
* Includes extensions for handling Map and Set objects.
|
||
*/
|
||
function applyReviver(reviver, obj, key, val) {
|
||
if (val && typeof val === "object") if (Array.isArray(val)) for (let i = 0, len = val.length; i < len; ++i) {
|
||
const v0 = val[i];
|
||
const v1 = applyReviver(reviver, val, String(i), v0);
|
||
if (v1 === void 0) delete val[i];
|
||
else if (v1 !== v0) val[i] = v1;
|
||
}
|
||
else if (val instanceof Map) for (const k of Array.from(val.keys())) {
|
||
const v0 = val.get(k);
|
||
const v1 = applyReviver(reviver, val, k, v0);
|
||
if (v1 === void 0) val.delete(k);
|
||
else if (v1 !== v0) val.set(k, v1);
|
||
}
|
||
else if (val instanceof Set) for (const v0 of Array.from(val)) {
|
||
const v1 = applyReviver(reviver, val, v0, v0);
|
||
if (v1 === void 0) val.delete(v0);
|
||
else if (v1 !== v0) {
|
||
val.delete(v0);
|
||
val.add(v1);
|
||
}
|
||
}
|
||
else for (const [k, v0] of Object.entries(val)) {
|
||
const v1 = applyReviver(reviver, val, k, v0);
|
||
if (v1 === void 0) delete val[k];
|
||
else if (v1 !== v0) val[k] = v1;
|
||
}
|
||
return reviver.call(obj, key, val);
|
||
}
|
||
exports.applyReviver = applyReviver;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/nodes/toJS.js
|
||
var require_toJS = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
/**
|
||
* Recursively convert any node or its contents to native JavaScript
|
||
*
|
||
* @param value - The input value
|
||
* @param arg - If `value` defines a `toJSON()` method, use this
|
||
* as its first argument
|
||
* @param ctx - Conversion context, originally set in Document#toJS(). If
|
||
* `{ keep: true }` is not set, output should be suitable for JSON
|
||
* stringification.
|
||
*/
|
||
function toJS(value, arg, ctx) {
|
||
if (Array.isArray(value)) return value.map((v, i) => toJS(v, String(i), ctx));
|
||
if (value && typeof value.toJSON === "function") {
|
||
if (!ctx || !identity.hasAnchor(value)) return value.toJSON(arg, ctx);
|
||
const data = {
|
||
aliasCount: 0,
|
||
count: 1,
|
||
res: void 0
|
||
};
|
||
ctx.anchors.set(value, data);
|
||
ctx.onCreate = (res) => {
|
||
data.res = res;
|
||
delete ctx.onCreate;
|
||
};
|
||
const res = value.toJSON(arg, ctx);
|
||
if (ctx.onCreate) ctx.onCreate(res);
|
||
return res;
|
||
}
|
||
if (typeof value === "bigint" && !ctx?.keep) return Number(value);
|
||
return value;
|
||
}
|
||
exports.toJS = toJS;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/nodes/Node.js
|
||
var require_Node = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var applyReviver = require_applyReviver();
|
||
var identity = require_identity();
|
||
var toJS = require_toJS();
|
||
var NodeBase = class {
|
||
constructor(type) {
|
||
Object.defineProperty(this, identity.NODE_TYPE, { value: type });
|
||
}
|
||
/** Create a copy of this node. */
|
||
clone() {
|
||
const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));
|
||
if (this.range) copy.range = this.range.slice();
|
||
return copy;
|
||
}
|
||
/** A plain JavaScript representation of this node. */
|
||
toJS(doc, { mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {
|
||
if (!identity.isDocument(doc)) throw new TypeError("A document argument is required");
|
||
const ctx = {
|
||
anchors: /* @__PURE__ */ new Map(),
|
||
doc,
|
||
keep: true,
|
||
mapAsMap: mapAsMap === true,
|
||
mapKeyWarned: false,
|
||
maxAliasCount: typeof maxAliasCount === "number" ? maxAliasCount : 100
|
||
};
|
||
const res = toJS.toJS(this, "", ctx);
|
||
if (typeof onAnchor === "function") for (const { count, res } of ctx.anchors.values()) onAnchor(res, count);
|
||
return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res;
|
||
}
|
||
};
|
||
exports.NodeBase = NodeBase;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/nodes/Alias.js
|
||
var require_Alias = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var anchors = require_anchors();
|
||
var visit = require_visit();
|
||
var identity = require_identity();
|
||
var Node = require_Node();
|
||
var toJS = require_toJS();
|
||
var Alias = class extends Node.NodeBase {
|
||
constructor(source) {
|
||
super(identity.ALIAS);
|
||
this.source = source;
|
||
Object.defineProperty(this, "tag", { set() {
|
||
throw new Error("Alias nodes cannot have tags");
|
||
} });
|
||
}
|
||
/**
|
||
* Resolve the value of this alias within `doc`, finding the last
|
||
* instance of the `source` anchor before this node.
|
||
*/
|
||
resolve(doc, ctx) {
|
||
let nodes;
|
||
if (ctx?.aliasResolveCache) nodes = ctx.aliasResolveCache;
|
||
else {
|
||
nodes = [];
|
||
visit.visit(doc, { Node: (_key, node) => {
|
||
if (identity.isAlias(node) || identity.hasAnchor(node)) nodes.push(node);
|
||
} });
|
||
if (ctx) ctx.aliasResolveCache = nodes;
|
||
}
|
||
let found = void 0;
|
||
for (const node of nodes) {
|
||
if (node === this) break;
|
||
if (node.anchor === this.source) found = node;
|
||
}
|
||
return found;
|
||
}
|
||
toJSON(_arg, ctx) {
|
||
if (!ctx) return { source: this.source };
|
||
const { anchors, doc, maxAliasCount } = ctx;
|
||
const source = this.resolve(doc, ctx);
|
||
if (!source) {
|
||
const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
|
||
throw new ReferenceError(msg);
|
||
}
|
||
let data = anchors.get(source);
|
||
if (!data) {
|
||
toJS.toJS(source, null, ctx);
|
||
data = anchors.get(source);
|
||
}
|
||
/* istanbul ignore if */
|
||
if (data?.res === void 0) throw new ReferenceError("This should not happen: Alias anchor was not resolved?");
|
||
if (maxAliasCount >= 0) {
|
||
data.count += 1;
|
||
if (data.aliasCount === 0) data.aliasCount = getAliasCount(doc, source, anchors);
|
||
if (data.count * data.aliasCount > maxAliasCount) throw new ReferenceError("Excessive alias count indicates a resource exhaustion attack");
|
||
}
|
||
return data.res;
|
||
}
|
||
toString(ctx, _onComment, _onChompKeep) {
|
||
const src = `*${this.source}`;
|
||
if (ctx) {
|
||
anchors.anchorIsValid(this.source);
|
||
if (ctx.options.verifyAliasOrder && !ctx.anchors.has(this.source)) {
|
||
const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
|
||
throw new Error(msg);
|
||
}
|
||
if (ctx.implicitKey) return `${src} `;
|
||
}
|
||
return src;
|
||
}
|
||
};
|
||
function getAliasCount(doc, node, anchors) {
|
||
if (identity.isAlias(node)) {
|
||
const source = node.resolve(doc);
|
||
const anchor = anchors && source && anchors.get(source);
|
||
return anchor ? anchor.count * anchor.aliasCount : 0;
|
||
} else if (identity.isCollection(node)) {
|
||
let count = 0;
|
||
for (const item of node.items) {
|
||
const c = getAliasCount(doc, item, anchors);
|
||
if (c > count) count = c;
|
||
}
|
||
return count;
|
||
} else if (identity.isPair(node)) {
|
||
const kc = getAliasCount(doc, node.key, anchors);
|
||
const vc = getAliasCount(doc, node.value, anchors);
|
||
return Math.max(kc, vc);
|
||
}
|
||
return 1;
|
||
}
|
||
exports.Alias = Alias;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/nodes/Scalar.js
|
||
var require_Scalar = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var Node = require_Node();
|
||
var toJS = require_toJS();
|
||
const isScalarValue = (value) => !value || typeof value !== "function" && typeof value !== "object";
|
||
var Scalar = class extends Node.NodeBase {
|
||
constructor(value) {
|
||
super(identity.SCALAR);
|
||
this.value = value;
|
||
}
|
||
toJSON(arg, ctx) {
|
||
return ctx?.keep ? this.value : toJS.toJS(this.value, arg, ctx);
|
||
}
|
||
toString() {
|
||
return String(this.value);
|
||
}
|
||
};
|
||
Scalar.BLOCK_FOLDED = "BLOCK_FOLDED";
|
||
Scalar.BLOCK_LITERAL = "BLOCK_LITERAL";
|
||
Scalar.PLAIN = "PLAIN";
|
||
Scalar.QUOTE_DOUBLE = "QUOTE_DOUBLE";
|
||
Scalar.QUOTE_SINGLE = "QUOTE_SINGLE";
|
||
exports.Scalar = Scalar;
|
||
exports.isScalarValue = isScalarValue;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/doc/createNode.js
|
||
var require_createNode = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Alias = require_Alias();
|
||
var identity = require_identity();
|
||
var Scalar = require_Scalar();
|
||
const defaultTagPrefix = "tag:yaml.org,2002:";
|
||
function findTagObject(value, tagName, tags) {
|
||
if (tagName) {
|
||
const match = tags.filter((t) => t.tag === tagName);
|
||
const tagObj = match.find((t) => !t.format) ?? match[0];
|
||
if (!tagObj) throw new Error(`Tag ${tagName} not found`);
|
||
return tagObj;
|
||
}
|
||
return tags.find((t) => t.identify?.(value) && !t.format);
|
||
}
|
||
function createNode(value, tagName, ctx) {
|
||
if (identity.isDocument(value)) value = value.contents;
|
||
if (identity.isNode(value)) return value;
|
||
if (identity.isPair(value)) {
|
||
const map = ctx.schema[identity.MAP].createNode?.(ctx.schema, null, ctx);
|
||
map.items.push(value);
|
||
return map;
|
||
}
|
||
if (value instanceof String || value instanceof Number || value instanceof Boolean || typeof BigInt !== "undefined" && value instanceof BigInt) value = value.valueOf();
|
||
const { aliasDuplicateObjects, onAnchor, onTagObj, schema, sourceObjects } = ctx;
|
||
let ref = void 0;
|
||
if (aliasDuplicateObjects && value && typeof value === "object") {
|
||
ref = sourceObjects.get(value);
|
||
if (ref) {
|
||
ref.anchor ?? (ref.anchor = onAnchor(value));
|
||
return new Alias.Alias(ref.anchor);
|
||
} else {
|
||
ref = {
|
||
anchor: null,
|
||
node: null
|
||
};
|
||
sourceObjects.set(value, ref);
|
||
}
|
||
}
|
||
if (tagName?.startsWith("!!")) tagName = defaultTagPrefix + tagName.slice(2);
|
||
let tagObj = findTagObject(value, tagName, schema.tags);
|
||
if (!tagObj) {
|
||
if (value && typeof value.toJSON === "function") value = value.toJSON();
|
||
if (!value || typeof value !== "object") {
|
||
const node = new Scalar.Scalar(value);
|
||
if (ref) ref.node = node;
|
||
return node;
|
||
}
|
||
tagObj = value instanceof Map ? schema[identity.MAP] : Symbol.iterator in Object(value) ? schema[identity.SEQ] : schema[identity.MAP];
|
||
}
|
||
if (onTagObj) {
|
||
onTagObj(tagObj);
|
||
delete ctx.onTagObj;
|
||
}
|
||
const node = tagObj?.createNode ? tagObj.createNode(ctx.schema, value, ctx) : typeof tagObj?.nodeClass?.from === "function" ? tagObj.nodeClass.from(ctx.schema, value, ctx) : new Scalar.Scalar(value);
|
||
if (tagName) node.tag = tagName;
|
||
else if (!tagObj.default) node.tag = tagObj.tag;
|
||
if (ref) ref.node = node;
|
||
return node;
|
||
}
|
||
exports.createNode = createNode;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/nodes/Collection.js
|
||
var require_Collection = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var createNode = require_createNode();
|
||
var identity = require_identity();
|
||
var Node = require_Node();
|
||
function collectionFromPath(schema, path, value) {
|
||
let v = value;
|
||
for (let i = path.length - 1; i >= 0; --i) {
|
||
const k = path[i];
|
||
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
||
const a = [];
|
||
a[k] = v;
|
||
v = a;
|
||
} else v = new Map([[k, v]]);
|
||
}
|
||
return createNode.createNode(v, void 0, {
|
||
aliasDuplicateObjects: false,
|
||
keepUndefined: false,
|
||
onAnchor: () => {
|
||
throw new Error("This should not happen, please report a bug.");
|
||
},
|
||
schema,
|
||
sourceObjects: /* @__PURE__ */ new Map()
|
||
});
|
||
}
|
||
const isEmptyPath = (path) => path == null || typeof path === "object" && !!path[Symbol.iterator]().next().done;
|
||
var Collection = class extends Node.NodeBase {
|
||
constructor(type, schema) {
|
||
super(type);
|
||
Object.defineProperty(this, "schema", {
|
||
value: schema,
|
||
configurable: true,
|
||
enumerable: false,
|
||
writable: true
|
||
});
|
||
}
|
||
/**
|
||
* Create a copy of this collection.
|
||
*
|
||
* @param schema - If defined, overwrites the original's schema
|
||
*/
|
||
clone(schema) {
|
||
const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));
|
||
if (schema) copy.schema = schema;
|
||
copy.items = copy.items.map((it) => identity.isNode(it) || identity.isPair(it) ? it.clone(schema) : it);
|
||
if (this.range) copy.range = this.range.slice();
|
||
return copy;
|
||
}
|
||
/**
|
||
* Adds a value to the collection. For `!!map` and `!!omap` the value must
|
||
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
||
* that already exists in the map.
|
||
*/
|
||
addIn(path, value) {
|
||
if (isEmptyPath(path)) this.add(value);
|
||
else {
|
||
const [key, ...rest] = path;
|
||
const node = this.get(key, true);
|
||
if (identity.isCollection(node)) node.addIn(rest, value);
|
||
else if (node === void 0 && this.schema) this.set(key, collectionFromPath(this.schema, rest, value));
|
||
else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
|
||
}
|
||
}
|
||
/**
|
||
* Removes a value from the collection.
|
||
* @returns `true` if the item was found and removed.
|
||
*/
|
||
deleteIn(path) {
|
||
const [key, ...rest] = path;
|
||
if (rest.length === 0) return this.delete(key);
|
||
const node = this.get(key, true);
|
||
if (identity.isCollection(node)) return node.deleteIn(rest);
|
||
else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
|
||
}
|
||
/**
|
||
* Returns item at `key`, or `undefined` if not found. By default unwraps
|
||
* scalar values from their surrounding node; to disable set `keepScalar` to
|
||
* `true` (collections are always returned intact).
|
||
*/
|
||
getIn(path, keepScalar) {
|
||
const [key, ...rest] = path;
|
||
const node = this.get(key, true);
|
||
if (rest.length === 0) return !keepScalar && identity.isScalar(node) ? node.value : node;
|
||
else return identity.isCollection(node) ? node.getIn(rest, keepScalar) : void 0;
|
||
}
|
||
hasAllNullValues(allowScalar) {
|
||
return this.items.every((node) => {
|
||
if (!identity.isPair(node)) return false;
|
||
const n = node.value;
|
||
return n == null || allowScalar && identity.isScalar(n) && n.value == null && !n.commentBefore && !n.comment && !n.tag;
|
||
});
|
||
}
|
||
/**
|
||
* Checks if the collection includes a value with the key `key`.
|
||
*/
|
||
hasIn(path) {
|
||
const [key, ...rest] = path;
|
||
if (rest.length === 0) return this.has(key);
|
||
const node = this.get(key, true);
|
||
return identity.isCollection(node) ? node.hasIn(rest) : false;
|
||
}
|
||
/**
|
||
* Sets a value in this collection. For `!!set`, `value` needs to be a
|
||
* boolean to add/remove the item from the set.
|
||
*/
|
||
setIn(path, value) {
|
||
const [key, ...rest] = path;
|
||
if (rest.length === 0) this.set(key, value);
|
||
else {
|
||
const node = this.get(key, true);
|
||
if (identity.isCollection(node)) node.setIn(rest, value);
|
||
else if (node === void 0 && this.schema) this.set(key, collectionFromPath(this.schema, rest, value));
|
||
else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
|
||
}
|
||
}
|
||
};
|
||
exports.Collection = Collection;
|
||
exports.collectionFromPath = collectionFromPath;
|
||
exports.isEmptyPath = isEmptyPath;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/stringify/stringifyComment.js
|
||
var require_stringifyComment = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
/**
|
||
* Stringifies a comment.
|
||
*
|
||
* Empty comment lines are left empty,
|
||
* lines consisting of a single space are replaced by `#`,
|
||
* and all other lines are prefixed with a `#`.
|
||
*/
|
||
const stringifyComment = (str) => str.replace(/^(?!$)(?: $)?/gm, "#");
|
||
function indentComment(comment, indent) {
|
||
if (/^\n+$/.test(comment)) return comment.substring(1);
|
||
return indent ? comment.replace(/^(?! *$)/gm, indent) : comment;
|
||
}
|
||
const lineComment = (str, indent, comment) => str.endsWith("\n") ? indentComment(comment, indent) : comment.includes("\n") ? "\n" + indentComment(comment, indent) : (str.endsWith(" ") ? "" : " ") + comment;
|
||
exports.indentComment = indentComment;
|
||
exports.lineComment = lineComment;
|
||
exports.stringifyComment = stringifyComment;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/stringify/foldFlowLines.js
|
||
var require_foldFlowLines = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
const FOLD_FLOW = "flow";
|
||
const FOLD_BLOCK = "block";
|
||
const FOLD_QUOTED = "quoted";
|
||
/**
|
||
* Tries to keep input at up to `lineWidth` characters, splitting only on spaces
|
||
* not followed by newlines or spaces unless `mode` is `'quoted'`. Lines are
|
||
* terminated with `\n` and started with `indent`.
|
||
*/
|
||
function foldFlowLines(text, indent, mode = "flow", { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {
|
||
if (!lineWidth || lineWidth < 0) return text;
|
||
if (lineWidth < minContentWidth) minContentWidth = 0;
|
||
const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length);
|
||
if (text.length <= endStep) return text;
|
||
const folds = [];
|
||
const escapedFolds = {};
|
||
let end = lineWidth - indent.length;
|
||
if (typeof indentAtStart === "number") if (indentAtStart > lineWidth - Math.max(2, minContentWidth)) folds.push(0);
|
||
else end = lineWidth - indentAtStart;
|
||
let split = void 0;
|
||
let prev = void 0;
|
||
let overflow = false;
|
||
let i = -1;
|
||
let escStart = -1;
|
||
let escEnd = -1;
|
||
if (mode === FOLD_BLOCK) {
|
||
i = consumeMoreIndentedLines(text, i, indent.length);
|
||
if (i !== -1) end = i + endStep;
|
||
}
|
||
for (let ch; ch = text[i += 1];) {
|
||
if (mode === FOLD_QUOTED && ch === "\\") {
|
||
escStart = i;
|
||
switch (text[i + 1]) {
|
||
case "x":
|
||
i += 3;
|
||
break;
|
||
case "u":
|
||
i += 5;
|
||
break;
|
||
case "U":
|
||
i += 9;
|
||
break;
|
||
default: i += 1;
|
||
}
|
||
escEnd = i;
|
||
}
|
||
if (ch === "\n") {
|
||
if (mode === FOLD_BLOCK) i = consumeMoreIndentedLines(text, i, indent.length);
|
||
end = i + indent.length + endStep;
|
||
split = void 0;
|
||
} else {
|
||
if (ch === " " && prev && prev !== " " && prev !== "\n" && prev !== " ") {
|
||
const next = text[i + 1];
|
||
if (next && next !== " " && next !== "\n" && next !== " ") split = i;
|
||
}
|
||
if (i >= end) if (split) {
|
||
folds.push(split);
|
||
end = split + endStep;
|
||
split = void 0;
|
||
} else if (mode === FOLD_QUOTED) {
|
||
while (prev === " " || prev === " ") {
|
||
prev = ch;
|
||
ch = text[i += 1];
|
||
overflow = true;
|
||
}
|
||
const j = i > escEnd + 1 ? i - 2 : escStart - 1;
|
||
if (escapedFolds[j]) return text;
|
||
folds.push(j);
|
||
escapedFolds[j] = true;
|
||
end = j + endStep;
|
||
split = void 0;
|
||
} else overflow = true;
|
||
}
|
||
prev = ch;
|
||
}
|
||
if (overflow && onOverflow) onOverflow();
|
||
if (folds.length === 0) return text;
|
||
if (onFold) onFold();
|
||
let res = text.slice(0, folds[0]);
|
||
for (let i = 0; i < folds.length; ++i) {
|
||
const fold = folds[i];
|
||
const end = folds[i + 1] || text.length;
|
||
if (fold === 0) res = `\n${indent}${text.slice(0, end)}`;
|
||
else {
|
||
if (mode === FOLD_QUOTED && escapedFolds[fold]) res += `${text[fold]}\\`;
|
||
res += `\n${indent}${text.slice(fold + 1, end)}`;
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
/**
|
||
* Presumes `i + 1` is at the start of a line
|
||
* @returns index of last newline in more-indented block
|
||
*/
|
||
function consumeMoreIndentedLines(text, i, indent) {
|
||
let end = i;
|
||
let start = i + 1;
|
||
let ch = text[start];
|
||
while (ch === " " || ch === " ") if (i < start + indent) ch = text[++i];
|
||
else {
|
||
do
|
||
ch = text[++i];
|
||
while (ch && ch !== "\n");
|
||
end = i;
|
||
start = i + 1;
|
||
ch = text[start];
|
||
}
|
||
return end;
|
||
}
|
||
exports.FOLD_BLOCK = FOLD_BLOCK;
|
||
exports.FOLD_FLOW = FOLD_FLOW;
|
||
exports.FOLD_QUOTED = FOLD_QUOTED;
|
||
exports.foldFlowLines = foldFlowLines;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/stringify/stringifyString.js
|
||
var require_stringifyString = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Scalar = require_Scalar();
|
||
var foldFlowLines = require_foldFlowLines();
|
||
const getFoldOptions = (ctx, isBlock) => ({
|
||
indentAtStart: isBlock ? ctx.indent.length : ctx.indentAtStart,
|
||
lineWidth: ctx.options.lineWidth,
|
||
minContentWidth: ctx.options.minContentWidth
|
||
});
|
||
const containsDocumentMarker = (str) => /^(%|---|\.\.\.)/m.test(str);
|
||
function lineLengthOverLimit(str, lineWidth, indentLength) {
|
||
if (!lineWidth || lineWidth < 0) return false;
|
||
const limit = lineWidth - indentLength;
|
||
const strLen = str.length;
|
||
if (strLen <= limit) return false;
|
||
for (let i = 0, start = 0; i < strLen; ++i) if (str[i] === "\n") {
|
||
if (i - start > limit) return true;
|
||
start = i + 1;
|
||
if (strLen - start <= limit) return false;
|
||
}
|
||
return true;
|
||
}
|
||
function doubleQuotedString(value, ctx) {
|
||
const json = JSON.stringify(value);
|
||
if (ctx.options.doubleQuotedAsJSON) return json;
|
||
const { implicitKey } = ctx;
|
||
const minMultiLineLength = ctx.options.doubleQuotedMinMultiLineLength;
|
||
const indent = ctx.indent || (containsDocumentMarker(value) ? " " : "");
|
||
let str = "";
|
||
let start = 0;
|
||
for (let i = 0, ch = json[i]; ch; ch = json[++i]) {
|
||
if (ch === " " && json[i + 1] === "\\" && json[i + 2] === "n") {
|
||
str += json.slice(start, i) + "\\ ";
|
||
i += 1;
|
||
start = i;
|
||
ch = "\\";
|
||
}
|
||
if (ch === "\\") switch (json[i + 1]) {
|
||
case "u":
|
||
{
|
||
str += json.slice(start, i);
|
||
const code = json.substr(i + 2, 4);
|
||
switch (code) {
|
||
case "0000":
|
||
str += "\\0";
|
||
break;
|
||
case "0007":
|
||
str += "\\a";
|
||
break;
|
||
case "000b":
|
||
str += "\\v";
|
||
break;
|
||
case "001b":
|
||
str += "\\e";
|
||
break;
|
||
case "0085":
|
||
str += "\\N";
|
||
break;
|
||
case "00a0":
|
||
str += "\\_";
|
||
break;
|
||
case "2028":
|
||
str += "\\L";
|
||
break;
|
||
case "2029":
|
||
str += "\\P";
|
||
break;
|
||
default: if (code.substr(0, 2) === "00") str += "\\x" + code.substr(2);
|
||
else str += json.substr(i, 6);
|
||
}
|
||
i += 5;
|
||
start = i + 1;
|
||
}
|
||
break;
|
||
case "n":
|
||
if (implicitKey || json[i + 2] === "\"" || json.length < minMultiLineLength) i += 1;
|
||
else {
|
||
str += json.slice(start, i) + "\n\n";
|
||
while (json[i + 2] === "\\" && json[i + 3] === "n" && json[i + 4] !== "\"") {
|
||
str += "\n";
|
||
i += 2;
|
||
}
|
||
str += indent;
|
||
if (json[i + 2] === " ") str += "\\";
|
||
i += 1;
|
||
start = i + 1;
|
||
}
|
||
break;
|
||
default: i += 1;
|
||
}
|
||
}
|
||
str = start ? str + json.slice(start) : json;
|
||
return implicitKey ? str : foldFlowLines.foldFlowLines(str, indent, foldFlowLines.FOLD_QUOTED, getFoldOptions(ctx, false));
|
||
}
|
||
function singleQuotedString(value, ctx) {
|
||
if (ctx.options.singleQuote === false || ctx.implicitKey && value.includes("\n") || /[ \t]\n|\n[ \t]/.test(value)) return doubleQuotedString(value, ctx);
|
||
const indent = ctx.indent || (containsDocumentMarker(value) ? " " : "");
|
||
const res = "'" + value.replace(/'/g, "''").replace(/\n+/g, `$&\n${indent}`) + "'";
|
||
return ctx.implicitKey ? res : foldFlowLines.foldFlowLines(res, indent, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
|
||
}
|
||
function quotedString(value, ctx) {
|
||
const { singleQuote } = ctx.options;
|
||
let qs;
|
||
if (singleQuote === false) qs = doubleQuotedString;
|
||
else {
|
||
const hasDouble = value.includes("\"");
|
||
const hasSingle = value.includes("'");
|
||
if (hasDouble && !hasSingle) qs = singleQuotedString;
|
||
else if (hasSingle && !hasDouble) qs = doubleQuotedString;
|
||
else qs = singleQuote ? singleQuotedString : doubleQuotedString;
|
||
}
|
||
return qs(value, ctx);
|
||
}
|
||
let blockEndNewlines;
|
||
try {
|
||
blockEndNewlines = /* @__PURE__ */ new RegExp("(^|(?<!\n))\n+(?!\n|$)", "g");
|
||
} catch {
|
||
blockEndNewlines = /\n+(?!\n|$)/g;
|
||
}
|
||
function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
|
||
const { blockQuote, commentString, lineWidth } = ctx.options;
|
||
if (!blockQuote || /\n[\t ]+$/.test(value)) return quotedString(value, ctx);
|
||
const indent = ctx.indent || (ctx.forceBlockIndent || containsDocumentMarker(value) ? " " : "");
|
||
const literal = blockQuote === "literal" ? true : blockQuote === "folded" || type === Scalar.Scalar.BLOCK_FOLDED ? false : type === Scalar.Scalar.BLOCK_LITERAL ? true : !lineLengthOverLimit(value, lineWidth, indent.length);
|
||
if (!value) return literal ? "|\n" : ">\n";
|
||
let chomp;
|
||
let endStart;
|
||
for (endStart = value.length; endStart > 0; --endStart) {
|
||
const ch = value[endStart - 1];
|
||
if (ch !== "\n" && ch !== " " && ch !== " ") break;
|
||
}
|
||
let end = value.substring(endStart);
|
||
const endNlPos = end.indexOf("\n");
|
||
if (endNlPos === -1) chomp = "-";
|
||
else if (value === end || endNlPos !== end.length - 1) {
|
||
chomp = "+";
|
||
if (onChompKeep) onChompKeep();
|
||
} else chomp = "";
|
||
if (end) {
|
||
value = value.slice(0, -end.length);
|
||
if (end[end.length - 1] === "\n") end = end.slice(0, -1);
|
||
end = end.replace(blockEndNewlines, `$&${indent}`);
|
||
}
|
||
let startWithSpace = false;
|
||
let startEnd;
|
||
let startNlPos = -1;
|
||
for (startEnd = 0; startEnd < value.length; ++startEnd) {
|
||
const ch = value[startEnd];
|
||
if (ch === " ") startWithSpace = true;
|
||
else if (ch === "\n") startNlPos = startEnd;
|
||
else break;
|
||
}
|
||
let start = value.substring(0, startNlPos < startEnd ? startNlPos + 1 : startEnd);
|
||
if (start) {
|
||
value = value.substring(start.length);
|
||
start = start.replace(/\n+/g, `$&${indent}`);
|
||
}
|
||
let header = (startWithSpace ? indent ? "2" : "1" : "") + chomp;
|
||
if (comment) {
|
||
header += " " + commentString(comment.replace(/ ?[\r\n]+/g, " "));
|
||
if (onComment) onComment();
|
||
}
|
||
if (!literal) {
|
||
const foldedValue = value.replace(/\n+/g, "\n$&").replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, "$1$2").replace(/\n+/g, `$&${indent}`);
|
||
let literalFallback = false;
|
||
const foldOptions = getFoldOptions(ctx, true);
|
||
if (blockQuote !== "folded" && type !== Scalar.Scalar.BLOCK_FOLDED) foldOptions.onOverflow = () => {
|
||
literalFallback = true;
|
||
};
|
||
const body = foldFlowLines.foldFlowLines(`${start}${foldedValue}${end}`, indent, foldFlowLines.FOLD_BLOCK, foldOptions);
|
||
if (!literalFallback) return `>${header}\n${indent}${body}`;
|
||
}
|
||
value = value.replace(/\n+/g, `$&${indent}`);
|
||
return `|${header}\n${indent}${start}${value}${end}`;
|
||
}
|
||
function plainString(item, ctx, onComment, onChompKeep) {
|
||
const { type, value } = item;
|
||
const { actualString, implicitKey, indent, indentStep, inFlow } = ctx;
|
||
if (implicitKey && value.includes("\n") || inFlow && /[[\]{},]/.test(value)) return quotedString(value, ctx);
|
||
if (/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) return implicitKey || inFlow || !value.includes("\n") ? quotedString(value, ctx) : blockString(item, ctx, onComment, onChompKeep);
|
||
if (!implicitKey && !inFlow && type !== Scalar.Scalar.PLAIN && value.includes("\n")) return blockString(item, ctx, onComment, onChompKeep);
|
||
if (containsDocumentMarker(value)) {
|
||
if (indent === "") {
|
||
ctx.forceBlockIndent = true;
|
||
return blockString(item, ctx, onComment, onChompKeep);
|
||
} else if (implicitKey && indent === indentStep) return quotedString(value, ctx);
|
||
}
|
||
const str = value.replace(/\n+/g, `$&\n${indent}`);
|
||
if (actualString) {
|
||
const test = (tag) => tag.default && tag.tag !== "tag:yaml.org,2002:str" && tag.test?.test(str);
|
||
const { compat, tags } = ctx.doc.schema;
|
||
if (tags.some(test) || compat?.some(test)) return quotedString(value, ctx);
|
||
}
|
||
return implicitKey ? str : foldFlowLines.foldFlowLines(str, indent, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
|
||
}
|
||
function stringifyString(item, ctx, onComment, onChompKeep) {
|
||
const { implicitKey, inFlow } = ctx;
|
||
const ss = typeof item.value === "string" ? item : Object.assign({}, item, { value: String(item.value) });
|
||
let { type } = item;
|
||
if (type !== Scalar.Scalar.QUOTE_DOUBLE) {
|
||
if (/[\x00-\x08\x0b-\x1f\x7f-\x9f\u{D800}-\u{DFFF}]/u.test(ss.value)) type = Scalar.Scalar.QUOTE_DOUBLE;
|
||
}
|
||
const _stringify = (_type) => {
|
||
switch (_type) {
|
||
case Scalar.Scalar.BLOCK_FOLDED:
|
||
case Scalar.Scalar.BLOCK_LITERAL: return implicitKey || inFlow ? quotedString(ss.value, ctx) : blockString(ss, ctx, onComment, onChompKeep);
|
||
case Scalar.Scalar.QUOTE_DOUBLE: return doubleQuotedString(ss.value, ctx);
|
||
case Scalar.Scalar.QUOTE_SINGLE: return singleQuotedString(ss.value, ctx);
|
||
case Scalar.Scalar.PLAIN: return plainString(ss, ctx, onComment, onChompKeep);
|
||
default: return null;
|
||
}
|
||
};
|
||
let res = _stringify(type);
|
||
if (res === null) {
|
||
const { defaultKeyType, defaultStringType } = ctx.options;
|
||
const t = implicitKey && defaultKeyType || defaultStringType;
|
||
res = _stringify(t);
|
||
if (res === null) throw new Error(`Unsupported default string type ${t}`);
|
||
}
|
||
return res;
|
||
}
|
||
exports.stringifyString = stringifyString;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/stringify/stringify.js
|
||
var require_stringify = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var anchors = require_anchors();
|
||
var identity = require_identity();
|
||
var stringifyComment = require_stringifyComment();
|
||
var stringifyString = require_stringifyString();
|
||
function createStringifyContext(doc, options) {
|
||
const opt = Object.assign({
|
||
blockQuote: true,
|
||
commentString: stringifyComment.stringifyComment,
|
||
defaultKeyType: null,
|
||
defaultStringType: "PLAIN",
|
||
directives: null,
|
||
doubleQuotedAsJSON: false,
|
||
doubleQuotedMinMultiLineLength: 40,
|
||
falseStr: "false",
|
||
flowCollectionPadding: true,
|
||
indentSeq: true,
|
||
lineWidth: 80,
|
||
minContentWidth: 20,
|
||
nullStr: "null",
|
||
simpleKeys: false,
|
||
singleQuote: null,
|
||
trueStr: "true",
|
||
verifyAliasOrder: true
|
||
}, doc.schema.toStringOptions, options);
|
||
let inFlow;
|
||
switch (opt.collectionStyle) {
|
||
case "block":
|
||
inFlow = false;
|
||
break;
|
||
case "flow":
|
||
inFlow = true;
|
||
break;
|
||
default: inFlow = null;
|
||
}
|
||
return {
|
||
anchors: /* @__PURE__ */ new Set(),
|
||
doc,
|
||
flowCollectionPadding: opt.flowCollectionPadding ? " " : "",
|
||
indent: "",
|
||
indentStep: typeof opt.indent === "number" ? " ".repeat(opt.indent) : " ",
|
||
inFlow,
|
||
options: opt
|
||
};
|
||
}
|
||
function getTagObject(tags, item) {
|
||
if (item.tag) {
|
||
const match = tags.filter((t) => t.tag === item.tag);
|
||
if (match.length > 0) return match.find((t) => t.format === item.format) ?? match[0];
|
||
}
|
||
let tagObj = void 0;
|
||
let obj;
|
||
if (identity.isScalar(item)) {
|
||
obj = item.value;
|
||
let match = tags.filter((t) => t.identify?.(obj));
|
||
if (match.length > 1) {
|
||
const testMatch = match.filter((t) => t.test);
|
||
if (testMatch.length > 0) match = testMatch;
|
||
}
|
||
tagObj = match.find((t) => t.format === item.format) ?? match.find((t) => !t.format);
|
||
} else {
|
||
obj = item;
|
||
tagObj = tags.find((t) => t.nodeClass && obj instanceof t.nodeClass);
|
||
}
|
||
if (!tagObj) {
|
||
const name = obj?.constructor?.name ?? (obj === null ? "null" : typeof obj);
|
||
throw new Error(`Tag not resolved for ${name} value`);
|
||
}
|
||
return tagObj;
|
||
}
|
||
function stringifyProps(node, tagObj, { anchors: anchors$1, doc }) {
|
||
if (!doc.directives) return "";
|
||
const props = [];
|
||
const anchor = (identity.isScalar(node) || identity.isCollection(node)) && node.anchor;
|
||
if (anchor && anchors.anchorIsValid(anchor)) {
|
||
anchors$1.add(anchor);
|
||
props.push(`&${anchor}`);
|
||
}
|
||
const tag = node.tag ?? (tagObj.default ? null : tagObj.tag);
|
||
if (tag) props.push(doc.directives.tagString(tag));
|
||
return props.join(" ");
|
||
}
|
||
function stringify(item, ctx, onComment, onChompKeep) {
|
||
if (identity.isPair(item)) return item.toString(ctx, onComment, onChompKeep);
|
||
if (identity.isAlias(item)) {
|
||
if (ctx.doc.directives) return item.toString(ctx);
|
||
if (ctx.resolvedAliases?.has(item)) throw new TypeError(`Cannot stringify circular structure without alias nodes`);
|
||
else {
|
||
if (ctx.resolvedAliases) ctx.resolvedAliases.add(item);
|
||
else ctx.resolvedAliases = new Set([item]);
|
||
item = item.resolve(ctx.doc);
|
||
}
|
||
}
|
||
let tagObj = void 0;
|
||
const node = identity.isNode(item) ? item : ctx.doc.createNode(item, { onTagObj: (o) => tagObj = o });
|
||
tagObj ?? (tagObj = getTagObject(ctx.doc.schema.tags, node));
|
||
const props = stringifyProps(node, tagObj, ctx);
|
||
if (props.length > 0) ctx.indentAtStart = (ctx.indentAtStart ?? 0) + props.length + 1;
|
||
const str = typeof tagObj.stringify === "function" ? tagObj.stringify(node, ctx, onComment, onChompKeep) : identity.isScalar(node) ? stringifyString.stringifyString(node, ctx, onComment, onChompKeep) : node.toString(ctx, onComment, onChompKeep);
|
||
if (!props) return str;
|
||
return identity.isScalar(node) || str[0] === "{" || str[0] === "[" ? `${props} ${str}` : `${props}\n${ctx.indent}${str}`;
|
||
}
|
||
exports.createStringifyContext = createStringifyContext;
|
||
exports.stringify = stringify;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/stringify/stringifyPair.js
|
||
var require_stringifyPair = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var Scalar = require_Scalar();
|
||
var stringify = require_stringify();
|
||
var stringifyComment = require_stringifyComment();
|
||
function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
|
||
const { allNullValues, doc, indent, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx;
|
||
let keyComment = identity.isNode(key) && key.comment || null;
|
||
if (simpleKeys) {
|
||
if (keyComment) throw new Error("With simple keys, key nodes cannot have comments");
|
||
if (identity.isCollection(key) || !identity.isNode(key) && typeof key === "object") throw new Error("With simple keys, collection cannot be used as a key value");
|
||
}
|
||
let explicitKey = !simpleKeys && (!key || keyComment && value == null && !ctx.inFlow || identity.isCollection(key) || (identity.isScalar(key) ? key.type === Scalar.Scalar.BLOCK_FOLDED || key.type === Scalar.Scalar.BLOCK_LITERAL : typeof key === "object"));
|
||
ctx = Object.assign({}, ctx, {
|
||
allNullValues: false,
|
||
implicitKey: !explicitKey && (simpleKeys || !allNullValues),
|
||
indent: indent + indentStep
|
||
});
|
||
let keyCommentDone = false;
|
||
let chompKeep = false;
|
||
let str = stringify.stringify(key, ctx, () => keyCommentDone = true, () => chompKeep = true);
|
||
if (!explicitKey && !ctx.inFlow && str.length > 1024) {
|
||
if (simpleKeys) throw new Error("With simple keys, single line scalar must not span more than 1024 characters");
|
||
explicitKey = true;
|
||
}
|
||
if (ctx.inFlow) {
|
||
if (allNullValues || value == null) {
|
||
if (keyCommentDone && onComment) onComment();
|
||
return str === "" ? "?" : explicitKey ? `? ${str}` : str;
|
||
}
|
||
} else if (allNullValues && !simpleKeys || value == null && explicitKey) {
|
||
str = `? ${str}`;
|
||
if (keyComment && !keyCommentDone) str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
|
||
else if (chompKeep && onChompKeep) onChompKeep();
|
||
return str;
|
||
}
|
||
if (keyCommentDone) keyComment = null;
|
||
if (explicitKey) {
|
||
if (keyComment) str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
|
||
str = `? ${str}\n${indent}:`;
|
||
} else {
|
||
str = `${str}:`;
|
||
if (keyComment) str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
|
||
}
|
||
let vsb, vcb, valueComment;
|
||
if (identity.isNode(value)) {
|
||
vsb = !!value.spaceBefore;
|
||
vcb = value.commentBefore;
|
||
valueComment = value.comment;
|
||
} else {
|
||
vsb = false;
|
||
vcb = null;
|
||
valueComment = null;
|
||
if (value && typeof value === "object") value = doc.createNode(value);
|
||
}
|
||
ctx.implicitKey = false;
|
||
if (!explicitKey && !keyComment && identity.isScalar(value)) ctx.indentAtStart = str.length + 1;
|
||
chompKeep = false;
|
||
if (!indentSeq && indentStep.length >= 2 && !ctx.inFlow && !explicitKey && identity.isSeq(value) && !value.flow && !value.tag && !value.anchor) ctx.indent = ctx.indent.substring(2);
|
||
let valueCommentDone = false;
|
||
const valueStr = stringify.stringify(value, ctx, () => valueCommentDone = true, () => chompKeep = true);
|
||
let ws = " ";
|
||
if (keyComment || vsb || vcb) {
|
||
ws = vsb ? "\n" : "";
|
||
if (vcb) {
|
||
const cs = commentString(vcb);
|
||
ws += `\n${stringifyComment.indentComment(cs, ctx.indent)}`;
|
||
}
|
||
if (valueStr === "" && !ctx.inFlow) {
|
||
if (ws === "\n" && valueComment) ws = "\n\n";
|
||
} else ws += `\n${ctx.indent}`;
|
||
} else if (!explicitKey && identity.isCollection(value)) {
|
||
const vs0 = valueStr[0];
|
||
const nl0 = valueStr.indexOf("\n");
|
||
const hasNewline = nl0 !== -1;
|
||
const flow = ctx.inFlow ?? value.flow ?? value.items.length === 0;
|
||
if (hasNewline || !flow) {
|
||
let hasPropsLine = false;
|
||
if (hasNewline && (vs0 === "&" || vs0 === "!")) {
|
||
let sp0 = valueStr.indexOf(" ");
|
||
if (vs0 === "&" && sp0 !== -1 && sp0 < nl0 && valueStr[sp0 + 1] === "!") sp0 = valueStr.indexOf(" ", sp0 + 1);
|
||
if (sp0 === -1 || nl0 < sp0) hasPropsLine = true;
|
||
}
|
||
if (!hasPropsLine) ws = `\n${ctx.indent}`;
|
||
}
|
||
} else if (valueStr === "" || valueStr[0] === "\n") ws = "";
|
||
str += ws + valueStr;
|
||
if (ctx.inFlow) {
|
||
if (valueCommentDone && onComment) onComment();
|
||
} else if (valueComment && !valueCommentDone) str += stringifyComment.lineComment(str, ctx.indent, commentString(valueComment));
|
||
else if (chompKeep && onChompKeep) onChompKeep();
|
||
return str;
|
||
}
|
||
exports.stringifyPair = stringifyPair;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/log.js
|
||
var require_log = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var node_process$2 = __require("process");
|
||
function debug(logLevel, ...messages) {
|
||
if (logLevel === "debug") console.log(...messages);
|
||
}
|
||
function warn(logLevel, warning) {
|
||
if (logLevel === "debug" || logLevel === "warn") if (typeof node_process$2.emitWarning === "function") node_process$2.emitWarning(warning);
|
||
else console.warn(warning);
|
||
}
|
||
exports.debug = debug;
|
||
exports.warn = warn;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/yaml-1.1/merge.js
|
||
var require_merge = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var Scalar = require_Scalar();
|
||
const MERGE_KEY = "<<";
|
||
const merge = {
|
||
identify: (value) => value === MERGE_KEY || typeof value === "symbol" && value.description === MERGE_KEY,
|
||
default: "key",
|
||
tag: "tag:yaml.org,2002:merge",
|
||
test: /^<<$/,
|
||
resolve: () => Object.assign(new Scalar.Scalar(Symbol(MERGE_KEY)), { addToJSMap: addMergeToJSMap }),
|
||
stringify: () => MERGE_KEY
|
||
};
|
||
const isMergeKey = (ctx, key) => (merge.identify(key) || identity.isScalar(key) && (!key.type || key.type === Scalar.Scalar.PLAIN) && merge.identify(key.value)) && ctx?.doc.schema.tags.some((tag) => tag.tag === merge.tag && tag.default);
|
||
function addMergeToJSMap(ctx, map, value) {
|
||
value = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value;
|
||
if (identity.isSeq(value)) for (const it of value.items) mergeValue(ctx, map, it);
|
||
else if (Array.isArray(value)) for (const it of value) mergeValue(ctx, map, it);
|
||
else mergeValue(ctx, map, value);
|
||
}
|
||
function mergeValue(ctx, map, value) {
|
||
const source = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value;
|
||
if (!identity.isMap(source)) throw new Error("Merge sources must be maps or map aliases");
|
||
const srcMap = source.toJSON(null, ctx, Map);
|
||
for (const [key, value] of srcMap) if (map instanceof Map) {
|
||
if (!map.has(key)) map.set(key, value);
|
||
} else if (map instanceof Set) map.add(key);
|
||
else if (!Object.prototype.hasOwnProperty.call(map, key)) Object.defineProperty(map, key, {
|
||
value,
|
||
writable: true,
|
||
enumerable: true,
|
||
configurable: true
|
||
});
|
||
return map;
|
||
}
|
||
exports.addMergeToJSMap = addMergeToJSMap;
|
||
exports.isMergeKey = isMergeKey;
|
||
exports.merge = merge;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/nodes/addPairToJSMap.js
|
||
var require_addPairToJSMap = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var log = require_log();
|
||
var merge = require_merge();
|
||
var stringify = require_stringify();
|
||
var identity = require_identity();
|
||
var toJS = require_toJS();
|
||
function addPairToJSMap(ctx, map, { key, value }) {
|
||
if (identity.isNode(key) && key.addToJSMap) key.addToJSMap(ctx, map, value);
|
||
else if (merge.isMergeKey(ctx, key)) merge.addMergeToJSMap(ctx, map, value);
|
||
else {
|
||
const jsKey = toJS.toJS(key, "", ctx);
|
||
if (map instanceof Map) map.set(jsKey, toJS.toJS(value, jsKey, ctx));
|
||
else if (map instanceof Set) map.add(jsKey);
|
||
else {
|
||
const stringKey = stringifyKey(key, jsKey, ctx);
|
||
const jsValue = toJS.toJS(value, stringKey, ctx);
|
||
if (stringKey in map) Object.defineProperty(map, stringKey, {
|
||
value: jsValue,
|
||
writable: true,
|
||
enumerable: true,
|
||
configurable: true
|
||
});
|
||
else map[stringKey] = jsValue;
|
||
}
|
||
}
|
||
return map;
|
||
}
|
||
function stringifyKey(key, jsKey, ctx) {
|
||
if (jsKey === null) return "";
|
||
if (typeof jsKey !== "object") return String(jsKey);
|
||
if (identity.isNode(key) && ctx?.doc) {
|
||
const strCtx = stringify.createStringifyContext(ctx.doc, {});
|
||
strCtx.anchors = /* @__PURE__ */ new Set();
|
||
for (const node of ctx.anchors.keys()) strCtx.anchors.add(node.anchor);
|
||
strCtx.inFlow = true;
|
||
strCtx.inStringifyKey = true;
|
||
const strKey = key.toString(strCtx);
|
||
if (!ctx.mapKeyWarned) {
|
||
let jsonStr = JSON.stringify(strKey);
|
||
if (jsonStr.length > 40) jsonStr = jsonStr.substring(0, 36) + "...\"";
|
||
log.warn(ctx.doc.options.logLevel, `Keys with collection values will be stringified due to JS Object restrictions: ${jsonStr}. Set mapAsMap: true to use object keys.`);
|
||
ctx.mapKeyWarned = true;
|
||
}
|
||
return strKey;
|
||
}
|
||
return JSON.stringify(jsKey);
|
||
}
|
||
exports.addPairToJSMap = addPairToJSMap;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/nodes/Pair.js
|
||
var require_Pair = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var createNode = require_createNode();
|
||
var stringifyPair = require_stringifyPair();
|
||
var addPairToJSMap = require_addPairToJSMap();
|
||
var identity = require_identity();
|
||
function createPair(key, value, ctx) {
|
||
return new Pair(createNode.createNode(key, void 0, ctx), createNode.createNode(value, void 0, ctx));
|
||
}
|
||
var Pair = class Pair {
|
||
constructor(key, value = null) {
|
||
Object.defineProperty(this, identity.NODE_TYPE, { value: identity.PAIR });
|
||
this.key = key;
|
||
this.value = value;
|
||
}
|
||
clone(schema) {
|
||
let { key, value } = this;
|
||
if (identity.isNode(key)) key = key.clone(schema);
|
||
if (identity.isNode(value)) value = value.clone(schema);
|
||
return new Pair(key, value);
|
||
}
|
||
toJSON(_, ctx) {
|
||
const pair = ctx?.mapAsMap ? /* @__PURE__ */ new Map() : {};
|
||
return addPairToJSMap.addPairToJSMap(ctx, pair, this);
|
||
}
|
||
toString(ctx, onComment, onChompKeep) {
|
||
return ctx?.doc ? stringifyPair.stringifyPair(this, ctx, onComment, onChompKeep) : JSON.stringify(this);
|
||
}
|
||
};
|
||
exports.Pair = Pair;
|
||
exports.createPair = createPair;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/stringify/stringifyCollection.js
|
||
var require_stringifyCollection = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var stringify = require_stringify();
|
||
var stringifyComment = require_stringifyComment();
|
||
function stringifyCollection(collection, ctx, options) {
|
||
return (ctx.inFlow ?? collection.flow ? stringifyFlowCollection : stringifyBlockCollection)(collection, ctx, options);
|
||
}
|
||
function stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, flowChars, itemIndent, onChompKeep, onComment }) {
|
||
const { indent, options: { commentString } } = ctx;
|
||
const itemCtx = Object.assign({}, ctx, {
|
||
indent: itemIndent,
|
||
type: null
|
||
});
|
||
let chompKeep = false;
|
||
const lines = [];
|
||
for (let i = 0; i < items.length; ++i) {
|
||
const item = items[i];
|
||
let comment = null;
|
||
if (identity.isNode(item)) {
|
||
if (!chompKeep && item.spaceBefore) lines.push("");
|
||
addCommentBefore(ctx, lines, item.commentBefore, chompKeep);
|
||
if (item.comment) comment = item.comment;
|
||
} else if (identity.isPair(item)) {
|
||
const ik = identity.isNode(item.key) ? item.key : null;
|
||
if (ik) {
|
||
if (!chompKeep && ik.spaceBefore) lines.push("");
|
||
addCommentBefore(ctx, lines, ik.commentBefore, chompKeep);
|
||
}
|
||
}
|
||
chompKeep = false;
|
||
let str = stringify.stringify(item, itemCtx, () => comment = null, () => chompKeep = true);
|
||
if (comment) str += stringifyComment.lineComment(str, itemIndent, commentString(comment));
|
||
if (chompKeep && comment) chompKeep = false;
|
||
lines.push(blockItemPrefix + str);
|
||
}
|
||
let str;
|
||
if (lines.length === 0) str = flowChars.start + flowChars.end;
|
||
else {
|
||
str = lines[0];
|
||
for (let i = 1; i < lines.length; ++i) {
|
||
const line = lines[i];
|
||
str += line ? `\n${indent}${line}` : "\n";
|
||
}
|
||
}
|
||
if (comment) {
|
||
str += "\n" + stringifyComment.indentComment(commentString(comment), indent);
|
||
if (onComment) onComment();
|
||
} else if (chompKeep && onChompKeep) onChompKeep();
|
||
return str;
|
||
}
|
||
function stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {
|
||
const { indent, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx;
|
||
itemIndent += indentStep;
|
||
const itemCtx = Object.assign({}, ctx, {
|
||
indent: itemIndent,
|
||
inFlow: true,
|
||
type: null
|
||
});
|
||
let reqNewline = false;
|
||
let linesAtValue = 0;
|
||
const lines = [];
|
||
for (let i = 0; i < items.length; ++i) {
|
||
const item = items[i];
|
||
let comment = null;
|
||
if (identity.isNode(item)) {
|
||
if (item.spaceBefore) lines.push("");
|
||
addCommentBefore(ctx, lines, item.commentBefore, false);
|
||
if (item.comment) comment = item.comment;
|
||
} else if (identity.isPair(item)) {
|
||
const ik = identity.isNode(item.key) ? item.key : null;
|
||
if (ik) {
|
||
if (ik.spaceBefore) lines.push("");
|
||
addCommentBefore(ctx, lines, ik.commentBefore, false);
|
||
if (ik.comment) reqNewline = true;
|
||
}
|
||
const iv = identity.isNode(item.value) ? item.value : null;
|
||
if (iv) {
|
||
if (iv.comment) comment = iv.comment;
|
||
if (iv.commentBefore) reqNewline = true;
|
||
} else if (item.value == null && ik?.comment) comment = ik.comment;
|
||
}
|
||
if (comment) reqNewline = true;
|
||
let str = stringify.stringify(item, itemCtx, () => comment = null);
|
||
if (i < items.length - 1) str += ",";
|
||
if (comment) str += stringifyComment.lineComment(str, itemIndent, commentString(comment));
|
||
if (!reqNewline && (lines.length > linesAtValue || str.includes("\n"))) reqNewline = true;
|
||
lines.push(str);
|
||
linesAtValue = lines.length;
|
||
}
|
||
const { start, end } = flowChars;
|
||
if (lines.length === 0) return start + end;
|
||
else {
|
||
if (!reqNewline) {
|
||
const len = lines.reduce((sum, line) => sum + line.length + 2, 2);
|
||
reqNewline = ctx.options.lineWidth > 0 && len > ctx.options.lineWidth;
|
||
}
|
||
if (reqNewline) {
|
||
let str = start;
|
||
for (const line of lines) str += line ? `\n${indentStep}${indent}${line}` : "\n";
|
||
return `${str}\n${indent}${end}`;
|
||
} else return `${start}${fcPadding}${lines.join(" ")}${fcPadding}${end}`;
|
||
}
|
||
}
|
||
function addCommentBefore({ indent, options: { commentString } }, lines, comment, chompKeep) {
|
||
if (comment && chompKeep) comment = comment.replace(/^\n+/, "");
|
||
if (comment) {
|
||
const ic = stringifyComment.indentComment(commentString(comment), indent);
|
||
lines.push(ic.trimStart());
|
||
}
|
||
}
|
||
exports.stringifyCollection = stringifyCollection;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/nodes/YAMLMap.js
|
||
var require_YAMLMap = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var stringifyCollection = require_stringifyCollection();
|
||
var addPairToJSMap = require_addPairToJSMap();
|
||
var Collection = require_Collection();
|
||
var identity = require_identity();
|
||
var Pair = require_Pair();
|
||
var Scalar = require_Scalar();
|
||
function findPair(items, key) {
|
||
const k = identity.isScalar(key) ? key.value : key;
|
||
for (const it of items) if (identity.isPair(it)) {
|
||
if (it.key === key || it.key === k) return it;
|
||
if (identity.isScalar(it.key) && it.key.value === k) return it;
|
||
}
|
||
}
|
||
var YAMLMap = class extends Collection.Collection {
|
||
static get tagName() {
|
||
return "tag:yaml.org,2002:map";
|
||
}
|
||
constructor(schema) {
|
||
super(identity.MAP, schema);
|
||
this.items = [];
|
||
}
|
||
/**
|
||
* A generic collection parsing method that can be extended
|
||
* to other node classes that inherit from YAMLMap
|
||
*/
|
||
static from(schema, obj, ctx) {
|
||
const { keepUndefined, replacer } = ctx;
|
||
const map = new this(schema);
|
||
const add = (key, value) => {
|
||
if (typeof replacer === "function") value = replacer.call(obj, key, value);
|
||
else if (Array.isArray(replacer) && !replacer.includes(key)) return;
|
||
if (value !== void 0 || keepUndefined) map.items.push(Pair.createPair(key, value, ctx));
|
||
};
|
||
if (obj instanceof Map) for (const [key, value] of obj) add(key, value);
|
||
else if (obj && typeof obj === "object") for (const key of Object.keys(obj)) add(key, obj[key]);
|
||
if (typeof schema.sortMapEntries === "function") map.items.sort(schema.sortMapEntries);
|
||
return map;
|
||
}
|
||
/**
|
||
* Adds a value to the collection.
|
||
*
|
||
* @param overwrite - If not set `true`, using a key that is already in the
|
||
* collection will throw. Otherwise, overwrites the previous value.
|
||
*/
|
||
add(pair, overwrite) {
|
||
let _pair;
|
||
if (identity.isPair(pair)) _pair = pair;
|
||
else if (!pair || typeof pair !== "object" || !("key" in pair)) _pair = new Pair.Pair(pair, pair?.value);
|
||
else _pair = new Pair.Pair(pair.key, pair.value);
|
||
const prev = findPair(this.items, _pair.key);
|
||
const sortEntries = this.schema?.sortMapEntries;
|
||
if (prev) {
|
||
if (!overwrite) throw new Error(`Key ${_pair.key} already set`);
|
||
if (identity.isScalar(prev.value) && Scalar.isScalarValue(_pair.value)) prev.value.value = _pair.value;
|
||
else prev.value = _pair.value;
|
||
} else if (sortEntries) {
|
||
const i = this.items.findIndex((item) => sortEntries(_pair, item) < 0);
|
||
if (i === -1) this.items.push(_pair);
|
||
else this.items.splice(i, 0, _pair);
|
||
} else this.items.push(_pair);
|
||
}
|
||
delete(key) {
|
||
const it = findPair(this.items, key);
|
||
if (!it) return false;
|
||
return this.items.splice(this.items.indexOf(it), 1).length > 0;
|
||
}
|
||
get(key, keepScalar) {
|
||
const node = findPair(this.items, key)?.value;
|
||
return (!keepScalar && identity.isScalar(node) ? node.value : node) ?? void 0;
|
||
}
|
||
has(key) {
|
||
return !!findPair(this.items, key);
|
||
}
|
||
set(key, value) {
|
||
this.add(new Pair.Pair(key, value), true);
|
||
}
|
||
/**
|
||
* @param ctx - Conversion context, originally set in Document#toJS()
|
||
* @param {Class} Type - If set, forces the returned collection type
|
||
* @returns Instance of Type, Map, or Object
|
||
*/
|
||
toJSON(_, ctx, Type) {
|
||
const map = Type ? new Type() : ctx?.mapAsMap ? /* @__PURE__ */ new Map() : {};
|
||
if (ctx?.onCreate) ctx.onCreate(map);
|
||
for (const item of this.items) addPairToJSMap.addPairToJSMap(ctx, map, item);
|
||
return map;
|
||
}
|
||
toString(ctx, onComment, onChompKeep) {
|
||
if (!ctx) return JSON.stringify(this);
|
||
for (const item of this.items) if (!identity.isPair(item)) throw new Error(`Map items must all be pairs; found ${JSON.stringify(item)} instead`);
|
||
if (!ctx.allNullValues && this.hasAllNullValues(false)) ctx = Object.assign({}, ctx, { allNullValues: true });
|
||
return stringifyCollection.stringifyCollection(this, ctx, {
|
||
blockItemPrefix: "",
|
||
flowChars: {
|
||
start: "{",
|
||
end: "}"
|
||
},
|
||
itemIndent: ctx.indent || "",
|
||
onChompKeep,
|
||
onComment
|
||
});
|
||
}
|
||
};
|
||
exports.YAMLMap = YAMLMap;
|
||
exports.findPair = findPair;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/common/map.js
|
||
var require_map = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var YAMLMap = require_YAMLMap();
|
||
const map = {
|
||
collection: "map",
|
||
default: true,
|
||
nodeClass: YAMLMap.YAMLMap,
|
||
tag: "tag:yaml.org,2002:map",
|
||
resolve(map, onError) {
|
||
if (!identity.isMap(map)) onError("Expected a mapping for this tag");
|
||
return map;
|
||
},
|
||
createNode: (schema, obj, ctx) => YAMLMap.YAMLMap.from(schema, obj, ctx)
|
||
};
|
||
exports.map = map;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/nodes/YAMLSeq.js
|
||
var require_YAMLSeq = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var createNode = require_createNode();
|
||
var stringifyCollection = require_stringifyCollection();
|
||
var Collection = require_Collection();
|
||
var identity = require_identity();
|
||
var Scalar = require_Scalar();
|
||
var toJS = require_toJS();
|
||
var YAMLSeq = class extends Collection.Collection {
|
||
static get tagName() {
|
||
return "tag:yaml.org,2002:seq";
|
||
}
|
||
constructor(schema) {
|
||
super(identity.SEQ, schema);
|
||
this.items = [];
|
||
}
|
||
add(value) {
|
||
this.items.push(value);
|
||
}
|
||
/**
|
||
* Removes a value from the collection.
|
||
*
|
||
* `key` must contain a representation of an integer for this to succeed.
|
||
* It may be wrapped in a `Scalar`.
|
||
*
|
||
* @returns `true` if the item was found and removed.
|
||
*/
|
||
delete(key) {
|
||
const idx = asItemIndex(key);
|
||
if (typeof idx !== "number") return false;
|
||
return this.items.splice(idx, 1).length > 0;
|
||
}
|
||
get(key, keepScalar) {
|
||
const idx = asItemIndex(key);
|
||
if (typeof idx !== "number") return void 0;
|
||
const it = this.items[idx];
|
||
return !keepScalar && identity.isScalar(it) ? it.value : it;
|
||
}
|
||
/**
|
||
* Checks if the collection includes a value with the key `key`.
|
||
*
|
||
* `key` must contain a representation of an integer for this to succeed.
|
||
* It may be wrapped in a `Scalar`.
|
||
*/
|
||
has(key) {
|
||
const idx = asItemIndex(key);
|
||
return typeof idx === "number" && idx < this.items.length;
|
||
}
|
||
/**
|
||
* Sets a value in this collection. For `!!set`, `value` needs to be a
|
||
* boolean to add/remove the item from the set.
|
||
*
|
||
* If `key` does not contain a representation of an integer, this will throw.
|
||
* It may be wrapped in a `Scalar`.
|
||
*/
|
||
set(key, value) {
|
||
const idx = asItemIndex(key);
|
||
if (typeof idx !== "number") throw new Error(`Expected a valid index, not ${key}.`);
|
||
const prev = this.items[idx];
|
||
if (identity.isScalar(prev) && Scalar.isScalarValue(value)) prev.value = value;
|
||
else this.items[idx] = value;
|
||
}
|
||
toJSON(_, ctx) {
|
||
const seq = [];
|
||
if (ctx?.onCreate) ctx.onCreate(seq);
|
||
let i = 0;
|
||
for (const item of this.items) seq.push(toJS.toJS(item, String(i++), ctx));
|
||
return seq;
|
||
}
|
||
toString(ctx, onComment, onChompKeep) {
|
||
if (!ctx) return JSON.stringify(this);
|
||
return stringifyCollection.stringifyCollection(this, ctx, {
|
||
blockItemPrefix: "- ",
|
||
flowChars: {
|
||
start: "[",
|
||
end: "]"
|
||
},
|
||
itemIndent: (ctx.indent || "") + " ",
|
||
onChompKeep,
|
||
onComment
|
||
});
|
||
}
|
||
static from(schema, obj, ctx) {
|
||
const { replacer } = ctx;
|
||
const seq = new this(schema);
|
||
if (obj && Symbol.iterator in Object(obj)) {
|
||
let i = 0;
|
||
for (let it of obj) {
|
||
if (typeof replacer === "function") {
|
||
const key = obj instanceof Set ? it : String(i++);
|
||
it = replacer.call(obj, key, it);
|
||
}
|
||
seq.items.push(createNode.createNode(it, void 0, ctx));
|
||
}
|
||
}
|
||
return seq;
|
||
}
|
||
};
|
||
function asItemIndex(key) {
|
||
let idx = identity.isScalar(key) ? key.value : key;
|
||
if (idx && typeof idx === "string") idx = Number(idx);
|
||
return typeof idx === "number" && Number.isInteger(idx) && idx >= 0 ? idx : null;
|
||
}
|
||
exports.YAMLSeq = YAMLSeq;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/common/seq.js
|
||
var require_seq = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var YAMLSeq = require_YAMLSeq();
|
||
const seq = {
|
||
collection: "seq",
|
||
default: true,
|
||
nodeClass: YAMLSeq.YAMLSeq,
|
||
tag: "tag:yaml.org,2002:seq",
|
||
resolve(seq, onError) {
|
||
if (!identity.isSeq(seq)) onError("Expected a sequence for this tag");
|
||
return seq;
|
||
},
|
||
createNode: (schema, obj, ctx) => YAMLSeq.YAMLSeq.from(schema, obj, ctx)
|
||
};
|
||
exports.seq = seq;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/common/string.js
|
||
var require_string = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var stringifyString = require_stringifyString();
|
||
const string = {
|
||
identify: (value) => typeof value === "string",
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:str",
|
||
resolve: (str) => str,
|
||
stringify(item, ctx, onComment, onChompKeep) {
|
||
ctx = Object.assign({ actualString: true }, ctx);
|
||
return stringifyString.stringifyString(item, ctx, onComment, onChompKeep);
|
||
}
|
||
};
|
||
exports.string = string;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/common/null.js
|
||
var require_null = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Scalar = require_Scalar();
|
||
const nullTag = {
|
||
identify: (value) => value == null,
|
||
createNode: () => new Scalar.Scalar(null),
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:null",
|
||
test: /^(?:~|[Nn]ull|NULL)?$/,
|
||
resolve: () => new Scalar.Scalar(null),
|
||
stringify: ({ source }, ctx) => typeof source === "string" && nullTag.test.test(source) ? source : ctx.options.nullStr
|
||
};
|
||
exports.nullTag = nullTag;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/core/bool.js
|
||
var require_bool$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Scalar = require_Scalar();
|
||
const boolTag = {
|
||
identify: (value) => typeof value === "boolean",
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:bool",
|
||
test: /^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/,
|
||
resolve: (str) => new Scalar.Scalar(str[0] === "t" || str[0] === "T"),
|
||
stringify({ source, value }, ctx) {
|
||
if (source && boolTag.test.test(source)) {
|
||
if (value === (source[0] === "t" || source[0] === "T")) return source;
|
||
}
|
||
return value ? ctx.options.trueStr : ctx.options.falseStr;
|
||
}
|
||
};
|
||
exports.boolTag = boolTag;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/stringify/stringifyNumber.js
|
||
var require_stringifyNumber = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
function stringifyNumber({ format, minFractionDigits, tag, value }) {
|
||
if (typeof value === "bigint") return String(value);
|
||
const num = typeof value === "number" ? value : Number(value);
|
||
if (!isFinite(num)) return isNaN(num) ? ".nan" : num < 0 ? "-.inf" : ".inf";
|
||
let n = Object.is(value, -0) ? "-0" : JSON.stringify(value);
|
||
if (!format && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^\d/.test(n)) {
|
||
let i = n.indexOf(".");
|
||
if (i < 0) {
|
||
i = n.length;
|
||
n += ".";
|
||
}
|
||
let d = minFractionDigits - (n.length - i - 1);
|
||
while (d-- > 0) n += "0";
|
||
}
|
||
return n;
|
||
}
|
||
exports.stringifyNumber = stringifyNumber;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/core/float.js
|
||
var require_float$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Scalar = require_Scalar();
|
||
var stringifyNumber = require_stringifyNumber();
|
||
const floatNaN = {
|
||
identify: (value) => typeof value === "number",
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:float",
|
||
test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
|
||
resolve: (str) => str.slice(-3).toLowerCase() === "nan" ? NaN : str[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
|
||
stringify: stringifyNumber.stringifyNumber
|
||
};
|
||
const floatExp = {
|
||
identify: (value) => typeof value === "number",
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:float",
|
||
format: "EXP",
|
||
test: /^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/,
|
||
resolve: (str) => parseFloat(str),
|
||
stringify(node) {
|
||
const num = Number(node.value);
|
||
return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node);
|
||
}
|
||
};
|
||
const float = {
|
||
identify: (value) => typeof value === "number",
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:float",
|
||
test: /^[-+]?(?:\.[0-9]+|[0-9]+\.[0-9]*)$/,
|
||
resolve(str) {
|
||
const node = new Scalar.Scalar(parseFloat(str));
|
||
const dot = str.indexOf(".");
|
||
if (dot !== -1 && str[str.length - 1] === "0") node.minFractionDigits = str.length - dot - 1;
|
||
return node;
|
||
},
|
||
stringify: stringifyNumber.stringifyNumber
|
||
};
|
||
exports.float = float;
|
||
exports.floatExp = floatExp;
|
||
exports.floatNaN = floatNaN;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/core/int.js
|
||
var require_int$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var stringifyNumber = require_stringifyNumber();
|
||
const intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
|
||
const intResolve = (str, offset, radix, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str.substring(offset), radix);
|
||
function intStringify(node, radix, prefix) {
|
||
const { value } = node;
|
||
if (intIdentify(value) && value >= 0) return prefix + value.toString(radix);
|
||
return stringifyNumber.stringifyNumber(node);
|
||
}
|
||
const intOct = {
|
||
identify: (value) => intIdentify(value) && value >= 0,
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:int",
|
||
format: "OCT",
|
||
test: /^0o[0-7]+$/,
|
||
resolve: (str, _onError, opt) => intResolve(str, 2, 8, opt),
|
||
stringify: (node) => intStringify(node, 8, "0o")
|
||
};
|
||
const int = {
|
||
identify: intIdentify,
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:int",
|
||
test: /^[-+]?[0-9]+$/,
|
||
resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt),
|
||
stringify: stringifyNumber.stringifyNumber
|
||
};
|
||
const intHex = {
|
||
identify: (value) => intIdentify(value) && value >= 0,
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:int",
|
||
format: "HEX",
|
||
test: /^0x[0-9a-fA-F]+$/,
|
||
resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),
|
||
stringify: (node) => intStringify(node, 16, "0x")
|
||
};
|
||
exports.int = int;
|
||
exports.intHex = intHex;
|
||
exports.intOct = intOct;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/core/schema.js
|
||
var require_schema$2 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var map = require_map();
|
||
var _null = require_null();
|
||
var seq = require_seq();
|
||
var string = require_string();
|
||
var bool = require_bool$1();
|
||
var float = require_float$1();
|
||
var int = require_int$1();
|
||
const schema = [
|
||
map.map,
|
||
seq.seq,
|
||
string.string,
|
||
_null.nullTag,
|
||
bool.boolTag,
|
||
int.intOct,
|
||
int.int,
|
||
int.intHex,
|
||
float.floatNaN,
|
||
float.floatExp,
|
||
float.float
|
||
];
|
||
exports.schema = schema;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/json/schema.js
|
||
var require_schema$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Scalar = require_Scalar();
|
||
var map = require_map();
|
||
var seq = require_seq();
|
||
function intIdentify(value) {
|
||
return typeof value === "bigint" || Number.isInteger(value);
|
||
}
|
||
const stringifyJSON = ({ value }) => JSON.stringify(value);
|
||
const jsonScalars = [
|
||
{
|
||
identify: (value) => typeof value === "string",
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:str",
|
||
resolve: (str) => str,
|
||
stringify: stringifyJSON
|
||
},
|
||
{
|
||
identify: (value) => value == null,
|
||
createNode: () => new Scalar.Scalar(null),
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:null",
|
||
test: /^null$/,
|
||
resolve: () => null,
|
||
stringify: stringifyJSON
|
||
},
|
||
{
|
||
identify: (value) => typeof value === "boolean",
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:bool",
|
||
test: /^true$|^false$/,
|
||
resolve: (str) => str === "true",
|
||
stringify: stringifyJSON
|
||
},
|
||
{
|
||
identify: intIdentify,
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:int",
|
||
test: /^-?(?:0|[1-9][0-9]*)$/,
|
||
resolve: (str, _onError, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str, 10),
|
||
stringify: ({ value }) => intIdentify(value) ? value.toString() : JSON.stringify(value)
|
||
},
|
||
{
|
||
identify: (value) => typeof value === "number",
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:float",
|
||
test: /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/,
|
||
resolve: (str) => parseFloat(str),
|
||
stringify: stringifyJSON
|
||
}
|
||
];
|
||
const schema = [map.map, seq.seq].concat(jsonScalars, {
|
||
default: true,
|
||
tag: "",
|
||
test: /^/,
|
||
resolve(str, onError) {
|
||
onError(`Unresolved plain scalar ${JSON.stringify(str)}`);
|
||
return str;
|
||
}
|
||
});
|
||
exports.schema = schema;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/yaml-1.1/binary.js
|
||
var require_binary = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var node_buffer = __require("buffer");
|
||
var Scalar = require_Scalar();
|
||
var stringifyString = require_stringifyString();
|
||
const binary = {
|
||
identify: (value) => value instanceof Uint8Array,
|
||
default: false,
|
||
tag: "tag:yaml.org,2002:binary",
|
||
resolve(src, onError) {
|
||
if (typeof node_buffer.Buffer === "function") return node_buffer.Buffer.from(src, "base64");
|
||
else if (typeof atob === "function") {
|
||
const str = atob(src.replace(/[\n\r]/g, ""));
|
||
const buffer = new Uint8Array(str.length);
|
||
for (let i = 0; i < str.length; ++i) buffer[i] = str.charCodeAt(i);
|
||
return buffer;
|
||
} else {
|
||
onError("This environment does not support reading binary tags; either Buffer or atob is required");
|
||
return src;
|
||
}
|
||
},
|
||
stringify({ comment, type, value }, ctx, onComment, onChompKeep) {
|
||
if (!value) return "";
|
||
const buf = value;
|
||
let str;
|
||
if (typeof node_buffer.Buffer === "function") str = buf instanceof node_buffer.Buffer ? buf.toString("base64") : node_buffer.Buffer.from(buf.buffer).toString("base64");
|
||
else if (typeof btoa === "function") {
|
||
let s = "";
|
||
for (let i = 0; i < buf.length; ++i) s += String.fromCharCode(buf[i]);
|
||
str = btoa(s);
|
||
} else throw new Error("This environment does not support writing binary tags; either Buffer or btoa is required");
|
||
type ?? (type = Scalar.Scalar.BLOCK_LITERAL);
|
||
if (type !== Scalar.Scalar.QUOTE_DOUBLE) {
|
||
const lineWidth = Math.max(ctx.options.lineWidth - ctx.indent.length, ctx.options.minContentWidth);
|
||
const n = Math.ceil(str.length / lineWidth);
|
||
const lines = new Array(n);
|
||
for (let i = 0, o = 0; i < n; ++i, o += lineWidth) lines[i] = str.substr(o, lineWidth);
|
||
str = lines.join(type === Scalar.Scalar.BLOCK_LITERAL ? "\n" : " ");
|
||
}
|
||
return stringifyString.stringifyString({
|
||
comment,
|
||
type,
|
||
value: str
|
||
}, ctx, onComment, onChompKeep);
|
||
}
|
||
};
|
||
exports.binary = binary;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/yaml-1.1/pairs.js
|
||
var require_pairs = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var Pair = require_Pair();
|
||
var Scalar = require_Scalar();
|
||
var YAMLSeq = require_YAMLSeq();
|
||
function resolvePairs(seq, onError) {
|
||
if (identity.isSeq(seq)) for (let i = 0; i < seq.items.length; ++i) {
|
||
let item = seq.items[i];
|
||
if (identity.isPair(item)) continue;
|
||
else if (identity.isMap(item)) {
|
||
if (item.items.length > 1) onError("Each pair must have its own sequence indicator");
|
||
const pair = item.items[0] || new Pair.Pair(new Scalar.Scalar(null));
|
||
if (item.commentBefore) pair.key.commentBefore = pair.key.commentBefore ? `${item.commentBefore}\n${pair.key.commentBefore}` : item.commentBefore;
|
||
if (item.comment) {
|
||
const cn = pair.value ?? pair.key;
|
||
cn.comment = cn.comment ? `${item.comment}\n${cn.comment}` : item.comment;
|
||
}
|
||
item = pair;
|
||
}
|
||
seq.items[i] = identity.isPair(item) ? item : new Pair.Pair(item);
|
||
}
|
||
else onError("Expected a sequence for this tag");
|
||
return seq;
|
||
}
|
||
function createPairs(schema, iterable, ctx) {
|
||
const { replacer } = ctx;
|
||
const pairs = new YAMLSeq.YAMLSeq(schema);
|
||
pairs.tag = "tag:yaml.org,2002:pairs";
|
||
let i = 0;
|
||
if (iterable && Symbol.iterator in Object(iterable)) for (let it of iterable) {
|
||
if (typeof replacer === "function") it = replacer.call(iterable, String(i++), it);
|
||
let key, value;
|
||
if (Array.isArray(it)) if (it.length === 2) {
|
||
key = it[0];
|
||
value = it[1];
|
||
} else throw new TypeError(`Expected [key, value] tuple: ${it}`);
|
||
else if (it && it instanceof Object) {
|
||
const keys = Object.keys(it);
|
||
if (keys.length === 1) {
|
||
key = keys[0];
|
||
value = it[key];
|
||
} else throw new TypeError(`Expected tuple with one key, not ${keys.length} keys`);
|
||
} else key = it;
|
||
pairs.items.push(Pair.createPair(key, value, ctx));
|
||
}
|
||
return pairs;
|
||
}
|
||
const pairs = {
|
||
collection: "seq",
|
||
default: false,
|
||
tag: "tag:yaml.org,2002:pairs",
|
||
resolve: resolvePairs,
|
||
createNode: createPairs
|
||
};
|
||
exports.createPairs = createPairs;
|
||
exports.pairs = pairs;
|
||
exports.resolvePairs = resolvePairs;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/yaml-1.1/omap.js
|
||
var require_omap = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var toJS = require_toJS();
|
||
var YAMLMap = require_YAMLMap();
|
||
var YAMLSeq = require_YAMLSeq();
|
||
var pairs = require_pairs();
|
||
var YAMLOMap = class YAMLOMap extends YAMLSeq.YAMLSeq {
|
||
constructor() {
|
||
super();
|
||
this.add = YAMLMap.YAMLMap.prototype.add.bind(this);
|
||
this.delete = YAMLMap.YAMLMap.prototype.delete.bind(this);
|
||
this.get = YAMLMap.YAMLMap.prototype.get.bind(this);
|
||
this.has = YAMLMap.YAMLMap.prototype.has.bind(this);
|
||
this.set = YAMLMap.YAMLMap.prototype.set.bind(this);
|
||
this.tag = YAMLOMap.tag;
|
||
}
|
||
/**
|
||
* If `ctx` is given, the return type is actually `Map<unknown, unknown>`,
|
||
* but TypeScript won't allow widening the signature of a child method.
|
||
*/
|
||
toJSON(_, ctx) {
|
||
if (!ctx) return super.toJSON(_);
|
||
const map = /* @__PURE__ */ new Map();
|
||
if (ctx?.onCreate) ctx.onCreate(map);
|
||
for (const pair of this.items) {
|
||
let key, value;
|
||
if (identity.isPair(pair)) {
|
||
key = toJS.toJS(pair.key, "", ctx);
|
||
value = toJS.toJS(pair.value, key, ctx);
|
||
} else key = toJS.toJS(pair, "", ctx);
|
||
if (map.has(key)) throw new Error("Ordered maps must not include duplicate keys");
|
||
map.set(key, value);
|
||
}
|
||
return map;
|
||
}
|
||
static from(schema, iterable, ctx) {
|
||
const pairs$1 = pairs.createPairs(schema, iterable, ctx);
|
||
const omap = new this();
|
||
omap.items = pairs$1.items;
|
||
return omap;
|
||
}
|
||
};
|
||
YAMLOMap.tag = "tag:yaml.org,2002:omap";
|
||
const omap = {
|
||
collection: "seq",
|
||
identify: (value) => value instanceof Map,
|
||
nodeClass: YAMLOMap,
|
||
default: false,
|
||
tag: "tag:yaml.org,2002:omap",
|
||
resolve(seq, onError) {
|
||
const pairs$1 = pairs.resolvePairs(seq, onError);
|
||
const seenKeys = [];
|
||
for (const { key } of pairs$1.items) if (identity.isScalar(key)) if (seenKeys.includes(key.value)) onError(`Ordered maps must not include duplicate keys: ${key.value}`);
|
||
else seenKeys.push(key.value);
|
||
return Object.assign(new YAMLOMap(), pairs$1);
|
||
},
|
||
createNode: (schema, iterable, ctx) => YAMLOMap.from(schema, iterable, ctx)
|
||
};
|
||
exports.YAMLOMap = YAMLOMap;
|
||
exports.omap = omap;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/yaml-1.1/bool.js
|
||
var require_bool = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Scalar = require_Scalar();
|
||
function boolStringify({ value, source }, ctx) {
|
||
if (source && (value ? trueTag : falseTag).test.test(source)) return source;
|
||
return value ? ctx.options.trueStr : ctx.options.falseStr;
|
||
}
|
||
const trueTag = {
|
||
identify: (value) => value === true,
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:bool",
|
||
test: /^(?:Y|y|[Yy]es|YES|[Tt]rue|TRUE|[Oo]n|ON)$/,
|
||
resolve: () => new Scalar.Scalar(true),
|
||
stringify: boolStringify
|
||
};
|
||
const falseTag = {
|
||
identify: (value) => value === false,
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:bool",
|
||
test: /^(?:N|n|[Nn]o|NO|[Ff]alse|FALSE|[Oo]ff|OFF)$/,
|
||
resolve: () => new Scalar.Scalar(false),
|
||
stringify: boolStringify
|
||
};
|
||
exports.falseTag = falseTag;
|
||
exports.trueTag = trueTag;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/yaml-1.1/float.js
|
||
var require_float = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Scalar = require_Scalar();
|
||
var stringifyNumber = require_stringifyNumber();
|
||
const floatNaN = {
|
||
identify: (value) => typeof value === "number",
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:float",
|
||
test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
|
||
resolve: (str) => str.slice(-3).toLowerCase() === "nan" ? NaN : str[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
|
||
stringify: stringifyNumber.stringifyNumber
|
||
};
|
||
const floatExp = {
|
||
identify: (value) => typeof value === "number",
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:float",
|
||
format: "EXP",
|
||
test: /^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/,
|
||
resolve: (str) => parseFloat(str.replace(/_/g, "")),
|
||
stringify(node) {
|
||
const num = Number(node.value);
|
||
return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node);
|
||
}
|
||
};
|
||
const float = {
|
||
identify: (value) => typeof value === "number",
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:float",
|
||
test: /^[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*$/,
|
||
resolve(str) {
|
||
const node = new Scalar.Scalar(parseFloat(str.replace(/_/g, "")));
|
||
const dot = str.indexOf(".");
|
||
if (dot !== -1) {
|
||
const f = str.substring(dot + 1).replace(/_/g, "");
|
||
if (f[f.length - 1] === "0") node.minFractionDigits = f.length;
|
||
}
|
||
return node;
|
||
},
|
||
stringify: stringifyNumber.stringifyNumber
|
||
};
|
||
exports.float = float;
|
||
exports.floatExp = floatExp;
|
||
exports.floatNaN = floatNaN;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/yaml-1.1/int.js
|
||
var require_int = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var stringifyNumber = require_stringifyNumber();
|
||
const intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
|
||
function intResolve(str, offset, radix, { intAsBigInt }) {
|
||
const sign = str[0];
|
||
if (sign === "-" || sign === "+") offset += 1;
|
||
str = str.substring(offset).replace(/_/g, "");
|
||
if (intAsBigInt) {
|
||
switch (radix) {
|
||
case 2:
|
||
str = `0b${str}`;
|
||
break;
|
||
case 8:
|
||
str = `0o${str}`;
|
||
break;
|
||
case 16:
|
||
str = `0x${str}`;
|
||
break;
|
||
}
|
||
const n = BigInt(str);
|
||
return sign === "-" ? BigInt(-1) * n : n;
|
||
}
|
||
const n = parseInt(str, radix);
|
||
return sign === "-" ? -1 * n : n;
|
||
}
|
||
function intStringify(node, radix, prefix) {
|
||
const { value } = node;
|
||
if (intIdentify(value)) {
|
||
const str = value.toString(radix);
|
||
return value < 0 ? "-" + prefix + str.substr(1) : prefix + str;
|
||
}
|
||
return stringifyNumber.stringifyNumber(node);
|
||
}
|
||
const intBin = {
|
||
identify: intIdentify,
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:int",
|
||
format: "BIN",
|
||
test: /^[-+]?0b[0-1_]+$/,
|
||
resolve: (str, _onError, opt) => intResolve(str, 2, 2, opt),
|
||
stringify: (node) => intStringify(node, 2, "0b")
|
||
};
|
||
const intOct = {
|
||
identify: intIdentify,
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:int",
|
||
format: "OCT",
|
||
test: /^[-+]?0[0-7_]+$/,
|
||
resolve: (str, _onError, opt) => intResolve(str, 1, 8, opt),
|
||
stringify: (node) => intStringify(node, 8, "0")
|
||
};
|
||
const int = {
|
||
identify: intIdentify,
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:int",
|
||
test: /^[-+]?[0-9][0-9_]*$/,
|
||
resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt),
|
||
stringify: stringifyNumber.stringifyNumber
|
||
};
|
||
const intHex = {
|
||
identify: intIdentify,
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:int",
|
||
format: "HEX",
|
||
test: /^[-+]?0x[0-9a-fA-F_]+$/,
|
||
resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),
|
||
stringify: (node) => intStringify(node, 16, "0x")
|
||
};
|
||
exports.int = int;
|
||
exports.intBin = intBin;
|
||
exports.intHex = intHex;
|
||
exports.intOct = intOct;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/yaml-1.1/set.js
|
||
var require_set = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var Pair = require_Pair();
|
||
var YAMLMap = require_YAMLMap();
|
||
var YAMLSet = class YAMLSet extends YAMLMap.YAMLMap {
|
||
constructor(schema) {
|
||
super(schema);
|
||
this.tag = YAMLSet.tag;
|
||
}
|
||
add(key) {
|
||
let pair;
|
||
if (identity.isPair(key)) pair = key;
|
||
else if (key && typeof key === "object" && "key" in key && "value" in key && key.value === null) pair = new Pair.Pair(key.key, null);
|
||
else pair = new Pair.Pair(key, null);
|
||
if (!YAMLMap.findPair(this.items, pair.key)) this.items.push(pair);
|
||
}
|
||
/**
|
||
* If `keepPair` is `true`, returns the Pair matching `key`.
|
||
* Otherwise, returns the value of that Pair's key.
|
||
*/
|
||
get(key, keepPair) {
|
||
const pair = YAMLMap.findPair(this.items, key);
|
||
return !keepPair && identity.isPair(pair) ? identity.isScalar(pair.key) ? pair.key.value : pair.key : pair;
|
||
}
|
||
set(key, value) {
|
||
if (typeof value !== "boolean") throw new Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof value}`);
|
||
const prev = YAMLMap.findPair(this.items, key);
|
||
if (prev && !value) this.items.splice(this.items.indexOf(prev), 1);
|
||
else if (!prev && value) this.items.push(new Pair.Pair(key));
|
||
}
|
||
toJSON(_, ctx) {
|
||
return super.toJSON(_, ctx, Set);
|
||
}
|
||
toString(ctx, onComment, onChompKeep) {
|
||
if (!ctx) return JSON.stringify(this);
|
||
if (this.hasAllNullValues(true)) return super.toString(Object.assign({}, ctx, { allNullValues: true }), onComment, onChompKeep);
|
||
else throw new Error("Set items must all have null values");
|
||
}
|
||
static from(schema, iterable, ctx) {
|
||
const { replacer } = ctx;
|
||
const set = new this(schema);
|
||
if (iterable && Symbol.iterator in Object(iterable)) for (let value of iterable) {
|
||
if (typeof replacer === "function") value = replacer.call(iterable, value, value);
|
||
set.items.push(Pair.createPair(value, null, ctx));
|
||
}
|
||
return set;
|
||
}
|
||
};
|
||
YAMLSet.tag = "tag:yaml.org,2002:set";
|
||
const set = {
|
||
collection: "map",
|
||
identify: (value) => value instanceof Set,
|
||
nodeClass: YAMLSet,
|
||
default: false,
|
||
tag: "tag:yaml.org,2002:set",
|
||
createNode: (schema, iterable, ctx) => YAMLSet.from(schema, iterable, ctx),
|
||
resolve(map, onError) {
|
||
if (identity.isMap(map)) if (map.hasAllNullValues(true)) return Object.assign(new YAMLSet(), map);
|
||
else onError("Set items must all have null values");
|
||
else onError("Expected a mapping for this tag");
|
||
return map;
|
||
}
|
||
};
|
||
exports.YAMLSet = YAMLSet;
|
||
exports.set = set;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js
|
||
var require_timestamp = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var stringifyNumber = require_stringifyNumber();
|
||
/** Internal types handle bigint as number, because TS can't figure it out. */
|
||
function parseSexagesimal(str, asBigInt) {
|
||
const sign = str[0];
|
||
const parts = sign === "-" || sign === "+" ? str.substring(1) : str;
|
||
const num = (n) => asBigInt ? BigInt(n) : Number(n);
|
||
const res = parts.replace(/_/g, "").split(":").reduce((res, p) => res * num(60) + num(p), num(0));
|
||
return sign === "-" ? num(-1) * res : res;
|
||
}
|
||
/**
|
||
* hhhh:mm:ss.sss
|
||
*
|
||
* Internal types handle bigint as number, because TS can't figure it out.
|
||
*/
|
||
function stringifySexagesimal(node) {
|
||
let { value } = node;
|
||
let num = (n) => n;
|
||
if (typeof value === "bigint") num = (n) => BigInt(n);
|
||
else if (isNaN(value) || !isFinite(value)) return stringifyNumber.stringifyNumber(node);
|
||
let sign = "";
|
||
if (value < 0) {
|
||
sign = "-";
|
||
value *= num(-1);
|
||
}
|
||
const _60 = num(60);
|
||
const parts = [value % _60];
|
||
if (value < 60) parts.unshift(0);
|
||
else {
|
||
value = (value - parts[0]) / _60;
|
||
parts.unshift(value % _60);
|
||
if (value >= 60) {
|
||
value = (value - parts[0]) / _60;
|
||
parts.unshift(value);
|
||
}
|
||
}
|
||
return sign + parts.map((n) => String(n).padStart(2, "0")).join(":").replace(/000000\d*$/, "");
|
||
}
|
||
const intTime = {
|
||
identify: (value) => typeof value === "bigint" || Number.isInteger(value),
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:int",
|
||
format: "TIME",
|
||
test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+$/,
|
||
resolve: (str, _onError, { intAsBigInt }) => parseSexagesimal(str, intAsBigInt),
|
||
stringify: stringifySexagesimal
|
||
};
|
||
const floatTime = {
|
||
identify: (value) => typeof value === "number",
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:float",
|
||
format: "TIME",
|
||
test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*$/,
|
||
resolve: (str) => parseSexagesimal(str, false),
|
||
stringify: stringifySexagesimal
|
||
};
|
||
const timestamp = {
|
||
identify: (value) => value instanceof Date,
|
||
default: true,
|
||
tag: "tag:yaml.org,2002:timestamp",
|
||
test: RegExp("^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})(?:(?:t|T|[ \\t]+)([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\.[0-9]+)?)(?:[ \\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?)?$"),
|
||
resolve(str) {
|
||
const match = str.match(timestamp.test);
|
||
if (!match) throw new Error("!!timestamp expects a date, starting with yyyy-mm-dd");
|
||
const [, year, month, day, hour, minute, second] = match.map(Number);
|
||
const millisec = match[7] ? Number((match[7] + "00").substr(1, 3)) : 0;
|
||
let date = Date.UTC(year, month - 1, day, hour || 0, minute || 0, second || 0, millisec);
|
||
const tz = match[8];
|
||
if (tz && tz !== "Z") {
|
||
let d = parseSexagesimal(tz, false);
|
||
if (Math.abs(d) < 30) d *= 60;
|
||
date -= 6e4 * d;
|
||
}
|
||
return new Date(date);
|
||
},
|
||
stringify: ({ value }) => value?.toISOString().replace(/(T00:00:00)?\.000Z$/, "") ?? ""
|
||
};
|
||
exports.floatTime = floatTime;
|
||
exports.intTime = intTime;
|
||
exports.timestamp = timestamp;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/yaml-1.1/schema.js
|
||
var require_schema = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var map = require_map();
|
||
var _null = require_null();
|
||
var seq = require_seq();
|
||
var string = require_string();
|
||
var binary = require_binary();
|
||
var bool = require_bool();
|
||
var float = require_float();
|
||
var int = require_int();
|
||
var merge = require_merge();
|
||
var omap = require_omap();
|
||
var pairs = require_pairs();
|
||
var set = require_set();
|
||
var timestamp = require_timestamp();
|
||
const schema = [
|
||
map.map,
|
||
seq.seq,
|
||
string.string,
|
||
_null.nullTag,
|
||
bool.trueTag,
|
||
bool.falseTag,
|
||
int.intBin,
|
||
int.intOct,
|
||
int.int,
|
||
int.intHex,
|
||
float.floatNaN,
|
||
float.floatExp,
|
||
float.float,
|
||
binary.binary,
|
||
merge.merge,
|
||
omap.omap,
|
||
pairs.pairs,
|
||
set.set,
|
||
timestamp.intTime,
|
||
timestamp.floatTime,
|
||
timestamp.timestamp
|
||
];
|
||
exports.schema = schema;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/tags.js
|
||
var require_tags = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var map = require_map();
|
||
var _null = require_null();
|
||
var seq = require_seq();
|
||
var string = require_string();
|
||
var bool = require_bool$1();
|
||
var float = require_float$1();
|
||
var int = require_int$1();
|
||
var schema = require_schema$2();
|
||
var schema$1 = require_schema$1();
|
||
var binary = require_binary();
|
||
var merge = require_merge();
|
||
var omap = require_omap();
|
||
var pairs = require_pairs();
|
||
var schema$2 = require_schema();
|
||
var set = require_set();
|
||
var timestamp = require_timestamp();
|
||
const schemas = new Map([
|
||
["core", schema.schema],
|
||
["failsafe", [
|
||
map.map,
|
||
seq.seq,
|
||
string.string
|
||
]],
|
||
["json", schema$1.schema],
|
||
["yaml11", schema$2.schema],
|
||
["yaml-1.1", schema$2.schema]
|
||
]);
|
||
const tagsByName = {
|
||
binary: binary.binary,
|
||
bool: bool.boolTag,
|
||
float: float.float,
|
||
floatExp: float.floatExp,
|
||
floatNaN: float.floatNaN,
|
||
floatTime: timestamp.floatTime,
|
||
int: int.int,
|
||
intHex: int.intHex,
|
||
intOct: int.intOct,
|
||
intTime: timestamp.intTime,
|
||
map: map.map,
|
||
merge: merge.merge,
|
||
null: _null.nullTag,
|
||
omap: omap.omap,
|
||
pairs: pairs.pairs,
|
||
seq: seq.seq,
|
||
set: set.set,
|
||
timestamp: timestamp.timestamp
|
||
};
|
||
const coreKnownTags = {
|
||
"tag:yaml.org,2002:binary": binary.binary,
|
||
"tag:yaml.org,2002:merge": merge.merge,
|
||
"tag:yaml.org,2002:omap": omap.omap,
|
||
"tag:yaml.org,2002:pairs": pairs.pairs,
|
||
"tag:yaml.org,2002:set": set.set,
|
||
"tag:yaml.org,2002:timestamp": timestamp.timestamp
|
||
};
|
||
function getTags(customTags, schemaName, addMergeTag) {
|
||
const schemaTags = schemas.get(schemaName);
|
||
if (schemaTags && !customTags) return addMergeTag && !schemaTags.includes(merge.merge) ? schemaTags.concat(merge.merge) : schemaTags.slice();
|
||
let tags = schemaTags;
|
||
if (!tags) if (Array.isArray(customTags)) tags = [];
|
||
else {
|
||
const keys = Array.from(schemas.keys()).filter((key) => key !== "yaml11").map((key) => JSON.stringify(key)).join(", ");
|
||
throw new Error(`Unknown schema "${schemaName}"; use one of ${keys} or define customTags array`);
|
||
}
|
||
if (Array.isArray(customTags)) for (const tag of customTags) tags = tags.concat(tag);
|
||
else if (typeof customTags === "function") tags = customTags(tags.slice());
|
||
if (addMergeTag) tags = tags.concat(merge.merge);
|
||
return tags.reduce((tags, tag) => {
|
||
const tagObj = typeof tag === "string" ? tagsByName[tag] : tag;
|
||
if (!tagObj) {
|
||
const tagName = JSON.stringify(tag);
|
||
const keys = Object.keys(tagsByName).map((key) => JSON.stringify(key)).join(", ");
|
||
throw new Error(`Unknown custom tag ${tagName}; use one of ${keys}`);
|
||
}
|
||
if (!tags.includes(tagObj)) tags.push(tagObj);
|
||
return tags;
|
||
}, []);
|
||
}
|
||
exports.coreKnownTags = coreKnownTags;
|
||
exports.getTags = getTags;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/schema/Schema.js
|
||
var require_Schema = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var map = require_map();
|
||
var seq = require_seq();
|
||
var string = require_string();
|
||
var tags = require_tags();
|
||
const sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0;
|
||
var Schema = class Schema {
|
||
constructor({ compat, customTags, merge, resolveKnownTags, schema, sortMapEntries, toStringDefaults }) {
|
||
this.compat = Array.isArray(compat) ? tags.getTags(compat, "compat") : compat ? tags.getTags(null, compat) : null;
|
||
this.name = typeof schema === "string" && schema || "core";
|
||
this.knownTags = resolveKnownTags ? tags.coreKnownTags : {};
|
||
this.tags = tags.getTags(customTags, this.name, merge);
|
||
this.toStringOptions = toStringDefaults ?? null;
|
||
Object.defineProperty(this, identity.MAP, { value: map.map });
|
||
Object.defineProperty(this, identity.SCALAR, { value: string.string });
|
||
Object.defineProperty(this, identity.SEQ, { value: seq.seq });
|
||
this.sortMapEntries = typeof sortMapEntries === "function" ? sortMapEntries : sortMapEntries === true ? sortMapEntriesByKey : null;
|
||
}
|
||
clone() {
|
||
const copy = Object.create(Schema.prototype, Object.getOwnPropertyDescriptors(this));
|
||
copy.tags = this.tags.slice();
|
||
return copy;
|
||
}
|
||
};
|
||
exports.Schema = Schema;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/stringify/stringifyDocument.js
|
||
var require_stringifyDocument = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var stringify = require_stringify();
|
||
var stringifyComment = require_stringifyComment();
|
||
function stringifyDocument(doc, options) {
|
||
const lines = [];
|
||
let hasDirectives = options.directives === true;
|
||
if (options.directives !== false && doc.directives) {
|
||
const dir = doc.directives.toString(doc);
|
||
if (dir) {
|
||
lines.push(dir);
|
||
hasDirectives = true;
|
||
} else if (doc.directives.docStart) hasDirectives = true;
|
||
}
|
||
if (hasDirectives) lines.push("---");
|
||
const ctx = stringify.createStringifyContext(doc, options);
|
||
const { commentString } = ctx.options;
|
||
if (doc.commentBefore) {
|
||
if (lines.length !== 1) lines.unshift("");
|
||
const cs = commentString(doc.commentBefore);
|
||
lines.unshift(stringifyComment.indentComment(cs, ""));
|
||
}
|
||
let chompKeep = false;
|
||
let contentComment = null;
|
||
if (doc.contents) {
|
||
if (identity.isNode(doc.contents)) {
|
||
if (doc.contents.spaceBefore && hasDirectives) lines.push("");
|
||
if (doc.contents.commentBefore) {
|
||
const cs = commentString(doc.contents.commentBefore);
|
||
lines.push(stringifyComment.indentComment(cs, ""));
|
||
}
|
||
ctx.forceBlockIndent = !!doc.comment;
|
||
contentComment = doc.contents.comment;
|
||
}
|
||
const onChompKeep = contentComment ? void 0 : () => chompKeep = true;
|
||
let body = stringify.stringify(doc.contents, ctx, () => contentComment = null, onChompKeep);
|
||
if (contentComment) body += stringifyComment.lineComment(body, "", commentString(contentComment));
|
||
if ((body[0] === "|" || body[0] === ">") && lines[lines.length - 1] === "---") lines[lines.length - 1] = `--- ${body}`;
|
||
else lines.push(body);
|
||
} else lines.push(stringify.stringify(doc.contents, ctx));
|
||
if (doc.directives?.docEnd) if (doc.comment) {
|
||
const cs = commentString(doc.comment);
|
||
if (cs.includes("\n")) {
|
||
lines.push("...");
|
||
lines.push(stringifyComment.indentComment(cs, ""));
|
||
} else lines.push(`... ${cs}`);
|
||
} else lines.push("...");
|
||
else {
|
||
let dc = doc.comment;
|
||
if (dc && chompKeep) dc = dc.replace(/^\n+/, "");
|
||
if (dc) {
|
||
if ((!chompKeep || contentComment) && lines[lines.length - 1] !== "") lines.push("");
|
||
lines.push(stringifyComment.indentComment(commentString(dc), ""));
|
||
}
|
||
}
|
||
return lines.join("\n") + "\n";
|
||
}
|
||
exports.stringifyDocument = stringifyDocument;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/doc/Document.js
|
||
var require_Document = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Alias = require_Alias();
|
||
var Collection = require_Collection();
|
||
var identity = require_identity();
|
||
var Pair = require_Pair();
|
||
var toJS = require_toJS();
|
||
var Schema = require_Schema();
|
||
var stringifyDocument = require_stringifyDocument();
|
||
var anchors = require_anchors();
|
||
var applyReviver = require_applyReviver();
|
||
var createNode = require_createNode();
|
||
var directives = require_directives();
|
||
var Document = class Document {
|
||
constructor(value, replacer, options) {
|
||
/** A comment before this Document */
|
||
this.commentBefore = null;
|
||
/** A comment immediately after this Document */
|
||
this.comment = null;
|
||
/** Errors encountered during parsing. */
|
||
this.errors = [];
|
||
/** Warnings encountered during parsing. */
|
||
this.warnings = [];
|
||
Object.defineProperty(this, identity.NODE_TYPE, { value: identity.DOC });
|
||
let _replacer = null;
|
||
if (typeof replacer === "function" || Array.isArray(replacer)) _replacer = replacer;
|
||
else if (options === void 0 && replacer) {
|
||
options = replacer;
|
||
replacer = void 0;
|
||
}
|
||
const opt = Object.assign({
|
||
intAsBigInt: false,
|
||
keepSourceTokens: false,
|
||
logLevel: "warn",
|
||
prettyErrors: true,
|
||
strict: true,
|
||
stringKeys: false,
|
||
uniqueKeys: true,
|
||
version: "1.2"
|
||
}, options);
|
||
this.options = opt;
|
||
let { version } = opt;
|
||
if (options?._directives) {
|
||
this.directives = options._directives.atDocument();
|
||
if (this.directives.yaml.explicit) version = this.directives.yaml.version;
|
||
} else this.directives = new directives.Directives({ version });
|
||
this.setSchema(version, options);
|
||
this.contents = value === void 0 ? null : this.createNode(value, _replacer, options);
|
||
}
|
||
/**
|
||
* Create a deep copy of this Document and its contents.
|
||
*
|
||
* Custom Node values that inherit from `Object` still refer to their original instances.
|
||
*/
|
||
clone() {
|
||
const copy = Object.create(Document.prototype, { [identity.NODE_TYPE]: { value: identity.DOC } });
|
||
copy.commentBefore = this.commentBefore;
|
||
copy.comment = this.comment;
|
||
copy.errors = this.errors.slice();
|
||
copy.warnings = this.warnings.slice();
|
||
copy.options = Object.assign({}, this.options);
|
||
if (this.directives) copy.directives = this.directives.clone();
|
||
copy.schema = this.schema.clone();
|
||
copy.contents = identity.isNode(this.contents) ? this.contents.clone(copy.schema) : this.contents;
|
||
if (this.range) copy.range = this.range.slice();
|
||
return copy;
|
||
}
|
||
/** Adds a value to the document. */
|
||
add(value) {
|
||
if (assertCollection(this.contents)) this.contents.add(value);
|
||
}
|
||
/** Adds a value to the document. */
|
||
addIn(path, value) {
|
||
if (assertCollection(this.contents)) this.contents.addIn(path, value);
|
||
}
|
||
/**
|
||
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
|
||
*
|
||
* If `node` already has an anchor, `name` is ignored.
|
||
* Otherwise, the `node.anchor` value will be set to `name`,
|
||
* or if an anchor with that name is already present in the document,
|
||
* `name` will be used as a prefix for a new unique anchor.
|
||
* If `name` is undefined, the generated anchor will use 'a' as a prefix.
|
||
*/
|
||
createAlias(node, name) {
|
||
if (!node.anchor) {
|
||
const prev = anchors.anchorNames(this);
|
||
node.anchor = !name || prev.has(name) ? anchors.findNewAnchor(name || "a", prev) : name;
|
||
}
|
||
return new Alias.Alias(node.anchor);
|
||
}
|
||
createNode(value, replacer, options) {
|
||
let _replacer = void 0;
|
||
if (typeof replacer === "function") {
|
||
value = replacer.call({ "": value }, "", value);
|
||
_replacer = replacer;
|
||
} else if (Array.isArray(replacer)) {
|
||
const keyToStr = (v) => typeof v === "number" || v instanceof String || v instanceof Number;
|
||
const asStr = replacer.filter(keyToStr).map(String);
|
||
if (asStr.length > 0) replacer = replacer.concat(asStr);
|
||
_replacer = replacer;
|
||
} else if (options === void 0 && replacer) {
|
||
options = replacer;
|
||
replacer = void 0;
|
||
}
|
||
const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options ?? {};
|
||
const { onAnchor, setAnchors, sourceObjects } = anchors.createNodeAnchors(this, anchorPrefix || "a");
|
||
const ctx = {
|
||
aliasDuplicateObjects: aliasDuplicateObjects ?? true,
|
||
keepUndefined: keepUndefined ?? false,
|
||
onAnchor,
|
||
onTagObj,
|
||
replacer: _replacer,
|
||
schema: this.schema,
|
||
sourceObjects
|
||
};
|
||
const node = createNode.createNode(value, tag, ctx);
|
||
if (flow && identity.isCollection(node)) node.flow = true;
|
||
setAnchors();
|
||
return node;
|
||
}
|
||
/**
|
||
* Convert a key and a value into a `Pair` using the current schema,
|
||
* recursively wrapping all values as `Scalar` or `Collection` nodes.
|
||
*/
|
||
createPair(key, value, options = {}) {
|
||
const k = this.createNode(key, null, options);
|
||
const v = this.createNode(value, null, options);
|
||
return new Pair.Pair(k, v);
|
||
}
|
||
/**
|
||
* Removes a value from the document.
|
||
* @returns `true` if the item was found and removed.
|
||
*/
|
||
delete(key) {
|
||
return assertCollection(this.contents) ? this.contents.delete(key) : false;
|
||
}
|
||
/**
|
||
* Removes a value from the document.
|
||
* @returns `true` if the item was found and removed.
|
||
*/
|
||
deleteIn(path) {
|
||
if (Collection.isEmptyPath(path)) {
|
||
if (this.contents == null) return false;
|
||
this.contents = null;
|
||
return true;
|
||
}
|
||
return assertCollection(this.contents) ? this.contents.deleteIn(path) : false;
|
||
}
|
||
/**
|
||
* Returns item at `key`, or `undefined` if not found. By default unwraps
|
||
* scalar values from their surrounding node; to disable set `keepScalar` to
|
||
* `true` (collections are always returned intact).
|
||
*/
|
||
get(key, keepScalar) {
|
||
return identity.isCollection(this.contents) ? this.contents.get(key, keepScalar) : void 0;
|
||
}
|
||
/**
|
||
* Returns item at `path`, or `undefined` if not found. By default unwraps
|
||
* scalar values from their surrounding node; to disable set `keepScalar` to
|
||
* `true` (collections are always returned intact).
|
||
*/
|
||
getIn(path, keepScalar) {
|
||
if (Collection.isEmptyPath(path)) return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
|
||
return identity.isCollection(this.contents) ? this.contents.getIn(path, keepScalar) : void 0;
|
||
}
|
||
/**
|
||
* Checks if the document includes a value with the key `key`.
|
||
*/
|
||
has(key) {
|
||
return identity.isCollection(this.contents) ? this.contents.has(key) : false;
|
||
}
|
||
/**
|
||
* Checks if the document includes a value at `path`.
|
||
*/
|
||
hasIn(path) {
|
||
if (Collection.isEmptyPath(path)) return this.contents !== void 0;
|
||
return identity.isCollection(this.contents) ? this.contents.hasIn(path) : false;
|
||
}
|
||
/**
|
||
* Sets a value in this document. For `!!set`, `value` needs to be a
|
||
* boolean to add/remove the item from the set.
|
||
*/
|
||
set(key, value) {
|
||
if (this.contents == null) this.contents = Collection.collectionFromPath(this.schema, [key], value);
|
||
else if (assertCollection(this.contents)) this.contents.set(key, value);
|
||
}
|
||
/**
|
||
* Sets a value in this document. For `!!set`, `value` needs to be a
|
||
* boolean to add/remove the item from the set.
|
||
*/
|
||
setIn(path, value) {
|
||
if (Collection.isEmptyPath(path)) this.contents = value;
|
||
else if (this.contents == null) this.contents = Collection.collectionFromPath(this.schema, Array.from(path), value);
|
||
else if (assertCollection(this.contents)) this.contents.setIn(path, value);
|
||
}
|
||
/**
|
||
* Change the YAML version and schema used by the document.
|
||
* A `null` version disables support for directives, explicit tags, anchors, and aliases.
|
||
* It also requires the `schema` option to be given as a `Schema` instance value.
|
||
*
|
||
* Overrides all previously set schema options.
|
||
*/
|
||
setSchema(version, options = {}) {
|
||
if (typeof version === "number") version = String(version);
|
||
let opt;
|
||
switch (version) {
|
||
case "1.1":
|
||
if (this.directives) this.directives.yaml.version = "1.1";
|
||
else this.directives = new directives.Directives({ version: "1.1" });
|
||
opt = {
|
||
resolveKnownTags: false,
|
||
schema: "yaml-1.1"
|
||
};
|
||
break;
|
||
case "1.2":
|
||
case "next":
|
||
if (this.directives) this.directives.yaml.version = version;
|
||
else this.directives = new directives.Directives({ version });
|
||
opt = {
|
||
resolveKnownTags: true,
|
||
schema: "core"
|
||
};
|
||
break;
|
||
case null:
|
||
if (this.directives) delete this.directives;
|
||
opt = null;
|
||
break;
|
||
default: {
|
||
const sv = JSON.stringify(version);
|
||
throw new Error(`Expected '1.1', '1.2' or null as first argument, but found: ${sv}`);
|
||
}
|
||
}
|
||
if (options.schema instanceof Object) this.schema = options.schema;
|
||
else if (opt) this.schema = new Schema.Schema(Object.assign(opt, options));
|
||
else throw new Error(`With a null YAML version, the { schema: Schema } option is required`);
|
||
}
|
||
toJS({ json, jsonArg, mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {
|
||
const ctx = {
|
||
anchors: /* @__PURE__ */ new Map(),
|
||
doc: this,
|
||
keep: !json,
|
||
mapAsMap: mapAsMap === true,
|
||
mapKeyWarned: false,
|
||
maxAliasCount: typeof maxAliasCount === "number" ? maxAliasCount : 100
|
||
};
|
||
const res = toJS.toJS(this.contents, jsonArg ?? "", ctx);
|
||
if (typeof onAnchor === "function") for (const { count, res } of ctx.anchors.values()) onAnchor(res, count);
|
||
return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res;
|
||
}
|
||
/**
|
||
* A JSON representation of the document `contents`.
|
||
*
|
||
* @param jsonArg Used by `JSON.stringify` to indicate the array index or
|
||
* property name.
|
||
*/
|
||
toJSON(jsonArg, onAnchor) {
|
||
return this.toJS({
|
||
json: true,
|
||
jsonArg,
|
||
mapAsMap: false,
|
||
onAnchor
|
||
});
|
||
}
|
||
/** A YAML representation of the document. */
|
||
toString(options = {}) {
|
||
if (this.errors.length > 0) throw new Error("Document with errors cannot be stringified");
|
||
if ("indent" in options && (!Number.isInteger(options.indent) || Number(options.indent) <= 0)) {
|
||
const s = JSON.stringify(options.indent);
|
||
throw new Error(`"indent" option must be a positive integer, not ${s}`);
|
||
}
|
||
return stringifyDocument.stringifyDocument(this, options);
|
||
}
|
||
};
|
||
function assertCollection(contents) {
|
||
if (identity.isCollection(contents)) return true;
|
||
throw new Error("Expected a YAML collection as document contents");
|
||
}
|
||
exports.Document = Document;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/errors.js
|
||
var require_errors = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var YAMLError = class extends Error {
|
||
constructor(name, pos, code, message) {
|
||
super();
|
||
this.name = name;
|
||
this.code = code;
|
||
this.message = message;
|
||
this.pos = pos;
|
||
}
|
||
};
|
||
var YAMLParseError = class extends YAMLError {
|
||
constructor(pos, code, message) {
|
||
super("YAMLParseError", pos, code, message);
|
||
}
|
||
};
|
||
var YAMLWarning = class extends YAMLError {
|
||
constructor(pos, code, message) {
|
||
super("YAMLWarning", pos, code, message);
|
||
}
|
||
};
|
||
const prettifyError = (src, lc) => (error) => {
|
||
if (error.pos[0] === -1) return;
|
||
error.linePos = error.pos.map((pos) => lc.linePos(pos));
|
||
const { line, col } = error.linePos[0];
|
||
error.message += ` at line ${line}, column ${col}`;
|
||
let ci = col - 1;
|
||
let lineStr = src.substring(lc.lineStarts[line - 1], lc.lineStarts[line]).replace(/[\n\r]+$/, "");
|
||
if (ci >= 60 && lineStr.length > 80) {
|
||
const trimStart = Math.min(ci - 39, lineStr.length - 79);
|
||
lineStr = "…" + lineStr.substring(trimStart);
|
||
ci -= trimStart - 1;
|
||
}
|
||
if (lineStr.length > 80) lineStr = lineStr.substring(0, 79) + "…";
|
||
if (line > 1 && /^ *$/.test(lineStr.substring(0, ci))) {
|
||
let prev = src.substring(lc.lineStarts[line - 2], lc.lineStarts[line - 1]);
|
||
if (prev.length > 80) prev = prev.substring(0, 79) + "…\n";
|
||
lineStr = prev + lineStr;
|
||
}
|
||
if (/[^ ]/.test(lineStr)) {
|
||
let count = 1;
|
||
const end = error.linePos[1];
|
||
if (end?.line === line && end.col > col) count = Math.max(1, Math.min(end.col - col, 80 - ci));
|
||
const pointer = " ".repeat(ci) + "^".repeat(count);
|
||
error.message += `:\n\n${lineStr}\n${pointer}\n`;
|
||
}
|
||
};
|
||
exports.YAMLError = YAMLError;
|
||
exports.YAMLParseError = YAMLParseError;
|
||
exports.YAMLWarning = YAMLWarning;
|
||
exports.prettifyError = prettifyError;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/resolve-props.js
|
||
var require_resolve_props = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) {
|
||
let spaceBefore = false;
|
||
let atNewline = startOnNewline;
|
||
let hasSpace = startOnNewline;
|
||
let comment = "";
|
||
let commentSep = "";
|
||
let hasNewline = false;
|
||
let reqSpace = false;
|
||
let tab = null;
|
||
let anchor = null;
|
||
let tag = null;
|
||
let newlineAfterProp = null;
|
||
let comma = null;
|
||
let found = null;
|
||
let start = null;
|
||
for (const token of tokens) {
|
||
if (reqSpace) {
|
||
if (token.type !== "space" && token.type !== "newline" && token.type !== "comma") onError(token.offset, "MISSING_CHAR", "Tags and anchors must be separated from the next token by white space");
|
||
reqSpace = false;
|
||
}
|
||
if (tab) {
|
||
if (atNewline && token.type !== "comment" && token.type !== "newline") onError(tab, "TAB_AS_INDENT", "Tabs are not allowed as indentation");
|
||
tab = null;
|
||
}
|
||
switch (token.type) {
|
||
case "space":
|
||
if (!flow && (indicator !== "doc-start" || next?.type !== "flow-collection") && token.source.includes(" ")) tab = token;
|
||
hasSpace = true;
|
||
break;
|
||
case "comment": {
|
||
if (!hasSpace) onError(token, "MISSING_CHAR", "Comments must be separated from other tokens by white space characters");
|
||
const cb = token.source.substring(1) || " ";
|
||
if (!comment) comment = cb;
|
||
else comment += commentSep + cb;
|
||
commentSep = "";
|
||
atNewline = false;
|
||
break;
|
||
}
|
||
case "newline":
|
||
if (atNewline) {
|
||
if (comment) comment += token.source;
|
||
else if (!found || indicator !== "seq-item-ind") spaceBefore = true;
|
||
} else commentSep += token.source;
|
||
atNewline = true;
|
||
hasNewline = true;
|
||
if (anchor || tag) newlineAfterProp = token;
|
||
hasSpace = true;
|
||
break;
|
||
case "anchor":
|
||
if (anchor) onError(token, "MULTIPLE_ANCHORS", "A node can have at most one anchor");
|
||
if (token.source.endsWith(":")) onError(token.offset + token.source.length - 1, "BAD_ALIAS", "Anchor ending in : is ambiguous", true);
|
||
anchor = token;
|
||
start ?? (start = token.offset);
|
||
atNewline = false;
|
||
hasSpace = false;
|
||
reqSpace = true;
|
||
break;
|
||
case "tag":
|
||
if (tag) onError(token, "MULTIPLE_TAGS", "A node can have at most one tag");
|
||
tag = token;
|
||
start ?? (start = token.offset);
|
||
atNewline = false;
|
||
hasSpace = false;
|
||
reqSpace = true;
|
||
break;
|
||
case indicator:
|
||
if (anchor || tag) onError(token, "BAD_PROP_ORDER", `Anchors and tags must be after the ${token.source} indicator`);
|
||
if (found) onError(token, "UNEXPECTED_TOKEN", `Unexpected ${token.source} in ${flow ?? "collection"}`);
|
||
found = token;
|
||
atNewline = indicator === "seq-item-ind" || indicator === "explicit-key-ind";
|
||
hasSpace = false;
|
||
break;
|
||
case "comma": if (flow) {
|
||
if (comma) onError(token, "UNEXPECTED_TOKEN", `Unexpected , in ${flow}`);
|
||
comma = token;
|
||
atNewline = false;
|
||
hasSpace = false;
|
||
break;
|
||
}
|
||
default:
|
||
onError(token, "UNEXPECTED_TOKEN", `Unexpected ${token.type} token`);
|
||
atNewline = false;
|
||
hasSpace = false;
|
||
}
|
||
}
|
||
const last = tokens[tokens.length - 1];
|
||
const end = last ? last.offset + last.source.length : offset;
|
||
if (reqSpace && next && next.type !== "space" && next.type !== "newline" && next.type !== "comma" && (next.type !== "scalar" || next.source !== "")) onError(next.offset, "MISSING_CHAR", "Tags and anchors must be separated from the next token by white space");
|
||
if (tab && (atNewline && tab.indent <= parentIndent || next?.type === "block-map" || next?.type === "block-seq")) onError(tab, "TAB_AS_INDENT", "Tabs are not allowed as indentation");
|
||
return {
|
||
comma,
|
||
found,
|
||
spaceBefore,
|
||
comment,
|
||
hasNewline,
|
||
anchor,
|
||
tag,
|
||
newlineAfterProp,
|
||
end,
|
||
start: start ?? end
|
||
};
|
||
}
|
||
exports.resolveProps = resolveProps;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/util-contains-newline.js
|
||
var require_util_contains_newline = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
function containsNewline(key) {
|
||
if (!key) return null;
|
||
switch (key.type) {
|
||
case "alias":
|
||
case "scalar":
|
||
case "double-quoted-scalar":
|
||
case "single-quoted-scalar":
|
||
if (key.source.includes("\n")) return true;
|
||
if (key.end) {
|
||
for (const st of key.end) if (st.type === "newline") return true;
|
||
}
|
||
return false;
|
||
case "flow-collection":
|
||
for (const it of key.items) {
|
||
for (const st of it.start) if (st.type === "newline") return true;
|
||
if (it.sep) {
|
||
for (const st of it.sep) if (st.type === "newline") return true;
|
||
}
|
||
if (containsNewline(it.key) || containsNewline(it.value)) return true;
|
||
}
|
||
return false;
|
||
default: return true;
|
||
}
|
||
}
|
||
exports.containsNewline = containsNewline;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/util-flow-indent-check.js
|
||
var require_util_flow_indent_check = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var utilContainsNewline = require_util_contains_newline();
|
||
function flowIndentCheck(indent, fc, onError) {
|
||
if (fc?.type === "flow-collection") {
|
||
const end = fc.end[0];
|
||
if (end.indent === indent && (end.source === "]" || end.source === "}") && utilContainsNewline.containsNewline(fc)) onError(end, "BAD_INDENT", "Flow end indicator should be more indented than parent", true);
|
||
}
|
||
}
|
||
exports.flowIndentCheck = flowIndentCheck;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/util-map-includes.js
|
||
var require_util_map_includes = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
function mapIncludes(ctx, items, search) {
|
||
const { uniqueKeys } = ctx.options;
|
||
if (uniqueKeys === false) return false;
|
||
const isEqual = typeof uniqueKeys === "function" ? uniqueKeys : (a, b) => a === b || identity.isScalar(a) && identity.isScalar(b) && a.value === b.value;
|
||
return items.some((pair) => isEqual(pair.key, search));
|
||
}
|
||
exports.mapIncludes = mapIncludes;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/resolve-block-map.js
|
||
var require_resolve_block_map = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Pair = require_Pair();
|
||
var YAMLMap = require_YAMLMap();
|
||
var resolveProps = require_resolve_props();
|
||
var utilContainsNewline = require_util_contains_newline();
|
||
var utilFlowIndentCheck = require_util_flow_indent_check();
|
||
var utilMapIncludes = require_util_map_includes();
|
||
const startColMsg = "All mapping items must start at the same column";
|
||
function resolveBlockMap({ composeNode, composeEmptyNode }, ctx, bm, onError, tag) {
|
||
const map = new (tag?.nodeClass ?? YAMLMap.YAMLMap)(ctx.schema);
|
||
if (ctx.atRoot) ctx.atRoot = false;
|
||
let offset = bm.offset;
|
||
let commentEnd = null;
|
||
for (const collItem of bm.items) {
|
||
const { start, key, sep, value } = collItem;
|
||
const keyProps = resolveProps.resolveProps(start, {
|
||
indicator: "explicit-key-ind",
|
||
next: key ?? sep?.[0],
|
||
offset,
|
||
onError,
|
||
parentIndent: bm.indent,
|
||
startOnNewline: true
|
||
});
|
||
const implicitKey = !keyProps.found;
|
||
if (implicitKey) {
|
||
if (key) {
|
||
if (key.type === "block-seq") onError(offset, "BLOCK_AS_IMPLICIT_KEY", "A block sequence may not be used as an implicit map key");
|
||
else if ("indent" in key && key.indent !== bm.indent) onError(offset, "BAD_INDENT", startColMsg);
|
||
}
|
||
if (!keyProps.anchor && !keyProps.tag && !sep) {
|
||
commentEnd = keyProps.end;
|
||
if (keyProps.comment) if (map.comment) map.comment += "\n" + keyProps.comment;
|
||
else map.comment = keyProps.comment;
|
||
continue;
|
||
}
|
||
if (keyProps.newlineAfterProp || utilContainsNewline.containsNewline(key)) onError(key ?? start[start.length - 1], "MULTILINE_IMPLICIT_KEY", "Implicit keys need to be on a single line");
|
||
} else if (keyProps.found?.indent !== bm.indent) onError(offset, "BAD_INDENT", startColMsg);
|
||
ctx.atKey = true;
|
||
const keyStart = keyProps.end;
|
||
const keyNode = key ? composeNode(ctx, key, keyProps, onError) : composeEmptyNode(ctx, keyStart, start, null, keyProps, onError);
|
||
if (ctx.schema.compat) utilFlowIndentCheck.flowIndentCheck(bm.indent, key, onError);
|
||
ctx.atKey = false;
|
||
if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode)) onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
|
||
const valueProps = resolveProps.resolveProps(sep ?? [], {
|
||
indicator: "map-value-ind",
|
||
next: value,
|
||
offset: keyNode.range[2],
|
||
onError,
|
||
parentIndent: bm.indent,
|
||
startOnNewline: !key || key.type === "block-scalar"
|
||
});
|
||
offset = valueProps.end;
|
||
if (valueProps.found) {
|
||
if (implicitKey) {
|
||
if (value?.type === "block-map" && !valueProps.hasNewline) onError(offset, "BLOCK_AS_IMPLICIT_KEY", "Nested mappings are not allowed in compact mappings");
|
||
if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024) onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
|
||
}
|
||
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep, null, valueProps, onError);
|
||
if (ctx.schema.compat) utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
|
||
offset = valueNode.range[2];
|
||
const pair = new Pair.Pair(keyNode, valueNode);
|
||
if (ctx.options.keepSourceTokens) pair.srcToken = collItem;
|
||
map.items.push(pair);
|
||
} else {
|
||
if (implicitKey) onError(keyNode.range, "MISSING_CHAR", "Implicit map keys need to be followed by map values");
|
||
if (valueProps.comment) if (keyNode.comment) keyNode.comment += "\n" + valueProps.comment;
|
||
else keyNode.comment = valueProps.comment;
|
||
const pair = new Pair.Pair(keyNode);
|
||
if (ctx.options.keepSourceTokens) pair.srcToken = collItem;
|
||
map.items.push(pair);
|
||
}
|
||
}
|
||
if (commentEnd && commentEnd < offset) onError(commentEnd, "IMPOSSIBLE", "Map comment with trailing content");
|
||
map.range = [
|
||
bm.offset,
|
||
offset,
|
||
commentEnd ?? offset
|
||
];
|
||
return map;
|
||
}
|
||
exports.resolveBlockMap = resolveBlockMap;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/resolve-block-seq.js
|
||
var require_resolve_block_seq = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var YAMLSeq = require_YAMLSeq();
|
||
var resolveProps = require_resolve_props();
|
||
var utilFlowIndentCheck = require_util_flow_indent_check();
|
||
function resolveBlockSeq({ composeNode, composeEmptyNode }, ctx, bs, onError, tag) {
|
||
const seq = new (tag?.nodeClass ?? YAMLSeq.YAMLSeq)(ctx.schema);
|
||
if (ctx.atRoot) ctx.atRoot = false;
|
||
if (ctx.atKey) ctx.atKey = false;
|
||
let offset = bs.offset;
|
||
let commentEnd = null;
|
||
for (const { start, value } of bs.items) {
|
||
const props = resolveProps.resolveProps(start, {
|
||
indicator: "seq-item-ind",
|
||
next: value,
|
||
offset,
|
||
onError,
|
||
parentIndent: bs.indent,
|
||
startOnNewline: true
|
||
});
|
||
if (!props.found) if (props.anchor || props.tag || value) if (value?.type === "block-seq") onError(props.end, "BAD_INDENT", "All sequence items must start at the same column");
|
||
else onError(offset, "MISSING_CHAR", "Sequence item without - indicator");
|
||
else {
|
||
commentEnd = props.end;
|
||
if (props.comment) seq.comment = props.comment;
|
||
continue;
|
||
}
|
||
const node = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, start, null, props, onError);
|
||
if (ctx.schema.compat) utilFlowIndentCheck.flowIndentCheck(bs.indent, value, onError);
|
||
offset = node.range[2];
|
||
seq.items.push(node);
|
||
}
|
||
seq.range = [
|
||
bs.offset,
|
||
offset,
|
||
commentEnd ?? offset
|
||
];
|
||
return seq;
|
||
}
|
||
exports.resolveBlockSeq = resolveBlockSeq;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/resolve-end.js
|
||
var require_resolve_end = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
function resolveEnd(end, offset, reqSpace, onError) {
|
||
let comment = "";
|
||
if (end) {
|
||
let hasSpace = false;
|
||
let sep = "";
|
||
for (const token of end) {
|
||
const { source, type } = token;
|
||
switch (type) {
|
||
case "space":
|
||
hasSpace = true;
|
||
break;
|
||
case "comment": {
|
||
if (reqSpace && !hasSpace) onError(token, "MISSING_CHAR", "Comments must be separated from other tokens by white space characters");
|
||
const cb = source.substring(1) || " ";
|
||
if (!comment) comment = cb;
|
||
else comment += sep + cb;
|
||
sep = "";
|
||
break;
|
||
}
|
||
case "newline":
|
||
if (comment) sep += source;
|
||
hasSpace = true;
|
||
break;
|
||
default: onError(token, "UNEXPECTED_TOKEN", `Unexpected ${type} at node end`);
|
||
}
|
||
offset += source.length;
|
||
}
|
||
}
|
||
return {
|
||
comment,
|
||
offset
|
||
};
|
||
}
|
||
exports.resolveEnd = resolveEnd;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/resolve-flow-collection.js
|
||
var require_resolve_flow_collection = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var Pair = require_Pair();
|
||
var YAMLMap = require_YAMLMap();
|
||
var YAMLSeq = require_YAMLSeq();
|
||
var resolveEnd = require_resolve_end();
|
||
var resolveProps = require_resolve_props();
|
||
var utilContainsNewline = require_util_contains_newline();
|
||
var utilMapIncludes = require_util_map_includes();
|
||
const blockMsg = "Block collections are not allowed within flow collections";
|
||
const isBlock = (token) => token && (token.type === "block-map" || token.type === "block-seq");
|
||
function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onError, tag) {
|
||
const isMap = fc.start.source === "{";
|
||
const fcName = isMap ? "flow map" : "flow sequence";
|
||
const coll = new (tag?.nodeClass ?? (isMap ? YAMLMap.YAMLMap : YAMLSeq.YAMLSeq))(ctx.schema);
|
||
coll.flow = true;
|
||
const atRoot = ctx.atRoot;
|
||
if (atRoot) ctx.atRoot = false;
|
||
if (ctx.atKey) ctx.atKey = false;
|
||
let offset = fc.offset + fc.start.source.length;
|
||
for (let i = 0; i < fc.items.length; ++i) {
|
||
const collItem = fc.items[i];
|
||
const { start, key, sep, value } = collItem;
|
||
const props = resolveProps.resolveProps(start, {
|
||
flow: fcName,
|
||
indicator: "explicit-key-ind",
|
||
next: key ?? sep?.[0],
|
||
offset,
|
||
onError,
|
||
parentIndent: fc.indent,
|
||
startOnNewline: false
|
||
});
|
||
if (!props.found) {
|
||
if (!props.anchor && !props.tag && !sep && !value) {
|
||
if (i === 0 && props.comma) onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
|
||
else if (i < fc.items.length - 1) onError(props.start, "UNEXPECTED_TOKEN", `Unexpected empty item in ${fcName}`);
|
||
if (props.comment) if (coll.comment) coll.comment += "\n" + props.comment;
|
||
else coll.comment = props.comment;
|
||
offset = props.end;
|
||
continue;
|
||
}
|
||
if (!isMap && ctx.options.strict && utilContainsNewline.containsNewline(key)) onError(key, "MULTILINE_IMPLICIT_KEY", "Implicit keys of flow sequence pairs need to be on a single line");
|
||
}
|
||
if (i === 0) {
|
||
if (props.comma) onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
|
||
} else {
|
||
if (!props.comma) onError(props.start, "MISSING_CHAR", `Missing , between ${fcName} items`);
|
||
if (props.comment) {
|
||
let prevItemComment = "";
|
||
loop: for (const st of start) switch (st.type) {
|
||
case "comma":
|
||
case "space": break;
|
||
case "comment":
|
||
prevItemComment = st.source.substring(1);
|
||
break loop;
|
||
default: break loop;
|
||
}
|
||
if (prevItemComment) {
|
||
let prev = coll.items[coll.items.length - 1];
|
||
if (identity.isPair(prev)) prev = prev.value ?? prev.key;
|
||
if (prev.comment) prev.comment += "\n" + prevItemComment;
|
||
else prev.comment = prevItemComment;
|
||
props.comment = props.comment.substring(prevItemComment.length + 1);
|
||
}
|
||
}
|
||
}
|
||
if (!isMap && !sep && !props.found) {
|
||
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep, null, props, onError);
|
||
coll.items.push(valueNode);
|
||
offset = valueNode.range[2];
|
||
if (isBlock(value)) onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
|
||
} else {
|
||
ctx.atKey = true;
|
||
const keyStart = props.end;
|
||
const keyNode = key ? composeNode(ctx, key, props, onError) : composeEmptyNode(ctx, keyStart, start, null, props, onError);
|
||
if (isBlock(key)) onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
|
||
ctx.atKey = false;
|
||
const valueProps = resolveProps.resolveProps(sep ?? [], {
|
||
flow: fcName,
|
||
indicator: "map-value-ind",
|
||
next: value,
|
||
offset: keyNode.range[2],
|
||
onError,
|
||
parentIndent: fc.indent,
|
||
startOnNewline: false
|
||
});
|
||
if (valueProps.found) {
|
||
if (!isMap && !props.found && ctx.options.strict) {
|
||
if (sep) for (const st of sep) {
|
||
if (st === valueProps.found) break;
|
||
if (st.type === "newline") {
|
||
onError(st, "MULTILINE_IMPLICIT_KEY", "Implicit keys of flow sequence pairs need to be on a single line");
|
||
break;
|
||
}
|
||
}
|
||
if (props.start < valueProps.found.offset - 1024) onError(valueProps.found, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit flow sequence key");
|
||
}
|
||
} else if (value) if ("source" in value && value.source?.[0] === ":") onError(value, "MISSING_CHAR", `Missing space after : in ${fcName}`);
|
||
else onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
|
||
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep, null, valueProps, onError) : null;
|
||
if (valueNode) {
|
||
if (isBlock(value)) onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
|
||
} else if (valueProps.comment) if (keyNode.comment) keyNode.comment += "\n" + valueProps.comment;
|
||
else keyNode.comment = valueProps.comment;
|
||
const pair = new Pair.Pair(keyNode, valueNode);
|
||
if (ctx.options.keepSourceTokens) pair.srcToken = collItem;
|
||
if (isMap) {
|
||
const map = coll;
|
||
if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode)) onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
|
||
map.items.push(pair);
|
||
} else {
|
||
const map = new YAMLMap.YAMLMap(ctx.schema);
|
||
map.flow = true;
|
||
map.items.push(pair);
|
||
const endRange = (valueNode ?? keyNode).range;
|
||
map.range = [
|
||
keyNode.range[0],
|
||
endRange[1],
|
||
endRange[2]
|
||
];
|
||
coll.items.push(map);
|
||
}
|
||
offset = valueNode ? valueNode.range[2] : valueProps.end;
|
||
}
|
||
}
|
||
const expectedEnd = isMap ? "}" : "]";
|
||
const [ce, ...ee] = fc.end;
|
||
let cePos = offset;
|
||
if (ce?.source === expectedEnd) cePos = ce.offset + ce.source.length;
|
||
else {
|
||
const name = fcName[0].toUpperCase() + fcName.substring(1);
|
||
const msg = atRoot ? `${name} must end with a ${expectedEnd}` : `${name} in block collection must be sufficiently indented and end with a ${expectedEnd}`;
|
||
onError(offset, atRoot ? "MISSING_CHAR" : "BAD_INDENT", msg);
|
||
if (ce && ce.source.length !== 1) ee.unshift(ce);
|
||
}
|
||
if (ee.length > 0) {
|
||
const end = resolveEnd.resolveEnd(ee, cePos, ctx.options.strict, onError);
|
||
if (end.comment) if (coll.comment) coll.comment += "\n" + end.comment;
|
||
else coll.comment = end.comment;
|
||
coll.range = [
|
||
fc.offset,
|
||
cePos,
|
||
end.offset
|
||
];
|
||
} else coll.range = [
|
||
fc.offset,
|
||
cePos,
|
||
cePos
|
||
];
|
||
return coll;
|
||
}
|
||
exports.resolveFlowCollection = resolveFlowCollection;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/compose-collection.js
|
||
var require_compose_collection = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var Scalar = require_Scalar();
|
||
var YAMLMap = require_YAMLMap();
|
||
var YAMLSeq = require_YAMLSeq();
|
||
var resolveBlockMap = require_resolve_block_map();
|
||
var resolveBlockSeq = require_resolve_block_seq();
|
||
var resolveFlowCollection = require_resolve_flow_collection();
|
||
function resolveCollection(CN, ctx, token, onError, tagName, tag) {
|
||
const coll = token.type === "block-map" ? resolveBlockMap.resolveBlockMap(CN, ctx, token, onError, tag) : token.type === "block-seq" ? resolveBlockSeq.resolveBlockSeq(CN, ctx, token, onError, tag) : resolveFlowCollection.resolveFlowCollection(CN, ctx, token, onError, tag);
|
||
const Coll = coll.constructor;
|
||
if (tagName === "!" || tagName === Coll.tagName) {
|
||
coll.tag = Coll.tagName;
|
||
return coll;
|
||
}
|
||
if (tagName) coll.tag = tagName;
|
||
return coll;
|
||
}
|
||
function composeCollection(CN, ctx, token, props, onError) {
|
||
const tagToken = props.tag;
|
||
const tagName = !tagToken ? null : ctx.directives.tagName(tagToken.source, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg));
|
||
if (token.type === "block-seq") {
|
||
const { anchor, newlineAfterProp: nl } = props;
|
||
const lastProp = anchor && tagToken ? anchor.offset > tagToken.offset ? anchor : tagToken : anchor ?? tagToken;
|
||
if (lastProp && (!nl || nl.offset < lastProp.offset)) onError(lastProp, "MISSING_CHAR", "Missing newline after block sequence props");
|
||
}
|
||
const expType = token.type === "block-map" ? "map" : token.type === "block-seq" ? "seq" : token.start.source === "{" ? "map" : "seq";
|
||
if (!tagToken || !tagName || tagName === "!" || tagName === YAMLMap.YAMLMap.tagName && expType === "map" || tagName === YAMLSeq.YAMLSeq.tagName && expType === "seq") return resolveCollection(CN, ctx, token, onError, tagName);
|
||
let tag = ctx.schema.tags.find((t) => t.tag === tagName && t.collection === expType);
|
||
if (!tag) {
|
||
const kt = ctx.schema.knownTags[tagName];
|
||
if (kt?.collection === expType) {
|
||
ctx.schema.tags.push(Object.assign({}, kt, { default: false }));
|
||
tag = kt;
|
||
} else {
|
||
if (kt) onError(tagToken, "BAD_COLLECTION_TYPE", `${kt.tag} used for ${expType} collection, but expects ${kt.collection ?? "scalar"}`, true);
|
||
else onError(tagToken, "TAG_RESOLVE_FAILED", `Unresolved tag: ${tagName}`, true);
|
||
return resolveCollection(CN, ctx, token, onError, tagName);
|
||
}
|
||
}
|
||
const coll = resolveCollection(CN, ctx, token, onError, tagName, tag);
|
||
const res = tag.resolve?.(coll, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg), ctx.options) ?? coll;
|
||
const node = identity.isNode(res) ? res : new Scalar.Scalar(res);
|
||
node.range = coll.range;
|
||
node.tag = tagName;
|
||
if (tag?.format) node.format = tag.format;
|
||
return node;
|
||
}
|
||
exports.composeCollection = composeCollection;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/resolve-block-scalar.js
|
||
var require_resolve_block_scalar = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Scalar = require_Scalar();
|
||
function resolveBlockScalar(ctx, scalar, onError) {
|
||
const start = scalar.offset;
|
||
const header = parseBlockScalarHeader(scalar, ctx.options.strict, onError);
|
||
if (!header) return {
|
||
value: "",
|
||
type: null,
|
||
comment: "",
|
||
range: [
|
||
start,
|
||
start,
|
||
start
|
||
]
|
||
};
|
||
const type = header.mode === ">" ? Scalar.Scalar.BLOCK_FOLDED : Scalar.Scalar.BLOCK_LITERAL;
|
||
const lines = scalar.source ? splitLines(scalar.source) : [];
|
||
let chompStart = lines.length;
|
||
for (let i = lines.length - 1; i >= 0; --i) {
|
||
const content = lines[i][1];
|
||
if (content === "" || content === "\r") chompStart = i;
|
||
else break;
|
||
}
|
||
if (chompStart === 0) {
|
||
const value = header.chomp === "+" && lines.length > 0 ? "\n".repeat(Math.max(1, lines.length - 1)) : "";
|
||
let end = start + header.length;
|
||
if (scalar.source) end += scalar.source.length;
|
||
return {
|
||
value,
|
||
type,
|
||
comment: header.comment,
|
||
range: [
|
||
start,
|
||
end,
|
||
end
|
||
]
|
||
};
|
||
}
|
||
let trimIndent = scalar.indent + header.indent;
|
||
let offset = scalar.offset + header.length;
|
||
let contentStart = 0;
|
||
for (let i = 0; i < chompStart; ++i) {
|
||
const [indent, content] = lines[i];
|
||
if (content === "" || content === "\r") {
|
||
if (header.indent === 0 && indent.length > trimIndent) trimIndent = indent.length;
|
||
} else {
|
||
if (indent.length < trimIndent) onError(offset + indent.length, "MISSING_CHAR", "Block scalars with more-indented leading empty lines must use an explicit indentation indicator");
|
||
if (header.indent === 0) trimIndent = indent.length;
|
||
contentStart = i;
|
||
if (trimIndent === 0 && !ctx.atRoot) onError(offset, "BAD_INDENT", "Block scalar values in collections must be indented");
|
||
break;
|
||
}
|
||
offset += indent.length + content.length + 1;
|
||
}
|
||
for (let i = lines.length - 1; i >= chompStart; --i) if (lines[i][0].length > trimIndent) chompStart = i + 1;
|
||
let value = "";
|
||
let sep = "";
|
||
let prevMoreIndented = false;
|
||
for (let i = 0; i < contentStart; ++i) value += lines[i][0].slice(trimIndent) + "\n";
|
||
for (let i = contentStart; i < chompStart; ++i) {
|
||
let [indent, content] = lines[i];
|
||
offset += indent.length + content.length + 1;
|
||
const crlf = content[content.length - 1] === "\r";
|
||
if (crlf) content = content.slice(0, -1);
|
||
/* istanbul ignore if already caught in lexer */
|
||
if (content && indent.length < trimIndent) {
|
||
const message = `Block scalar lines must not be less indented than their ${header.indent ? "explicit indentation indicator" : "first line"}`;
|
||
onError(offset - content.length - (crlf ? 2 : 1), "BAD_INDENT", message);
|
||
indent = "";
|
||
}
|
||
if (type === Scalar.Scalar.BLOCK_LITERAL) {
|
||
value += sep + indent.slice(trimIndent) + content;
|
||
sep = "\n";
|
||
} else if (indent.length > trimIndent || content[0] === " ") {
|
||
if (sep === " ") sep = "\n";
|
||
else if (!prevMoreIndented && sep === "\n") sep = "\n\n";
|
||
value += sep + indent.slice(trimIndent) + content;
|
||
sep = "\n";
|
||
prevMoreIndented = true;
|
||
} else if (content === "") if (sep === "\n") value += "\n";
|
||
else sep = "\n";
|
||
else {
|
||
value += sep + content;
|
||
sep = " ";
|
||
prevMoreIndented = false;
|
||
}
|
||
}
|
||
switch (header.chomp) {
|
||
case "-": break;
|
||
case "+":
|
||
for (let i = chompStart; i < lines.length; ++i) value += "\n" + lines[i][0].slice(trimIndent);
|
||
if (value[value.length - 1] !== "\n") value += "\n";
|
||
break;
|
||
default: value += "\n";
|
||
}
|
||
const end = start + header.length + scalar.source.length;
|
||
return {
|
||
value,
|
||
type,
|
||
comment: header.comment,
|
||
range: [
|
||
start,
|
||
end,
|
||
end
|
||
]
|
||
};
|
||
}
|
||
function parseBlockScalarHeader({ offset, props }, strict, onError) {
|
||
/* istanbul ignore if should not happen */
|
||
if (props[0].type !== "block-scalar-header") {
|
||
onError(props[0], "IMPOSSIBLE", "Block scalar header not found");
|
||
return null;
|
||
}
|
||
const { source } = props[0];
|
||
const mode = source[0];
|
||
let indent = 0;
|
||
let chomp = "";
|
||
let error = -1;
|
||
for (let i = 1; i < source.length; ++i) {
|
||
const ch = source[i];
|
||
if (!chomp && (ch === "-" || ch === "+")) chomp = ch;
|
||
else {
|
||
const n = Number(ch);
|
||
if (!indent && n) indent = n;
|
||
else if (error === -1) error = offset + i;
|
||
}
|
||
}
|
||
if (error !== -1) onError(error, "UNEXPECTED_TOKEN", `Block scalar header includes extra characters: ${source}`);
|
||
let hasSpace = false;
|
||
let comment = "";
|
||
let length = source.length;
|
||
for (let i = 1; i < props.length; ++i) {
|
||
const token = props[i];
|
||
switch (token.type) {
|
||
case "space": hasSpace = true;
|
||
case "newline":
|
||
length += token.source.length;
|
||
break;
|
||
case "comment":
|
||
if (strict && !hasSpace) onError(token, "MISSING_CHAR", "Comments must be separated from other tokens by white space characters");
|
||
length += token.source.length;
|
||
comment = token.source.substring(1);
|
||
break;
|
||
case "error":
|
||
onError(token, "UNEXPECTED_TOKEN", token.message);
|
||
length += token.source.length;
|
||
break;
|
||
default: {
|
||
onError(token, "UNEXPECTED_TOKEN", `Unexpected token in block scalar header: ${token.type}`);
|
||
const ts = token.source;
|
||
if (ts && typeof ts === "string") length += ts.length;
|
||
}
|
||
}
|
||
}
|
||
return {
|
||
mode,
|
||
indent,
|
||
chomp,
|
||
comment,
|
||
length
|
||
};
|
||
}
|
||
/** @returns Array of lines split up as `[indent, content]` */
|
||
function splitLines(source) {
|
||
const split = source.split(/\n( *)/);
|
||
const first = split[0];
|
||
const m = first.match(/^( *)/);
|
||
const lines = [m?.[1] ? [m[1], first.slice(m[1].length)] : ["", first]];
|
||
for (let i = 1; i < split.length; i += 2) lines.push([split[i], split[i + 1]]);
|
||
return lines;
|
||
}
|
||
exports.resolveBlockScalar = resolveBlockScalar;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/resolve-flow-scalar.js
|
||
var require_resolve_flow_scalar = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Scalar = require_Scalar();
|
||
var resolveEnd = require_resolve_end();
|
||
function resolveFlowScalar(scalar, strict, onError) {
|
||
const { offset, type, source, end } = scalar;
|
||
let _type;
|
||
let value;
|
||
const _onError = (rel, code, msg) => onError(offset + rel, code, msg);
|
||
switch (type) {
|
||
case "scalar":
|
||
_type = Scalar.Scalar.PLAIN;
|
||
value = plainValue(source, _onError);
|
||
break;
|
||
case "single-quoted-scalar":
|
||
_type = Scalar.Scalar.QUOTE_SINGLE;
|
||
value = singleQuotedValue(source, _onError);
|
||
break;
|
||
case "double-quoted-scalar":
|
||
_type = Scalar.Scalar.QUOTE_DOUBLE;
|
||
value = doubleQuotedValue(source, _onError);
|
||
break;
|
||
default:
|
||
onError(scalar, "UNEXPECTED_TOKEN", `Expected a flow scalar value, but found: ${type}`);
|
||
return {
|
||
value: "",
|
||
type: null,
|
||
comment: "",
|
||
range: [
|
||
offset,
|
||
offset + source.length,
|
||
offset + source.length
|
||
]
|
||
};
|
||
}
|
||
const valueEnd = offset + source.length;
|
||
const re = resolveEnd.resolveEnd(end, valueEnd, strict, onError);
|
||
return {
|
||
value,
|
||
type: _type,
|
||
comment: re.comment,
|
||
range: [
|
||
offset,
|
||
valueEnd,
|
||
re.offset
|
||
]
|
||
};
|
||
}
|
||
function plainValue(source, onError) {
|
||
let badChar = "";
|
||
switch (source[0]) {
|
||
case " ":
|
||
badChar = "a tab character";
|
||
break;
|
||
case ",":
|
||
badChar = "flow indicator character ,";
|
||
break;
|
||
case "%":
|
||
badChar = "directive indicator character %";
|
||
break;
|
||
case "|":
|
||
case ">":
|
||
badChar = `block scalar indicator ${source[0]}`;
|
||
break;
|
||
case "@":
|
||
case "`":
|
||
badChar = `reserved character ${source[0]}`;
|
||
break;
|
||
}
|
||
if (badChar) onError(0, "BAD_SCALAR_START", `Plain value cannot start with ${badChar}`);
|
||
return foldLines(source);
|
||
}
|
||
function singleQuotedValue(source, onError) {
|
||
if (source[source.length - 1] !== "'" || source.length === 1) onError(source.length, "MISSING_CHAR", "Missing closing 'quote");
|
||
return foldLines(source.slice(1, -1)).replace(/''/g, "'");
|
||
}
|
||
function foldLines(source) {
|
||
/**
|
||
* The negative lookbehind here and in the `re` RegExp is to
|
||
* prevent causing a polynomial search time in certain cases.
|
||
*
|
||
* The try-catch is for Safari, which doesn't support this yet:
|
||
* https://caniuse.com/js-regexp-lookbehind
|
||
*/
|
||
let first, line;
|
||
try {
|
||
first = /* @__PURE__ */ new RegExp("(.*?)(?<![ ])[ ]*\r?\n", "sy");
|
||
line = /* @__PURE__ */ new RegExp("[ ]*(.*?)(?:(?<![ ])[ ]*)?\r?\n", "sy");
|
||
} catch {
|
||
first = /(.*?)[ \t]*\r?\n/sy;
|
||
line = /[ \t]*(.*?)[ \t]*\r?\n/sy;
|
||
}
|
||
let match = first.exec(source);
|
||
if (!match) return source;
|
||
let res = match[1];
|
||
let sep = " ";
|
||
let pos = first.lastIndex;
|
||
line.lastIndex = pos;
|
||
while (match = line.exec(source)) {
|
||
if (match[1] === "") if (sep === "\n") res += sep;
|
||
else sep = "\n";
|
||
else {
|
||
res += sep + match[1];
|
||
sep = " ";
|
||
}
|
||
pos = line.lastIndex;
|
||
}
|
||
const last = /[ \t]*(.*)/sy;
|
||
last.lastIndex = pos;
|
||
match = last.exec(source);
|
||
return res + sep + (match?.[1] ?? "");
|
||
}
|
||
function doubleQuotedValue(source, onError) {
|
||
let res = "";
|
||
for (let i = 1; i < source.length - 1; ++i) {
|
||
const ch = source[i];
|
||
if (ch === "\r" && source[i + 1] === "\n") continue;
|
||
if (ch === "\n") {
|
||
const { fold, offset } = foldNewline(source, i);
|
||
res += fold;
|
||
i = offset;
|
||
} else if (ch === "\\") {
|
||
let next = source[++i];
|
||
const cc = escapeCodes[next];
|
||
if (cc) res += cc;
|
||
else if (next === "\n") {
|
||
next = source[i + 1];
|
||
while (next === " " || next === " ") next = source[++i + 1];
|
||
} else if (next === "\r" && source[i + 1] === "\n") {
|
||
next = source[++i + 1];
|
||
while (next === " " || next === " ") next = source[++i + 1];
|
||
} else if (next === "x" || next === "u" || next === "U") {
|
||
const length = {
|
||
x: 2,
|
||
u: 4,
|
||
U: 8
|
||
}[next];
|
||
res += parseCharCode(source, i + 1, length, onError);
|
||
i += length;
|
||
} else {
|
||
const raw = source.substr(i - 1, 2);
|
||
onError(i - 1, "BAD_DQ_ESCAPE", `Invalid escape sequence ${raw}`);
|
||
res += raw;
|
||
}
|
||
} else if (ch === " " || ch === " ") {
|
||
const wsStart = i;
|
||
let next = source[i + 1];
|
||
while (next === " " || next === " ") next = source[++i + 1];
|
||
if (next !== "\n" && !(next === "\r" && source[i + 2] === "\n")) res += i > wsStart ? source.slice(wsStart, i + 1) : ch;
|
||
} else res += ch;
|
||
}
|
||
if (source[source.length - 1] !== "\"" || source.length === 1) onError(source.length, "MISSING_CHAR", "Missing closing \"quote");
|
||
return res;
|
||
}
|
||
/**
|
||
* Fold a single newline into a space, multiple newlines to N - 1 newlines.
|
||
* Presumes `source[offset] === '\n'`
|
||
*/
|
||
function foldNewline(source, offset) {
|
||
let fold = "";
|
||
let ch = source[offset + 1];
|
||
while (ch === " " || ch === " " || ch === "\n" || ch === "\r") {
|
||
if (ch === "\r" && source[offset + 2] !== "\n") break;
|
||
if (ch === "\n") fold += "\n";
|
||
offset += 1;
|
||
ch = source[offset + 1];
|
||
}
|
||
if (!fold) fold = " ";
|
||
return {
|
||
fold,
|
||
offset
|
||
};
|
||
}
|
||
const escapeCodes = {
|
||
"0": "\0",
|
||
a: "\x07",
|
||
b: "\b",
|
||
e: "\x1B",
|
||
f: "\f",
|
||
n: "\n",
|
||
r: "\r",
|
||
t: " ",
|
||
v: "\v",
|
||
N: "
",
|
||
_: "\xA0",
|
||
L: "\u2028",
|
||
P: "\u2029",
|
||
" ": " ",
|
||
"\"": "\"",
|
||
"/": "/",
|
||
"\\": "\\",
|
||
" ": " "
|
||
};
|
||
function parseCharCode(source, offset, length, onError) {
|
||
const cc = source.substr(offset, length);
|
||
const code = cc.length === length && /^[0-9a-fA-F]+$/.test(cc) ? parseInt(cc, 16) : NaN;
|
||
if (isNaN(code)) {
|
||
const raw = source.substr(offset - 2, length + 2);
|
||
onError(offset - 2, "BAD_DQ_ESCAPE", `Invalid escape sequence ${raw}`);
|
||
return raw;
|
||
}
|
||
return String.fromCodePoint(code);
|
||
}
|
||
exports.resolveFlowScalar = resolveFlowScalar;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/compose-scalar.js
|
||
var require_compose_scalar = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var identity = require_identity();
|
||
var Scalar = require_Scalar();
|
||
var resolveBlockScalar = require_resolve_block_scalar();
|
||
var resolveFlowScalar = require_resolve_flow_scalar();
|
||
function composeScalar(ctx, token, tagToken, onError) {
|
||
const { value, type, comment, range } = token.type === "block-scalar" ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError) : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
|
||
const tagName = tagToken ? ctx.directives.tagName(tagToken.source, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg)) : null;
|
||
let tag;
|
||
if (ctx.options.stringKeys && ctx.atKey) tag = ctx.schema[identity.SCALAR];
|
||
else if (tagName) tag = findScalarTagByName(ctx.schema, value, tagName, tagToken, onError);
|
||
else if (token.type === "scalar") tag = findScalarTagByTest(ctx, value, token, onError);
|
||
else tag = ctx.schema[identity.SCALAR];
|
||
let scalar;
|
||
try {
|
||
const res = tag.resolve(value, (msg) => onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg), ctx.options);
|
||
scalar = identity.isScalar(res) ? res : new Scalar.Scalar(res);
|
||
} catch (error) {
|
||
const msg = error instanceof Error ? error.message : String(error);
|
||
onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg);
|
||
scalar = new Scalar.Scalar(value);
|
||
}
|
||
scalar.range = range;
|
||
scalar.source = value;
|
||
if (type) scalar.type = type;
|
||
if (tagName) scalar.tag = tagName;
|
||
if (tag.format) scalar.format = tag.format;
|
||
if (comment) scalar.comment = comment;
|
||
return scalar;
|
||
}
|
||
function findScalarTagByName(schema, value, tagName, tagToken, onError) {
|
||
if (tagName === "!") return schema[identity.SCALAR];
|
||
const matchWithTest = [];
|
||
for (const tag of schema.tags) if (!tag.collection && tag.tag === tagName) if (tag.default && tag.test) matchWithTest.push(tag);
|
||
else return tag;
|
||
for (const tag of matchWithTest) if (tag.test?.test(value)) return tag;
|
||
const kt = schema.knownTags[tagName];
|
||
if (kt && !kt.collection) {
|
||
schema.tags.push(Object.assign({}, kt, {
|
||
default: false,
|
||
test: void 0
|
||
}));
|
||
return kt;
|
||
}
|
||
onError(tagToken, "TAG_RESOLVE_FAILED", `Unresolved tag: ${tagName}`, tagName !== "tag:yaml.org,2002:str");
|
||
return schema[identity.SCALAR];
|
||
}
|
||
function findScalarTagByTest({ atKey, directives, schema }, value, token, onError) {
|
||
const tag = schema.tags.find((tag) => (tag.default === true || atKey && tag.default === "key") && tag.test?.test(value)) || schema[identity.SCALAR];
|
||
if (schema.compat) {
|
||
const compat = schema.compat.find((tag) => tag.default && tag.test?.test(value)) ?? schema[identity.SCALAR];
|
||
if (tag.tag !== compat.tag) onError(token, "TAG_RESOLVE_FAILED", `Value may be parsed as either ${directives.tagString(tag.tag)} or ${directives.tagString(compat.tag)}`, true);
|
||
}
|
||
return tag;
|
||
}
|
||
exports.composeScalar = composeScalar;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/util-empty-scalar-position.js
|
||
var require_util_empty_scalar_position = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
function emptyScalarPosition(offset, before, pos) {
|
||
if (before) {
|
||
pos ?? (pos = before.length);
|
||
for (let i = pos - 1; i >= 0; --i) {
|
||
let st = before[i];
|
||
switch (st.type) {
|
||
case "space":
|
||
case "comment":
|
||
case "newline":
|
||
offset -= st.source.length;
|
||
continue;
|
||
}
|
||
st = before[++i];
|
||
while (st?.type === "space") {
|
||
offset += st.source.length;
|
||
st = before[++i];
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return offset;
|
||
}
|
||
exports.emptyScalarPosition = emptyScalarPosition;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/compose-node.js
|
||
var require_compose_node = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Alias = require_Alias();
|
||
var identity = require_identity();
|
||
var composeCollection = require_compose_collection();
|
||
var composeScalar = require_compose_scalar();
|
||
var resolveEnd = require_resolve_end();
|
||
var utilEmptyScalarPosition = require_util_empty_scalar_position();
|
||
const CN = {
|
||
composeNode,
|
||
composeEmptyNode
|
||
};
|
||
function composeNode(ctx, token, props, onError) {
|
||
const atKey = ctx.atKey;
|
||
const { spaceBefore, comment, anchor, tag } = props;
|
||
let node;
|
||
let isSrcToken = true;
|
||
switch (token.type) {
|
||
case "alias":
|
||
node = composeAlias(ctx, token, onError);
|
||
if (anchor || tag) onError(token, "ALIAS_PROPS", "An alias node must not specify any properties");
|
||
break;
|
||
case "scalar":
|
||
case "single-quoted-scalar":
|
||
case "double-quoted-scalar":
|
||
case "block-scalar":
|
||
node = composeScalar.composeScalar(ctx, token, tag, onError);
|
||
if (anchor) node.anchor = anchor.source.substring(1);
|
||
break;
|
||
case "block-map":
|
||
case "block-seq":
|
||
case "flow-collection":
|
||
node = composeCollection.composeCollection(CN, ctx, token, props, onError);
|
||
if (anchor) node.anchor = anchor.source.substring(1);
|
||
break;
|
||
default:
|
||
onError(token, "UNEXPECTED_TOKEN", token.type === "error" ? token.message : `Unsupported token (type: ${token.type})`);
|
||
node = composeEmptyNode(ctx, token.offset, void 0, null, props, onError);
|
||
isSrcToken = false;
|
||
}
|
||
if (anchor && node.anchor === "") onError(anchor, "BAD_ALIAS", "Anchor cannot be an empty string");
|
||
if (atKey && ctx.options.stringKeys && (!identity.isScalar(node) || typeof node.value !== "string" || node.tag && node.tag !== "tag:yaml.org,2002:str")) onError(tag ?? token, "NON_STRING_KEY", "With stringKeys, all keys must be strings");
|
||
if (spaceBefore) node.spaceBefore = true;
|
||
if (comment) if (token.type === "scalar" && token.source === "") node.comment = comment;
|
||
else node.commentBefore = comment;
|
||
if (ctx.options.keepSourceTokens && isSrcToken) node.srcToken = token;
|
||
return node;
|
||
}
|
||
function composeEmptyNode(ctx, offset, before, pos, { spaceBefore, comment, anchor, tag, end }, onError) {
|
||
const token = {
|
||
type: "scalar",
|
||
offset: utilEmptyScalarPosition.emptyScalarPosition(offset, before, pos),
|
||
indent: -1,
|
||
source: ""
|
||
};
|
||
const node = composeScalar.composeScalar(ctx, token, tag, onError);
|
||
if (anchor) {
|
||
node.anchor = anchor.source.substring(1);
|
||
if (node.anchor === "") onError(anchor, "BAD_ALIAS", "Anchor cannot be an empty string");
|
||
}
|
||
if (spaceBefore) node.spaceBefore = true;
|
||
if (comment) {
|
||
node.comment = comment;
|
||
node.range[2] = end;
|
||
}
|
||
return node;
|
||
}
|
||
function composeAlias({ options }, { offset, source, end }, onError) {
|
||
const alias = new Alias.Alias(source.substring(1));
|
||
if (alias.source === "") onError(offset, "BAD_ALIAS", "Alias cannot be an empty string");
|
||
if (alias.source.endsWith(":")) onError(offset + source.length - 1, "BAD_ALIAS", "Alias ending in : is ambiguous", true);
|
||
const valueEnd = offset + source.length;
|
||
const re = resolveEnd.resolveEnd(end, valueEnd, options.strict, onError);
|
||
alias.range = [
|
||
offset,
|
||
valueEnd,
|
||
re.offset
|
||
];
|
||
if (re.comment) alias.comment = re.comment;
|
||
return alias;
|
||
}
|
||
exports.composeEmptyNode = composeEmptyNode;
|
||
exports.composeNode = composeNode;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/compose-doc.js
|
||
var require_compose_doc = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var Document = require_Document();
|
||
var composeNode = require_compose_node();
|
||
var resolveEnd = require_resolve_end();
|
||
var resolveProps = require_resolve_props();
|
||
function composeDoc(options, directives, { offset, start, value, end }, onError) {
|
||
const opts = Object.assign({ _directives: directives }, options);
|
||
const doc = new Document.Document(void 0, opts);
|
||
const ctx = {
|
||
atKey: false,
|
||
atRoot: true,
|
||
directives: doc.directives,
|
||
options: doc.options,
|
||
schema: doc.schema
|
||
};
|
||
const props = resolveProps.resolveProps(start, {
|
||
indicator: "doc-start",
|
||
next: value ?? end?.[0],
|
||
offset,
|
||
onError,
|
||
parentIndent: 0,
|
||
startOnNewline: true
|
||
});
|
||
if (props.found) {
|
||
doc.directives.docStart = true;
|
||
if (value && (value.type === "block-map" || value.type === "block-seq") && !props.hasNewline) onError(props.end, "MISSING_CHAR", "Block collection cannot start on same line with directives-end marker");
|
||
}
|
||
doc.contents = value ? composeNode.composeNode(ctx, value, props, onError) : composeNode.composeEmptyNode(ctx, props.end, start, null, props, onError);
|
||
const contentEnd = doc.contents.range[2];
|
||
const re = resolveEnd.resolveEnd(end, contentEnd, false, onError);
|
||
if (re.comment) doc.comment = re.comment;
|
||
doc.range = [
|
||
offset,
|
||
contentEnd,
|
||
re.offset
|
||
];
|
||
return doc;
|
||
}
|
||
exports.composeDoc = composeDoc;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/compose/composer.js
|
||
var require_composer = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var node_process$1 = __require("process");
|
||
var directives = require_directives();
|
||
var Document = require_Document();
|
||
var errors = require_errors();
|
||
var identity = require_identity();
|
||
var composeDoc = require_compose_doc();
|
||
var resolveEnd = require_resolve_end();
|
||
function getErrorPos(src) {
|
||
if (typeof src === "number") return [src, src + 1];
|
||
if (Array.isArray(src)) return src.length === 2 ? src : [src[0], src[1]];
|
||
const { offset, source } = src;
|
||
return [offset, offset + (typeof source === "string" ? source.length : 1)];
|
||
}
|
||
function parsePrelude(prelude) {
|
||
let comment = "";
|
||
let atComment = false;
|
||
let afterEmptyLine = false;
|
||
for (let i = 0; i < prelude.length; ++i) {
|
||
const source = prelude[i];
|
||
switch (source[0]) {
|
||
case "#":
|
||
comment += (comment === "" ? "" : afterEmptyLine ? "\n\n" : "\n") + (source.substring(1) || " ");
|
||
atComment = true;
|
||
afterEmptyLine = false;
|
||
break;
|
||
case "%":
|
||
if (prelude[i + 1]?.[0] !== "#") i += 1;
|
||
atComment = false;
|
||
break;
|
||
default:
|
||
if (!atComment) afterEmptyLine = true;
|
||
atComment = false;
|
||
}
|
||
}
|
||
return {
|
||
comment,
|
||
afterEmptyLine
|
||
};
|
||
}
|
||
/**
|
||
* Compose a stream of CST nodes into a stream of YAML Documents.
|
||
*
|
||
* ```ts
|
||
* import { Composer, Parser } from 'yaml'
|
||
*
|
||
* const src: string = ...
|
||
* const tokens = new Parser().parse(src)
|
||
* const docs = new Composer().compose(tokens)
|
||
* ```
|
||
*/
|
||
var Composer = class {
|
||
constructor(options = {}) {
|
||
this.doc = null;
|
||
this.atDirectives = false;
|
||
this.prelude = [];
|
||
this.errors = [];
|
||
this.warnings = [];
|
||
this.onError = (source, code, message, warning) => {
|
||
const pos = getErrorPos(source);
|
||
if (warning) this.warnings.push(new errors.YAMLWarning(pos, code, message));
|
||
else this.errors.push(new errors.YAMLParseError(pos, code, message));
|
||
};
|
||
this.directives = new directives.Directives({ version: options.version || "1.2" });
|
||
this.options = options;
|
||
}
|
||
decorate(doc, afterDoc) {
|
||
const { comment, afterEmptyLine } = parsePrelude(this.prelude);
|
||
if (comment) {
|
||
const dc = doc.contents;
|
||
if (afterDoc) doc.comment = doc.comment ? `${doc.comment}\n${comment}` : comment;
|
||
else if (afterEmptyLine || doc.directives.docStart || !dc) doc.commentBefore = comment;
|
||
else if (identity.isCollection(dc) && !dc.flow && dc.items.length > 0) {
|
||
let it = dc.items[0];
|
||
if (identity.isPair(it)) it = it.key;
|
||
const cb = it.commentBefore;
|
||
it.commentBefore = cb ? `${comment}\n${cb}` : comment;
|
||
} else {
|
||
const cb = dc.commentBefore;
|
||
dc.commentBefore = cb ? `${comment}\n${cb}` : comment;
|
||
}
|
||
}
|
||
if (afterDoc) {
|
||
Array.prototype.push.apply(doc.errors, this.errors);
|
||
Array.prototype.push.apply(doc.warnings, this.warnings);
|
||
} else {
|
||
doc.errors = this.errors;
|
||
doc.warnings = this.warnings;
|
||
}
|
||
this.prelude = [];
|
||
this.errors = [];
|
||
this.warnings = [];
|
||
}
|
||
/**
|
||
* Current stream status information.
|
||
*
|
||
* Mostly useful at the end of input for an empty stream.
|
||
*/
|
||
streamInfo() {
|
||
return {
|
||
comment: parsePrelude(this.prelude).comment,
|
||
directives: this.directives,
|
||
errors: this.errors,
|
||
warnings: this.warnings
|
||
};
|
||
}
|
||
/**
|
||
* Compose tokens into documents.
|
||
*
|
||
* @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document.
|
||
* @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly.
|
||
*/
|
||
*compose(tokens, forceDoc = false, endOffset = -1) {
|
||
for (const token of tokens) yield* this.next(token);
|
||
yield* this.end(forceDoc, endOffset);
|
||
}
|
||
/** Advance the composer by one CST token. */
|
||
*next(token) {
|
||
if (node_process$1.env.LOG_STREAM) console.dir(token, { depth: null });
|
||
switch (token.type) {
|
||
case "directive":
|
||
this.directives.add(token.source, (offset, message, warning) => {
|
||
const pos = getErrorPos(token);
|
||
pos[0] += offset;
|
||
this.onError(pos, "BAD_DIRECTIVE", message, warning);
|
||
});
|
||
this.prelude.push(token.source);
|
||
this.atDirectives = true;
|
||
break;
|
||
case "document": {
|
||
const doc = composeDoc.composeDoc(this.options, this.directives, token, this.onError);
|
||
if (this.atDirectives && !doc.directives.docStart) this.onError(token, "MISSING_CHAR", "Missing directives-end/doc-start indicator line");
|
||
this.decorate(doc, false);
|
||
if (this.doc) yield this.doc;
|
||
this.doc = doc;
|
||
this.atDirectives = false;
|
||
break;
|
||
}
|
||
case "byte-order-mark":
|
||
case "space": break;
|
||
case "comment":
|
||
case "newline":
|
||
this.prelude.push(token.source);
|
||
break;
|
||
case "error": {
|
||
const msg = token.source ? `${token.message}: ${JSON.stringify(token.source)}` : token.message;
|
||
const error = new errors.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", msg);
|
||
if (this.atDirectives || !this.doc) this.errors.push(error);
|
||
else this.doc.errors.push(error);
|
||
break;
|
||
}
|
||
case "doc-end": {
|
||
if (!this.doc) {
|
||
this.errors.push(new errors.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", "Unexpected doc-end without preceding document"));
|
||
break;
|
||
}
|
||
this.doc.directives.docEnd = true;
|
||
const end = resolveEnd.resolveEnd(token.end, token.offset + token.source.length, this.doc.options.strict, this.onError);
|
||
this.decorate(this.doc, true);
|
||
if (end.comment) {
|
||
const dc = this.doc.comment;
|
||
this.doc.comment = dc ? `${dc}\n${end.comment}` : end.comment;
|
||
}
|
||
this.doc.range[2] = end.offset;
|
||
break;
|
||
}
|
||
default: this.errors.push(new errors.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", `Unsupported token ${token.type}`));
|
||
}
|
||
}
|
||
/**
|
||
* Call at end of input to yield any remaining document.
|
||
*
|
||
* @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document.
|
||
* @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly.
|
||
*/
|
||
*end(forceDoc = false, endOffset = -1) {
|
||
if (this.doc) {
|
||
this.decorate(this.doc, true);
|
||
yield this.doc;
|
||
this.doc = null;
|
||
} else if (forceDoc) {
|
||
const opts = Object.assign({ _directives: this.directives }, this.options);
|
||
const doc = new Document.Document(void 0, opts);
|
||
if (this.atDirectives) this.onError(endOffset, "MISSING_CHAR", "Missing directives-end indicator line");
|
||
doc.range = [
|
||
0,
|
||
endOffset,
|
||
endOffset
|
||
];
|
||
this.decorate(doc, false);
|
||
yield doc;
|
||
}
|
||
}
|
||
};
|
||
exports.Composer = Composer;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/parse/cst-scalar.js
|
||
var require_cst_scalar = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var resolveBlockScalar = require_resolve_block_scalar();
|
||
var resolveFlowScalar = require_resolve_flow_scalar();
|
||
var errors = require_errors();
|
||
var stringifyString = require_stringifyString();
|
||
function resolveAsScalar(token, strict = true, onError) {
|
||
if (token) {
|
||
const _onError = (pos, code, message) => {
|
||
const offset = typeof pos === "number" ? pos : Array.isArray(pos) ? pos[0] : pos.offset;
|
||
if (onError) onError(offset, code, message);
|
||
else throw new errors.YAMLParseError([offset, offset + 1], code, message);
|
||
};
|
||
switch (token.type) {
|
||
case "scalar":
|
||
case "single-quoted-scalar":
|
||
case "double-quoted-scalar": return resolveFlowScalar.resolveFlowScalar(token, strict, _onError);
|
||
case "block-scalar": return resolveBlockScalar.resolveBlockScalar({ options: { strict } }, token, _onError);
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
/**
|
||
* Create a new scalar token with `value`
|
||
*
|
||
* Values that represent an actual string but may be parsed as a different type should use a `type` other than `'PLAIN'`,
|
||
* as this function does not support any schema operations and won't check for such conflicts.
|
||
*
|
||
* @param value The string representation of the value, which will have its content properly indented.
|
||
* @param context.end Comments and whitespace after the end of the value, or after the block scalar header. If undefined, a newline will be added.
|
||
* @param context.implicitKey Being within an implicit key may affect the resolved type of the token's value.
|
||
* @param context.indent The indent level of the token.
|
||
* @param context.inFlow Is this scalar within a flow collection? This may affect the resolved type of the token's value.
|
||
* @param context.offset The offset position of the token.
|
||
* @param context.type The preferred type of the scalar token. If undefined, the previous type of the `token` will be used, defaulting to `'PLAIN'`.
|
||
*/
|
||
function createScalarToken(value, context) {
|
||
const { implicitKey = false, indent, inFlow = false, offset = -1, type = "PLAIN" } = context;
|
||
const source = stringifyString.stringifyString({
|
||
type,
|
||
value
|
||
}, {
|
||
implicitKey,
|
||
indent: indent > 0 ? " ".repeat(indent) : "",
|
||
inFlow,
|
||
options: {
|
||
blockQuote: true,
|
||
lineWidth: -1
|
||
}
|
||
});
|
||
const end = context.end ?? [{
|
||
type: "newline",
|
||
offset: -1,
|
||
indent,
|
||
source: "\n"
|
||
}];
|
||
switch (source[0]) {
|
||
case "|":
|
||
case ">": {
|
||
const he = source.indexOf("\n");
|
||
const head = source.substring(0, he);
|
||
const body = source.substring(he + 1) + "\n";
|
||
const props = [{
|
||
type: "block-scalar-header",
|
||
offset,
|
||
indent,
|
||
source: head
|
||
}];
|
||
if (!addEndtoBlockProps(props, end)) props.push({
|
||
type: "newline",
|
||
offset: -1,
|
||
indent,
|
||
source: "\n"
|
||
});
|
||
return {
|
||
type: "block-scalar",
|
||
offset,
|
||
indent,
|
||
props,
|
||
source: body
|
||
};
|
||
}
|
||
case "\"": return {
|
||
type: "double-quoted-scalar",
|
||
offset,
|
||
indent,
|
||
source,
|
||
end
|
||
};
|
||
case "'": return {
|
||
type: "single-quoted-scalar",
|
||
offset,
|
||
indent,
|
||
source,
|
||
end
|
||
};
|
||
default: return {
|
||
type: "scalar",
|
||
offset,
|
||
indent,
|
||
source,
|
||
end
|
||
};
|
||
}
|
||
}
|
||
/**
|
||
* Set the value of `token` to the given string `value`, overwriting any previous contents and type that it may have.
|
||
*
|
||
* Best efforts are made to retain any comments previously associated with the `token`,
|
||
* though all contents within a collection's `items` will be overwritten.
|
||
*
|
||
* Values that represent an actual string but may be parsed as a different type should use a `type` other than `'PLAIN'`,
|
||
* as this function does not support any schema operations and won't check for such conflicts.
|
||
*
|
||
* @param token Any token. If it does not include an `indent` value, the value will be stringified as if it were an implicit key.
|
||
* @param value The string representation of the value, which will have its content properly indented.
|
||
* @param context.afterKey In most cases, values after a key should have an additional level of indentation.
|
||
* @param context.implicitKey Being within an implicit key may affect the resolved type of the token's value.
|
||
* @param context.inFlow Being within a flow collection may affect the resolved type of the token's value.
|
||
* @param context.type The preferred type of the scalar token. If undefined, the previous type of the `token` will be used, defaulting to `'PLAIN'`.
|
||
*/
|
||
function setScalarValue(token, value, context = {}) {
|
||
let { afterKey = false, implicitKey = false, inFlow = false, type } = context;
|
||
let indent = "indent" in token ? token.indent : null;
|
||
if (afterKey && typeof indent === "number") indent += 2;
|
||
if (!type) switch (token.type) {
|
||
case "single-quoted-scalar":
|
||
type = "QUOTE_SINGLE";
|
||
break;
|
||
case "double-quoted-scalar":
|
||
type = "QUOTE_DOUBLE";
|
||
break;
|
||
case "block-scalar": {
|
||
const header = token.props[0];
|
||
if (header.type !== "block-scalar-header") throw new Error("Invalid block scalar header");
|
||
type = header.source[0] === ">" ? "BLOCK_FOLDED" : "BLOCK_LITERAL";
|
||
break;
|
||
}
|
||
default: type = "PLAIN";
|
||
}
|
||
const source = stringifyString.stringifyString({
|
||
type,
|
||
value
|
||
}, {
|
||
implicitKey: implicitKey || indent === null,
|
||
indent: indent !== null && indent > 0 ? " ".repeat(indent) : "",
|
||
inFlow,
|
||
options: {
|
||
blockQuote: true,
|
||
lineWidth: -1
|
||
}
|
||
});
|
||
switch (source[0]) {
|
||
case "|":
|
||
case ">":
|
||
setBlockScalarValue(token, source);
|
||
break;
|
||
case "\"":
|
||
setFlowScalarValue(token, source, "double-quoted-scalar");
|
||
break;
|
||
case "'":
|
||
setFlowScalarValue(token, source, "single-quoted-scalar");
|
||
break;
|
||
default: setFlowScalarValue(token, source, "scalar");
|
||
}
|
||
}
|
||
function setBlockScalarValue(token, source) {
|
||
const he = source.indexOf("\n");
|
||
const head = source.substring(0, he);
|
||
const body = source.substring(he + 1) + "\n";
|
||
if (token.type === "block-scalar") {
|
||
const header = token.props[0];
|
||
if (header.type !== "block-scalar-header") throw new Error("Invalid block scalar header");
|
||
header.source = head;
|
||
token.source = body;
|
||
} else {
|
||
const { offset } = token;
|
||
const indent = "indent" in token ? token.indent : -1;
|
||
const props = [{
|
||
type: "block-scalar-header",
|
||
offset,
|
||
indent,
|
||
source: head
|
||
}];
|
||
if (!addEndtoBlockProps(props, "end" in token ? token.end : void 0)) props.push({
|
||
type: "newline",
|
||
offset: -1,
|
||
indent,
|
||
source: "\n"
|
||
});
|
||
for (const key of Object.keys(token)) if (key !== "type" && key !== "offset") delete token[key];
|
||
Object.assign(token, {
|
||
type: "block-scalar",
|
||
indent,
|
||
props,
|
||
source: body
|
||
});
|
||
}
|
||
}
|
||
/** @returns `true` if last token is a newline */
|
||
function addEndtoBlockProps(props, end) {
|
||
if (end) for (const st of end) switch (st.type) {
|
||
case "space":
|
||
case "comment":
|
||
props.push(st);
|
||
break;
|
||
case "newline":
|
||
props.push(st);
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
function setFlowScalarValue(token, source, type) {
|
||
switch (token.type) {
|
||
case "scalar":
|
||
case "double-quoted-scalar":
|
||
case "single-quoted-scalar":
|
||
token.type = type;
|
||
token.source = source;
|
||
break;
|
||
case "block-scalar": {
|
||
const end = token.props.slice(1);
|
||
let oa = source.length;
|
||
if (token.props[0].type === "block-scalar-header") oa -= token.props[0].source.length;
|
||
for (const tok of end) tok.offset += oa;
|
||
delete token.props;
|
||
Object.assign(token, {
|
||
type,
|
||
source,
|
||
end
|
||
});
|
||
break;
|
||
}
|
||
case "block-map":
|
||
case "block-seq": {
|
||
const nl = {
|
||
type: "newline",
|
||
offset: token.offset + source.length,
|
||
indent: token.indent,
|
||
source: "\n"
|
||
};
|
||
delete token.items;
|
||
Object.assign(token, {
|
||
type,
|
||
source,
|
||
end: [nl]
|
||
});
|
||
break;
|
||
}
|
||
default: {
|
||
const indent = "indent" in token ? token.indent : -1;
|
||
const end = "end" in token && Array.isArray(token.end) ? token.end.filter((st) => st.type === "space" || st.type === "comment" || st.type === "newline") : [];
|
||
for (const key of Object.keys(token)) if (key !== "type" && key !== "offset") delete token[key];
|
||
Object.assign(token, {
|
||
type,
|
||
indent,
|
||
source,
|
||
end
|
||
});
|
||
}
|
||
}
|
||
}
|
||
exports.createScalarToken = createScalarToken;
|
||
exports.resolveAsScalar = resolveAsScalar;
|
||
exports.setScalarValue = setScalarValue;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/parse/cst-stringify.js
|
||
var require_cst_stringify = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
/**
|
||
* Stringify a CST document, token, or collection item
|
||
*
|
||
* Fair warning: This applies no validation whatsoever, and
|
||
* simply concatenates the sources in their logical order.
|
||
*/
|
||
const stringify = (cst) => "type" in cst ? stringifyToken(cst) : stringifyItem(cst);
|
||
function stringifyToken(token) {
|
||
switch (token.type) {
|
||
case "block-scalar": {
|
||
let res = "";
|
||
for (const tok of token.props) res += stringifyToken(tok);
|
||
return res + token.source;
|
||
}
|
||
case "block-map":
|
||
case "block-seq": {
|
||
let res = "";
|
||
for (const item of token.items) res += stringifyItem(item);
|
||
return res;
|
||
}
|
||
case "flow-collection": {
|
||
let res = token.start.source;
|
||
for (const item of token.items) res += stringifyItem(item);
|
||
for (const st of token.end) res += st.source;
|
||
return res;
|
||
}
|
||
case "document": {
|
||
let res = stringifyItem(token);
|
||
if (token.end) for (const st of token.end) res += st.source;
|
||
return res;
|
||
}
|
||
default: {
|
||
let res = token.source;
|
||
if ("end" in token && token.end) for (const st of token.end) res += st.source;
|
||
return res;
|
||
}
|
||
}
|
||
}
|
||
function stringifyItem({ start, key, sep, value }) {
|
||
let res = "";
|
||
for (const st of start) res += st.source;
|
||
if (key) res += stringifyToken(key);
|
||
if (sep) for (const st of sep) res += st.source;
|
||
if (value) res += stringifyToken(value);
|
||
return res;
|
||
}
|
||
exports.stringify = stringify;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/parse/cst-visit.js
|
||
var require_cst_visit = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
const BREAK = Symbol("break visit");
|
||
const SKIP = Symbol("skip children");
|
||
const REMOVE = Symbol("remove item");
|
||
/**
|
||
* Apply a visitor to a CST document or item.
|
||
*
|
||
* Walks through the tree (depth-first) starting from the root, calling a
|
||
* `visitor` function with two arguments when entering each item:
|
||
* - `item`: The current item, which included the following members:
|
||
* - `start: SourceToken[]` – Source tokens before the key or value,
|
||
* possibly including its anchor or tag.
|
||
* - `key?: Token | null` – Set for pair values. May then be `null`, if
|
||
* the key before the `:` separator is empty.
|
||
* - `sep?: SourceToken[]` – Source tokens between the key and the value,
|
||
* which should include the `:` map value indicator if `value` is set.
|
||
* - `value?: Token` – The value of a sequence item, or of a map pair.
|
||
* - `path`: The steps from the root to the current node, as an array of
|
||
* `['key' | 'value', number]` tuples.
|
||
*
|
||
* The return value of the visitor may be used to control the traversal:
|
||
* - `undefined` (default): Do nothing and continue
|
||
* - `visit.SKIP`: Do not visit the children of this token, continue with
|
||
* next sibling
|
||
* - `visit.BREAK`: Terminate traversal completely
|
||
* - `visit.REMOVE`: Remove the current item, then continue with the next one
|
||
* - `number`: Set the index of the next step. This is useful especially if
|
||
* the index of the current token has changed.
|
||
* - `function`: Define the next visitor for this item. After the original
|
||
* visitor is called on item entry, next visitors are called after handling
|
||
* a non-empty `key` and when exiting the item.
|
||
*/
|
||
function visit(cst, visitor) {
|
||
if ("type" in cst && cst.type === "document") cst = {
|
||
start: cst.start,
|
||
value: cst.value
|
||
};
|
||
_visit(Object.freeze([]), cst, visitor);
|
||
}
|
||
/** Terminate visit traversal completely */
|
||
visit.BREAK = BREAK;
|
||
/** Do not visit the children of the current item */
|
||
visit.SKIP = SKIP;
|
||
/** Remove the current item */
|
||
visit.REMOVE = REMOVE;
|
||
/** Find the item at `path` from `cst` as the root */
|
||
visit.itemAtPath = (cst, path) => {
|
||
let item = cst;
|
||
for (const [field, index] of path) {
|
||
const tok = item?.[field];
|
||
if (tok && "items" in tok) item = tok.items[index];
|
||
else return void 0;
|
||
}
|
||
return item;
|
||
};
|
||
/**
|
||
* Get the immediate parent collection of the item at `path` from `cst` as the root.
|
||
*
|
||
* Throws an error if the collection is not found, which should never happen if the item itself exists.
|
||
*/
|
||
visit.parentCollection = (cst, path) => {
|
||
const parent = visit.itemAtPath(cst, path.slice(0, -1));
|
||
const field = path[path.length - 1][0];
|
||
const coll = parent?.[field];
|
||
if (coll && "items" in coll) return coll;
|
||
throw new Error("Parent collection not found");
|
||
};
|
||
function _visit(path, item, visitor) {
|
||
let ctrl = visitor(item, path);
|
||
if (typeof ctrl === "symbol") return ctrl;
|
||
for (const field of ["key", "value"]) {
|
||
const token = item[field];
|
||
if (token && "items" in token) {
|
||
for (let i = 0; i < token.items.length; ++i) {
|
||
const ci = _visit(Object.freeze(path.concat([[field, i]])), token.items[i], visitor);
|
||
if (typeof ci === "number") i = ci - 1;
|
||
else if (ci === BREAK) return BREAK;
|
||
else if (ci === REMOVE) {
|
||
token.items.splice(i, 1);
|
||
i -= 1;
|
||
}
|
||
}
|
||
if (typeof ctrl === "function" && field === "key") ctrl = ctrl(item, path);
|
||
}
|
||
}
|
||
return typeof ctrl === "function" ? ctrl(item, path) : ctrl;
|
||
}
|
||
exports.visit = visit;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/parse/cst.js
|
||
var require_cst = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var cstScalar = require_cst_scalar();
|
||
var cstStringify = require_cst_stringify();
|
||
var cstVisit = require_cst_visit();
|
||
/** The byte order mark */
|
||
const BOM = "";
|
||
/** Start of doc-mode */
|
||
const DOCUMENT = "";
|
||
/** Unexpected end of flow-mode */
|
||
const FLOW_END = "";
|
||
/** Next token is a scalar value */
|
||
const SCALAR = "";
|
||
/** @returns `true` if `token` is a flow or block collection */
|
||
const isCollection = (token) => !!token && "items" in token;
|
||
/** @returns `true` if `token` is a flow or block scalar; not an alias */
|
||
const isScalar = (token) => !!token && (token.type === "scalar" || token.type === "single-quoted-scalar" || token.type === "double-quoted-scalar" || token.type === "block-scalar");
|
||
/* istanbul ignore next */
|
||
/** Get a printable representation of a lexer token */
|
||
function prettyToken(token) {
|
||
switch (token) {
|
||
case BOM: return "<BOM>";
|
||
case DOCUMENT: return "<DOC>";
|
||
case FLOW_END: return "<FLOW_END>";
|
||
case SCALAR: return "<SCALAR>";
|
||
default: return JSON.stringify(token);
|
||
}
|
||
}
|
||
/** Identify the type of a lexer token. May return `null` for unknown tokens. */
|
||
function tokenType(source) {
|
||
switch (source) {
|
||
case BOM: return "byte-order-mark";
|
||
case DOCUMENT: return "doc-mode";
|
||
case FLOW_END: return "flow-error-end";
|
||
case SCALAR: return "scalar";
|
||
case "---": return "doc-start";
|
||
case "...": return "doc-end";
|
||
case "":
|
||
case "\n":
|
||
case "\r\n": return "newline";
|
||
case "-": return "seq-item-ind";
|
||
case "?": return "explicit-key-ind";
|
||
case ":": return "map-value-ind";
|
||
case "{": return "flow-map-start";
|
||
case "}": return "flow-map-end";
|
||
case "[": return "flow-seq-start";
|
||
case "]": return "flow-seq-end";
|
||
case ",": return "comma";
|
||
}
|
||
switch (source[0]) {
|
||
case " ":
|
||
case " ": return "space";
|
||
case "#": return "comment";
|
||
case "%": return "directive-line";
|
||
case "*": return "alias";
|
||
case "&": return "anchor";
|
||
case "!": return "tag";
|
||
case "'": return "single-quoted-scalar";
|
||
case "\"": return "double-quoted-scalar";
|
||
case "|":
|
||
case ">": return "block-scalar-header";
|
||
}
|
||
return null;
|
||
}
|
||
exports.createScalarToken = cstScalar.createScalarToken;
|
||
exports.resolveAsScalar = cstScalar.resolveAsScalar;
|
||
exports.setScalarValue = cstScalar.setScalarValue;
|
||
exports.stringify = cstStringify.stringify;
|
||
exports.visit = cstVisit.visit;
|
||
exports.BOM = BOM;
|
||
exports.DOCUMENT = DOCUMENT;
|
||
exports.FLOW_END = FLOW_END;
|
||
exports.SCALAR = SCALAR;
|
||
exports.isCollection = isCollection;
|
||
exports.isScalar = isScalar;
|
||
exports.prettyToken = prettyToken;
|
||
exports.tokenType = tokenType;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/parse/lexer.js
|
||
var require_lexer = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var cst = require_cst();
|
||
function isEmpty(ch) {
|
||
switch (ch) {
|
||
case void 0:
|
||
case " ":
|
||
case "\n":
|
||
case "\r":
|
||
case " ": return true;
|
||
default: return false;
|
||
}
|
||
}
|
||
const hexDigits = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef");
|
||
const tagChars = /* @__PURE__ */ new Set("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()");
|
||
const flowIndicatorChars = /* @__PURE__ */ new Set(",[]{}");
|
||
const invalidAnchorChars = /* @__PURE__ */ new Set(" ,[]{}\n\r ");
|
||
const isNotAnchorChar = (ch) => !ch || invalidAnchorChars.has(ch);
|
||
/**
|
||
* Splits an input string into lexical tokens, i.e. smaller strings that are
|
||
* easily identifiable by `tokens.tokenType()`.
|
||
*
|
||
* Lexing starts always in a "stream" context. Incomplete input may be buffered
|
||
* until a complete token can be emitted.
|
||
*
|
||
* In addition to slices of the original input, the following control characters
|
||
* may also be emitted:
|
||
*
|
||
* - `\x02` (Start of Text): A document starts with the next token
|
||
* - `\x18` (Cancel): Unexpected end of flow-mode (indicates an error)
|
||
* - `\x1f` (Unit Separator): Next token is a scalar value
|
||
* - `\u{FEFF}` (Byte order mark): Emitted separately outside documents
|
||
*/
|
||
var Lexer = class {
|
||
constructor() {
|
||
/**
|
||
* Flag indicating whether the end of the current buffer marks the end of
|
||
* all input
|
||
*/
|
||
this.atEnd = false;
|
||
/**
|
||
* Explicit indent set in block scalar header, as an offset from the current
|
||
* minimum indent, so e.g. set to 1 from a header `|2+`. Set to -1 if not
|
||
* explicitly set.
|
||
*/
|
||
this.blockScalarIndent = -1;
|
||
/**
|
||
* Block scalars that include a + (keep) chomping indicator in their header
|
||
* include trailing empty lines, which are otherwise excluded from the
|
||
* scalar's contents.
|
||
*/
|
||
this.blockScalarKeep = false;
|
||
/** Current input */
|
||
this.buffer = "";
|
||
/**
|
||
* Flag noting whether the map value indicator : can immediately follow this
|
||
* node within a flow context.
|
||
*/
|
||
this.flowKey = false;
|
||
/** Count of surrounding flow collection levels. */
|
||
this.flowLevel = 0;
|
||
/**
|
||
* Minimum level of indentation required for next lines to be parsed as a
|
||
* part of the current scalar value.
|
||
*/
|
||
this.indentNext = 0;
|
||
/** Indentation level of the current line. */
|
||
this.indentValue = 0;
|
||
/** Position of the next \n character. */
|
||
this.lineEndPos = null;
|
||
/** Stores the state of the lexer if reaching the end of incpomplete input */
|
||
this.next = null;
|
||
/** A pointer to `buffer`; the current position of the lexer. */
|
||
this.pos = 0;
|
||
}
|
||
/**
|
||
* Generate YAML tokens from the `source` string. If `incomplete`,
|
||
* a part of the last line may be left as a buffer for the next call.
|
||
*
|
||
* @returns A generator of lexical tokens
|
||
*/
|
||
*lex(source, incomplete = false) {
|
||
if (source) {
|
||
if (typeof source !== "string") throw TypeError("source is not a string");
|
||
this.buffer = this.buffer ? this.buffer + source : source;
|
||
this.lineEndPos = null;
|
||
}
|
||
this.atEnd = !incomplete;
|
||
let next = this.next ?? "stream";
|
||
while (next && (incomplete || this.hasChars(1))) next = yield* this.parseNext(next);
|
||
}
|
||
atLineEnd() {
|
||
let i = this.pos;
|
||
let ch = this.buffer[i];
|
||
while (ch === " " || ch === " ") ch = this.buffer[++i];
|
||
if (!ch || ch === "#" || ch === "\n") return true;
|
||
if (ch === "\r") return this.buffer[i + 1] === "\n";
|
||
return false;
|
||
}
|
||
charAt(n) {
|
||
return this.buffer[this.pos + n];
|
||
}
|
||
continueScalar(offset) {
|
||
let ch = this.buffer[offset];
|
||
if (this.indentNext > 0) {
|
||
let indent = 0;
|
||
while (ch === " ") ch = this.buffer[++indent + offset];
|
||
if (ch === "\r") {
|
||
const next = this.buffer[indent + offset + 1];
|
||
if (next === "\n" || !next && !this.atEnd) return offset + indent + 1;
|
||
}
|
||
return ch === "\n" || indent >= this.indentNext || !ch && !this.atEnd ? offset + indent : -1;
|
||
}
|
||
if (ch === "-" || ch === ".") {
|
||
const dt = this.buffer.substr(offset, 3);
|
||
if ((dt === "---" || dt === "...") && isEmpty(this.buffer[offset + 3])) return -1;
|
||
}
|
||
return offset;
|
||
}
|
||
getLine() {
|
||
let end = this.lineEndPos;
|
||
if (typeof end !== "number" || end !== -1 && end < this.pos) {
|
||
end = this.buffer.indexOf("\n", this.pos);
|
||
this.lineEndPos = end;
|
||
}
|
||
if (end === -1) return this.atEnd ? this.buffer.substring(this.pos) : null;
|
||
if (this.buffer[end - 1] === "\r") end -= 1;
|
||
return this.buffer.substring(this.pos, end);
|
||
}
|
||
hasChars(n) {
|
||
return this.pos + n <= this.buffer.length;
|
||
}
|
||
setNext(state) {
|
||
this.buffer = this.buffer.substring(this.pos);
|
||
this.pos = 0;
|
||
this.lineEndPos = null;
|
||
this.next = state;
|
||
return null;
|
||
}
|
||
peek(n) {
|
||
return this.buffer.substr(this.pos, n);
|
||
}
|
||
*parseNext(next) {
|
||
switch (next) {
|
||
case "stream": return yield* this.parseStream();
|
||
case "line-start": return yield* this.parseLineStart();
|
||
case "block-start": return yield* this.parseBlockStart();
|
||
case "doc": return yield* this.parseDocument();
|
||
case "flow": return yield* this.parseFlowCollection();
|
||
case "quoted-scalar": return yield* this.parseQuotedScalar();
|
||
case "block-scalar": return yield* this.parseBlockScalar();
|
||
case "plain-scalar": return yield* this.parsePlainScalar();
|
||
}
|
||
}
|
||
*parseStream() {
|
||
let line = this.getLine();
|
||
if (line === null) return this.setNext("stream");
|
||
if (line[0] === cst.BOM) {
|
||
yield* this.pushCount(1);
|
||
line = line.substring(1);
|
||
}
|
||
if (line[0] === "%") {
|
||
let dirEnd = line.length;
|
||
let cs = line.indexOf("#");
|
||
while (cs !== -1) {
|
||
const ch = line[cs - 1];
|
||
if (ch === " " || ch === " ") {
|
||
dirEnd = cs - 1;
|
||
break;
|
||
} else cs = line.indexOf("#", cs + 1);
|
||
}
|
||
while (true) {
|
||
const ch = line[dirEnd - 1];
|
||
if (ch === " " || ch === " ") dirEnd -= 1;
|
||
else break;
|
||
}
|
||
const n = (yield* this.pushCount(dirEnd)) + (yield* this.pushSpaces(true));
|
||
yield* this.pushCount(line.length - n);
|
||
this.pushNewline();
|
||
return "stream";
|
||
}
|
||
if (this.atLineEnd()) {
|
||
const sp = yield* this.pushSpaces(true);
|
||
yield* this.pushCount(line.length - sp);
|
||
yield* this.pushNewline();
|
||
return "stream";
|
||
}
|
||
yield cst.DOCUMENT;
|
||
return yield* this.parseLineStart();
|
||
}
|
||
*parseLineStart() {
|
||
const ch = this.charAt(0);
|
||
if (!ch && !this.atEnd) return this.setNext("line-start");
|
||
if (ch === "-" || ch === ".") {
|
||
if (!this.atEnd && !this.hasChars(4)) return this.setNext("line-start");
|
||
const s = this.peek(3);
|
||
if ((s === "---" || s === "...") && isEmpty(this.charAt(3))) {
|
||
yield* this.pushCount(3);
|
||
this.indentValue = 0;
|
||
this.indentNext = 0;
|
||
return s === "---" ? "doc" : "stream";
|
||
}
|
||
}
|
||
this.indentValue = yield* this.pushSpaces(false);
|
||
if (this.indentNext > this.indentValue && !isEmpty(this.charAt(1))) this.indentNext = this.indentValue;
|
||
return yield* this.parseBlockStart();
|
||
}
|
||
*parseBlockStart() {
|
||
const [ch0, ch1] = this.peek(2);
|
||
if (!ch1 && !this.atEnd) return this.setNext("block-start");
|
||
if ((ch0 === "-" || ch0 === "?" || ch0 === ":") && isEmpty(ch1)) {
|
||
const n = (yield* this.pushCount(1)) + (yield* this.pushSpaces(true));
|
||
this.indentNext = this.indentValue + 1;
|
||
this.indentValue += n;
|
||
return yield* this.parseBlockStart();
|
||
}
|
||
return "doc";
|
||
}
|
||
*parseDocument() {
|
||
yield* this.pushSpaces(true);
|
||
const line = this.getLine();
|
||
if (line === null) return this.setNext("doc");
|
||
let n = yield* this.pushIndicators();
|
||
switch (line[n]) {
|
||
case "#": yield* this.pushCount(line.length - n);
|
||
case void 0:
|
||
yield* this.pushNewline();
|
||
return yield* this.parseLineStart();
|
||
case "{":
|
||
case "[":
|
||
yield* this.pushCount(1);
|
||
this.flowKey = false;
|
||
this.flowLevel = 1;
|
||
return "flow";
|
||
case "}":
|
||
case "]":
|
||
yield* this.pushCount(1);
|
||
return "doc";
|
||
case "*":
|
||
yield* this.pushUntil(isNotAnchorChar);
|
||
return "doc";
|
||
case "\"":
|
||
case "'": return yield* this.parseQuotedScalar();
|
||
case "|":
|
||
case ">":
|
||
n += yield* this.parseBlockScalarHeader();
|
||
n += yield* this.pushSpaces(true);
|
||
yield* this.pushCount(line.length - n);
|
||
yield* this.pushNewline();
|
||
return yield* this.parseBlockScalar();
|
||
default: return yield* this.parsePlainScalar();
|
||
}
|
||
}
|
||
*parseFlowCollection() {
|
||
let nl, sp;
|
||
let indent = -1;
|
||
do {
|
||
nl = yield* this.pushNewline();
|
||
if (nl > 0) {
|
||
sp = yield* this.pushSpaces(false);
|
||
this.indentValue = indent = sp;
|
||
} else sp = 0;
|
||
sp += yield* this.pushSpaces(true);
|
||
} while (nl + sp > 0);
|
||
const line = this.getLine();
|
||
if (line === null) return this.setNext("flow");
|
||
if (indent !== -1 && indent < this.indentNext && line[0] !== "#" || indent === 0 && (line.startsWith("---") || line.startsWith("...")) && isEmpty(line[3])) {
|
||
if (!(indent === this.indentNext - 1 && this.flowLevel === 1 && (line[0] === "]" || line[0] === "}"))) {
|
||
this.flowLevel = 0;
|
||
yield cst.FLOW_END;
|
||
return yield* this.parseLineStart();
|
||
}
|
||
}
|
||
let n = 0;
|
||
while (line[n] === ",") {
|
||
n += yield* this.pushCount(1);
|
||
n += yield* this.pushSpaces(true);
|
||
this.flowKey = false;
|
||
}
|
||
n += yield* this.pushIndicators();
|
||
switch (line[n]) {
|
||
case void 0: return "flow";
|
||
case "#":
|
||
yield* this.pushCount(line.length - n);
|
||
return "flow";
|
||
case "{":
|
||
case "[":
|
||
yield* this.pushCount(1);
|
||
this.flowKey = false;
|
||
this.flowLevel += 1;
|
||
return "flow";
|
||
case "}":
|
||
case "]":
|
||
yield* this.pushCount(1);
|
||
this.flowKey = true;
|
||
this.flowLevel -= 1;
|
||
return this.flowLevel ? "flow" : "doc";
|
||
case "*":
|
||
yield* this.pushUntil(isNotAnchorChar);
|
||
return "flow";
|
||
case "\"":
|
||
case "'":
|
||
this.flowKey = true;
|
||
return yield* this.parseQuotedScalar();
|
||
case ":": {
|
||
const next = this.charAt(1);
|
||
if (this.flowKey || isEmpty(next) || next === ",") {
|
||
this.flowKey = false;
|
||
yield* this.pushCount(1);
|
||
yield* this.pushSpaces(true);
|
||
return "flow";
|
||
}
|
||
}
|
||
default:
|
||
this.flowKey = false;
|
||
return yield* this.parsePlainScalar();
|
||
}
|
||
}
|
||
*parseQuotedScalar() {
|
||
const quote = this.charAt(0);
|
||
let end = this.buffer.indexOf(quote, this.pos + 1);
|
||
if (quote === "'") while (end !== -1 && this.buffer[end + 1] === "'") end = this.buffer.indexOf("'", end + 2);
|
||
else while (end !== -1) {
|
||
let n = 0;
|
||
while (this.buffer[end - 1 - n] === "\\") n += 1;
|
||
if (n % 2 === 0) break;
|
||
end = this.buffer.indexOf("\"", end + 1);
|
||
}
|
||
const qb = this.buffer.substring(0, end);
|
||
let nl = qb.indexOf("\n", this.pos);
|
||
if (nl !== -1) {
|
||
while (nl !== -1) {
|
||
const cs = this.continueScalar(nl + 1);
|
||
if (cs === -1) break;
|
||
nl = qb.indexOf("\n", cs);
|
||
}
|
||
if (nl !== -1) end = nl - (qb[nl - 1] === "\r" ? 2 : 1);
|
||
}
|
||
if (end === -1) {
|
||
if (!this.atEnd) return this.setNext("quoted-scalar");
|
||
end = this.buffer.length;
|
||
}
|
||
yield* this.pushToIndex(end + 1, false);
|
||
return this.flowLevel ? "flow" : "doc";
|
||
}
|
||
*parseBlockScalarHeader() {
|
||
this.blockScalarIndent = -1;
|
||
this.blockScalarKeep = false;
|
||
let i = this.pos;
|
||
while (true) {
|
||
const ch = this.buffer[++i];
|
||
if (ch === "+") this.blockScalarKeep = true;
|
||
else if (ch > "0" && ch <= "9") this.blockScalarIndent = Number(ch) - 1;
|
||
else if (ch !== "-") break;
|
||
}
|
||
return yield* this.pushUntil((ch) => isEmpty(ch) || ch === "#");
|
||
}
|
||
*parseBlockScalar() {
|
||
let nl = this.pos - 1;
|
||
let indent = 0;
|
||
let ch;
|
||
loop: for (let i = this.pos; ch = this.buffer[i]; ++i) switch (ch) {
|
||
case " ":
|
||
indent += 1;
|
||
break;
|
||
case "\n":
|
||
nl = i;
|
||
indent = 0;
|
||
break;
|
||
case "\r": {
|
||
const next = this.buffer[i + 1];
|
||
if (!next && !this.atEnd) return this.setNext("block-scalar");
|
||
if (next === "\n") break;
|
||
}
|
||
default: break loop;
|
||
}
|
||
if (!ch && !this.atEnd) return this.setNext("block-scalar");
|
||
if (indent >= this.indentNext) {
|
||
if (this.blockScalarIndent === -1) this.indentNext = indent;
|
||
else this.indentNext = this.blockScalarIndent + (this.indentNext === 0 ? 1 : this.indentNext);
|
||
do {
|
||
const cs = this.continueScalar(nl + 1);
|
||
if (cs === -1) break;
|
||
nl = this.buffer.indexOf("\n", cs);
|
||
} while (nl !== -1);
|
||
if (nl === -1) {
|
||
if (!this.atEnd) return this.setNext("block-scalar");
|
||
nl = this.buffer.length;
|
||
}
|
||
}
|
||
let i = nl + 1;
|
||
ch = this.buffer[i];
|
||
while (ch === " ") ch = this.buffer[++i];
|
||
if (ch === " ") {
|
||
while (ch === " " || ch === " " || ch === "\r" || ch === "\n") ch = this.buffer[++i];
|
||
nl = i - 1;
|
||
} else if (!this.blockScalarKeep) do {
|
||
let i = nl - 1;
|
||
let ch = this.buffer[i];
|
||
if (ch === "\r") ch = this.buffer[--i];
|
||
const lastChar = i;
|
||
while (ch === " ") ch = this.buffer[--i];
|
||
if (ch === "\n" && i >= this.pos && i + 1 + indent > lastChar) nl = i;
|
||
else break;
|
||
} while (true);
|
||
yield cst.SCALAR;
|
||
yield* this.pushToIndex(nl + 1, true);
|
||
return yield* this.parseLineStart();
|
||
}
|
||
*parsePlainScalar() {
|
||
const inFlow = this.flowLevel > 0;
|
||
let end = this.pos - 1;
|
||
let i = this.pos - 1;
|
||
let ch;
|
||
while (ch = this.buffer[++i]) if (ch === ":") {
|
||
const next = this.buffer[i + 1];
|
||
if (isEmpty(next) || inFlow && flowIndicatorChars.has(next)) break;
|
||
end = i;
|
||
} else if (isEmpty(ch)) {
|
||
let next = this.buffer[i + 1];
|
||
if (ch === "\r") if (next === "\n") {
|
||
i += 1;
|
||
ch = "\n";
|
||
next = this.buffer[i + 1];
|
||
} else end = i;
|
||
if (next === "#" || inFlow && flowIndicatorChars.has(next)) break;
|
||
if (ch === "\n") {
|
||
const cs = this.continueScalar(i + 1);
|
||
if (cs === -1) break;
|
||
i = Math.max(i, cs - 2);
|
||
}
|
||
} else {
|
||
if (inFlow && flowIndicatorChars.has(ch)) break;
|
||
end = i;
|
||
}
|
||
if (!ch && !this.atEnd) return this.setNext("plain-scalar");
|
||
yield cst.SCALAR;
|
||
yield* this.pushToIndex(end + 1, true);
|
||
return inFlow ? "flow" : "doc";
|
||
}
|
||
*pushCount(n) {
|
||
if (n > 0) {
|
||
yield this.buffer.substr(this.pos, n);
|
||
this.pos += n;
|
||
return n;
|
||
}
|
||
return 0;
|
||
}
|
||
*pushToIndex(i, allowEmpty) {
|
||
const s = this.buffer.slice(this.pos, i);
|
||
if (s) {
|
||
yield s;
|
||
this.pos += s.length;
|
||
return s.length;
|
||
} else if (allowEmpty) yield "";
|
||
return 0;
|
||
}
|
||
*pushIndicators() {
|
||
switch (this.charAt(0)) {
|
||
case "!": return (yield* this.pushTag()) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators());
|
||
case "&": return (yield* this.pushUntil(isNotAnchorChar)) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators());
|
||
case "-":
|
||
case "?":
|
||
case ":": {
|
||
const inFlow = this.flowLevel > 0;
|
||
const ch1 = this.charAt(1);
|
||
if (isEmpty(ch1) || inFlow && flowIndicatorChars.has(ch1)) {
|
||
if (!inFlow) this.indentNext = this.indentValue + 1;
|
||
else if (this.flowKey) this.flowKey = false;
|
||
return (yield* this.pushCount(1)) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators());
|
||
}
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
*pushTag() {
|
||
if (this.charAt(1) === "<") {
|
||
let i = this.pos + 2;
|
||
let ch = this.buffer[i];
|
||
while (!isEmpty(ch) && ch !== ">") ch = this.buffer[++i];
|
||
return yield* this.pushToIndex(ch === ">" ? i + 1 : i, false);
|
||
} else {
|
||
let i = this.pos + 1;
|
||
let ch = this.buffer[i];
|
||
while (ch) if (tagChars.has(ch)) ch = this.buffer[++i];
|
||
else if (ch === "%" && hexDigits.has(this.buffer[i + 1]) && hexDigits.has(this.buffer[i + 2])) ch = this.buffer[i += 3];
|
||
else break;
|
||
return yield* this.pushToIndex(i, false);
|
||
}
|
||
}
|
||
*pushNewline() {
|
||
const ch = this.buffer[this.pos];
|
||
if (ch === "\n") return yield* this.pushCount(1);
|
||
else if (ch === "\r" && this.charAt(1) === "\n") return yield* this.pushCount(2);
|
||
else return 0;
|
||
}
|
||
*pushSpaces(allowTabs) {
|
||
let i = this.pos - 1;
|
||
let ch;
|
||
do
|
||
ch = this.buffer[++i];
|
||
while (ch === " " || allowTabs && ch === " ");
|
||
const n = i - this.pos;
|
||
if (n > 0) {
|
||
yield this.buffer.substr(this.pos, n);
|
||
this.pos = i;
|
||
}
|
||
return n;
|
||
}
|
||
*pushUntil(test) {
|
||
let i = this.pos;
|
||
let ch = this.buffer[i];
|
||
while (!test(ch)) ch = this.buffer[++i];
|
||
return yield* this.pushToIndex(i, false);
|
||
}
|
||
};
|
||
exports.Lexer = Lexer;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/parse/line-counter.js
|
||
var require_line_counter = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
/**
|
||
* Tracks newlines during parsing in order to provide an efficient API for
|
||
* determining the one-indexed `{ line, col }` position for any offset
|
||
* within the input.
|
||
*/
|
||
var LineCounter = class {
|
||
constructor() {
|
||
this.lineStarts = [];
|
||
/**
|
||
* Should be called in ascending order. Otherwise, call
|
||
* `lineCounter.lineStarts.sort()` before calling `linePos()`.
|
||
*/
|
||
this.addNewLine = (offset) => this.lineStarts.push(offset);
|
||
/**
|
||
* Performs a binary search and returns the 1-indexed { line, col }
|
||
* position of `offset`. If `line === 0`, `addNewLine` has never been
|
||
* called or `offset` is before the first known newline.
|
||
*/
|
||
this.linePos = (offset) => {
|
||
let low = 0;
|
||
let high = this.lineStarts.length;
|
||
while (low < high) {
|
||
const mid = low + high >> 1;
|
||
if (this.lineStarts[mid] < offset) low = mid + 1;
|
||
else high = mid;
|
||
}
|
||
if (this.lineStarts[low] === offset) return {
|
||
line: low + 1,
|
||
col: 1
|
||
};
|
||
if (low === 0) return {
|
||
line: 0,
|
||
col: offset
|
||
};
|
||
const start = this.lineStarts[low - 1];
|
||
return {
|
||
line: low,
|
||
col: offset - start + 1
|
||
};
|
||
};
|
||
}
|
||
};
|
||
exports.LineCounter = LineCounter;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/parse/parser.js
|
||
var require_parser = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var node_process = __require("process");
|
||
var cst = require_cst();
|
||
var lexer = require_lexer();
|
||
function includesToken(list, type) {
|
||
for (let i = 0; i < list.length; ++i) if (list[i].type === type) return true;
|
||
return false;
|
||
}
|
||
function findNonEmptyIndex(list) {
|
||
for (let i = 0; i < list.length; ++i) switch (list[i].type) {
|
||
case "space":
|
||
case "comment":
|
||
case "newline": break;
|
||
default: return i;
|
||
}
|
||
return -1;
|
||
}
|
||
function isFlowToken(token) {
|
||
switch (token?.type) {
|
||
case "alias":
|
||
case "scalar":
|
||
case "single-quoted-scalar":
|
||
case "double-quoted-scalar":
|
||
case "flow-collection": return true;
|
||
default: return false;
|
||
}
|
||
}
|
||
function getPrevProps(parent) {
|
||
switch (parent.type) {
|
||
case "document": return parent.start;
|
||
case "block-map": {
|
||
const it = parent.items[parent.items.length - 1];
|
||
return it.sep ?? it.start;
|
||
}
|
||
case "block-seq": return parent.items[parent.items.length - 1].start;
|
||
default: return [];
|
||
}
|
||
}
|
||
/** Note: May modify input array */
|
||
function getFirstKeyStartProps(prev) {
|
||
if (prev.length === 0) return [];
|
||
let i = prev.length;
|
||
loop: while (--i >= 0) switch (prev[i].type) {
|
||
case "doc-start":
|
||
case "explicit-key-ind":
|
||
case "map-value-ind":
|
||
case "seq-item-ind":
|
||
case "newline": break loop;
|
||
}
|
||
while (prev[++i]?.type === "space");
|
||
return prev.splice(i, prev.length);
|
||
}
|
||
function fixFlowSeqItems(fc) {
|
||
if (fc.start.type === "flow-seq-start") {
|
||
for (const it of fc.items) if (it.sep && !it.value && !includesToken(it.start, "explicit-key-ind") && !includesToken(it.sep, "map-value-ind")) {
|
||
if (it.key) it.value = it.key;
|
||
delete it.key;
|
||
if (isFlowToken(it.value)) if (it.value.end) Array.prototype.push.apply(it.value.end, it.sep);
|
||
else it.value.end = it.sep;
|
||
else Array.prototype.push.apply(it.start, it.sep);
|
||
delete it.sep;
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* A YAML concrete syntax tree (CST) parser
|
||
*
|
||
* ```ts
|
||
* const src: string = ...
|
||
* for (const token of new Parser().parse(src)) {
|
||
* // token: Token
|
||
* }
|
||
* ```
|
||
*
|
||
* To use the parser with a user-provided lexer:
|
||
*
|
||
* ```ts
|
||
* function* parse(source: string, lexer: Lexer) {
|
||
* const parser = new Parser()
|
||
* for (const lexeme of lexer.lex(source))
|
||
* yield* parser.next(lexeme)
|
||
* yield* parser.end()
|
||
* }
|
||
*
|
||
* const src: string = ...
|
||
* const lexer = new Lexer()
|
||
* for (const token of parse(src, lexer)) {
|
||
* // token: Token
|
||
* }
|
||
* ```
|
||
*/
|
||
var Parser = class {
|
||
/**
|
||
* @param onNewLine - If defined, called separately with the start position of
|
||
* each new line (in `parse()`, including the start of input).
|
||
*/
|
||
constructor(onNewLine) {
|
||
/** If true, space and sequence indicators count as indentation */
|
||
this.atNewLine = true;
|
||
/** If true, next token is a scalar value */
|
||
this.atScalar = false;
|
||
/** Current indentation level */
|
||
this.indent = 0;
|
||
/** Current offset since the start of parsing */
|
||
this.offset = 0;
|
||
/** On the same line with a block map key */
|
||
this.onKeyLine = false;
|
||
/** Top indicates the node that's currently being built */
|
||
this.stack = [];
|
||
/** The source of the current token, set in parse() */
|
||
this.source = "";
|
||
/** The type of the current token, set in parse() */
|
||
this.type = "";
|
||
this.lexer = new lexer.Lexer();
|
||
this.onNewLine = onNewLine;
|
||
}
|
||
/**
|
||
* Parse `source` as a YAML stream.
|
||
* If `incomplete`, a part of the last line may be left as a buffer for the next call.
|
||
*
|
||
* Errors are not thrown, but yielded as `{ type: 'error', message }` tokens.
|
||
*
|
||
* @returns A generator of tokens representing each directive, document, and other structure.
|
||
*/
|
||
*parse(source, incomplete = false) {
|
||
if (this.onNewLine && this.offset === 0) this.onNewLine(0);
|
||
for (const lexeme of this.lexer.lex(source, incomplete)) yield* this.next(lexeme);
|
||
if (!incomplete) yield* this.end();
|
||
}
|
||
/**
|
||
* Advance the parser by the `source` of one lexical token.
|
||
*/
|
||
*next(source) {
|
||
this.source = source;
|
||
if (node_process.env.LOG_TOKENS) console.log("|", cst.prettyToken(source));
|
||
if (this.atScalar) {
|
||
this.atScalar = false;
|
||
yield* this.step();
|
||
this.offset += source.length;
|
||
return;
|
||
}
|
||
const type = cst.tokenType(source);
|
||
if (!type) {
|
||
const message = `Not a YAML token: ${source}`;
|
||
yield* this.pop({
|
||
type: "error",
|
||
offset: this.offset,
|
||
message,
|
||
source
|
||
});
|
||
this.offset += source.length;
|
||
} else if (type === "scalar") {
|
||
this.atNewLine = false;
|
||
this.atScalar = true;
|
||
this.type = "scalar";
|
||
} else {
|
||
this.type = type;
|
||
yield* this.step();
|
||
switch (type) {
|
||
case "newline":
|
||
this.atNewLine = true;
|
||
this.indent = 0;
|
||
if (this.onNewLine) this.onNewLine(this.offset + source.length);
|
||
break;
|
||
case "space":
|
||
if (this.atNewLine && source[0] === " ") this.indent += source.length;
|
||
break;
|
||
case "explicit-key-ind":
|
||
case "map-value-ind":
|
||
case "seq-item-ind":
|
||
if (this.atNewLine) this.indent += source.length;
|
||
break;
|
||
case "doc-mode":
|
||
case "flow-error-end": return;
|
||
default: this.atNewLine = false;
|
||
}
|
||
this.offset += source.length;
|
||
}
|
||
}
|
||
/** Call at end of input to push out any remaining constructions */
|
||
*end() {
|
||
while (this.stack.length > 0) yield* this.pop();
|
||
}
|
||
get sourceToken() {
|
||
return {
|
||
type: this.type,
|
||
offset: this.offset,
|
||
indent: this.indent,
|
||
source: this.source
|
||
};
|
||
}
|
||
*step() {
|
||
const top = this.peek(1);
|
||
if (this.type === "doc-end" && top?.type !== "doc-end") {
|
||
while (this.stack.length > 0) yield* this.pop();
|
||
this.stack.push({
|
||
type: "doc-end",
|
||
offset: this.offset,
|
||
source: this.source
|
||
});
|
||
return;
|
||
}
|
||
if (!top) return yield* this.stream();
|
||
switch (top.type) {
|
||
case "document": return yield* this.document(top);
|
||
case "alias":
|
||
case "scalar":
|
||
case "single-quoted-scalar":
|
||
case "double-quoted-scalar": return yield* this.scalar(top);
|
||
case "block-scalar": return yield* this.blockScalar(top);
|
||
case "block-map": return yield* this.blockMap(top);
|
||
case "block-seq": return yield* this.blockSequence(top);
|
||
case "flow-collection": return yield* this.flowCollection(top);
|
||
case "doc-end": return yield* this.documentEnd(top);
|
||
}
|
||
/* istanbul ignore next should not happen */
|
||
yield* this.pop();
|
||
}
|
||
peek(n) {
|
||
return this.stack[this.stack.length - n];
|
||
}
|
||
*pop(error) {
|
||
const token = error ?? this.stack.pop();
|
||
/* istanbul ignore if should not happen */
|
||
if (!token) yield {
|
||
type: "error",
|
||
offset: this.offset,
|
||
source: "",
|
||
message: "Tried to pop an empty stack"
|
||
};
|
||
else if (this.stack.length === 0) yield token;
|
||
else {
|
||
const top = this.peek(1);
|
||
if (token.type === "block-scalar") token.indent = "indent" in top ? top.indent : 0;
|
||
else if (token.type === "flow-collection" && top.type === "document") token.indent = 0;
|
||
if (token.type === "flow-collection") fixFlowSeqItems(token);
|
||
switch (top.type) {
|
||
case "document":
|
||
top.value = token;
|
||
break;
|
||
case "block-scalar":
|
||
top.props.push(token);
|
||
break;
|
||
case "block-map": {
|
||
const it = top.items[top.items.length - 1];
|
||
if (it.value) {
|
||
top.items.push({
|
||
start: [],
|
||
key: token,
|
||
sep: []
|
||
});
|
||
this.onKeyLine = true;
|
||
return;
|
||
} else if (it.sep) it.value = token;
|
||
else {
|
||
Object.assign(it, {
|
||
key: token,
|
||
sep: []
|
||
});
|
||
this.onKeyLine = !it.explicitKey;
|
||
return;
|
||
}
|
||
break;
|
||
}
|
||
case "block-seq": {
|
||
const it = top.items[top.items.length - 1];
|
||
if (it.value) top.items.push({
|
||
start: [],
|
||
value: token
|
||
});
|
||
else it.value = token;
|
||
break;
|
||
}
|
||
case "flow-collection": {
|
||
const it = top.items[top.items.length - 1];
|
||
if (!it || it.value) top.items.push({
|
||
start: [],
|
||
key: token,
|
||
sep: []
|
||
});
|
||
else if (it.sep) it.value = token;
|
||
else Object.assign(it, {
|
||
key: token,
|
||
sep: []
|
||
});
|
||
return;
|
||
}
|
||
default:
|
||
yield* this.pop();
|
||
yield* this.pop(token);
|
||
}
|
||
if ((top.type === "document" || top.type === "block-map" || top.type === "block-seq") && (token.type === "block-map" || token.type === "block-seq")) {
|
||
const last = token.items[token.items.length - 1];
|
||
if (last && !last.sep && !last.value && last.start.length > 0 && findNonEmptyIndex(last.start) === -1 && (token.indent === 0 || last.start.every((st) => st.type !== "comment" || st.indent < token.indent))) {
|
||
if (top.type === "document") top.end = last.start;
|
||
else top.items.push({ start: last.start });
|
||
token.items.splice(-1, 1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
*stream() {
|
||
switch (this.type) {
|
||
case "directive-line":
|
||
yield {
|
||
type: "directive",
|
||
offset: this.offset,
|
||
source: this.source
|
||
};
|
||
return;
|
||
case "byte-order-mark":
|
||
case "space":
|
||
case "comment":
|
||
case "newline":
|
||
yield this.sourceToken;
|
||
return;
|
||
case "doc-mode":
|
||
case "doc-start": {
|
||
const doc = {
|
||
type: "document",
|
||
offset: this.offset,
|
||
start: []
|
||
};
|
||
if (this.type === "doc-start") doc.start.push(this.sourceToken);
|
||
this.stack.push(doc);
|
||
return;
|
||
}
|
||
}
|
||
yield {
|
||
type: "error",
|
||
offset: this.offset,
|
||
message: `Unexpected ${this.type} token in YAML stream`,
|
||
source: this.source
|
||
};
|
||
}
|
||
*document(doc) {
|
||
if (doc.value) return yield* this.lineEnd(doc);
|
||
switch (this.type) {
|
||
case "doc-start":
|
||
if (findNonEmptyIndex(doc.start) !== -1) {
|
||
yield* this.pop();
|
||
yield* this.step();
|
||
} else doc.start.push(this.sourceToken);
|
||
return;
|
||
case "anchor":
|
||
case "tag":
|
||
case "space":
|
||
case "comment":
|
||
case "newline":
|
||
doc.start.push(this.sourceToken);
|
||
return;
|
||
}
|
||
const bv = this.startBlockValue(doc);
|
||
if (bv) this.stack.push(bv);
|
||
else yield {
|
||
type: "error",
|
||
offset: this.offset,
|
||
message: `Unexpected ${this.type} token in YAML document`,
|
||
source: this.source
|
||
};
|
||
}
|
||
*scalar(scalar) {
|
||
if (this.type === "map-value-ind") {
|
||
const start = getFirstKeyStartProps(getPrevProps(this.peek(2)));
|
||
let sep;
|
||
if (scalar.end) {
|
||
sep = scalar.end;
|
||
sep.push(this.sourceToken);
|
||
delete scalar.end;
|
||
} else sep = [this.sourceToken];
|
||
const map = {
|
||
type: "block-map",
|
||
offset: scalar.offset,
|
||
indent: scalar.indent,
|
||
items: [{
|
||
start,
|
||
key: scalar,
|
||
sep
|
||
}]
|
||
};
|
||
this.onKeyLine = true;
|
||
this.stack[this.stack.length - 1] = map;
|
||
} else yield* this.lineEnd(scalar);
|
||
}
|
||
*blockScalar(scalar) {
|
||
switch (this.type) {
|
||
case "space":
|
||
case "comment":
|
||
case "newline":
|
||
scalar.props.push(this.sourceToken);
|
||
return;
|
||
case "scalar":
|
||
scalar.source = this.source;
|
||
this.atNewLine = true;
|
||
this.indent = 0;
|
||
if (this.onNewLine) {
|
||
let nl = this.source.indexOf("\n") + 1;
|
||
while (nl !== 0) {
|
||
this.onNewLine(this.offset + nl);
|
||
nl = this.source.indexOf("\n", nl) + 1;
|
||
}
|
||
}
|
||
yield* this.pop();
|
||
break;
|
||
default:
|
||
yield* this.pop();
|
||
yield* this.step();
|
||
}
|
||
}
|
||
*blockMap(map) {
|
||
const it = map.items[map.items.length - 1];
|
||
switch (this.type) {
|
||
case "newline":
|
||
this.onKeyLine = false;
|
||
if (it.value) {
|
||
const end = "end" in it.value ? it.value.end : void 0;
|
||
if ((Array.isArray(end) ? end[end.length - 1] : void 0)?.type === "comment") end?.push(this.sourceToken);
|
||
else map.items.push({ start: [this.sourceToken] });
|
||
} else if (it.sep) it.sep.push(this.sourceToken);
|
||
else it.start.push(this.sourceToken);
|
||
return;
|
||
case "space":
|
||
case "comment":
|
||
if (it.value) map.items.push({ start: [this.sourceToken] });
|
||
else if (it.sep) it.sep.push(this.sourceToken);
|
||
else {
|
||
if (this.atIndentedComment(it.start, map.indent)) {
|
||
const end = map.items[map.items.length - 2]?.value?.end;
|
||
if (Array.isArray(end)) {
|
||
Array.prototype.push.apply(end, it.start);
|
||
end.push(this.sourceToken);
|
||
map.items.pop();
|
||
return;
|
||
}
|
||
}
|
||
it.start.push(this.sourceToken);
|
||
}
|
||
return;
|
||
}
|
||
if (this.indent >= map.indent) {
|
||
const atMapIndent = !this.onKeyLine && this.indent === map.indent;
|
||
const atNextItem = atMapIndent && (it.sep || it.explicitKey) && this.type !== "seq-item-ind";
|
||
let start = [];
|
||
if (atNextItem && it.sep && !it.value) {
|
||
const nl = [];
|
||
for (let i = 0; i < it.sep.length; ++i) {
|
||
const st = it.sep[i];
|
||
switch (st.type) {
|
||
case "newline":
|
||
nl.push(i);
|
||
break;
|
||
case "space": break;
|
||
case "comment":
|
||
if (st.indent > map.indent) nl.length = 0;
|
||
break;
|
||
default: nl.length = 0;
|
||
}
|
||
}
|
||
if (nl.length >= 2) start = it.sep.splice(nl[1]);
|
||
}
|
||
switch (this.type) {
|
||
case "anchor":
|
||
case "tag":
|
||
if (atNextItem || it.value) {
|
||
start.push(this.sourceToken);
|
||
map.items.push({ start });
|
||
this.onKeyLine = true;
|
||
} else if (it.sep) it.sep.push(this.sourceToken);
|
||
else it.start.push(this.sourceToken);
|
||
return;
|
||
case "explicit-key-ind":
|
||
if (!it.sep && !it.explicitKey) {
|
||
it.start.push(this.sourceToken);
|
||
it.explicitKey = true;
|
||
} else if (atNextItem || it.value) {
|
||
start.push(this.sourceToken);
|
||
map.items.push({
|
||
start,
|
||
explicitKey: true
|
||
});
|
||
} else this.stack.push({
|
||
type: "block-map",
|
||
offset: this.offset,
|
||
indent: this.indent,
|
||
items: [{
|
||
start: [this.sourceToken],
|
||
explicitKey: true
|
||
}]
|
||
});
|
||
this.onKeyLine = true;
|
||
return;
|
||
case "map-value-ind":
|
||
if (it.explicitKey) if (!it.sep) if (includesToken(it.start, "newline")) Object.assign(it, {
|
||
key: null,
|
||
sep: [this.sourceToken]
|
||
});
|
||
else {
|
||
const start = getFirstKeyStartProps(it.start);
|
||
this.stack.push({
|
||
type: "block-map",
|
||
offset: this.offset,
|
||
indent: this.indent,
|
||
items: [{
|
||
start,
|
||
key: null,
|
||
sep: [this.sourceToken]
|
||
}]
|
||
});
|
||
}
|
||
else if (it.value) map.items.push({
|
||
start: [],
|
||
key: null,
|
||
sep: [this.sourceToken]
|
||
});
|
||
else if (includesToken(it.sep, "map-value-ind")) this.stack.push({
|
||
type: "block-map",
|
||
offset: this.offset,
|
||
indent: this.indent,
|
||
items: [{
|
||
start,
|
||
key: null,
|
||
sep: [this.sourceToken]
|
||
}]
|
||
});
|
||
else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
|
||
const start = getFirstKeyStartProps(it.start);
|
||
const key = it.key;
|
||
const sep = it.sep;
|
||
sep.push(this.sourceToken);
|
||
delete it.key;
|
||
delete it.sep;
|
||
this.stack.push({
|
||
type: "block-map",
|
||
offset: this.offset,
|
||
indent: this.indent,
|
||
items: [{
|
||
start,
|
||
key,
|
||
sep
|
||
}]
|
||
});
|
||
} else if (start.length > 0) it.sep = it.sep.concat(start, this.sourceToken);
|
||
else it.sep.push(this.sourceToken);
|
||
else if (!it.sep) Object.assign(it, {
|
||
key: null,
|
||
sep: [this.sourceToken]
|
||
});
|
||
else if (it.value || atNextItem) map.items.push({
|
||
start,
|
||
key: null,
|
||
sep: [this.sourceToken]
|
||
});
|
||
else if (includesToken(it.sep, "map-value-ind")) this.stack.push({
|
||
type: "block-map",
|
||
offset: this.offset,
|
||
indent: this.indent,
|
||
items: [{
|
||
start: [],
|
||
key: null,
|
||
sep: [this.sourceToken]
|
||
}]
|
||
});
|
||
else it.sep.push(this.sourceToken);
|
||
this.onKeyLine = true;
|
||
return;
|
||
case "alias":
|
||
case "scalar":
|
||
case "single-quoted-scalar":
|
||
case "double-quoted-scalar": {
|
||
const fs = this.flowScalar(this.type);
|
||
if (atNextItem || it.value) {
|
||
map.items.push({
|
||
start,
|
||
key: fs,
|
||
sep: []
|
||
});
|
||
this.onKeyLine = true;
|
||
} else if (it.sep) this.stack.push(fs);
|
||
else {
|
||
Object.assign(it, {
|
||
key: fs,
|
||
sep: []
|
||
});
|
||
this.onKeyLine = true;
|
||
}
|
||
return;
|
||
}
|
||
default: {
|
||
const bv = this.startBlockValue(map);
|
||
if (bv) {
|
||
if (bv.type === "block-seq") {
|
||
if (!it.explicitKey && it.sep && !includesToken(it.sep, "newline")) {
|
||
yield* this.pop({
|
||
type: "error",
|
||
offset: this.offset,
|
||
message: "Unexpected block-seq-ind on same line with key",
|
||
source: this.source
|
||
});
|
||
return;
|
||
}
|
||
} else if (atMapIndent) map.items.push({ start });
|
||
this.stack.push(bv);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
yield* this.pop();
|
||
yield* this.step();
|
||
}
|
||
*blockSequence(seq) {
|
||
const it = seq.items[seq.items.length - 1];
|
||
switch (this.type) {
|
||
case "newline":
|
||
if (it.value) {
|
||
const end = "end" in it.value ? it.value.end : void 0;
|
||
if ((Array.isArray(end) ? end[end.length - 1] : void 0)?.type === "comment") end?.push(this.sourceToken);
|
||
else seq.items.push({ start: [this.sourceToken] });
|
||
} else it.start.push(this.sourceToken);
|
||
return;
|
||
case "space":
|
||
case "comment":
|
||
if (it.value) seq.items.push({ start: [this.sourceToken] });
|
||
else {
|
||
if (this.atIndentedComment(it.start, seq.indent)) {
|
||
const end = seq.items[seq.items.length - 2]?.value?.end;
|
||
if (Array.isArray(end)) {
|
||
Array.prototype.push.apply(end, it.start);
|
||
end.push(this.sourceToken);
|
||
seq.items.pop();
|
||
return;
|
||
}
|
||
}
|
||
it.start.push(this.sourceToken);
|
||
}
|
||
return;
|
||
case "anchor":
|
||
case "tag":
|
||
if (it.value || this.indent <= seq.indent) break;
|
||
it.start.push(this.sourceToken);
|
||
return;
|
||
case "seq-item-ind":
|
||
if (this.indent !== seq.indent) break;
|
||
if (it.value || includesToken(it.start, "seq-item-ind")) seq.items.push({ start: [this.sourceToken] });
|
||
else it.start.push(this.sourceToken);
|
||
return;
|
||
}
|
||
if (this.indent > seq.indent) {
|
||
const bv = this.startBlockValue(seq);
|
||
if (bv) {
|
||
this.stack.push(bv);
|
||
return;
|
||
}
|
||
}
|
||
yield* this.pop();
|
||
yield* this.step();
|
||
}
|
||
*flowCollection(fc) {
|
||
const it = fc.items[fc.items.length - 1];
|
||
if (this.type === "flow-error-end") {
|
||
let top;
|
||
do {
|
||
yield* this.pop();
|
||
top = this.peek(1);
|
||
} while (top?.type === "flow-collection");
|
||
} else if (fc.end.length === 0) {
|
||
switch (this.type) {
|
||
case "comma":
|
||
case "explicit-key-ind":
|
||
if (!it || it.sep) fc.items.push({ start: [this.sourceToken] });
|
||
else it.start.push(this.sourceToken);
|
||
return;
|
||
case "map-value-ind":
|
||
if (!it || it.value) fc.items.push({
|
||
start: [],
|
||
key: null,
|
||
sep: [this.sourceToken]
|
||
});
|
||
else if (it.sep) it.sep.push(this.sourceToken);
|
||
else Object.assign(it, {
|
||
key: null,
|
||
sep: [this.sourceToken]
|
||
});
|
||
return;
|
||
case "space":
|
||
case "comment":
|
||
case "newline":
|
||
case "anchor":
|
||
case "tag":
|
||
if (!it || it.value) fc.items.push({ start: [this.sourceToken] });
|
||
else if (it.sep) it.sep.push(this.sourceToken);
|
||
else it.start.push(this.sourceToken);
|
||
return;
|
||
case "alias":
|
||
case "scalar":
|
||
case "single-quoted-scalar":
|
||
case "double-quoted-scalar": {
|
||
const fs = this.flowScalar(this.type);
|
||
if (!it || it.value) fc.items.push({
|
||
start: [],
|
||
key: fs,
|
||
sep: []
|
||
});
|
||
else if (it.sep) this.stack.push(fs);
|
||
else Object.assign(it, {
|
||
key: fs,
|
||
sep: []
|
||
});
|
||
return;
|
||
}
|
||
case "flow-map-end":
|
||
case "flow-seq-end":
|
||
fc.end.push(this.sourceToken);
|
||
return;
|
||
}
|
||
const bv = this.startBlockValue(fc);
|
||
/* istanbul ignore else should not happen */
|
||
if (bv) this.stack.push(bv);
|
||
else {
|
||
yield* this.pop();
|
||
yield* this.step();
|
||
}
|
||
} else {
|
||
const parent = this.peek(2);
|
||
if (parent.type === "block-map" && (this.type === "map-value-ind" && parent.indent === fc.indent || this.type === "newline" && !parent.items[parent.items.length - 1].sep)) {
|
||
yield* this.pop();
|
||
yield* this.step();
|
||
} else if (this.type === "map-value-ind" && parent.type !== "flow-collection") {
|
||
const start = getFirstKeyStartProps(getPrevProps(parent));
|
||
fixFlowSeqItems(fc);
|
||
const sep = fc.end.splice(1, fc.end.length);
|
||
sep.push(this.sourceToken);
|
||
const map = {
|
||
type: "block-map",
|
||
offset: fc.offset,
|
||
indent: fc.indent,
|
||
items: [{
|
||
start,
|
||
key: fc,
|
||
sep
|
||
}]
|
||
};
|
||
this.onKeyLine = true;
|
||
this.stack[this.stack.length - 1] = map;
|
||
} else yield* this.lineEnd(fc);
|
||
}
|
||
}
|
||
flowScalar(type) {
|
||
if (this.onNewLine) {
|
||
let nl = this.source.indexOf("\n") + 1;
|
||
while (nl !== 0) {
|
||
this.onNewLine(this.offset + nl);
|
||
nl = this.source.indexOf("\n", nl) + 1;
|
||
}
|
||
}
|
||
return {
|
||
type,
|
||
offset: this.offset,
|
||
indent: this.indent,
|
||
source: this.source
|
||
};
|
||
}
|
||
startBlockValue(parent) {
|
||
switch (this.type) {
|
||
case "alias":
|
||
case "scalar":
|
||
case "single-quoted-scalar":
|
||
case "double-quoted-scalar": return this.flowScalar(this.type);
|
||
case "block-scalar-header": return {
|
||
type: "block-scalar",
|
||
offset: this.offset,
|
||
indent: this.indent,
|
||
props: [this.sourceToken],
|
||
source: ""
|
||
};
|
||
case "flow-map-start":
|
||
case "flow-seq-start": return {
|
||
type: "flow-collection",
|
||
offset: this.offset,
|
||
indent: this.indent,
|
||
start: this.sourceToken,
|
||
items: [],
|
||
end: []
|
||
};
|
||
case "seq-item-ind": return {
|
||
type: "block-seq",
|
||
offset: this.offset,
|
||
indent: this.indent,
|
||
items: [{ start: [this.sourceToken] }]
|
||
};
|
||
case "explicit-key-ind": {
|
||
this.onKeyLine = true;
|
||
const start = getFirstKeyStartProps(getPrevProps(parent));
|
||
start.push(this.sourceToken);
|
||
return {
|
||
type: "block-map",
|
||
offset: this.offset,
|
||
indent: this.indent,
|
||
items: [{
|
||
start,
|
||
explicitKey: true
|
||
}]
|
||
};
|
||
}
|
||
case "map-value-ind": {
|
||
this.onKeyLine = true;
|
||
const start = getFirstKeyStartProps(getPrevProps(parent));
|
||
return {
|
||
type: "block-map",
|
||
offset: this.offset,
|
||
indent: this.indent,
|
||
items: [{
|
||
start,
|
||
key: null,
|
||
sep: [this.sourceToken]
|
||
}]
|
||
};
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
atIndentedComment(start, indent) {
|
||
if (this.type !== "comment") return false;
|
||
if (this.indent <= indent) return false;
|
||
return start.every((st) => st.type === "newline" || st.type === "space");
|
||
}
|
||
*documentEnd(docEnd) {
|
||
if (this.type !== "doc-mode") {
|
||
if (docEnd.end) docEnd.end.push(this.sourceToken);
|
||
else docEnd.end = [this.sourceToken];
|
||
if (this.type === "newline") yield* this.pop();
|
||
}
|
||
}
|
||
*lineEnd(token) {
|
||
switch (this.type) {
|
||
case "comma":
|
||
case "doc-start":
|
||
case "doc-end":
|
||
case "flow-seq-end":
|
||
case "flow-map-end":
|
||
case "map-value-ind":
|
||
yield* this.pop();
|
||
yield* this.step();
|
||
break;
|
||
case "newline": this.onKeyLine = false;
|
||
default:
|
||
if (token.end) token.end.push(this.sourceToken);
|
||
else token.end = [this.sourceToken];
|
||
if (this.type === "newline") yield* this.pop();
|
||
}
|
||
}
|
||
};
|
||
exports.Parser = Parser;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/public-api.js
|
||
var require_public_api = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var composer = require_composer();
|
||
var Document = require_Document();
|
||
var errors = require_errors();
|
||
var log = require_log();
|
||
var identity = require_identity();
|
||
var lineCounter = require_line_counter();
|
||
var parser = require_parser();
|
||
function parseOptions(options) {
|
||
const prettyErrors = options.prettyErrors !== false;
|
||
return {
|
||
lineCounter: options.lineCounter || prettyErrors && new lineCounter.LineCounter() || null,
|
||
prettyErrors
|
||
};
|
||
}
|
||
/**
|
||
* Parse the input as a stream of YAML documents.
|
||
*
|
||
* Documents should be separated from each other by `...` or `---` marker lines.
|
||
*
|
||
* @returns If an empty `docs` array is returned, it will be of type
|
||
* EmptyStream and contain additional stream information. In
|
||
* TypeScript, you should use `'empty' in docs` as a type guard for it.
|
||
*/
|
||
function parseAllDocuments(source, options = {}) {
|
||
const { lineCounter, prettyErrors } = parseOptions(options);
|
||
const parser$1 = new parser.Parser(lineCounter?.addNewLine);
|
||
const composer$1 = new composer.Composer(options);
|
||
const docs = Array.from(composer$1.compose(parser$1.parse(source)));
|
||
if (prettyErrors && lineCounter) for (const doc of docs) {
|
||
doc.errors.forEach(errors.prettifyError(source, lineCounter));
|
||
doc.warnings.forEach(errors.prettifyError(source, lineCounter));
|
||
}
|
||
if (docs.length > 0) return docs;
|
||
return Object.assign([], { empty: true }, composer$1.streamInfo());
|
||
}
|
||
/** Parse an input string into a single YAML.Document */
|
||
function parseDocument(source, options = {}) {
|
||
const { lineCounter, prettyErrors } = parseOptions(options);
|
||
const parser$1 = new parser.Parser(lineCounter?.addNewLine);
|
||
const composer$1 = new composer.Composer(options);
|
||
let doc = null;
|
||
for (const _doc of composer$1.compose(parser$1.parse(source), true, source.length)) if (!doc) doc = _doc;
|
||
else if (doc.options.logLevel !== "silent") {
|
||
doc.errors.push(new errors.YAMLParseError(_doc.range.slice(0, 2), "MULTIPLE_DOCS", "Source contains multiple documents; please use YAML.parseAllDocuments()"));
|
||
break;
|
||
}
|
||
if (prettyErrors && lineCounter) {
|
||
doc.errors.forEach(errors.prettifyError(source, lineCounter));
|
||
doc.warnings.forEach(errors.prettifyError(source, lineCounter));
|
||
}
|
||
return doc;
|
||
}
|
||
function parse(src, reviver, options) {
|
||
let _reviver = void 0;
|
||
if (typeof reviver === "function") _reviver = reviver;
|
||
else if (options === void 0 && reviver && typeof reviver === "object") options = reviver;
|
||
const doc = parseDocument(src, options);
|
||
if (!doc) return null;
|
||
doc.warnings.forEach((warning) => log.warn(doc.options.logLevel, warning));
|
||
if (doc.errors.length > 0) if (doc.options.logLevel !== "silent") throw doc.errors[0];
|
||
else doc.errors = [];
|
||
return doc.toJS(Object.assign({ reviver: _reviver }, options));
|
||
}
|
||
function stringify(value, replacer, options) {
|
||
let _replacer = null;
|
||
if (typeof replacer === "function" || Array.isArray(replacer)) _replacer = replacer;
|
||
else if (options === void 0 && replacer) options = replacer;
|
||
if (typeof options === "string") options = options.length;
|
||
if (typeof options === "number") {
|
||
const indent = Math.round(options);
|
||
options = indent < 1 ? void 0 : indent > 8 ? { indent: 8 } : { indent };
|
||
}
|
||
if (value === void 0) {
|
||
const { keepUndefined } = options ?? replacer ?? {};
|
||
if (!keepUndefined) return void 0;
|
||
}
|
||
if (identity.isDocument(value) && !_replacer) return value.toString(options);
|
||
return new Document.Document(value, _replacer, options).toString(options);
|
||
}
|
||
exports.parse = parse;
|
||
exports.parseAllDocuments = parseAllDocuments;
|
||
exports.parseDocument = parseDocument;
|
||
exports.stringify = stringify;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/index.js
|
||
var require_dist = /* @__PURE__ */ __commonJSMin(((exports) => {
|
||
var composer = require_composer();
|
||
var Document = require_Document();
|
||
var Schema = require_Schema();
|
||
var errors = require_errors();
|
||
var Alias = require_Alias();
|
||
var identity = require_identity();
|
||
var Pair = require_Pair();
|
||
var Scalar = require_Scalar();
|
||
var YAMLMap = require_YAMLMap();
|
||
var YAMLSeq = require_YAMLSeq();
|
||
var cst = require_cst();
|
||
var lexer = require_lexer();
|
||
var lineCounter = require_line_counter();
|
||
var parser = require_parser();
|
||
var publicApi = require_public_api();
|
||
var visit = require_visit();
|
||
exports.Composer = composer.Composer;
|
||
exports.Document = Document.Document;
|
||
exports.Schema = Schema.Schema;
|
||
exports.YAMLError = errors.YAMLError;
|
||
exports.YAMLParseError = errors.YAMLParseError;
|
||
exports.YAMLWarning = errors.YAMLWarning;
|
||
exports.Alias = Alias.Alias;
|
||
exports.isAlias = identity.isAlias;
|
||
exports.isCollection = identity.isCollection;
|
||
exports.isDocument = identity.isDocument;
|
||
exports.isMap = identity.isMap;
|
||
exports.isNode = identity.isNode;
|
||
exports.isPair = identity.isPair;
|
||
exports.isScalar = identity.isScalar;
|
||
exports.isSeq = identity.isSeq;
|
||
exports.Pair = Pair.Pair;
|
||
exports.Scalar = Scalar.Scalar;
|
||
exports.YAMLMap = YAMLMap.YAMLMap;
|
||
exports.YAMLSeq = YAMLSeq.YAMLSeq;
|
||
exports.Lexer = lexer.Lexer;
|
||
exports.LineCounter = lineCounter.LineCounter;
|
||
exports.Parser = parser.Parser;
|
||
exports.parse = publicApi.parse;
|
||
exports.parseAllDocuments = publicApi.parseAllDocuments;
|
||
exports.parseDocument = publicApi.parseDocument;
|
||
exports.stringify = publicApi.stringify;
|
||
exports.visit = visit.visit;
|
||
exports.visitAsync = visit.visitAsync;
|
||
}));
|
||
|
||
//#endregion
|
||
//#region src/skills/catalog.ts
|
||
var import_dist = require_dist();
|
||
function loadSkillsCatalog(mosaicHome) {
|
||
const skills = [];
|
||
const canonicalDir = join(mosaicHome, "skills");
|
||
if (existsSync(canonicalDir)) skills.push(...loadSkillsFromDir(canonicalDir, "canonical"));
|
||
const sourceDir = join(mosaicHome, "sources", "agent-skills", "skills");
|
||
if (skills.length === 0 && existsSync(sourceDir)) skills.push(...loadSkillsFromDir(sourceDir, "canonical"));
|
||
const localDir = join(mosaicHome, "skills-local");
|
||
if (existsSync(localDir)) skills.push(...loadSkillsFromDir(localDir, "local"));
|
||
return skills.sort((a, b) => a.name.localeCompare(b.name));
|
||
}
|
||
function loadSkillsFromDir(dir, source) {
|
||
const entries = [];
|
||
let dirEntries;
|
||
try {
|
||
dirEntries = readdirSync(dir, { withFileTypes: true });
|
||
} catch {
|
||
return entries;
|
||
}
|
||
for (const entry of dirEntries) {
|
||
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
||
const skillMdPath = join(dir, entry.name, "SKILL.md");
|
||
if (!existsSync(skillMdPath)) continue;
|
||
try {
|
||
const frontmatter = parseFrontmatter(readFileSync(skillMdPath, "utf-8"));
|
||
entries.push({
|
||
name: frontmatter.name ?? entry.name,
|
||
description: frontmatter.description ?? "",
|
||
version: frontmatter.version,
|
||
recommended: RECOMMENDED_SKILLS.has(entry.name),
|
||
source
|
||
});
|
||
} catch {
|
||
entries.push({
|
||
name: entry.name,
|
||
description: "",
|
||
recommended: RECOMMENDED_SKILLS.has(entry.name),
|
||
source
|
||
});
|
||
}
|
||
}
|
||
return entries;
|
||
}
|
||
function parseFrontmatter(content) {
|
||
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
||
if (!match) return {};
|
||
try {
|
||
return (0, import_dist.parse)(match[1]) ?? {};
|
||
} catch {
|
||
const result = {};
|
||
for (const line of match[1].split("\n")) {
|
||
const kv = line.match(/^(\w[\w-]*)\s*:\s*(.+)/);
|
||
if (kv) result[kv[1]] = kv[2].replace(/^['"]|['"]$/g, "");
|
||
}
|
||
return result;
|
||
}
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/skills/categories.ts
|
||
/**
|
||
* Skill category definitions and mapping.
|
||
* Skills are assigned to categories by name, with keyword fallback.
|
||
*/
|
||
const SKILL_CATEGORIES = {
|
||
"Frontend & UI": [
|
||
"ai-sdk",
|
||
"algorithmic-art",
|
||
"antfu",
|
||
"canvas-design",
|
||
"frontend-design",
|
||
"next-best-practices",
|
||
"nuxt",
|
||
"pinia",
|
||
"shadcn-ui",
|
||
"slidev",
|
||
"tailwind-design-system",
|
||
"theme-factory",
|
||
"ui-animation",
|
||
"unocss",
|
||
"vercel-composition-patterns",
|
||
"vercel-react-best-practices",
|
||
"vercel-react-native-skills",
|
||
"vue",
|
||
"vue-best-practices",
|
||
"vue-router-best-practices",
|
||
"vueuse-functions",
|
||
"web-artifacts-builder",
|
||
"web-design-guidelines",
|
||
"vite",
|
||
"vitepress"
|
||
],
|
||
"Backend & Infrastructure": [
|
||
"architecture-patterns",
|
||
"fastapi",
|
||
"mcp-builder",
|
||
"nestjs-best-practices",
|
||
"python-performance-optimization",
|
||
"tsdown",
|
||
"turborepo",
|
||
"pnpm",
|
||
"dispatching-parallel-agents",
|
||
"subagent-driven-development",
|
||
"create-agent",
|
||
"proactive-agent",
|
||
"using-superpowers",
|
||
"kickstart",
|
||
"executing-plans"
|
||
],
|
||
"Testing & Quality": [
|
||
"code-review-excellence",
|
||
"lint",
|
||
"pr-reviewer",
|
||
"receiving-code-review",
|
||
"requesting-code-review",
|
||
"systematic-debugging",
|
||
"test-driven-development",
|
||
"verification-before-completion",
|
||
"vitest",
|
||
"vue-testing-best-practices",
|
||
"webapp-testing"
|
||
],
|
||
"Marketing & Growth": [
|
||
"ab-test-setup",
|
||
"analytics-tracking",
|
||
"competitor-alternatives",
|
||
"copy-editing",
|
||
"copywriting",
|
||
"email-sequence",
|
||
"form-cro",
|
||
"free-tool-strategy",
|
||
"launch-strategy",
|
||
"marketing-ideas",
|
||
"marketing-psychology",
|
||
"onboarding-cro",
|
||
"page-cro",
|
||
"paid-ads",
|
||
"paywall-upgrade-cro",
|
||
"popup-cro",
|
||
"pricing-strategy",
|
||
"product-marketing-context",
|
||
"programmatic-seo",
|
||
"referral-program",
|
||
"schema-markup",
|
||
"seo-audit",
|
||
"signup-flow-cro",
|
||
"social-content"
|
||
],
|
||
"Product & Strategy": [
|
||
"brainstorming",
|
||
"brand-guidelines",
|
||
"content-strategy",
|
||
"writing-plans",
|
||
"skill-creator",
|
||
"writing-skills",
|
||
"prd"
|
||
],
|
||
"Developer Practices": ["finishing-a-development-branch", "using-git-worktrees"],
|
||
"Auth & Security": [
|
||
"better-auth-best-practices",
|
||
"create-auth-skill",
|
||
"email-and-password-best-practices",
|
||
"organization-best-practices",
|
||
"two-factor-authentication-best-practices"
|
||
],
|
||
"Content & Documentation": [
|
||
"doc-coauthoring",
|
||
"docx",
|
||
"internal-comms",
|
||
"pdf",
|
||
"pptx",
|
||
"slack-gif-creator",
|
||
"xlsx"
|
||
]
|
||
};
|
||
const SKILL_TO_CATEGORY = /* @__PURE__ */ new Map();
|
||
for (const [category, skills] of Object.entries(SKILL_CATEGORIES)) for (const skill of skills) SKILL_TO_CATEGORY.set(skill, category);
|
||
function categorizeSkill(name, description) {
|
||
const mapped = SKILL_TO_CATEGORY.get(name);
|
||
if (mapped) return mapped;
|
||
return inferCategoryFromDescription(description);
|
||
}
|
||
function inferCategoryFromDescription(desc) {
|
||
const lower = desc.toLowerCase();
|
||
if (/\b(react|vue|css|frontend|ui|component|tailwind|design)\b/.test(lower)) return "Frontend & UI";
|
||
if (/\b(api|backend|server|docker|infra|deploy)\b/.test(lower)) return "Backend & Infrastructure";
|
||
if (/\b(test|lint|review|debug|quality)\b/.test(lower)) return "Testing & Quality";
|
||
if (/\b(marketing|seo|copy|ads|cro|conversion|email)\b/.test(lower)) return "Marketing & Growth";
|
||
if (/\b(auth|security|2fa|password|credential)\b/.test(lower)) return "Auth & Security";
|
||
if (/\b(doc|pdf|word|sheet|writing|comms)\b/.test(lower)) return "Content & Documentation";
|
||
if (/\b(product|strategy|brainstorm|plan|prd)\b/.test(lower)) return "Product & Strategy";
|
||
return "Developer Practices";
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/stages/skills-select.ts
|
||
function truncate(str, max) {
|
||
if (str.length <= max) return str;
|
||
return str.slice(0, max - 1) + "…";
|
||
}
|
||
async function skillsSelectStage(p, state) {
|
||
p.separator();
|
||
const spin = p.spinner();
|
||
spin.update("Loading skills catalog...");
|
||
const catalog = loadSkillsCatalog(state.mosaicHome);
|
||
spin.stop(`Found ${catalog.length} available skills`);
|
||
if (catalog.length === 0) {
|
||
p.warn("No skills found. Run 'mosaic sync' after installation to fetch skills.");
|
||
state.selectedSkills = [];
|
||
return;
|
||
}
|
||
if (state.mode === "quick") {
|
||
const defaults = catalog.filter((s) => s.recommended).map((s) => s.name);
|
||
state.selectedSkills = defaults;
|
||
p.note(`Selected ${defaults.length} recommended skills.\nRun 'mosaic sync' later to browse the full catalog.`, "Skills");
|
||
return;
|
||
}
|
||
p.note("Skills give agents domain expertise for specific tasks.\nBrowse by category and select the ones you want.\nYou can always change this later with 'mosaic sync'.", "Skills Selection");
|
||
const grouped = {};
|
||
for (const categoryName of Object.keys(SKILL_CATEGORIES)) grouped[categoryName] = [];
|
||
for (const skill of catalog) {
|
||
const category = categorizeSkill(skill.name, skill.description);
|
||
if (!grouped[category]) grouped[category] = [];
|
||
grouped[category].push({
|
||
value: skill.name,
|
||
label: skill.name,
|
||
hint: truncate(skill.description, 60),
|
||
selected: skill.recommended
|
||
});
|
||
}
|
||
for (const key of Object.keys(grouped)) if (grouped[key].length === 0) delete grouped[key];
|
||
state.selectedSkills = await p.groupMultiselect({
|
||
message: "Select skills (space to toggle)",
|
||
options: grouped,
|
||
required: false
|
||
});
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/platform/detect.ts
|
||
function detectShell() {
|
||
const shell = process.env.SHELL ?? "";
|
||
if (shell.includes("zsh")) return "zsh";
|
||
if (shell.includes("bash")) return "bash";
|
||
if (shell.includes("fish")) return "fish";
|
||
if (platform() === "win32") return "powershell";
|
||
return "unknown";
|
||
}
|
||
function getShellProfilePath() {
|
||
const home = homedir();
|
||
if (platform() === "win32") return join(home, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
|
||
switch (detectShell()) {
|
||
case "zsh": return join(process.env.ZDOTDIR ?? home, ".zshrc");
|
||
case "bash": {
|
||
const bashrc = join(home, ".bashrc");
|
||
if (existsSync(bashrc)) return bashrc;
|
||
return join(home, ".profile");
|
||
}
|
||
case "fish": return join(home, ".config", "fish", "config.fish");
|
||
default: return join(home, ".profile");
|
||
}
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/stages/finalize.ts
|
||
function linkRuntimeAssets(mosaicHome) {
|
||
const script = join(mosaicHome, "bin", "mosaic-link-runtime-assets");
|
||
if (existsSync(script)) try {
|
||
spawnSync("bash", [script], {
|
||
timeout: 3e4,
|
||
stdio: "pipe"
|
||
});
|
||
} catch {}
|
||
}
|
||
function syncSkills(mosaicHome) {
|
||
const script = join(mosaicHome, "bin", "mosaic-sync-skills");
|
||
if (existsSync(script)) try {
|
||
spawnSync("bash", [script], {
|
||
timeout: 6e4,
|
||
stdio: "pipe"
|
||
});
|
||
} catch {}
|
||
}
|
||
function runDoctor(mosaicHome) {
|
||
const script = join(mosaicHome, "bin", "mosaic-doctor");
|
||
if (!existsSync(script)) return {
|
||
warnings: 0,
|
||
output: "mosaic-doctor not found"
|
||
};
|
||
try {
|
||
const output = spawnSync("bash", [script], {
|
||
timeout: 3e4,
|
||
encoding: "utf-8",
|
||
stdio: "pipe"
|
||
}).stdout ?? "";
|
||
return {
|
||
warnings: (output.match(/WARN/g) ?? []).length,
|
||
output
|
||
};
|
||
} catch {
|
||
return {
|
||
warnings: 1,
|
||
output: "Doctor check failed"
|
||
};
|
||
}
|
||
}
|
||
function setupPath(mosaicHome, p) {
|
||
const binDir = join(mosaicHome, "bin");
|
||
if ((process.env.PATH ?? "").includes(binDir)) return "already";
|
||
const profilePath = getShellProfilePath();
|
||
if (!profilePath) return "skipped";
|
||
const exportLine = platform() === "win32" ? `\n# Mosaic\n$env:Path = "${binDir};$env:Path"\n` : `\n# Mosaic\nexport PATH="${binDir}:$PATH"\n`;
|
||
if (existsSync(profilePath)) {
|
||
if (readFileSync(profilePath, "utf-8").includes(binDir)) return "already";
|
||
}
|
||
try {
|
||
appendFileSync(profilePath, exportLine, "utf-8");
|
||
return "added";
|
||
} catch {
|
||
return "skipped";
|
||
}
|
||
}
|
||
async function finalizeStage(p, state, config) {
|
||
p.separator();
|
||
const spin = p.spinner();
|
||
spin.update("Syncing framework files...");
|
||
await config.syncFramework(state.installAction);
|
||
if (state.installAction !== "keep") {
|
||
spin.update("Writing configuration files...");
|
||
await config.writeSoul(state.soul);
|
||
await config.writeUser(state.user);
|
||
await config.writeTools(state.tools);
|
||
}
|
||
spin.update("Linking runtime assets...");
|
||
linkRuntimeAssets(state.mosaicHome);
|
||
if (state.selectedSkills.length > 0) {
|
||
spin.update("Syncing skills...");
|
||
syncSkills(state.mosaicHome);
|
||
}
|
||
spin.update("Running health audit...");
|
||
const doctorResult = runDoctor(state.mosaicHome);
|
||
spin.stop("Installation complete");
|
||
const pathAction = setupPath(state.mosaicHome, p);
|
||
const summary = [
|
||
`Agent: ${state.soul.agentName ?? "Assistant"}`,
|
||
`Style: ${state.soul.communicationStyle ?? "direct"}`,
|
||
`Runtimes: ${state.runtimes.detected.join(", ") || "none detected"}`,
|
||
`Skills: ${state.selectedSkills.length} selected`,
|
||
`Config: ${state.mosaicHome}`
|
||
];
|
||
if (doctorResult.warnings > 0) summary.push(`Health: ${doctorResult.warnings} warning(s) — run 'mosaic doctor' for details`);
|
||
else summary.push("Health: all checks passed");
|
||
p.note(summary.join("\n"), "Installation Summary");
|
||
const nextSteps = [];
|
||
if (pathAction === "added") {
|
||
const profilePath = getShellProfilePath();
|
||
nextSteps.push(`Reload shell: source ${profilePath ?? "~/.profile"}`);
|
||
}
|
||
if (state.runtimes.detected.length === 0) nextSteps.push("Install at least one runtime (claude, codex, or opencode)");
|
||
nextSteps.push("Launch with 'mosaic claude' (or codex/opencode)");
|
||
nextSteps.push("Edit identity files directly in ~/.config/mosaic/ for fine-tuning");
|
||
p.note(nextSteps.map((s, i) => `${i + 1}. ${s}`).join("\n"), "Next Steps");
|
||
p.outro("Mosaic is ready.");
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/wizard.ts
|
||
async function runWizard(options) {
|
||
const { prompter, configService, mosaicHome, sourceDir } = options;
|
||
const state = {
|
||
mosaicHome,
|
||
sourceDir,
|
||
mode: "quick",
|
||
installAction: "fresh",
|
||
soul: {},
|
||
user: {},
|
||
tools: {},
|
||
runtimes: {
|
||
detected: [],
|
||
mcpConfigured: false
|
||
},
|
||
selectedSkills: []
|
||
};
|
||
if (options.cliOverrides) {
|
||
if (options.cliOverrides.soul) {
|
||
for (const [k, v] of Object.entries(options.cliOverrides.soul)) if (v !== void 0) state.soul[k] = v;
|
||
}
|
||
if (options.cliOverrides.user) {
|
||
for (const [k, v] of Object.entries(options.cliOverrides.user)) if (v !== void 0) state.user[k] = v;
|
||
}
|
||
if (options.cliOverrides.tools) {
|
||
for (const [k, v] of Object.entries(options.cliOverrides.tools)) if (v !== void 0) state.tools[k] = v;
|
||
}
|
||
if (options.cliOverrides.mode) state.mode = options.cliOverrides.mode;
|
||
}
|
||
await welcomeStage(prompter, state);
|
||
await detectInstallStage(prompter, state, configService);
|
||
if (state.installAction === "fresh" || state.installAction === "reset") await modeSelectStage(prompter, state);
|
||
else if (state.installAction === "reconfigure") state.mode = "advanced";
|
||
await soulSetupStage(prompter, state);
|
||
await userSetupStage(prompter, state);
|
||
await toolsSetupStage(prompter, state);
|
||
await runtimeSetupStage(prompter, state);
|
||
await skillsSelectStage(prompter, state);
|
||
await finalizeStage(prompter, state, configService);
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/index.ts
|
||
const program = new Command().name("mosaic-wizard").description("Mosaic Installation Wizard").version(VERSION);
|
||
program.option("--non-interactive", "Run without prompts (uses defaults + flags)").option("--source-dir <path>", "Source directory for framework files").option("--mosaic-home <path>", "Target config directory", DEFAULT_MOSAIC_HOME).option("--name <name>", "Agent name").option("--role <description>", "Agent role description").option("--style <style>", "Communication style: direct|friendly|formal").option("--accessibility <prefs>", "Accessibility preferences").option("--guardrails <rules>", "Custom guardrails").option("--user-name <name>", "Your name").option("--pronouns <pronouns>", "Your pronouns").option("--timezone <tz>", "Your timezone").action(async (opts) => {
|
||
try {
|
||
const mosaicHome = opts.mosaicHome;
|
||
const sourceDir = opts.sourceDir ?? mosaicHome;
|
||
const prompter = opts.nonInteractive ? new HeadlessPrompter() : new ClackPrompter();
|
||
const configService = createConfigService(mosaicHome, sourceDir);
|
||
const style = opts.style;
|
||
await runWizard({
|
||
mosaicHome,
|
||
sourceDir,
|
||
prompter,
|
||
configService,
|
||
cliOverrides: {
|
||
soul: {
|
||
agentName: opts.name,
|
||
roleDescription: opts.role,
|
||
communicationStyle: style,
|
||
accessibility: opts.accessibility,
|
||
customGuardrails: opts.guardrails
|
||
},
|
||
user: {
|
||
userName: opts.userName,
|
||
pronouns: opts.pronouns,
|
||
timezone: opts.timezone
|
||
}
|
||
}
|
||
});
|
||
} catch (err) {
|
||
if (err instanceof WizardCancelledError) {
|
||
console.log("\nWizard cancelled.");
|
||
process.exit(0);
|
||
}
|
||
console.error("Wizard failed:", err);
|
||
process.exit(1);
|
||
}
|
||
});
|
||
program.parse();
|
||
|
||
//#endregion
|
||
export { }; |