create-vue
Version:
🛠️ The recommended way to start a Vite-powered Vue project
2,753 lines • 97.8 kB
JavaScript
#!/usr/bin/env node
/*! create-vue v3.23.0 | MIT */
import * as fs$1 from "node:fs";
import fs from "node:fs";
import * as path$2 from "node:path";
import path from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { parseArgs, styleText } from "node:util";
import process$1, { stdin, stdout } from "node:process";
import l__default from "node:readline";
import * as path$1 from "path";
//#region \0rolldown/runtime.js
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
//#endregion
//#region node_modules/.pnpm/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/utils.js
const getCodePointsLength = (() => {
const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
return (input) => {
let surrogatePairsNr = 0;
SURROGATE_PAIR_RE.lastIndex = 0;
while (SURROGATE_PAIR_RE.test(input)) surrogatePairsNr += 1;
return input.length - surrogatePairsNr;
};
})();
const isFullWidth = (x) => {
return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
};
const isWideNotCJKTNotEmoji = (x) => {
return x === 8987 || x === 9001 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
};
//#endregion
//#region node_modules/.pnpm/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/index.js
const ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
const CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
const CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/uy;
const TAB_RE = /\t{1,1000}/y;
const EMOJI_RE = /[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/uy;
const LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
const MODIFIER_RE = /\p{M}+/gu;
const NO_TRUNCATION$1 = {
limit: Infinity,
ellipsis: ""
};
const getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
const LIMIT = truncationOptions.limit ?? Infinity;
const ELLIPSIS = truncationOptions.ellipsis ?? "";
const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION$1, widthOptions).width : 0);
const ANSI_WIDTH = 0;
const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
const TAB_WIDTH = widthOptions.tabWidth ?? 8;
const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
const FULL_WIDTH_WIDTH = 2;
const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
const PARSE_BLOCKS = [
[LATIN_RE, REGULAR_WIDTH],
[ANSI_RE, ANSI_WIDTH],
[CONTROL_RE, CONTROL_WIDTH],
[TAB_RE, TAB_WIDTH],
[EMOJI_RE, EMOJI_WIDTH],
[CJKT_WIDE_RE, WIDE_WIDTH]
];
let indexPrev = 0;
let index = 0;
let length = input.length;
let lengthExtra = 0;
let truncationEnabled = false;
let truncationIndex = length;
let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
let unmatchedStart = 0;
let unmatchedEnd = 0;
let width = 0;
let widthExtra = 0;
outer: while (true) {
if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
lengthExtra = 0;
for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
const codePoint = char.codePointAt(0) || 0;
if (isFullWidth(codePoint)) widthExtra = FULL_WIDTH_WIDTH;
else if (isWideNotCJKTNotEmoji(codePoint)) widthExtra = WIDE_WIDTH;
else widthExtra = REGULAR_WIDTH;
if (width + widthExtra > truncationLimit) truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
if (width + widthExtra > LIMIT) {
truncationEnabled = true;
break outer;
}
lengthExtra += char.length;
width += widthExtra;
}
unmatchedStart = unmatchedEnd = 0;
}
if (index >= length) break outer;
for (let i = 0, l = PARSE_BLOCKS.length; i < l; i++) {
const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];
BLOCK_RE.lastIndex = index;
if (BLOCK_RE.test(input)) {
lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
widthExtra = lengthExtra * BLOCK_WIDTH;
if (width + widthExtra > truncationLimit) truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
if (width + widthExtra > LIMIT) {
truncationEnabled = true;
break outer;
}
width += widthExtra;
unmatchedStart = indexPrev;
unmatchedEnd = index;
index = indexPrev = BLOCK_RE.lastIndex;
continue outer;
}
}
index += 1;
}
return {
width: truncationEnabled ? truncationLimit : width,
index: truncationEnabled ? truncationIndex : length,
truncated: truncationEnabled,
ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
};
};
//#endregion
//#region node_modules/.pnpm/fast-string-width@3.0.2/node_modules/fast-string-width/dist/index.js
const NO_TRUNCATION = {
limit: Infinity,
ellipsis: "",
ellipsisWidth: 0
};
const fastStringWidth = (input, options = {}) => {
return getStringTruncatedWidth(input, NO_TRUNCATION, options).width;
};
//#endregion
//#region node_modules/.pnpm/fast-wrap-ansi@0.2.2/node_modules/fast-wrap-ansi/lib/main.js
const ESC = "\x1B";
const CSI = "";
const END_CODE = 39;
const ANSI_ESCAPE_BELL = "\x07";
const ANSI_CSI = "[";
const ANSI_OSC = "]";
const ANSI_SGR_TERMINATOR = "m";
const ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
const GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
const getClosingCode = (openingCode) => {
if (openingCode >= 30 && openingCode <= 37) return 39;
if (openingCode >= 90 && openingCode <= 97) return 39;
if (openingCode >= 40 && openingCode <= 47) return 49;
if (openingCode >= 100 && openingCode <= 107) return 49;
if (openingCode === 1 || openingCode === 2) return 22;
if (openingCode === 3) return 23;
if (openingCode === 4) return 24;
if (openingCode === 7) return 27;
if (openingCode === 8) return 28;
if (openingCode === 9) return 29;
if (openingCode === 0) return 0;
};
const wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
const wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
const wrapWord = (rows, word, columns) => {
const characters = word[Symbol.iterator]();
let isInsideEscape = false;
let isInsideLinkEscape = false;
let lastRow = rows.at(-1);
let visible = lastRow === void 0 ? 0 : fastStringWidth(lastRow);
let currentCharacter = characters.next();
let nextCharacter = characters.next();
let rawCharacterIndex = 0;
while (!currentCharacter.done) {
const character = currentCharacter.value;
const characterLength = fastStringWidth(character);
if (visible + characterLength <= columns) rows[rows.length - 1] += character;
else {
rows.push(character);
visible = 0;
}
if (character === ESC || character === CSI) {
isInsideEscape = true;
isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
}
if (isInsideEscape) {
if (isInsideLinkEscape) {
if (character === ANSI_ESCAPE_BELL) {
isInsideEscape = false;
isInsideLinkEscape = false;
}
} else if (character === ANSI_SGR_TERMINATOR) isInsideEscape = false;
} else {
visible += characterLength;
if (visible === columns && !nextCharacter.done) {
rows.push("");
visible = 0;
}
}
currentCharacter = nextCharacter;
nextCharacter = characters.next();
rawCharacterIndex += character.length;
}
lastRow = rows.at(-1);
if (!visible && lastRow !== void 0 && lastRow.length && rows.length > 1) rows[rows.length - 2] += rows.pop();
};
const stringVisibleTrimSpacesRight = (string) => {
const words = string.split(" ");
let last = words.length;
while (last) {
if (fastStringWidth(words[last - 1])) break;
last--;
}
if (last === words.length) return string;
return words.slice(0, last).join(" ") + words.slice(last).join("");
};
const exec = (string, columns, options = {}) => {
if (options.trim !== false && string.trim() === "") return "";
let returnValue = "";
let escapeCode;
let escapeUrl;
const words = string.split(" ");
let rows = [""];
let rowLength = 0;
for (let index = 0; index < words.length; index++) {
const word = words[index];
if (options.trim !== false) {
const row = rows.at(-1) ?? "";
const trimmed = row.trimStart();
if (row.length !== trimmed.length) {
rows[rows.length - 1] = trimmed;
rowLength = fastStringWidth(trimmed);
}
}
if (index !== 0) {
if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
rows.push("");
rowLength = 0;
}
if (rowLength || options.trim === false) {
rows[rows.length - 1] += " ";
rowLength++;
}
}
const wordLength = fastStringWidth(word);
if (options.hard && wordLength > columns) {
const remainingColumns = columns - rowLength;
const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
if (Math.floor((wordLength - 1) / columns) < breaksStartingThisLine) rows.push("");
wrapWord(rows, word, columns);
rowLength = fastStringWidth(rows.at(-1) ?? "");
continue;
}
if (rowLength + wordLength > columns && rowLength && wordLength) {
if (options.wordWrap === false && rowLength < columns) {
wrapWord(rows, word, columns);
rowLength = fastStringWidth(rows.at(-1) ?? "");
continue;
}
rows.push("");
rowLength = 0;
}
if (rowLength + wordLength > columns && options.wordWrap === false) {
wrapWord(rows, word, columns);
rowLength = fastStringWidth(rows.at(-1) ?? "");
continue;
}
rows[rows.length - 1] += word;
rowLength += wordLength;
}
if (options.trim !== false) rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
const preString = rows.join("\n");
let inSurrogate = false;
for (let i = 0; i < preString.length; i++) {
const character = preString[i];
returnValue += character;
if (!inSurrogate) {
inSurrogate = character >= "\ud800" && character <= "\udbff";
if (inSurrogate) continue;
} else inSurrogate = false;
if (character === ESC || character === CSI) {
GROUP_REGEX.lastIndex = i + 1;
const groups = GROUP_REGEX.exec(preString)?.groups;
if (groups?.code !== void 0) {
const code = Number.parseFloat(groups.code);
escapeCode = code === END_CODE ? void 0 : code;
} else if (groups?.uri !== void 0) escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri;
}
if (preString[i + 1] === "\n") {
if (escapeUrl) returnValue += wrapAnsiHyperlink("");
const closingCode = escapeCode ? getClosingCode(escapeCode) : void 0;
if (escapeCode && closingCode) returnValue += wrapAnsiCode(closingCode);
} else if (character === "\n") {
if (escapeCode && getClosingCode(escapeCode)) returnValue += wrapAnsiCode(escapeCode);
if (escapeUrl) returnValue += wrapAnsiHyperlink(escapeUrl);
}
}
return returnValue;
};
const CRLF_OR_LF = /\r?\n/;
function wrapAnsi(string, columns, options) {
return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join("\n");
}
//#endregion
//#region node_modules/.pnpm/@clack+core@1.4.3/node_modules/@clack/core/dist/index.mjs
var import_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`
};
module.exports = {
cursor,
scroll: {
up: (count = 1) => `${CSI}S`.repeat(count),
down: (count = 1) => `${CSI}T`.repeat(count)
},
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;
}
},
beep
};
})))();
function findCursor(s, o, l) {
if (!l.some((r) => !r.disabled)) return s;
const t = s + o, n = Math.max(l.length - 1, 0), e = t < 0 ? n : t > n ? 0 : t;
return l[e]?.disabled ? findCursor(e, o < 0 ? -1 : 1, l) : e;
}
const settings = {
actions: /* @__PURE__ */ new Set([
"up",
"down",
"left",
"right",
"space",
"enter",
"cancel"
]),
aliases: /* @__PURE__ */ new Map([
["k", "up"],
["j", "down"],
["h", "left"],
["l", "right"],
["", "cancel"],
["escape", "cancel"]
]),
messages: {
cancel: "Canceled",
error: "Something went wrong"
},
withGuide: true,
date: {
monthNames: [...[
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
]],
messages: {
required: "Please enter a valid date",
invalidMonth: "There are only 12 months in a year",
invalidDay: (n, e) => `There are only ${n} days in ${e}`,
afterMin: (n) => `Date must be on or after ${n.toISOString().slice(0, 10)}`,
beforeMax: (n) => `Date must be on or before ${n.toISOString().slice(0, 10)}`
}
}
};
function isActionKey(n, e) {
if (typeof n == "string") return settings.aliases.get(n) === e;
for (const s of n) if (s !== void 0 && isActionKey(s, e)) return true;
return false;
}
function diffLines(i, s) {
if (i === s) return;
const e = i.split(`
`), t = s.split(`
`), r = Math.max(e.length, t.length), f = [];
for (let n = 0; n < r; n++) e[n] !== t[n] && f.push(n);
return {
lines: f,
numLinesBefore: e.length,
numLinesAfter: t.length,
numLines: r
};
}
globalThis.process.platform.startsWith("win");
const CANCEL_SYMBOL = Symbol("clack:cancel");
function isCancel(e) {
return e === CANCEL_SYMBOL;
}
function setRawMode(e, r) {
const o = e;
o.isTTY && o.setRawMode(r);
}
const getColumns = (e) => "columns" in e && typeof e.columns == "number" ? e.columns : 80;
const getRows = (e) => "rows" in e && typeof e.rows == "number" ? e.rows : 20;
function wrapTextWithPrefix(e, r, o, t = o, s = o, n) {
return wrapAnsi(r, getColumns(e ?? stdout) - o.length, {
hard: true,
trim: false
}).split(`
`).map((c, i, m) => {
const d = n ? n(c, i) : c;
return i === 0 ? `${t}${d}` : i === m.length - 1 ? `${s}${d}` : `${o}${d}`;
}).join(`
`);
}
function runValidation(e, n) {
if ("~standard" in e) {
const a = e["~standard"].validate(n);
if (a instanceof Promise) throw new TypeError("Schema validation must be synchronous. Update `validate()` and remove any asynchronous logic.");
return a.issues?.at(0)?.message;
}
return e(n);
}
var V = class {
input;
output;
_abortSignal;
rl;
opts;
_render;
_track = false;
_prevFrame = "";
_subscribers = /* @__PURE__ */ new Map();
_cursor = 0;
state = "initial";
error = "";
value;
userInput = "";
constructor(t, e = true) {
const { input: i = stdin, output: n = stdout, render: s, signal: r, ...o } = t;
this.opts = o, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = s.bind(this), this._track = e, this._abortSignal = r, this.input = i, this.output = n;
}
/**
* Unsubscribe all listeners
*/
unsubscribe() {
this._subscribers.clear();
}
/**
* Set a subscriber with opts
* @param event - The event name
*/
setSubscriber(t, e) {
const i = this._subscribers.get(t) ?? [];
i.push(e), this._subscribers.set(t, i);
}
/**
* Subscribe to an event
* @param event - The event name
* @param cb - The callback
*/
on(t, e) {
this.setSubscriber(t, { cb: e });
}
/**
* Subscribe to an event once
* @param event - The event name
* @param cb - The callback
*/
once(t, e) {
this.setSubscriber(t, {
cb: e,
once: true
});
}
/**
* Emit an event with data
* @param event - The event name
* @param data - The data to pass to the callback
*/
emit(t, ...e) {
const i = this._subscribers.get(t) ?? [], n = [];
for (const s of i) s.cb(...e), s.once && n.push(() => i.splice(i.indexOf(s), 1));
for (const s of n) s();
}
prompt() {
return new Promise((t) => {
if (this._abortSignal) {
if (this._abortSignal.aborted) return this.state = "cancel", this.close(), t(CANCEL_SYMBOL);
this._abortSignal.addEventListener("abort", () => {
this.state = "cancel", this.close();
}, { once: true });
}
this.rl = l__default.createInterface({
input: this.input,
tabSize: 2,
prompt: "",
escapeCodeTimeout: 50,
terminal: true
}), this.rl.prompt(), this.opts.initialUserInput !== void 0 && this._setUserInput(this.opts.initialUserInput, true), this.input.on("keypress", this.onKeypress), setRawMode(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
this.output.write(import_src.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t(this.value);
}), this.once("cancel", () => {
this.output.write(import_src.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t(CANCEL_SYMBOL);
});
});
}
_isActionKey(t, e) {
return t === " ";
}
_shouldSubmit(t, e) {
return true;
}
_setValue(t) {
this.value = t, this.emit("value", this.value);
}
_setUserInput(t, e) {
this.userInput = t ?? "", this.emit("userInput", this.userInput), e && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
}
_clearUserInput() {
this.rl?.write(null, {
ctrl: true,
name: "u"
}), this._setUserInput("");
}
onKeypress(t, e) {
if (this._track && e.name !== "return" && (e.name && this._isActionKey(t, e) && this.rl?.write(null, {
ctrl: true,
name: "h"
}), this._cursor = this.rl?.cursor ?? 0, this._setUserInput(this.rl?.line)), this.state === "error" && (this.state = "active"), e?.name && (!this._track && settings.aliases.has(e.name) && this.emit("cursor", settings.aliases.get(e.name)), settings.actions.has(e.name) && this.emit("cursor", e.name)), t && (t.toLowerCase() === "y" || t.toLowerCase() === "n") && this.emit("confirm", t.toLowerCase() === "y"), this.emit("key", t, e), e?.name === "return" && this._shouldSubmit(t, e)) {
if (this.opts.validate) {
const i = runValidation(this.opts.validate, this.value);
i && (this.error = i instanceof Error ? i.message : i, this.state = "error", this.rl?.write(this.userInput));
}
this.state !== "error" && (this.state = "submit");
}
isActionKey([
t,
e?.name,
e?.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(`
`), setRawMode(this.input, false), this.rl?.close(), this.rl = void 0, this.emit(`${this.state}`, this.value), this.unsubscribe();
}
restoreCursor() {
const t = wrapAnsi(this._prevFrame, process.stdout.columns, {
hard: true,
trim: false
}).split(`
`).length - 1;
this.output.write(import_src.cursor.move(-999, t * -1));
}
render() {
const t = wrapAnsi(this._render(this) ?? "", process.stdout.columns, {
hard: true,
trim: false
});
if (t !== this._prevFrame) {
if (this.state === "initial") this.output.write(import_src.cursor.hide);
else {
const e = diffLines(this._prevFrame, t), i = getRows(this.output);
if (this.restoreCursor(), e) {
const n = Math.max(0, e.numLinesAfter - i), s = Math.max(0, e.numLinesBefore - i);
let r = e.lines.find((o) => o >= n);
if (r === void 0) {
this._prevFrame = t;
return;
}
if (e.lines.length === 1) {
this.output.write(import_src.cursor.move(0, r - s)), this.output.write(import_src.erase.lines(1));
const o = t.split(`
`);
this.output.write(o[r]), this._prevFrame = t, this.output.write(import_src.cursor.move(0, o.length - r - 1));
return;
} else if (e.lines.length > 1) {
if (n < s) r = n;
else {
const h = r - s;
h > 0 && this.output.write(import_src.cursor.move(0, h));
}
this.output.write(import_src.erase.down());
const f = t.split(`
`).slice(r);
this.output.write(f.join(`
`)), this._prevFrame = t;
return;
}
}
this.output.write(import_src.erase.down());
}
this.output.write(t), this.state === "initial" && (this.state = "active"), this._prevFrame = t;
}
}
};
var r = class extends V {
get cursor() {
return this.value ? 0 : 1;
}
get _value() {
return this.cursor === 0;
}
constructor(t) {
super(t, false), this.value = !!t.initialValue, this.on("userInput", () => {
this.value = this._value;
}), this.on("confirm", (i) => {
this.output.write(import_src.cursor.move(0, -1)), this.value = i, this.state = "submit", this.close();
}), this.on("cursor", () => {
this.value = !this.value;
});
}
};
var a = class extends V {
options;
cursor = 0;
get _value() {
return this.options[this.cursor]?.value;
}
get _enabledOptions() {
return this.options.filter((e) => e.disabled !== true);
}
toggleAll() {
const e = this._enabledOptions, i = this.value !== void 0 && this.value.length === e.length;
this.value = i ? [] : e.map((t) => t.value);
}
toggleInvert() {
const e = this.value;
if (!e) return;
const i = this._enabledOptions.filter((t) => !e.includes(t.value));
this.value = i.map((t) => t.value);
}
toggleValue() {
this.value === void 0 && (this.value = []);
const e = this.value.includes(this._value);
this.value = e ? this.value.filter((i) => i !== this._value) : [...this.value, this._value];
}
constructor(e) {
super(e, false), this.options = e.options, this.value = [...e.initialValues ?? []];
const i = Math.max(this.options.findIndex(({ value: t }) => t === e.cursorAt), 0);
this.cursor = this.options[i]?.disabled ? findCursor(i, 1, this.options) : i, this.on("key", (t, l) => {
l.name === "a" && this.toggleAll(), l.name === "i" && this.toggleInvert();
}), this.on("cursor", (t) => {
switch (t) {
case "left":
case "up":
this.cursor = findCursor(this.cursor, -1, this.options);
break;
case "down":
case "right":
this.cursor = findCursor(this.cursor, 1, this.options);
break;
case "space":
this.toggleValue();
break;
}
});
}
};
let n$1 = class n extends V {
options;
cursor = 0;
get _selectedValue() {
return this.options[this.cursor];
}
changeValue() {
const e = this._selectedValue;
this.value = e === void 0 ? void 0 : e.value;
}
constructor(e) {
super(e, false), this.options = e.options;
const o = this.options.findIndex(({ value: s }) => s === e.initialValue), t = o === -1 ? 0 : o;
this.cursor = this.options[t]?.disabled ? findCursor(t, 1, this.options) : t, this.changeValue(), this.on("cursor", (s) => {
switch (s) {
case "left":
case "up":
this.cursor = findCursor(this.cursor, -1, this.options);
break;
case "down":
case "right":
this.cursor = findCursor(this.cursor, 1, this.options);
break;
}
this.changeValue();
});
}
};
var n = class extends V {
get userInputWithCursor() {
if (this.state === "submit") return this.userInput;
const t = this.userInput;
if (this.cursor >= t.length) return `${this.userInput}\u2588`;
const r = t.slice(0, this.cursor), s = t.slice(this.cursor, this.cursor + 1), e = t.slice(this.cursor + 1);
return `${r}${styleText("inverse", s)}${e}`;
}
get cursor() {
return this._cursor;
}
constructor(t) {
super({
...t,
initialUserInput: t.initialUserInput ?? t.initialValue
}), this.on("userInput", (r) => {
this._setValue(r);
}), this.on("finalize", () => {
this.value || (this.value = t.defaultValue), this.value === void 0 && (this.value = "");
});
}
};
//#endregion
//#region node_modules/.pnpm/@clack+prompts@1.7.0/node_modules/@clack/prompts/dist/index.mjs
function isUnicodeSupported() {
if (process$1.platform !== "win32") return process$1.env.TERM !== "linux";
return Boolean(process$1.env.CI) || Boolean(process$1.env.WT_SESSION) || Boolean(process$1.env.TERMINUS_SUBLIME) || process$1.env.ConEmuTask === "{cmd::Cmder}" || process$1.env.TERM_PROGRAM === "Terminus-Sublime" || process$1.env.TERM_PROGRAM === "vscode" || process$1.env.TERM === "xterm-256color" || process$1.env.TERM === "alacritty" || process$1.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
}
const unicode = isUnicodeSupported();
const unicodeOr = (o, e) => unicode ? o : e;
const S_STEP_ACTIVE = unicodeOr("◆", "*");
const S_STEP_CANCEL = unicodeOr("■", "x");
const S_STEP_ERROR = unicodeOr("▲", "x");
const S_STEP_SUBMIT = unicodeOr("◇", "o");
const S_BAR_START = unicodeOr("┌", "T");
const S_BAR = unicodeOr("│", "|");
const S_BAR_END = unicodeOr("└", "—");
const S_RADIO_ACTIVE = unicodeOr("●", ">");
const S_RADIO_INACTIVE = unicodeOr("○", " ");
const S_CHECKBOX_ACTIVE = unicodeOr("◻", "[•]");
const S_CHECKBOX_SELECTED = unicodeOr("◼", "[+]");
const S_CHECKBOX_INACTIVE = unicodeOr("◻", "[ ]");
const symbol = (o) => {
switch (o) {
case "initial":
case "active": return styleText("cyan", S_STEP_ACTIVE);
case "cancel": return styleText("red", S_STEP_CANCEL);
case "error": return styleText("yellow", S_STEP_ERROR);
case "submit": return styleText("green", S_STEP_SUBMIT);
}
};
const symbolBar = (o) => {
switch (o) {
case "initial":
case "active": return styleText("cyan", S_BAR);
case "cancel": return styleText("red", S_BAR);
case "error": return styleText("yellow", S_BAR);
case "submit": return styleText("green", S_BAR);
}
};
function formatInstructionFooter(o, e) {
const r = [`${e ? `${styleText("cyan", S_BAR)} ` : ""}${o.join(" • ")}`];
return e && r.push(styleText("cyan", S_BAR_END)), r;
}
const I = (l, e, w, p, b, C = false) => {
let r = e, O = 0;
if (C) for (let i = p - 1; i >= w; i--) {
const m = l[i];
if (m && (r -= m.length), O++, r <= b) break;
}
else for (let i = w; i < p; i++) {
const m = l[i];
if (m && (r -= m.length), O++, r <= b) break;
}
return {
lineCount: r,
removals: O
};
};
const limitOptions = ({ cursor: l, options: e, style: w, output: p = process.stdout, maxItems: b = Number.POSITIVE_INFINITY, columnPadding: C = 0, rowPadding: r = 4 }) => {
const i = getColumns(p) - C, m = getRows(p), M = styleText("dim", "..."), v = Math.max(m - r, 0), a = Math.max(Math.min(b, v), 5);
let f = 0;
l >= a - 3 && (f = Math.max(Math.min(l - a + 3, e.length - a), 0));
let d = a < e.length && f > 0, c = a < e.length && f + a < e.length;
const W = Math.min(f + a, e.length), s = [];
let g = 0;
d && g++, c && g++;
const T = f + (d ? 1 : 0), y = W - (c ? 1 : 0);
for (let t = T; t < y; t++) {
const n = e[t], h = wrapAnsi(n ? w(n, t === l) : "", i, {
hard: true,
trim: false
}).split(`
`);
s.push(h), g += h.length;
}
if (g > v) {
let t = 0, n = 0, o = g;
const h = l - T;
let u = v;
const L = () => I(s, o, 0, h, u), E = () => I(s, o, h + 1, s.length, u, true);
d ? ({lineCount: o, removals: t} = L(), o > u && (c || (u -= 1), {lineCount: o, removals: n} = E())) : (c || (u -= 1), {lineCount: o, removals: n} = E(), o > u && (u -= 1, {lineCount: o, removals: t} = L())), t > 0 && (d = true, s.splice(0, t)), n > 0 && (c = true, s.splice(s.length - n, n));
}
const x = [];
d && x.push(M);
for (const t of s) for (const n of t) x.push(n);
return c && x.push(M), x;
};
const confirm = (i) => {
const a = i.active ?? "Yes", s = i.inactive ?? "No";
return new r({
active: a,
inactive: s,
signal: i.signal,
input: i.input,
output: i.output,
initialValue: i.initialValue ?? true,
render() {
const e = i.withGuide ?? settings.withGuide, u = `${symbol(this.state)} `, l = e ? `${styleText("gray", S_BAR)} ` : "", f = wrapTextWithPrefix(i.output, i.message, l, u), o = `${e ? `${styleText("gray", S_BAR)}
` : ""}${f}
`, c = this.value ? a : s;
switch (this.state) {
case "submit": return `${o}${e ? `${styleText("gray", S_BAR)} ` : ""}${styleText("dim", c)}`;
case "cancel": return `${o}${e ? `${styleText("gray", S_BAR)} ` : ""}${styleText(["strikethrough", "dim"], c)}${e ? `
${styleText("gray", S_BAR)}` : ""}`;
default: {
const r = e ? `${styleText("cyan", S_BAR)} ` : "", g = e ? styleText("cyan", S_BAR_END) : "";
return `${o}${r}${this.value ? `${styleText("green", S_RADIO_ACTIVE)} ${a}` : `${styleText("dim", S_RADIO_INACTIVE)} ${styleText("dim", a)}`}${i.vertical ? e ? `
${styleText("cyan", S_BAR)} ` : `
` : ` ${styleText("dim", "/")} `}${this.value ? `${styleText("dim", S_RADIO_INACTIVE)} ${styleText("dim", s)}` : `${styleText("green", S_RADIO_ACTIVE)} ${s}`}
${g}
`;
}
}
}
}).prompt();
};
const MULTISELECT_INSTRUCTIONS = [
`${styleText("dim", "↑/↓")} to navigate`,
`${styleText("dim", "Space:")} select`,
`${styleText("dim", "Enter:")} confirm`
];
const m = (i, u) => i.split(`
`).map((d) => u(d)).join(`
`);
const multiselect = (i) => {
const u = (t, a) => {
const r = t.label ?? String(t.value);
return a === "disabled" ? `${styleText("gray", S_CHECKBOX_INACTIVE)} ${m(r, (o) => styleText(["strikethrough", "gray"], o))}${t.hint ? ` ${styleText("dim", `(${t.hint ?? "disabled"})`)}` : ""}` : a === "active" ? `${styleText("cyan", S_CHECKBOX_ACTIVE)} ${r}${t.hint ? ` ${styleText("dim", `(${t.hint})`)}` : ""}` : a === "selected" ? `${styleText("green", S_CHECKBOX_SELECTED)} ${m(r, (o) => styleText("dim", o))}${t.hint ? ` ${styleText("dim", `(${t.hint})`)}` : ""}` : a === "cancelled" ? `${m(r, (o) => styleText(["strikethrough", "dim"], o))}` : a === "active-selected" ? `${styleText("green", S_CHECKBOX_SELECTED)} ${r}${t.hint ? ` ${styleText("dim", `(${t.hint})`)}` : ""}` : a === "submitted" ? `${m(r, (o) => styleText("dim", o))}` : `${styleText("dim", S_CHECKBOX_INACTIVE)} ${m(r, (o) => styleText("dim", o))}`;
}, d = i.required ?? true, v = i.showInstructions ?? true;
return new a({
options: i.options,
signal: i.signal,
input: i.input,
output: i.output,
initialValues: i.initialValues,
required: d,
cursorAt: i.cursorAt,
validate(t) {
if (d && (t === void 0 || t.length === 0)) return `Please select at least one option.
${styleText("reset", styleText("dim", `Press ${styleText([
"gray",
"bgWhite",
"inverse"
], " space ")} to select, ${styleText("gray", styleText("bgWhite", styleText("inverse", " enter ")))} to submit`))}`;
},
render() {
const t = i.withGuide ?? settings.withGuide, a = wrapTextWithPrefix(i.output, i.message, t ? `${symbolBar(this.state)} ` : "", `${symbol(this.state)} `), r = `${t ? `${styleText("gray", S_BAR)}
` : ""}${a}
`, o = this.value ?? [], p = (n, l) => {
if (n.disabled) return u(n, "disabled");
const s = o.includes(n.value);
return l && s ? u(n, "active-selected") : s ? u(n, "selected") : u(n, l ? "active" : "inactive");
};
switch (this.state) {
case "submit": {
const n = this.options.filter(({ value: s }) => o.includes(s)).map((s) => u(s, "submitted")).join(styleText("dim", ", ")) || styleText("dim", "none");
return `${r}${wrapTextWithPrefix(i.output, n, t ? `${styleText("gray", S_BAR)} ` : "")}`;
}
case "cancel": {
const n = this.options.filter(({ value: s }) => o.includes(s)).map((s) => u(s, "cancelled")).join(styleText("dim", ", "));
if (n.trim() === "") return `${r}${styleText("gray", S_BAR)}`;
return `${r}${wrapTextWithPrefix(i.output, n, t ? `${styleText("gray", S_BAR)} ` : "")}${t ? `
${styleText("gray", S_BAR)}` : ""}`;
}
case "error": {
const n = t ? `${styleText("yellow", S_BAR)} ` : "", l = this.error.split(`
`).map(($, C) => C === 0 ? `${t ? `${styleText("yellow", S_BAR_END)} ` : ""}${styleText("yellow", $)}` : ` ${$}`).join(`
`), s = r.split(`
`).length, h = l.split(`
`).length + 1;
return `${r}${n}${limitOptions({
output: i.output,
options: this.options,
cursor: this.cursor,
maxItems: i.maxItems,
columnPadding: n.length,
rowPadding: s + h,
style: p
}).join(`
${n}`)}
${l}
`;
}
default: {
const n = t ? `${styleText("cyan", S_BAR)} ` : "", l = r.split(`
`).length, s = v ? formatInstructionFooter(MULTISELECT_INSTRUCTIONS, t) : t ? [styleText("cyan", S_BAR_END)] : [], h = s.join(`
`), $ = s.length + 1;
return `${r}${n}${limitOptions({
output: i.output,
options: this.options,
cursor: this.cursor,
maxItems: i.maxItems,
columnPadding: n.length,
rowPadding: l + $,
style: p
}).join(`
${n}`)}
${h}
`;
}
}
}
}).prompt();
};
const cancel = (o = "", t) => {
const i = t?.output ?? process.stdout, e = t?.withGuide ?? settings.withGuide ? `${styleText("gray", S_BAR_END)} ` : "";
i.write(`${e}${styleText("red", o)}
`);
};
const intro = (o = "", t) => {
const i = t?.output ?? process.stdout, e = t?.withGuide ?? settings.withGuide ? `${styleText("gray", S_BAR_START)} ` : "";
i.write(`${e}${o}
`);
};
const outro = (o = "", t) => {
const i = t?.output ?? process.stdout, e = t?.withGuide ?? settings.withGuide ? `${styleText("gray", S_BAR)}
${styleText("gray", S_BAR_END)} ` : "";
i.write(`${e}${o}
`);
};
const SELECT_INSTRUCTIONS = [`${styleText("dim", "↑/↓")} to navigate`, `${styleText("dim", "Enter:")} confirm`];
const c = (t, o) => t.includes(`
`) ? t.split(`
`).map((d) => o(d)).join(`
`) : o(t);
const select = (t) => {
const o = (n, m) => {
if (n === void 0) return "";
const s = n.label ?? String(n.value);
switch (m) {
case "disabled": return `${styleText("gray", S_RADIO_INACTIVE)} ${c(s, (i) => styleText("gray", i))}${n.hint ? ` ${styleText("dim", `(${n.hint ?? "disabled"})`)}` : ""}`;
case "selected": return `${c(s, (i) => styleText("dim", i))}`;
case "active": return `${styleText("green", S_RADIO_ACTIVE)} ${s}${n.hint ? ` ${styleText("dim", `(${n.hint})`)}` : ""}`;
case "cancelled": return `${c(s, (i) => styleText(["strikethrough", "dim"], i))}`;
default: return `${styleText("dim", S_RADIO_INACTIVE)} ${c(s, (i) => styleText("dim", i))}`;
}
}, d = t.showInstructions ?? true;
return new n$1({
options: t.options,
signal: t.signal,
input: t.input,
output: t.output,
initialValue: t.initialValue,
render() {
const n = t.withGuide ?? settings.withGuide, m = `${symbol(this.state)} `, s = `${symbolBar(this.state)} `, i = wrapTextWithPrefix(t.output, t.message, s, m), u = `${n ? `${styleText("gray", S_BAR)}
` : ""}${i}
`;
switch (this.state) {
case "submit": {
const r = n ? `${styleText("gray", S_BAR)} ` : "";
return `${u}${wrapTextWithPrefix(t.output, o(this.options[this.cursor], "selected"), r)}`;
}
case "cancel": {
const r = n ? `${styleText("gray", S_BAR)} ` : "";
return `${u}${wrapTextWithPrefix(t.output, o(this.options[this.cursor], "cancelled"), r)}${n ? `
${styleText("gray", S_BAR)}` : ""}`;
}
default: {
const r = n ? `${styleText("cyan", S_BAR)} ` : "", a = u.split(`
`).length, p = d ? formatInstructionFooter(SELECT_INSTRUCTIONS, n) : n ? [styleText("cyan", S_BAR_END)] : [], b = p.join(`
`), f = p.length + 1;
return `${u}${r}${limitOptions({
output: t.output,
cursor: this.cursor,
options: this.options,
maxItems: t.maxItems,
columnPadding: r.length,
rowPadding: a + f,
style: (g, x) => o(g, g.disabled ? "disabled" : x ? "active" : "inactive")
}).join(`
${r}`)}
${b}
`;
}
}
}
}).prompt();
};
`${styleText("gray", S_BAR)}`;
const text = (e) => new n({
validate: e.validate,
placeholder: e.placeholder,
defaultValue: e.defaultValue,
initialValue: e.initialValue,
output: e.output,
signal: e.signal,
input: e.input,
render() {
const i = e?.withGuide ?? settings.withGuide, s = `${`${i ? `${styleText("gray", S_BAR)}
` : ""}${symbol(this.state)} `}${e.message}
`, c = e.placeholder && e.placeholder.length > 0 ? styleText("inverse", e.placeholder[0]) + styleText("dim", e.placeholder.slice(1)) : styleText(["inverse", "hidden"], "_"), o = this.userInput ? this.userInputWithCursor : c, l = this.value ?? "";
switch (this.state) {
case "error": {
const n = this.error ? ` ${styleText("yellow", this.error)}` : "", r = i ? `${styleText("yellow", S_BAR)} ` : "", d = i ? styleText("yellow", S_BAR_END) : "";
return `${s.trim()}
${r}${o}
${d}${n}
`;
}
case "submit": {
const n = l ? ` ${styleText("dim", l)}` : "";
return `${s}${i ? styleText("gray", S_BAR) : ""}${n}`;
}
case "cancel": {
const n = l ? ` ${styleText(["strikethrough", "dim"], l)}` : "", r = i ? styleText("gray", S_BAR) : "";
return `${s}${r}${n}${l.trim() ? `
${r}` : ""}`;
}
default: return `${s}${i ? `${styleText("cyan", S_BAR)} ` : ""}${o}
${i ? styleText("cyan", S_BAR_END) : ""}
`;
}
}
}).prompt();
//#endregion
//#region node_modules/.pnpm/ejs@6.0.1/node_modules/ejs/lib/esm/utils.js
var import_picocolors = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
let p = process || {};
let argv = p.argv || [];
let 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;
})))();
/**
* Private utility functions
* @module utils
* @private
*/
const utils = {};
var regExpChars = /[|\\{}()[\]^$+*?.]/g;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var hasOwn = function(obj, key) {
return hasOwnProperty.apply(obj, [key]);
};
utils.hasOwn = hasOwn;
/**
* Escape characters reserved in regular expressions.
*
* If `string` is `undefined` or `null`, the empty string is returned.
*
* @param {String} string Input string
* @return {String} Escaped string
* @static
* @private
*/
utils.escapeRegExpChars = function(string) {
// istanbul ignore if
if (!string) return "";
return String(string).replace(regExpChars, "\\$&");
};
var _ENCODE_HTML_RULES = {
"&": "&",
"<": "<",
">": ">",
"\"": """,
"'": "'"
};
var _MATCH_HTML = /[&<>'"]/g;
function encode_char(c) {
return _ENCODE_HTML_RULES[c] || c;
}
/**
* Stringified version of constants used by {@link module:utils.escapeXML}.
*
* @readonly
* @type {String}
*/
var escapeFuncStr = "var _ENCODE_HTML_RULES = {\n \"&\": \"&\"\n , \"<\": \"<\"\n , \">\": \">\"\n , '\"': \""\"\n , \"'\": \"'\"\n }\n , _MATCH_HTML = /[&<>'\"]/g;\nfunction encode_char(c) {\n return _ENCODE_HTML_RULES[c] || c;\n};\n";
/**
* Escape characters reserved in XML.
*
* If `markup` is `undefined` or `null`, the empty string is returned.
*
* @implements {EscapeCallback}
* @param {String} markup Input string
* @return {String} Escaped string
* @static
* @private
*/
utils.escapeXML = function(markup) {
return markup == void 0 ? "" : String(markup).replace(_MATCH_HTML, encode_char);
};
function escapeXMLToString() {
return Function.prototype.toString.call(this) + ";\n" + escapeFuncStr;
}
try {
if (typeof Object.defineProperty === "function") Object.defineProperty(utils.escapeXML, "toString", { value: escapeXMLToString });
else utils.escapeXML.toString = escapeXMLToString;
} catch (err) {
console.warn("Unable to set escapeXML.toString (is the Function prototype frozen?)");
}
/**
* Naive copy of properties from one object to another.
* Does not recurse into non-scalar properties
* Does not check to see if the property has a value before copying
*
* @param {Object} to Destination object
* @param {Object} from Source object
* @return {Object} Destination object
* @static
* @private
*/
utils.shallowCopy = function(to, from) {
from = from || {};
if (to !== null && to !== void 0) for (var p in from) {
if (!hasOwn(from, p)) continue;
if (p === "__proto__" || p === "constructor") continue;
to[p] = from[p];
}
return to;
};
/**
* Naive copy of a list of key names, from one object to another.
* Only copies property if it is actually defined
* Does not recurse into non-scalar properties
*
* @param {Object} to Destination object
* @param {Object} from Source object
* @param {Array} list List of properties to copy
* @return {Object} Destination object
* @static
* @private
*/
utils.shallowCopyFromList = function(to, from, list) {
list = list || [];
from = from || {};
if (to !== null && to !== void 0) for (var i = 0; i < list.length; i++) {
var p = list[i];
if (typeof from[p] != "undefined") {
if (!hasOwn(from, p)) continue;
if (p === "__proto__" || p === "constructor") continue;
to[p] = from[p];
}
}
return to;
};
/**
* Simple in-process cache implementation. Does not implement limits of any
* sort.
*
* @implements {Cache}
* @static
* @private
*/
utils.cache = {
_data: {},
set: function(key, val) {
this._data[key] = val;
},
get: function(key) {
return this._data[key];
},
remove: function(key) {
delete this._data[key];
},
reset: function() {
this._data = {};
}
};
/**
* Transforms hyphen case variable into camel case.
*
* @param {String} string Hyphen case string
* @return {String} Camel case string
* @static
* @private
*/
utils.hyphenToCamel = function(str) {
return str.replace(/-[a-z]/g, function(match) {
return match[1].toUpperCase();
});
};
/**
* Returns a null-prototype object in runtimes that support it
*
* @return {Object} Object, prototype will be set to null where possible
* @static
* @private
*/
utils.createNullProtoObjWherePossible = (function() {
if (typeof Object.create == "function") return function() {
return Object.create(null);
};
if (!({ __proto__: null } instanceof Object)) return function() {
return { __proto__: null };
};
return function() {
return {};
};
})();
/**
* Copies own-properties from one object to a null-prototype object for basic
* protection against prototype pollution
*
* @return {Object} Object with own-properties of input object
* @static
* @private
*/
utils.hasOwnOnlyObject = function(obj) {
var o = utils.createNullProtoObjWherePossible();
for (var p in obj) if (hasOwn(obj, p)) o[p] = obj[p];
return o;
};
//#endregion
//#region node_modules/.pnpm/ejs@6.0.1/node_modules/ejs/lib/esm/ejs.js
/**
* @file Embedded JavaScript templating engine. {@link http://ejs.co}
* @author Matthew Eernisse <mde@fleegix.org>
* @project EJS
* @license {@link http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0}
*/
/**
* EJS internal functions.
*
* Technically this "module" lies in the same file as {@link module:ejs}, for
* the sake of organization all the private functions re grouped into this
* module.
*
* @module ejs-internal
* @private
*/
/**
* Embedded JavaScript templating engine.
*
* @module ejs
* @public
*/
const DECLARATION_KEYWORD = "let";
const ejs = {};
/** @type {string} */
let _DEFAULT_OPEN_DELIMITER = "<";
let _DEFAULT_CLOSE_DELIMITER = ">";
let _DEFAULT_DELIMITER = "%";
let _DEFAULT_LOCALS_NAME = "locals";
let _REGEX_STRING = "(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)";
let _OPTS_PASSABLE_WITH_DATA = [
"delimiter",
"scope",
"context",
"debug",
"compileDebug",
"_with",
"rmWhitespace",
"strict",
"filename",
"async"
];
let _OPTS_PASSABLE_WITH_DATA_EXPRESS = _OPTS_PASSABLE_WITH_DATA.concat("cache");
let _BOM = /^\uFEFF/;
let _JS_IDENTIFIER = /^[a-zA-Z_$][0-9a-zA-Z_$]*$/;
/**
* EJS template function cache. This can be a LRU object from lru-cache NPM
* module. By default, it is {@link module:utils.cache}, a simple in-process
* cache that grows continuously.
*
* @type {Cache}
*/
ejs.cache = utils.cache;
/**
* Custom file loader. Useful for template preprocessing or restricting access
* to a certain part of the filesystem.
*
* @type {fileLoader}
*/
ejs.fileLoader = fs.readFileSync;
/**
* Name of the object containing the locals.
*
* This variable is overridden by {@link Options}`.localsName` if it is not
* `undefined`.
*
* @type {String}
* @public
*/
ejs.localsName = _DEFAULT_LOCALS_NAME;
/**
* Promise implementation -- defaults to the native implementation if available
* This is mostly just for testability
*
* @type {PromiseConstructorLike}
* @public
*/
ejs.promiseImpl = new Function("return this;")().Promise;
/**
* Get the path to the included file from the parent file path and the
* specified path.
*
* @param {String} name specified path
* @param {String} filename parent file path
* @param {Boolean} [isDir=false] whether the parent file path is a directory
* @return {String}
*/
ejs.resolveInclude = function(name, filename, isDir) {
let dirname = path.dirname;
let extname = path.extname;
let resolve = path.resolve;
let includePath = resolve(isDir ? filename : dirname(filename), name);
if (!extname(name)) includePath += ".ejs";
return includePath;
};
/**
* Try to resolve file path on multiple directories
*
* @param {String} name specified path
* @param {Array<String>} paths list of possible parent directory paths
* @return {String}
*/
function resolvePaths(name, paths) {
let filePath;
if (paths.some(function(v) {
filePath = ejs.resolveInclude(name, v, true);
return fs.existsSync(filePath);
})) return filePath;
}
/**
* Get the path to the included file by Options
*
* @param {String} path specified path
* @param {Options} options compilation options
* @return {String}
*/
function getIncludePath(path, options) {
let includePath;
let filePath;
let views = options.views;
let match = /^[A-Za-z]+:\\|^\//.exec(path);
if (match && match.length) {
path = path.replace(/^\/*/, "");
if (Array.isArray(options.root)) includePath = resolvePaths(path, options.root);
else includePath = ejs.resolveInclude(path, options.root || "/", true);
} else {
if (options.filename) {
filePath = ejs.resolveInclude(path, options.filename);
if (fs.existsSync(filePath)) includePath = filePath;
}
if (!includePath && Array.isArray(views)) includePath = resolvePaths(path, views);
if (!includePath && typeof options.includer !== "function") throw new Error("Could not find the include file \"" + options.escapeFunction(path) + "\"");
}
return includePath;
}
/**
* Get the template from a string or a file, either compiled on-the-fly or
* read from cache (if enabled), and cache the template if needed.
*
* If `template` is not set, the file specified in `options.filename` will be
* read.
*
* If `options.cache` is true, this function reads the file from
* `options.filename` so it must be set prior to calling this function.
*
* @memberof module:ejs-internal
* @param {Options} options compilation options
* @param {String} [template] template source
* @return {TemplateFunction}
* @static
*/
function handleCache(options, template) {
let func;
let filename = options.filename;
let hasTemplate = arguments.length > 1;
if (options.cache) {
if (!filename) throw new Error("cache option requires a filename");
func = ejs.cache.get(filename);
if (func) return func;
if (!hasTemplate) template = fileLoader(filename).toString().replace(_BOM, "");
} else if (!hasTemplate) {
// istanbul ignore if: should not happen at all
if (!filename) throw new Error("Internal EJS error: no file name or template provided");
template = fileLoader(filename).toString().replace(_BOM, "");
}
func = ejs.compile(template, options);
if (options.cache) ejs.cache.set(filename, func);
return func;
}
/**
* Try calling handleCache with the given options and data and call the
* callback with the result. If an error occurs, call the callback with
* the error. Used by renderFile().
*
* @memberof module:ejs-internal
* @param {Options} options compilation options
* @param {Object} data template data
* @param {RenderFileCallback} cb callback
* @static
*/
function tryHandleCache(options, data, cb) {
let result;
if (!cb) if (typeof ejs.promiseImpl == "function") return new ejs.promiseImpl(function(resolve, reject) {
try {
result = handleCache(options)(data);
resolve(result);
} catch (err) {
reject(err);
}
});
else throw new Error("Please provide a callback function");
else {
try {
result = handleCache(options)(data);
} catch (err) {
return cb(err);
}
cb(null, result);
}
}
/**
* fileLoader is independent
*
* @param {String} filePath ejs file path.
* @return {String} The contents of the specified file.
* @static
*/
function fileLoader(filePath) {
return ejs.fileLoader(filePath);
}
/**
* Get the template function.
*
* If `options.cache` is `true`, then the template is cached.
*
* @memberof module:ejs-internal
* @param {String} path path for the specified file
* @param {Options} options compilation options
* @return {TemplateFunction}
* @static
*/
function includeFile(path, options) {
let opts = utils.shallowCopy(utils.createNullProtoObjWherePossible(), options);
opts.filename = getIncludePath(path, opts);
if (typeof options.includer === "function") {
let includerResult = options.includer(path, opts.filename);
if (includerResult) {
if (includerResult.filename) opts.filename = includerResult.filename;
if (includerResult.template) return handleCache(opts, includerResult.template);
}
}
return handleCache(opts);
}
/**
* Re-throw the given `err` in context to the `str` of ejs, `filename`, and
* `lineno`.
*
* @implements {RethrowCallback}
* @memberof module:ejs-internal
* @param {Error} err Error object
* @param {String} str EJS source
* @param {String} flnm file name of the EJS file
* @param {Number} lineno line number of the error
* @param {EscapeCallback} esc
* @static
*/
function rethrow(err, str, flnm, lineno, esc) {
let lines = str.split("\n");
let start = Math.max(lineno - 3, 0);
let end = Math.min(lines.length, lineno + 3);
let filename = esc(flnm);
let context = lines.slice(start, end).map(function(line, i) {
let curr = i + start + 1;
return (curr == lineno ? " >> " : " ") + curr + "| " + line;
}).join("\n");
err.path = filename;
err.message = (filename || "ejs") + ":" + lineno + "\n" + context + "\n\n" + err.message;
throw err;
}
function stripSemi(str) {
return str.replace(/;(\s*$)/, "$1");
}
/**
* Compile the given `str` of ejs into a template function.
*
* @param {String} template EJS template
*
* @param {Options} [opts] compilation options
*
* @return {TemplateFunction}
* Note that the return type of the function depends on the value of `opts.async`.
* @public
*/
ejs.compile = function compile(template, opts) {
let templ;
if (opts && opts.scope) {
console.warn("`scope` option is deprecated and will be removed in future EJS");
if (!opts.context) opts.context = opts.scope;
delete opts.scope;
}
templ = new Template(template, opts);
return templ.compile();
};
/**
* Render the given `template` of ejs.
*
* If you would like to include options but not data, you need to explicitly
* call this function with `data` being an empty object or `null`.
*
* @param {String} template EJS template
* @param {Object} [data={}] template data
* @param {Options} [opts={}] compilation and rendering options
* @return {(String|Promise<String>)}
* Return value type depends on `opts.async`.
* @public
*/
ejs.render = function(template, d, o) {
let data = d || utils.createNullProtoObjWherePossible();
let opts = o || utils.createNullProtoObjWherePossible();
if (arguments.length == 2) utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA);
return handleCache(opts, template)(data);
};
/**
* Render an EJS file at the given `path` and callback `cb(err, str)`.
*
* If you would like to include options but not data, you need to explicitly
* call this function with `data` being an empty object or `null`.
*
* @param {String} path path to the EJS file
* @param {Object} [data={}] template data
* @param {Options} [opts={}] compilation and rendering options
* @param {RenderFileCallback} cb callback
* @public
*/
ejs.renderFile = function() {
let args = Array.prototype.slice.call(arguments);
let filename = args.shift();
let cb;
let opts = { filename };
let data;
let viewOpts;
if (typeof arguments[arguments.length - 1] == "function") cb = args.pop();
if (args.length) {
data = args.shift();
if (args.length) utils.shallowCopy(opts, args.pop());
else {
if (utils.hasOwn(data, "settings") && data.settings) {
if (data.settings.views) opts.views = data.settings.views;
if (data.settings["view cache"]) opts.cache = true;
viewOpts = data.settings["view options"];
if (viewOpts) utils.shallowCopy(opts, viewOpts);
}
utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA_EXPRESS);
}
opts.filename = filename;
} else data = utils.createNullProtoObjWherePossible();
return tryHandleCache(opts, data, cb);
};
/**
* Clear intermediate JavaScript cache. Calls {@link Cache#reset}.
* @public
*/
/**
* EJS template class
* @public
*/
ejs.Template = Template;
ejs.clearCache = function() {
ejs.cache.reset();
};
function Template(text, optsParam) {
let opts = utils.hasOwnOnlyObject(optsParam);
let options = utils.createNullProtoObjWherePossible();
this.templateText = text;
/** @type {string | null} */
this.mode = null;
this.truncate = false;
this.currentLine = 1;
this.source = "";
options.escapeFunction = opts.escape || opts.escapeFunction || utils.escapeXML;
options.compileDebug = opts.compileDebug !== false;
options.debug = !!opts.debug;
options.filename = opts.filename;
options.openDelimiter = opts.openDelimiter || ejs.openDelimiter || _DEFAULT_OPEN_DELIMITER;
options.closeDelimiter = opts.closeDelimiter || ejs.closeDelimiter || _DEFAULT_CLOSE_DELIMITER;
options.delimiter = opts.delimiter || ejs.delimiter || _DEFAULT_DELIMITER;
options.strict = opts.strict || false;
options.context = opts.context;
options.cache = opts.cache || false;
options.rmWhitespace = opts.rmWhitespace;
options.root = opts.root;
options.includer = opts.includer;
options.outputFunctionName = opts.outputFunctionName;
options.localsName = opts.localsName || ejs.localsName || _DEFAULT_LOCALS_NAME;
options.views = opts.views;
options.async = opts.async;
options.destructuredLocals = opts.destructuredLocals;
options.legacyInclude = typeof opts.legacyInclude != "undefined" ? !!opts.legacyInclude : true;
options.unsafePrototypeLocals = !!opts.unsafePrototypeLocals;
if (options.strict) options._with = false;
else options._with = typeof opts._with != "undefined" ? opts._with : true;
this.opts = options;
this.regex = this.createRegex();
}
Template.modes = {
EVAL: "eval",
ESCAPED: "escaped",
RAW: "raw",
COMMENT: "comment",
LITERAL: "literal"
};
Template.prototype = {
createRegex: function() {
let str = _REGEX_STRING;
let delim = utils.escapeRegExpChars(this.opts.delimiter);
let open = utils.escapeRegExpChars(this.opts.openDelimiter);
let close = utils.escapeRegExpChars(this.opts.closeDelimiter);
str = str.replace(/%/g, delim).replace(/</g, open).replace(/>/g, close);
return new RegExp(str);
},
compile: function() {
/** @type {string} */
let src;
let fn;
let opts = this.opts;
let prepended = "";
let appended = "";
/** @type {EscapeCallback} */
let escapeFn = opts.escapeFunction;
/** @type {FunctionConstructor} */
let ctor;
/** @type {string} */
let sanitizedFilename = opts.filename ? JSON.stringify(opts.filename) : "undefined";
if (!this.source) {
this.generateSource();
prepended += ` ${DECLARATION_KEYWORD} __output = "";\n function __append(s) { if (s !== undefined && s !== null) __output += s }
`;
if (opts.outputFunctionName) {
if (!_JS_IDENTIFIER.test(opts.outputFunctionName)) throw new Error("outputFunctionName is not a valid JS identifier.");
prepended += ` ${DECLARATION_KEYWORD} ` + opts.outputFunctionName + " = __append;\n";
}
if (opts.localsName && !_JS_IDENTIFIER.test(opts.localsName)) throw new Error("localsName is not a valid JS identifier.");
if (opts.destructuredLocals && opts.destructuredLocals.length) {
let destructuring = ` ${DECLARATION_KEYWORD} __locals = (` + opts.localsName + " || {}),\n";
for (let i = 0; i < opts.destructuredLocals.length; i++) {
let name = opts.destructuredLocals[i];
if (!_JS_IDENTIFIER.test(name)) throw new Error("destructuredLocals[" + i + "] is not a valid JS identifier.");
if (i > 0) destructuring += ",\n ";
destructuring += name + " = __locals." + name;
}
prepended += destructuring + ";\n";
}
if (opts._with !== false) {
prepended += " with (" + opts.localsName + " || {}) {\n";
appended += " }\n";
}
appended += " return __output;\n";
this.source = prepended + this.source + appended;
}
if (opts.compileDebug) src = `${DECLARATION_KEYWORD} __line = 1
, __lines = ` + JSON.stringify(this.templateText) + "\n , __filename = " + sanitizedFilename + ";\ntry {\n" + this.source + "} catch (e) {\n rethrow(e, __lines, __filename, __line, escapeFn);\n}\n";
else src = this.source;
if (opts.strict) src = "\"use strict\";\n" + src;
if (opts.debug) console.log(src);
if (opts.compileDebug && opts.filename) src = src + "\n//# sourceURL=" + sanitizedFilename + "\n";
try {
if (opts.async) try {
ctor = new Function("return (async function(){}).constructor;")();
} catch (e) {
if (e instanceof SyntaxError) throw new Error("This environment does not support async/await");
else throw e;
}
else ctor = Function;
fn = new ctor(opts.localsName + ", escapeFn, include, rethrow", src);
} catch (e) {
// istanbul ignore else
if (e instanceof SyntaxError) {
if (opts.filename) e.message += " in " + opts.filename;
e.message += " while compiling ejs\n\n";
e.message += "If the above error is not helpful, you may want to try EJS-Lint:\n";
e.message += "https://github.com/RyanZim/EJS-Lint";
if (!opts.async) {
e.message += "\n";
e.message += "Or, if you meant to create an async function, pass `async: true` as an option.";
}
}
throw e;
}
let returnedFn = function anonymous(data) {
let include = function(path, includeData) {
let d = utils.shallowCopy(utils.createNullProtoObjWherePossible(), data);
if (includeData) d = utils.shallowCopy(d, includeData);
return includeFile(path, opts)(d);
};
let locals;
if (opts.unsafePrototypeLocals) locals = data || utils.createNullProtoObjWherePossible();
else locals = utils.shallowCopy(utils.createNullProtoObjWherePossible(), data);
return fn.apply(opts.context, [
locals,
escapeFn,
include,
rethrow
]);
};
if (opts.filename && typeof Object.defineProperty === "function") {
let filename = opts.filename;
let basename = path.basename(filename, path.extname(filename));
try {
Object.defineProperty(returnedFn, "name", {
value: basename,
writable: false,
enumerable: false,
configurable: true
});
} catch (e) {}
}
return returnedFn;
},
generateSource: function() {
if (this.opts.rmWhitespace) this.templateText = this.templateText.replace(/[\r\n]+/g, "\n").replace(/^\s+|\s+$/gm, "");
let self = this;
let d = this.opts.delimiter;
let o = this.opts.openDelimiter;
let c = this.opts.closeDelimiter;
let openWhitespaceSlurpTag = utils.escapeRegExpChars(o + d + "_");
let closeWhitespaceSlurpTag = utils.escapeRegExpChars("_" + d + c);
let openWhitespaceSlurpReplacement = o + d + "_";
let closeWhitespaceSlurpReplacement = "_" + d + c;
this.templateText = this.templateText.replace(new RegExp("[ \\t]*" + openWhitespaceSlurpTag, "gm"), openWhitespaceSlurpReplacement).replace(new RegExp(closeWhitespaceSlurpTag + "[ \\t]*", "gm"), closeWhitespaceSlurpReplacement);
let matches = this.parseTemplateText();
if (matches && matches.length) matches.forEach(function(line, index) {
let closing;
if (line.indexOf(o + d) === 0 && line.indexOf(o + d + d) !== 0) {
closing = matches[index + 2];
if (!(closing == d + c || closing == "-" + d + c || closing == "_" + d + c)) throw new Error("Could not find matching close tag for \"" + line + "\".");
}
self.scanLine(line);
});
},
parseTemplateText: function() {
let str = this.templateText;
let pat = this.regex;
let result = pat.exec(str);
let arr = [];
let firstPos;
while (result) {
firstPos = result.index;
if (firstPos !== 0) {
arr.push(str.substring(0, firstPos));
str = str.slice(firstPos);
}
arr.push(result[0]);
str = str.slice(result[0].length);
result = pat.exec(str);
}
if (str) arr.push(str);
return arr;
},
_addOutput: function(line) {
if (this.truncate) {
line = line.replace(/^(?:\r\n|\r|\n)/, "");
this.truncate = false;
}
if (!line) return line;
line = line.replace(/\\/g, "\\\\");
line = line.replace(/\n/g, "\\n");
line = line.replace(/\r/g, "\\r");
line = line.replace(/"/g, "\\\"");
this.source += " ; __append(\"" + line + "\")\n";
},
scanLine: function(line) {
let self = this;
let d = this.opts.delimiter;
let o = this.opts.openDelimiter;
let c = this.opts.closeDelimiter;
let newLineCount = 0;
newLineCount = line.split("\n").length - 1;
switch (line) {
case o + d:
case o + d + "_":
this.mode = Template.modes.EVAL;
break;
case o + d + "=":
this.mode = Template.modes.ESCAPED;
break;
case o + d + "-":
this.mode = Template.modes.RAW;
break;
case o + d + "#":
this.mode = Template.modes.COMMENT;
break;
case o + d + d:
this.mode = Template.modes.LITERAL;
this.source += " ; __append(\"" + line.replace(o + d + d, o + d) + "\")\n";
break;
case d + d + c:
this.mode = Template.modes.LITERAL;
this.source += " ; __append(\"" + line.replace(d + d + c, d + c) + "\")\n";
break;
case d + c:
case "-" + d + c:
case "_" + d + c:
if (this.mode == Template.modes.LITERAL) this._addOutput(line);
this.mode = null;
this.truncate = line.indexOf("-") === 0 || line.indexOf("_") === 0;
break;
default: if (this.mode) {
switch (this.mode) {
case Template.modes.EVAL:
case Template.modes.ESCAPED:
case Template.modes.RAW: if (line.lastIndexOf("//") > line.lastIndexOf("\n")) line += "\n";
}
switch (this.mode) {
case Template.modes.EVAL:
this.source += " ; " + line + "\n";
break;
case Template.modes.ESCAPED:
this.source += " ; __append(escapeFn(" + stripSemi(line) + "))\n";
break;
case Template.modes.RAW:
this.source += " ; __append(" + stripSemi(line) + ")\n";
break;
case Template.modes.COMMENT: break;
case Template.modes.LITERAL:
this._addOutput(line);
break;
}
} else this._addOutput(line);
}
if (self.opts.compileDebug && newLineCount) {
this.currentLine += newLineCount;
this.source += " ; __line = " + this.currentLine + "\n";
}
}
};
/**
* Escape characters reserved in XML.
*
* This is simply an export of {@link module:utils.escapeXML}.
*
* If `markup` is `undefined` or `null`, the empty string is returned.
*
* @param {String} markup Input string
* @return {String} Escaped string
* @public
* @func
* */
ejs.escapeXML = utils.escapeXML;
/**
* Express.js support.
*
* This is an alias for {@link module:ejs.renderFile}, in order to support
* Express.js out-of-the-box.
*
* @func
*/
ejs.__express = ejs.renderFile;
/* istanbul ignore if */
if (typeof window != "undefined") window.ejs = ejs;
//#endregion
//#region utils/banners.ts
const defaultBanner = "Vue.js - The Progressive JavaScript Framework";
const gradientBanner = "\x1B[38;2;66;211;146mV\x1B[39m\x1B[38;2;66;211;146mu\x1B[39m\x1B[38;2;66;211;146me\x1B[39m\x1B[38;2;66;211;146m.\x1B[39m\x1B[38;2;66;211;146mj\x1B[39m\x1B[38;2;67;209;149ms\x1B[39m \x1B[38;2;68;206;152m-\x1B[39m \x1B[38;2;69;204;155mT\x1B[39m\x1B[38;2;70;201;158mh\x1B[39m\x1B[38;2;71;199;162me\x1B[39m \x1B[38;2;72;196;165mP\x1B[39m\x1B[38;2;73;194;168mr\x1B[39m\x1B[38;2;74;192;171mo\x1B[39m\x1B[38;2;75;189;174mg\x1B[39m\x1B[38;2;76;187;177mr\x1B[39m\x1B[38;2;77;184;180me\x1B[39m\x1B[38;2;78;182;183ms\x1B[39m\x1B[38;2;79;179;186ms\x1B[39m\x1B[38;2;80;177;190mi\x1B[39m\x1B[38;2;81;175;193mv\x1B[39m\x1B[38;2;82;172;196me\x1B[39m \x1B[38;2;83;170;199mJ\x1B[39m\x1B[38;2;83;167;202ma\x1B[39m\x1B[38;2;84;165;205mv\x1B[39m\x1B[38;2;85;162;208ma\x1B[39m\x1B[38;2;86;160;211mS\x1B[39m\x1B[38;2;87;158;215mc\x1B[39m\x1B[38;2;88;155;218mr\x1B[39m\x1B[38;2;89;153;221mi\x1B[39m\x1B[38;2;90;150;224mp\x1B[39m\x1B[38;2;91;148;227mt\x1B[39m \x1B[38;2;92;145;230mF\x1B[39m\x1B[38;2;93;143;233mr\x1B[39m\x1B[38;2;94;141;236ma\x1B[39m\x1B[38;2;95;138;239mm\x1B[39m\x1B[38;2;96;136;243me\x1B[39m\x1B[38;2;97;133;246mw\x1B[39m\x1B[38;2;98;131;249mo\x1B[39m\x1B[38;2;99;128;252mr\x1B[39m\x1B[38;2;100;126;255mk\x1B[39m";
//#endregion
//#region utils/deepMerge.ts
const isObject = (val) => val && typeof val === "object";
const mergeArrayWithDedupe = (a, b) => Array.from(/* @__PURE__ */ new Set([...a, ...b]));
/**
* Recursively merge the content of the new object to the existing one
* @param {Object} target the existing object
* @param {Object} obj the new object
*/
function deepMerge(target, obj) {
for (const key of Object.keys(obj)) {
const oldVal = target[key];
const newVal = obj[key];
if (Array.isArray(oldVal) && Array.isArray(newVal)) target[key] = mergeArrayWithDedupe(oldVal, newVal);
else if (isObject(oldVal) && isObject(newVal)) target[key] = deepMerge(oldVal, newVal);
else target[key] = newVal;
}
return target;
}
//#endregion
//#region utils/sortDependencies.ts
function sortDependencies(packageJson) {
const sorted = {};
for (const depType of [
"dependencies",
"devDependencies",
"peerDependencies",
"optionalDependencies"
]) if (packageJson[depType]) {
sorted[depType] = {};
Object.keys(packageJson[depType]).sort().forEach((name) => {
sorted[depType][name] = packageJson[depType][name];
});
}
return {
...packageJson,
...sorted
};
}
//#endregion
//#region utils/renderTemplate.ts
/**
* Renders a template folder/file to the file system,
* by recursively copying all files under the `src` directory,
* with the following exception:
* - `_filename` should be renamed to `.filename`
* - Fields in `package.json` should be recursively merged
* @param {string} src source filename to copy
* @param {string} dest destination filename of the copy operation
*/
function renderTemplate(src, dest, callbacks) {
if (fs$1.statSync(src).isDirectory()) {
if (path$2.basename(src) === "node_modules") return;
fs$1.mkdirSync(dest, { recursive: true });
for (const file of fs$1.readdirSync(src)) renderTemplate(path$2.resolve(src, file), path$2.resolve(dest, file), callbacks);
return;
}
const filename = path$2.basename(src);
if (filename === "package.json" && fs$1.existsSync(dest)) {
const pkg = sortDependencies(deepMerge(JSON.parse(fs$1.readFileSync(dest, "utf8")), JSON.parse(fs$1.readFileSync(src, "utf8"))));
fs$1.writeFileSync(dest, JSON.stringify(pkg, null, 2) + "\n");
return;
}
if (filename === "extensions.json" && fs$1.existsSync(dest)) {
const extensions = deepMerge(JSON.parse(fs$1.readFileSync(dest, "utf8")), JSON.parse(fs$1.readFileSync(src, "utf8")));
fs$1.writeFileSync(dest, JSON.stringify(extensions, null, 2) + "\n");
return;
}
if (filename === "settings.json" && fs$1.existsSync(dest)) {
const settings = deepMerge(JSON.parse(fs$1.readFileSync(dest, "utf8")), JSON.parse(fs$1.readFileSync(src, "utf8")));
fs$1.writeFileSync(dest, JSON.stringify(settings, null, 2) + "\n");
return;
}
if (filename.startsWith("_")) dest = path$2.resolve(path$2.dirname(dest), filename.replace(/^_/, "."));
if (filename === "_gitignore" && fs$1.existsSync(dest)) {
const existing = fs$1.readFileSync(dest, "utf8");
const newGitignore = fs$1.readFileSync(src, "utf8");
fs$1.writeFileSync(dest, existing + "\n" + newGitignore);
return;
}
if (filename.endsWith(".data.mjs")) {
dest = dest.replace(/\.data\.mjs$/, "");
callbacks.push(async (dataStore) => {
const getData = (await import(pathToFileURL(src).toString())).default;
dataStore[dest] = await getData({ oldData: dataStore[dest] || {} });
});
return;
}
fs$1.copyFileSync(src, dest);
}
//#endregion
//#region utils/directoryTraverse.ts
function preOrderDirectoryTraverse(dir, dirCallback, fileCallback) {
for (const filename of fs$1.readdirSync(dir)) {
if (filename === ".git") continue;
const fullpath = path$2.resolve(dir, filename);
if (fs$1.lstatSync(fullpath).isDirectory()) {
dirCallback(fullpath);
if (fs$1.existsSync(fullpath)) preOrderDirectoryTraverse(fullpath, dirCallback, fileCallback);
continue;
}
fileCallback(fullpath);
}
}
const dotGitDirectoryState = { hasDotGitDirectory: false };
function postOrderDirectoryTraverse(dir, dirCallback, fileCallback) {
for (const filename of fs$1.readdirSync(dir)) {
if (filename === ".git") {
dotGitDirectoryState.hasDotGitDirectory = true;
continue;
}
const fullpath = path$2.resolve(dir, filename);
if (fs$1.lstatSync(fullpath).isDirectory()) {
postOrderDirectoryTraverse(fullpath, dirCallback, fileCallback);
dirCallback(fullpath);
continue;
}
fileCallback(fullpath);
}
}
//#endregion
//#region utils/getCommand.ts
function getCommand(packageManager, scriptName, args) {
if (scriptName === "install") return packageManager === "yarn" ? "yarn" : `${packageManager} install`;
if (scriptName === "build") return packageManager === "npm" || packageManager === "bun" || packageManager === "nub" ? `${packageManager} run build` : `${packageManager} build`;
if (args) return packageManager === "npm" || packageManager === "nub" ? `${packageManager} run ${scriptName} -- ${args}` : `${packageManager} ${scriptName} ${args}`;
else return packageManager === "npm" || packageManager === "nub" ? `${packageManager} run ${scriptName}` : `${packageManager} ${scriptName}`;
}
//#endregion
//#region utils/generateReadme.ts
const sfcTypeSupportDoc = [
"",
"## Type Support for `.vue` Imports in TS",
"",
"TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.",
""
].join("\n");
function generateReadme({ projectName, packageManager, needsTypeScript, needsCypress, needsCypressCT, needsPlaywright, needsVitest, needsEslint }) {
const commandFor = (scriptName, args) => getCommand(packageManager, scriptName, args);
let readme = `# ${projectName}
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VS Code](https://code.visualstudio.com/) + [Vue (Official)](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
## Recommended Browser Setup
- Chromium-based browsers (Chrome, Edge, Brave, etc.):
- [Vue.js devtools](https://chromewebstore.google.com/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd)
- [Turn on Custom Object Formatter in Chrome DevTools](http://bit.ly/object-formatters)
- Firefox:
- [Vue.js devtools](https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/)
- [Turn on Custom Object Formatter in Firefox DevTools](https://fxdx.dev/firefox-devtools-custom-object-formatters/)
${needsTypeScript ? sfcTypeSupportDoc : ""}
## Customize configuration
See [Vite Configuration Reference](https://vite.dev/config/).
## Project Setup
`;
let npmScriptsDescriptions = `\`\`\`sh
${commandFor("install")}
\`\`\`
### Compile and Hot-Reload for Development
\`\`\`sh
${commandFor("dev")}
\`\`\`
### ${needsTypeScript ? "Type-Check, " : ""}Compile and Minify for Production
\`\`\`sh
${commandFor("build")}
\`\`\`
`;
if (needsVitest) npmScriptsDescriptions += `
### Run Unit Tests with [Vitest](https://vitest.dev/)
\`\`\`sh
${commandFor("test:unit")}
\`\`\`
`;
if (needsCypressCT) npmScriptsDescriptions += `
### Run Headed Component Tests with [Cypress Component Testing](https://on.cypress.io/component)
\`\`\`sh
${commandFor("test:unit:dev")} # or \`${commandFor("test:unit")}\` for headless testing
\`\`\`
`;
if (needsCypress) npmScriptsDescriptions += `
### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
\`\`\`sh
${commandFor("test:e2e:dev")}
\`\`\`
This runs the end-to-end tests against the Vite development server.
It is much faster than the production build.
But it's still recommended to test the production build with \`test:e2e\` before deploying (e.g. in CI environments):
\`\`\`sh
${commandFor("build")}
${commandFor("test:e2e")}
\`\`\`
`;
if (needsPlaywright) npmScriptsDescriptions += `
### Run End-to-End Tests with [Playwright](https://playwright.dev)
\`\`\`sh
# Install browsers for the first run
npx playwright install
# When testing on CI, must build the project first
${commandFor("build")}
# Runs the end-to-end tests
${commandFor("test:e2e")}
# Runs the tests only on Chromium
${commandFor("test:e2e", "--project=chromium")}
# Runs the tests of a specific file
${commandFor("test:e2e", "tests/example.spec.ts")}
# Runs the tests in debug mode
${commandFor("test:e2e", "--debug")}
\`\`\`
`;
if (needsEslint) npmScriptsDescriptions += `
### Lint with [ESLint](https://eslint.org/)
\`\`\`sh
${commandFor("lint")}
\`\`\`
`;
readme += npmScriptsDescriptions;
return readme;
}
//#endregion
//#region utils/getLanguage.ts
/**
*
* This function is used to link obtained locale with correct locale file in order to make locales reusable
*
* @param locale the obtained locale
* @returns locale that linked with correct name
*/
function linkLocale(locale) {
if (locale === "C") return "en-US";
let linkedLocale;
try {
linkedLocale = Intl.getCanonicalLocales(locale)[0];
} catch (error) {
console.log(`${error.toString()}, invalid language tag: "${locale}"\n`);
}
switch (linkedLocale) {
case "zh-TW":
case "zh-HK":
case "zh-MO":
linkedLocale = "zh-Hant";
break;
case "zh-CN":
case "zh-SG":
linkedLocale = "zh-Hans";
break;
default: linkedLocale = locale;
}
return linkedLocale;
}
function getLocale() {
return linkLocale((process.env.LC_ALL || process.env.LC_MESSAGES || process.env.LANG || Intl.DateTimeFormat().resolvedOptions().locale || "en-US").split(".")[0].replace("_", "-"));
}
async function loadLanguageFile(filePath) {
return await fs$1.promises.readFile(filePath, "utf-8").then((data) => {
const parsedData = JSON.parse(data);
if (parsedData) return parsedData;
});
}
async function getLanguage(localesRoot) {
const locale = getLocale();
const languageFilePath = path$2.resolve(localesRoot, `${locale}.json`);
const fallbackPath = path$2.resolve(localesRoot, "en-US.json");
return fs$1.existsSync(languageFilePath) ? await loadLanguageFile(languageFilePath) : await loadLanguageFile(fallbackPath);
}
//#endregion
//#region utils/trimBoilerplate.ts
function replaceContent(filepath, replacer) {
const content = fs$1.readFileSync(filepath, "utf8");
fs$1.writeFileSync(filepath, replacer(content));
}
function trimBoilerplate(rootDir) {
const srcDir = path$1.resolve(rootDir, "src");
for (const filename of fs$1.readdirSync(srcDir)) {
if ([
"main.js",
"main.ts",
"router",
"stores"
].includes(filename)) continue;
const fullpath = path$1.resolve(srcDir, filename);
fs$1.rmSync(fullpath, { recursive: true });
}
}
function removeCSSImport(rootDir, needsTypeScript, needsCypressCT) {
replaceContent(path$1.resolve(rootDir, needsTypeScript ? "src/main.ts" : "src/main.js"), (content) => content.replace("import './assets/main.css'\n\n", ""));
if (needsCypressCT) replaceContent(path$1.resolve(rootDir, needsTypeScript ? "cypress/support/component.ts" : "cypress/support/component.js"), (content) => content.replace("import '@/assets/main.css'", "// import '@/assets/main.css'"));
}
function emptyRouterConfig(rootDir, needsTypeScript) {
const srcDir = path$1.resolve(rootDir, "src");
replaceContent(path$1.resolve(srcDir, needsTypeScript ? "router/index.ts" : "router/index.js"), (content) => content.replace(`import HomeView from '../views/HomeView.vue'\n`, "").replace(/routes:\s*\[[\s\S]*?\],/, "routes: [],"));
}
//#endregion
//#region utils/applyVueRc.ts
const CORE_VUE_PACKAGES = [
"vue",
"@vue/compiler-core",
"@vue/compiler-dom",
"@vue/compiler-sfc",
"@vue/compiler-ssr",
"@vue/compiler-vapor",
"@vue/reactivity",
"@vue/runtime-core",
"@vue/runtime-dom",
"@vue/runtime-vapor",
"@vue/server-renderer",
"@vue/shared",
"@vue/compat"
];
function generateOverridesMap() {
return Object.fromEntries(CORE_VUE_PACKAGES.map((name) => [name, "rc"]));
}
/**
* Apply Vue 3.6 release candidate overrides to the project based on the package manager.
* Different package managers have different mechanisms for version overrides:
* - npm/bun: uses `overrides` field in package.json
* - yarn: uses `resolutions` field in package.json
* - pnpm: uses `overrides` and `peerDependencyRules` in pnpm-workspace.yaml
* - nub: uses the neutral `overrides` field in package.json
*/
function applyVueRc(root, packageManager, pkg) {
const overrides = generateOverridesMap();
if (packageManager === "npm" || packageManager === "bun") {
pkg.overrides = {
...pkg.overrides,
...overrides
};
for (const dependencyName of CORE_VUE_PACKAGES) for (const dependencyType of [
"dependencies",
"devDependencies",
"optionalDependencies"
]) if (pkg[dependencyType]?.[dependencyName]) pkg[dependencyType][dependencyName] = overrides[dependencyName];
} else if (packageManager === "yarn") pkg.resolutions = {
...pkg.resolutions,
...overrides
};
else if (packageManager === "pnpm") {
const yamlContent = `overrides:
${Object.entries(overrides).map(([key, value]) => ` '${key}': '${value}'`).join("\n")}
peerDependencyRules:
allowAny:
- 'vue'
`;
fs$1.writeFileSync(path$2.resolve(root, "pnpm-workspace.yaml"), yamlContent, "utf-8");
} else if (packageManager === "nub") pkg.overrides = {
...pkg.overrides,
...overrides
};
}
//#endregion
//#region utils/packageManager.ts
/**
* Infers the package manager from the user agent string.
* Falls back to npm if unable to detect.
*/
function inferPackageManager() {
const userAgent = process.env.npm_config_user_agent ?? "";
if (/pnpm/.test(userAgent)) return "pnpm";
if (/yarn/.test(userAgent)) return "yarn";
if (/bun/.test(userAgent)) return "bun";
if (/nub/.test(userAgent)) return "nub";
return "npm";
}
/**
* Creates an ordered list of package managers with the preferred one first.
*/
function getPackageManagerOptions(preferred) {
return [preferred, ...[
"npm",
"pnpm",
"yarn",
"bun",
"nub"
].filter((pm) => pm !== preferred)];
}
//#endregion
//#region utils/resolveFeatures.ts
function resolveNeedsTypeScript(argv, promptedNeedsTypeScript) {
return Boolean(argv.default || argv.ts || argv.typescript || promptedNeedsTypeScript);
}
//#endregion
//#region package.json
var name = "create-vue";
var version = "3.23.0";
//#endregion
//#region index.ts
const language = await getLanguage(fileURLToPath(new URL("./locales", import.meta.url)));
const FEATURE_FLAGS = [
"default",
"ts",
"typescript",
"jsx",
"router",
"vue-router",
"pinia",
"tests",
"with-tests",
"vitest",
"cypress",
"playwright",
"eslint",
"prettier",
"eslint-with-prettier",
"oxlint",
"oxfmt",
"vue-rc",
"vue-beta"
];
const FEATURE_OPTIONS = [
{
value: "jsx",
label: language.needsJsx.message
},
{
value: "router",
label: language.needsRouter.message
},
{
value: "pinia",
label: language.needsPinia.message
},
{
value: "vitest",
label: language.needsVitest.message
},
{
value: "e2e",
label: language.needsE2eTesting.message
},
{
value: "eslint",
label: language.needsEslint.message
},
{
value: "prettier",
label: language.needsPrettier.message
}
];
const EXPERIMENTAL_FEATURE_OPTIONS = [{
value: "oxfmt",
label: language.needsOxfmt.message
}, {
value: "vue-rc",
label: language.needsVueRc.message
}];
function isValidPackageName(projectName) {
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(projectName);
}
function toValidPackageName(projectName) {
return projectName.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9-~]+/g, "-");
}
function canSkipEmptying(dir) {
if (!fs$1.existsSync(dir)) return true;
const files = fs$1.readdirSync(dir);
if (files.length === 0) return true;
if (files.length === 1 && files[0] === ".git") {
dotGitDirectoryState.hasDotGitDirectory = true;
return true;
}
return false;
}
function emptyDir(dir) {
if (!fs$1.existsSync(dir)) return;
postOrderDirectoryTraverse(dir, (dir) => fs$1.rmdirSync(dir), (file) => fs$1.unlinkSync(file));
}
async function unwrapPrompt(maybeCancelPromise) {
const result = await maybeCancelPromise;
if (isCancel(result)) {
cancel((0, import_picocolors.red)("✖") + ` ${language.errors.operationCancelled}`);
process.exit(0);
}
return result;
}
const helpMessage = `\
Usage: create-vue [FEATURE_FLAGS...] [OPTIONS...] [DIRECTORY]
Create a new Vue.js project.
Runs in interactive mode if started without feature flags, or if DIRECTORY is missing or not a valid package name.
Options:
--force
Create the project even if the directory is not empty.
--bare
Create a barebone project without example code.
--help
Display this help message.
--version
Display the version number of this CLI.
Available feature flags:
--default
Create a project with the default configuration without any additional features.
--ts, --typescript
Add TypeScript support.
--jsx
Add JSX support.
--router, --vue-router
Add Vue Router for SPA development.
--pinia
Add Pinia for state management.
--vitest
Add Vitest for unit testing.
--cypress
Add Cypress for end-to-end testing.
If used without ${(0, import_picocolors.cyan)("--vitest")}, it will also add Cypress Component Testing.
--playwright
Add Playwright for end-to-end testing.
--eslint
Add ESLint for code quality.
--prettier
Add Prettier for code formatting.
--oxfmt
Add Oxfmt for code formatting.
--vue-rc
Use Vue 3.6 Release Candidate. Requires specifying a package manager in interactive mode.
Unstable feature flags:
--tests, --with-tests
Add both unit testing and end-to-end testing support.
Currently equivalent to ${(0, import_picocolors.cyan)("--vitest --cypress")}, but may change in the future.
Deprecated feature flags:
--eslint-with-prettier
Please use ${(0, import_picocolors.cyan)("--eslint --prettier")} instead.
--oxlint
Oxlint is now always included when ESLint is selected.
`;
async function init() {
const cwd = process.cwd();
const args = process.argv.slice(2);
const flags = [
...FEATURE_FLAGS,
"force",
"bare",
"help",
"version"
];
const { values: argv, positionals } = parseArgs({
args,
options: Object.fromEntries(flags.map((key) => [key, { type: "boolean" }])),
strict: true,
allowPositionals: true
});
if (argv.help) {
console.log(helpMessage);
process.exit(0);
}
if (argv.version) {
console.log(`${name} v${version}`);
process.exit(0);
}
const isFeatureFlagsUsed = FEATURE_FLAGS.some((flag) => typeof argv[flag] === "boolean");
let targetDir = positionals[0];
const defaultProjectName = targetDir || "vue-project";
const forceOverwrite = argv.force;
const inferredPackageManager = inferPackageManager();
const result = {
projectName: defaultProjectName,
shouldOverwrite: forceOverwrite,
packageName: defaultProjectName,
features: [],
e2eFramework: void 0,
experimentFeatures: [],
needsBareboneTemplates: false
};
intro(process.stdout.isTTY && process.stdout.getColorDepth() > 8 ? gradientBanner : defaultBanner);
if (!targetDir) targetDir = result.projectName = result.packageName = (await unwrapPrompt(text({
message: language.projectName.message,
placeholder: defaultProjectName,
defaultValue: defaultProjectName,
validate: (value) => !value || value.trim().length > 0 ? void 0 : language.projectName.invalidMessage
})))?.trim() || defaultProjectName;
if (!canSkipEmptying(targetDir) && !forceOverwrite) {
result.shouldOverwrite = await unwrapPrompt(confirm({
message: `${targetDir === "." ? language.shouldOverwrite.dirForPrompts.current : `${language.shouldOverwrite.dirForPrompts.target} "${targetDir}"`} ${language.shouldOverwrite.message}`,
initialValue: false
}));
if (!result.shouldOverwrite) {
cancel((0, import_picocolors.red)("✖") + ` ${language.errors.operationCancelled}`);
process.exit(0);
}
}
if (!isValidPackageName(targetDir)) result.packageName = await unwrapPrompt(text({
message: language.packageName.message,
initialValue: toValidPackageName(targetDir),
validate: (value) => isValidPackageName(value) ? void 0 : language.packageName.invalidMessage
}));
if (!isFeatureFlagsUsed) {
result.needsTypeScript = await unwrapPrompt(confirm({
message: language.needsTypeScript.message,
initialValue: true
}));
result.features = await unwrapPrompt(multiselect({
message: `${language.featureSelection.message} ${(0, import_picocolors.dim)(language.featureSelection.hint)}`,
options: FEATURE_OPTIONS,
required: false
}));
if (result.features.includes("e2e")) {
const hasVitest = result.features.includes("vitest");
result.e2eFramework = await unwrapPrompt(select({
message: `${language.e2eSelection.message} ${(0, import_picocolors.dim)(language.e2eSelection.hint)}`,
options: [{
value: "playwright",
label: language.e2eSelection.selectOptions.playwright.title,
hint: language.e2eSelection.selectOptions.playwright.desc
}, {
value: "cypress",
label: language.e2eSelection.selectOptions.cypress.title,
hint: hasVitest ? language.e2eSelection.selectOptions.cypress.desc : language.e2eSelection.selectOptions.cypress.hintOnComponentTesting
}]
}));
}
result.experimentFeatures = await unwrapPrompt(multiselect({
message: `${language.needsExperimentalFeatures.message} ${(0, import_picocolors.dim)(language.needsExperimentalFeatures.hint)}`,
options: EXPERIMENTAL_FEATURE_OPTIONS,
required: false
}));
if (result.experimentFeatures.includes("vue-rc")) {
const packageManagerOptions = getPackageManagerOptions(inferredPackageManager).map((pm) => ({
value: pm,
label: pm
}));
result.packageManager = await unwrapPrompt(select({
message: `${language.packageManagerSelection.message} ${(0, import_picocolors.dim)(language.packageManagerSelection.hint)}`,
options: packageManagerOptions
}));
}
}
if (argv.bare) result.needsBareboneTemplates = true;
else if (!isFeatureFlagsUsed) result.needsBareboneTemplates = await unwrapPrompt(confirm({
message: language.needsBareboneTemplates.message,
initialValue: false
}));
const { features, experimentFeatures, needsBareboneTemplates } = result;
const needsTypeScript = resolveNeedsTypeScript(argv, result.needsTypeScript);
const needsJsx = argv.jsx || features.includes("jsx");
const needsRouter = argv.router || argv["vue-router"] || features.includes("router");
const needsPinia = argv.pinia || features.includes("pinia");
const needsVitest = argv.vitest || argv.tests || argv["with-tests"] || features.includes("vitest");
const needsEslint = argv.eslint || argv["eslint-with-prettier"] || features.includes("eslint");
const needsPrettier = argv.prettier || argv["eslint-with-prettier"] || features.includes("prettier");
const needsOxfmt = experimentFeatures.includes("oxfmt") || argv["oxfmt"];
const needsVueRc = experimentFeatures.includes("vue-rc") || argv["vue-rc"] || argv["vue-beta"];
const { e2eFramework } = result;
const needsCypress = argv.cypress || argv.tests || argv["with-tests"] || e2eFramework === "cypress";
const needsCypressCT = needsCypress && !needsVitest;
const needsPlaywright = argv.playwright || e2eFramework === "playwright";
const root = path$2.join(cwd, targetDir);
if (fs$1.existsSync(root) && result.shouldOverwrite) emptyDir(root);
else if (!fs$1.existsSync(root)) fs$1.mkdirSync(root);
console.log(`\n${language.infos.scaffolding} ${root}...`);
const pkg = {
name: result.packageName,
version: "0.0.0"
};
fs$1.writeFileSync(path$2.resolve(root, "package.json"), JSON.stringify(pkg, null, 2));
const templateRoot = fileURLToPath(new URL("./template", import.meta.url));
const callbacks = [];
const render = function render(templateName) {
renderTemplate(path$2.resolve(templateRoot, templateName), root, callbacks);
};
render("base");
if (needsJsx) render("config/jsx");
if (needsRouter) render("config/router");
if (needsPinia) render("config/pinia");
if (needsVitest) render("config/vitest");
if (needsCypress) render("config/cypress");
if (needsCypressCT) render("config/cypress-ct");
if (needsPlaywright) render("config/playwright");
if (needsTypeScript) {
render("config/typescript");
render("tsconfig/base");
const rootTsConfig = {
files: [],
references: [{ path: "./tsconfig.node.json" }, { path: "./tsconfig.app.json" }]
};
if (needsCypress) render("tsconfig/cypress");
if (needsCypressCT) {
render("tsconfig/cypress-ct");
rootTsConfig.references.push({ path: "./tsconfig.cypress-ct.json" });
}
if (needsPlaywright) render("tsconfig/playwright");
if (needsVitest) {
render("tsconfig/vitest");
rootTsConfig.references.push({ path: "./tsconfig.vitest.json" });
}
fs$1.writeFileSync(path$2.resolve(root, "tsconfig.json"), JSON.stringify(rootTsConfig, null, 2) + "\n", "utf-8");
}
if (needsEslint) {
render("linting/base");
if (needsTypeScript) render("linting/core/ts");
else render("linting/core/js");
if (needsCypress) render("linting/cypress");
if (needsCypressCT) render("linting/cypress-ct");
if (needsPlaywright) render("linting/playwright");
if (needsVitest) render("linting/vitest");
render("linting/oxlint");
callbacks.push(async (dataStore) => {
const oxlintrcPath = path$2.resolve(root, ".oxlintrc.json");
dataStore[oxlintrcPath] = {
needsTypeScript,
needsVitest
};
});
if (needsPrettier || needsOxfmt) render("linting/formatter");
}
if (needsOxfmt) render("formatting/oxfmt");
else if (needsPrettier) render("formatting/prettier");
render(`code/${(needsTypeScript ? "typescript-" : "") + (needsRouter ? "router" : "default")}`);
if (needsPinia && needsRouter) render("entry/router-and-pinia");
else if (needsPinia) render("entry/pinia");
else if (needsRouter) render("entry/router");
else render("entry/default");
const dataStore = {};
for (const cb of callbacks) await cb(dataStore);
preOrderDirectoryTraverse(root, () => {}, (filepath) => {
if (filepath.endsWith(".ejs")) {
const template = fs$1.readFileSync(filepath, "utf-8");
const dest = filepath.replace(/\.ejs$/, "");
const content = ejs.render(template, dataStore[dest]);
fs$1.writeFileSync(dest, content);
fs$1.unlinkSync(filepath);
}
});
if (needsBareboneTemplates) {
trimBoilerplate(root);
render("bare/base");
if (needsTypeScript) render("bare/typescript");
if (needsVitest) render("bare/vitest");
if (needsCypressCT) render("bare/cypress-ct");
}
if (needsTypeScript) {
preOrderDirectoryTraverse(root, () => {}, (filepath) => {
if (filepath.endsWith(".js")) {
const tsFilePath = filepath.replace(/\.js$/, ".ts");
if (fs$1.existsSync(tsFilePath)) fs$1.unlinkSync(filepath);
else fs$1.renameSync(filepath, tsFilePath);
} else if (path$2.basename(filepath) === "jsconfig.json") fs$1.unlinkSync(filepath);
});
const indexHtmlPath = path$2.resolve(root, "index.html");
const indexHtmlContent = fs$1.readFileSync(indexHtmlPath, "utf8");
fs$1.writeFileSync(indexHtmlPath, indexHtmlContent.replace("src/main.js", "src/main.ts"));
} else preOrderDirectoryTraverse(root, () => {}, (filepath) => {
if (filepath.endsWith(".ts")) fs$1.unlinkSync(filepath);
});
if (needsBareboneTemplates) {
removeCSSImport(root, needsTypeScript, needsCypressCT);
if (needsRouter) emptyRouterConfig(root, needsTypeScript);
}
const packageManager = result.packageManager ?? inferredPackageManager;
if (needsVueRc) {
const pkgPath = path$2.resolve(root, "package.json");
const pkg = JSON.parse(fs$1.readFileSync(pkgPath, "utf-8"));
applyVueRc(root, packageManager, pkg);
fs$1.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
}
fs$1.writeFileSync(path$2.resolve(root, "README.md"), generateReadme({
projectName: result.projectName ?? result.packageName ?? defaultProjectName,
packageManager,
needsTypeScript,
needsVitest,
needsCypress,
needsPlaywright,
needsCypressCT,
needsEslint
}));
let outroMessage = `${language.infos.done}\n\n`;
if (root !== cwd) {
const cdProjectName = path$2.relative(cwd, root);
outroMessage += ` ${(0, import_picocolors.bold)((0, import_picocolors.green)(`cd ${cdProjectName.includes(" ") ? `"${cdProjectName}"` : cdProjectName}`))}\n`;
}
outroMessage += ` ${(0, import_picocolors.bold)((0, import_picocolors.green)(getCommand(packageManager, "install")))}\n`;
if (needsPrettier || needsOxfmt) outroMessage += ` ${(0, import_picocolors.bold)((0, import_picocolors.green)(getCommand(packageManager, "format")))}\n`;
outroMessage += ` ${(0, import_picocolors.bold)((0, import_picocolors.green)(getCommand(packageManager, "dev")))}\n`;
if (!dotGitDirectoryState.hasDotGitDirectory) outroMessage += `
${(0, import_picocolors.dim)("|")} ${language.infos.optionalGitCommand}
${(0, import_picocolors.bold)((0, import_picocolors.green)("git init && git add -A && git commit -m \"initial commit\""))}`;
outro(outroMessage);
}
init().catch((e) => {
console.error(e);
process.exit(1);
});
//#endregion
export {};