superslate 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +63 -4
- package/README.md +34 -9
- package/dist/cli.js +2599 -206
- package/package.json +14 -11
package/dist/cli.js
CHANGED
|
@@ -1,15 +1,1691 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// @bun
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
function __accessProp(key) {
|
|
9
|
+
return this[key];
|
|
10
|
+
}
|
|
11
|
+
var __toESMCache_node;
|
|
12
|
+
var __toESMCache_esm;
|
|
13
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
+
var canCache = mod != null && typeof mod === "object";
|
|
15
|
+
if (canCache) {
|
|
16
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
+
var cached = cache.get(mod);
|
|
18
|
+
if (cached)
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
21
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
22
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
23
|
+
for (let key of __getOwnPropNames(mod))
|
|
24
|
+
if (!__hasOwnProp.call(to, key))
|
|
25
|
+
__defProp(to, key, {
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
27
|
+
enumerable: true
|
|
28
|
+
});
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
31
|
+
return to;
|
|
32
|
+
};
|
|
33
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
+
|
|
35
|
+
// node_modules/sisteransi/src/index.js
|
|
36
|
+
var require_src = __commonJS((exports, module) => {
|
|
37
|
+
var ESC2 = "\x1B";
|
|
38
|
+
var CSI2 = `${ESC2}[`;
|
|
39
|
+
var beep = "\x07";
|
|
40
|
+
var cursor = {
|
|
41
|
+
to(x, y) {
|
|
42
|
+
if (!y)
|
|
43
|
+
return `${CSI2}${x + 1}G`;
|
|
44
|
+
return `${CSI2}${y + 1};${x + 1}H`;
|
|
45
|
+
},
|
|
46
|
+
move(x, y) {
|
|
47
|
+
let ret = "";
|
|
48
|
+
if (x < 0)
|
|
49
|
+
ret += `${CSI2}${-x}D`;
|
|
50
|
+
else if (x > 0)
|
|
51
|
+
ret += `${CSI2}${x}C`;
|
|
52
|
+
if (y < 0)
|
|
53
|
+
ret += `${CSI2}${-y}A`;
|
|
54
|
+
else if (y > 0)
|
|
55
|
+
ret += `${CSI2}${y}B`;
|
|
56
|
+
return ret;
|
|
57
|
+
},
|
|
58
|
+
up: (count = 1) => `${CSI2}${count}A`,
|
|
59
|
+
down: (count = 1) => `${CSI2}${count}B`,
|
|
60
|
+
forward: (count = 1) => `${CSI2}${count}C`,
|
|
61
|
+
backward: (count = 1) => `${CSI2}${count}D`,
|
|
62
|
+
nextLine: (count = 1) => `${CSI2}E`.repeat(count),
|
|
63
|
+
prevLine: (count = 1) => `${CSI2}F`.repeat(count),
|
|
64
|
+
left: `${CSI2}G`,
|
|
65
|
+
hide: `${CSI2}?25l`,
|
|
66
|
+
show: `${CSI2}?25h`,
|
|
67
|
+
save: `${ESC2}7`,
|
|
68
|
+
restore: `${ESC2}8`
|
|
69
|
+
};
|
|
70
|
+
var scroll = {
|
|
71
|
+
up: (count = 1) => `${CSI2}S`.repeat(count),
|
|
72
|
+
down: (count = 1) => `${CSI2}T`.repeat(count)
|
|
73
|
+
};
|
|
74
|
+
var erase = {
|
|
75
|
+
screen: `${CSI2}2J`,
|
|
76
|
+
up: (count = 1) => `${CSI2}1J`.repeat(count),
|
|
77
|
+
down: (count = 1) => `${CSI2}J`.repeat(count),
|
|
78
|
+
line: `${CSI2}2K`,
|
|
79
|
+
lineEnd: `${CSI2}K`,
|
|
80
|
+
lineStart: `${CSI2}1K`,
|
|
81
|
+
lines(count) {
|
|
82
|
+
let clear = "";
|
|
83
|
+
for (let i = 0;i < count; i++)
|
|
84
|
+
clear += this.line + (i < count - 1 ? cursor.up() : "");
|
|
85
|
+
if (count)
|
|
86
|
+
clear += cursor.left;
|
|
87
|
+
return clear;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
module.exports = { cursor, scroll, erase, beep };
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// node_modules/@clack/core/dist/index.mjs
|
|
94
|
+
import { styleText } from "node:util";
|
|
95
|
+
import { stdout, stdin } from "node:process";
|
|
96
|
+
import * as l from "node:readline";
|
|
97
|
+
import l__default from "node:readline";
|
|
98
|
+
|
|
99
|
+
// node_modules/fast-string-truncated-width/dist/utils.js
|
|
100
|
+
var getCodePointsLength = (() => {
|
|
101
|
+
const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
102
|
+
return (input) => {
|
|
103
|
+
let surrogatePairsNr = 0;
|
|
104
|
+
SURROGATE_PAIR_RE.lastIndex = 0;
|
|
105
|
+
while (SURROGATE_PAIR_RE.test(input)) {
|
|
106
|
+
surrogatePairsNr += 1;
|
|
107
|
+
}
|
|
108
|
+
return input.length - surrogatePairsNr;
|
|
109
|
+
};
|
|
110
|
+
})();
|
|
111
|
+
var isFullWidth = (x) => {
|
|
112
|
+
return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
|
|
113
|
+
};
|
|
114
|
+
var isWideNotCJKTNotEmoji = (x) => {
|
|
115
|
+
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;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// node_modules/fast-string-truncated-width/dist/index.js
|
|
119
|
+
var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
|
|
120
|
+
var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
121
|
+
var CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu;
|
|
122
|
+
var TAB_RE = /\t{1,1000}/y;
|
|
123
|
+
var 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?))*/yu;
|
|
124
|
+
var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
|
|
125
|
+
var MODIFIER_RE = /\p{M}+/gu;
|
|
126
|
+
var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
|
|
127
|
+
var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
|
|
128
|
+
const LIMIT = truncationOptions.limit ?? Infinity;
|
|
129
|
+
const ELLIPSIS = truncationOptions.ellipsis ?? "";
|
|
130
|
+
const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
|
|
131
|
+
const ANSI_WIDTH = 0;
|
|
132
|
+
const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
|
|
133
|
+
const TAB_WIDTH = widthOptions.tabWidth ?? 8;
|
|
134
|
+
const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
|
|
135
|
+
const FULL_WIDTH_WIDTH = 2;
|
|
136
|
+
const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
|
|
137
|
+
const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
|
|
138
|
+
const PARSE_BLOCKS = [
|
|
139
|
+
[LATIN_RE, REGULAR_WIDTH],
|
|
140
|
+
[ANSI_RE, ANSI_WIDTH],
|
|
141
|
+
[CONTROL_RE, CONTROL_WIDTH],
|
|
142
|
+
[TAB_RE, TAB_WIDTH],
|
|
143
|
+
[EMOJI_RE, EMOJI_WIDTH],
|
|
144
|
+
[CJKT_WIDE_RE, WIDE_WIDTH]
|
|
145
|
+
];
|
|
146
|
+
let indexPrev = 0;
|
|
147
|
+
let index = 0;
|
|
148
|
+
let length = input.length;
|
|
149
|
+
let lengthExtra = 0;
|
|
150
|
+
let truncationEnabled = false;
|
|
151
|
+
let truncationIndex = length;
|
|
152
|
+
let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
|
|
153
|
+
let unmatchedStart = 0;
|
|
154
|
+
let unmatchedEnd = 0;
|
|
155
|
+
let width = 0;
|
|
156
|
+
let widthExtra = 0;
|
|
157
|
+
outer:
|
|
158
|
+
while (true) {
|
|
159
|
+
if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
|
|
160
|
+
const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
|
|
161
|
+
lengthExtra = 0;
|
|
162
|
+
for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
|
|
163
|
+
const codePoint = char.codePointAt(0) || 0;
|
|
164
|
+
if (isFullWidth(codePoint)) {
|
|
165
|
+
widthExtra = FULL_WIDTH_WIDTH;
|
|
166
|
+
} else if (isWideNotCJKTNotEmoji(codePoint)) {
|
|
167
|
+
widthExtra = WIDE_WIDTH;
|
|
168
|
+
} else {
|
|
169
|
+
widthExtra = REGULAR_WIDTH;
|
|
170
|
+
}
|
|
171
|
+
if (width + widthExtra > truncationLimit) {
|
|
172
|
+
truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
|
|
173
|
+
}
|
|
174
|
+
if (width + widthExtra > LIMIT) {
|
|
175
|
+
truncationEnabled = true;
|
|
176
|
+
break outer;
|
|
177
|
+
}
|
|
178
|
+
lengthExtra += char.length;
|
|
179
|
+
width += widthExtra;
|
|
180
|
+
}
|
|
181
|
+
unmatchedStart = unmatchedEnd = 0;
|
|
182
|
+
}
|
|
183
|
+
if (index >= length) {
|
|
184
|
+
break outer;
|
|
185
|
+
}
|
|
186
|
+
for (let i = 0, l = PARSE_BLOCKS.length;i < l; i++) {
|
|
187
|
+
const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];
|
|
188
|
+
BLOCK_RE.lastIndex = index;
|
|
189
|
+
if (BLOCK_RE.test(input)) {
|
|
190
|
+
lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
|
|
191
|
+
widthExtra = lengthExtra * BLOCK_WIDTH;
|
|
192
|
+
if (width + widthExtra > truncationLimit) {
|
|
193
|
+
truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
|
|
194
|
+
}
|
|
195
|
+
if (width + widthExtra > LIMIT) {
|
|
196
|
+
truncationEnabled = true;
|
|
197
|
+
break outer;
|
|
198
|
+
}
|
|
199
|
+
width += widthExtra;
|
|
200
|
+
unmatchedStart = indexPrev;
|
|
201
|
+
unmatchedEnd = index;
|
|
202
|
+
index = indexPrev = BLOCK_RE.lastIndex;
|
|
203
|
+
continue outer;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
index += 1;
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
width: truncationEnabled ? truncationLimit : width,
|
|
210
|
+
index: truncationEnabled ? truncationIndex : length,
|
|
211
|
+
truncated: truncationEnabled,
|
|
212
|
+
ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
var dist_default = getStringTruncatedWidth;
|
|
216
|
+
|
|
217
|
+
// node_modules/fast-string-width/dist/index.js
|
|
218
|
+
var NO_TRUNCATION2 = {
|
|
219
|
+
limit: Infinity,
|
|
220
|
+
ellipsis: "",
|
|
221
|
+
ellipsisWidth: 0
|
|
222
|
+
};
|
|
223
|
+
var fastStringWidth = (input, options = {}) => {
|
|
224
|
+
return dist_default(input, NO_TRUNCATION2, options).width;
|
|
225
|
+
};
|
|
226
|
+
var dist_default2 = fastStringWidth;
|
|
227
|
+
|
|
228
|
+
// node_modules/fast-wrap-ansi/lib/main.js
|
|
229
|
+
var ESC = "\x1B";
|
|
230
|
+
var CSI = "";
|
|
231
|
+
var END_CODE = 39;
|
|
232
|
+
var ANSI_ESCAPE_BELL = "\x07";
|
|
233
|
+
var ANSI_CSI = "[";
|
|
234
|
+
var ANSI_OSC = "]";
|
|
235
|
+
var ANSI_SGR_TERMINATOR = "m";
|
|
236
|
+
var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
237
|
+
var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
|
|
238
|
+
var getClosingCode = (openingCode) => {
|
|
239
|
+
if (openingCode >= 30 && openingCode <= 37)
|
|
240
|
+
return 39;
|
|
241
|
+
if (openingCode >= 90 && openingCode <= 97)
|
|
242
|
+
return 39;
|
|
243
|
+
if (openingCode >= 40 && openingCode <= 47)
|
|
244
|
+
return 49;
|
|
245
|
+
if (openingCode >= 100 && openingCode <= 107)
|
|
246
|
+
return 49;
|
|
247
|
+
if (openingCode === 1 || openingCode === 2)
|
|
248
|
+
return 22;
|
|
249
|
+
if (openingCode === 3)
|
|
250
|
+
return 23;
|
|
251
|
+
if (openingCode === 4)
|
|
252
|
+
return 24;
|
|
253
|
+
if (openingCode === 7)
|
|
254
|
+
return 27;
|
|
255
|
+
if (openingCode === 8)
|
|
256
|
+
return 28;
|
|
257
|
+
if (openingCode === 9)
|
|
258
|
+
return 29;
|
|
259
|
+
if (openingCode === 0)
|
|
260
|
+
return 0;
|
|
261
|
+
return;
|
|
262
|
+
};
|
|
263
|
+
var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
|
|
264
|
+
var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
|
|
265
|
+
var wrapWord = (rows, word, columns) => {
|
|
266
|
+
const characters = word[Symbol.iterator]();
|
|
267
|
+
let isInsideEscape = false;
|
|
268
|
+
let isInsideLinkEscape = false;
|
|
269
|
+
let lastRow = rows.at(-1);
|
|
270
|
+
let visible = lastRow === undefined ? 0 : dist_default2(lastRow);
|
|
271
|
+
let currentCharacter = characters.next();
|
|
272
|
+
let nextCharacter = characters.next();
|
|
273
|
+
let rawCharacterIndex = 0;
|
|
274
|
+
while (!currentCharacter.done) {
|
|
275
|
+
const character = currentCharacter.value;
|
|
276
|
+
const characterLength = dist_default2(character);
|
|
277
|
+
if (visible + characterLength <= columns) {
|
|
278
|
+
rows[rows.length - 1] += character;
|
|
279
|
+
} else {
|
|
280
|
+
rows.push(character);
|
|
281
|
+
visible = 0;
|
|
282
|
+
}
|
|
283
|
+
if (character === ESC || character === CSI) {
|
|
284
|
+
isInsideEscape = true;
|
|
285
|
+
isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
|
|
286
|
+
}
|
|
287
|
+
if (isInsideEscape) {
|
|
288
|
+
if (isInsideLinkEscape) {
|
|
289
|
+
if (character === ANSI_ESCAPE_BELL) {
|
|
290
|
+
isInsideEscape = false;
|
|
291
|
+
isInsideLinkEscape = false;
|
|
292
|
+
}
|
|
293
|
+
} else if (character === ANSI_SGR_TERMINATOR) {
|
|
294
|
+
isInsideEscape = false;
|
|
295
|
+
}
|
|
296
|
+
} else {
|
|
297
|
+
visible += characterLength;
|
|
298
|
+
if (visible === columns && !nextCharacter.done) {
|
|
299
|
+
rows.push("");
|
|
300
|
+
visible = 0;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
currentCharacter = nextCharacter;
|
|
304
|
+
nextCharacter = characters.next();
|
|
305
|
+
rawCharacterIndex += character.length;
|
|
306
|
+
}
|
|
307
|
+
lastRow = rows.at(-1);
|
|
308
|
+
if (!visible && lastRow !== undefined && lastRow.length && rows.length > 1) {
|
|
309
|
+
rows[rows.length - 2] += rows.pop();
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
var stringVisibleTrimSpacesRight = (string) => {
|
|
313
|
+
const words = string.split(" ");
|
|
314
|
+
let last = words.length;
|
|
315
|
+
while (last) {
|
|
316
|
+
if (dist_default2(words[last - 1])) {
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
last--;
|
|
320
|
+
}
|
|
321
|
+
if (last === words.length) {
|
|
322
|
+
return string;
|
|
323
|
+
}
|
|
324
|
+
return words.slice(0, last).join(" ") + words.slice(last).join("");
|
|
325
|
+
};
|
|
326
|
+
var exec = (string, columns, options = {}) => {
|
|
327
|
+
if (options.trim !== false && string.trim() === "") {
|
|
328
|
+
return "";
|
|
329
|
+
}
|
|
330
|
+
let returnValue = "";
|
|
331
|
+
let escapeCode;
|
|
332
|
+
let escapeUrl;
|
|
333
|
+
const words = string.split(" ");
|
|
334
|
+
let rows = [""];
|
|
335
|
+
let rowLength = 0;
|
|
336
|
+
for (let index = 0;index < words.length; index++) {
|
|
337
|
+
const word = words[index];
|
|
338
|
+
if (options.trim !== false) {
|
|
339
|
+
const row = rows.at(-1) ?? "";
|
|
340
|
+
const trimmed = row.trimStart();
|
|
341
|
+
if (row.length !== trimmed.length) {
|
|
342
|
+
rows[rows.length - 1] = trimmed;
|
|
343
|
+
rowLength = dist_default2(trimmed);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
if (index !== 0) {
|
|
347
|
+
if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
|
|
348
|
+
rows.push("");
|
|
349
|
+
rowLength = 0;
|
|
350
|
+
}
|
|
351
|
+
if (rowLength || options.trim === false) {
|
|
352
|
+
rows[rows.length - 1] += " ";
|
|
353
|
+
rowLength++;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
const wordLength = dist_default2(word);
|
|
357
|
+
if (options.hard && wordLength > columns) {
|
|
358
|
+
const remainingColumns = columns - rowLength;
|
|
359
|
+
const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
|
|
360
|
+
const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
|
|
361
|
+
if (breaksStartingNextLine < breaksStartingThisLine) {
|
|
362
|
+
rows.push("");
|
|
363
|
+
}
|
|
364
|
+
wrapWord(rows, word, columns);
|
|
365
|
+
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
if (rowLength + wordLength > columns && rowLength && wordLength) {
|
|
369
|
+
if (options.wordWrap === false && rowLength < columns) {
|
|
370
|
+
wrapWord(rows, word, columns);
|
|
371
|
+
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
rows.push("");
|
|
375
|
+
rowLength = 0;
|
|
376
|
+
}
|
|
377
|
+
if (rowLength + wordLength > columns && options.wordWrap === false) {
|
|
378
|
+
wrapWord(rows, word, columns);
|
|
379
|
+
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
rows[rows.length - 1] += word;
|
|
383
|
+
rowLength += wordLength;
|
|
384
|
+
}
|
|
385
|
+
if (options.trim !== false) {
|
|
386
|
+
rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
|
|
387
|
+
}
|
|
388
|
+
const preString = rows.join(`
|
|
389
|
+
`);
|
|
390
|
+
let inSurrogate = false;
|
|
391
|
+
for (let i = 0;i < preString.length; i++) {
|
|
392
|
+
const character = preString[i];
|
|
393
|
+
returnValue += character;
|
|
394
|
+
if (!inSurrogate) {
|
|
395
|
+
inSurrogate = character >= "\uD800" && character <= "\uDBFF";
|
|
396
|
+
if (inSurrogate) {
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
} else {
|
|
400
|
+
inSurrogate = false;
|
|
401
|
+
}
|
|
402
|
+
if (character === ESC || character === CSI) {
|
|
403
|
+
GROUP_REGEX.lastIndex = i + 1;
|
|
404
|
+
const groupsResult = GROUP_REGEX.exec(preString);
|
|
405
|
+
const groups = groupsResult?.groups;
|
|
406
|
+
if (groups?.code !== undefined) {
|
|
407
|
+
const code = Number.parseFloat(groups.code);
|
|
408
|
+
escapeCode = code === END_CODE ? undefined : code;
|
|
409
|
+
} else if (groups?.uri !== undefined) {
|
|
410
|
+
escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
if (preString[i + 1] === `
|
|
414
|
+
`) {
|
|
415
|
+
if (escapeUrl) {
|
|
416
|
+
returnValue += wrapAnsiHyperlink("");
|
|
417
|
+
}
|
|
418
|
+
const closingCode = escapeCode ? getClosingCode(escapeCode) : undefined;
|
|
419
|
+
if (escapeCode && closingCode) {
|
|
420
|
+
returnValue += wrapAnsiCode(closingCode);
|
|
421
|
+
}
|
|
422
|
+
} else if (character === `
|
|
423
|
+
`) {
|
|
424
|
+
if (escapeCode && getClosingCode(escapeCode)) {
|
|
425
|
+
returnValue += wrapAnsiCode(escapeCode);
|
|
426
|
+
}
|
|
427
|
+
if (escapeUrl) {
|
|
428
|
+
returnValue += wrapAnsiHyperlink(escapeUrl);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
return returnValue;
|
|
433
|
+
};
|
|
434
|
+
var CRLF_OR_LF = /\r?\n/;
|
|
435
|
+
function wrapAnsi(string, columns, options) {
|
|
436
|
+
return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join(`
|
|
437
|
+
`);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// node_modules/@clack/core/dist/index.mjs
|
|
441
|
+
var import_sisteransi = __toESM(require_src(), 1);
|
|
442
|
+
import { ReadStream } from "node:tty";
|
|
443
|
+
function findCursor(s, o, l2) {
|
|
444
|
+
if (!l2.some((r) => !r.disabled))
|
|
445
|
+
return s;
|
|
446
|
+
const t = s + o, n = Math.max(l2.length - 1, 0), e = t < 0 ? n : t > n ? 0 : t;
|
|
447
|
+
return l2[e]?.disabled ? findCursor(e, o < 0 ? -1 : 1, l2) : e;
|
|
448
|
+
}
|
|
449
|
+
function findTextCursor(s, o, l2, i) {
|
|
450
|
+
const t = i.split(`
|
|
451
|
+
`);
|
|
452
|
+
let n = 0, e = s;
|
|
453
|
+
for (const r of t) {
|
|
454
|
+
if (e <= r.length)
|
|
455
|
+
break;
|
|
456
|
+
e -= r.length + 1, n++;
|
|
457
|
+
}
|
|
458
|
+
for (n = Math.max(0, Math.min(t.length - 1, n + l2)), e = Math.min(e, t[n].length) + o;e < 0 && n > 0; )
|
|
459
|
+
n--, e += t[n].length + 1;
|
|
460
|
+
for (;e > t[n].length && n < t.length - 1; )
|
|
461
|
+
e -= t[n].length + 1, n++;
|
|
462
|
+
e = Math.max(0, Math.min(t[n].length, e));
|
|
463
|
+
let h = 0;
|
|
464
|
+
for (let r = 0;r < n; r++)
|
|
465
|
+
h += t[r].length + 1;
|
|
466
|
+
return h + e;
|
|
467
|
+
}
|
|
468
|
+
var a$1 = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
469
|
+
var t = [
|
|
470
|
+
"January",
|
|
471
|
+
"February",
|
|
472
|
+
"March",
|
|
473
|
+
"April",
|
|
474
|
+
"May",
|
|
475
|
+
"June",
|
|
476
|
+
"July",
|
|
477
|
+
"August",
|
|
478
|
+
"September",
|
|
479
|
+
"October",
|
|
480
|
+
"November",
|
|
481
|
+
"December"
|
|
482
|
+
];
|
|
483
|
+
var settings = {
|
|
484
|
+
actions: new Set(a$1),
|
|
485
|
+
aliases: /* @__PURE__ */ new Map([
|
|
486
|
+
["k", "up"],
|
|
487
|
+
["j", "down"],
|
|
488
|
+
["h", "left"],
|
|
489
|
+
["l", "right"],
|
|
490
|
+
["\x03", "cancel"],
|
|
491
|
+
["escape", "cancel"]
|
|
492
|
+
]),
|
|
493
|
+
messages: {
|
|
494
|
+
cancel: "Canceled",
|
|
495
|
+
error: "Something went wrong"
|
|
496
|
+
},
|
|
497
|
+
withGuide: true,
|
|
498
|
+
date: {
|
|
499
|
+
monthNames: [...t],
|
|
500
|
+
messages: {
|
|
501
|
+
required: "Please enter a valid date",
|
|
502
|
+
invalidMonth: "There are only 12 months in a year",
|
|
503
|
+
invalidDay: (n, e) => `There are only ${n} days in ${e}`,
|
|
504
|
+
afterMin: (n) => `Date must be on or after ${n.toISOString().slice(0, 10)}`,
|
|
505
|
+
beforeMax: (n) => `Date must be on or before ${n.toISOString().slice(0, 10)}`
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
function isActionKey(n, e) {
|
|
510
|
+
if (typeof n == "string")
|
|
511
|
+
return settings.aliases.get(n) === e;
|
|
512
|
+
for (const s of n)
|
|
513
|
+
if (s !== undefined && isActionKey(s, e))
|
|
514
|
+
return true;
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
function diffLines(i, s) {
|
|
518
|
+
if (i === s)
|
|
519
|
+
return;
|
|
520
|
+
const e = i.split(`
|
|
521
|
+
`), t2 = s.split(`
|
|
522
|
+
`), r = Math.max(e.length, t2.length), f = [];
|
|
523
|
+
for (let n = 0;n < r; n++)
|
|
524
|
+
e[n] !== t2[n] && f.push(n);
|
|
525
|
+
return {
|
|
526
|
+
lines: f,
|
|
527
|
+
numLinesBefore: e.length,
|
|
528
|
+
numLinesAfter: t2.length,
|
|
529
|
+
numLines: r
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
var R = globalThis.process.platform.startsWith("win");
|
|
533
|
+
var CANCEL_SYMBOL = Symbol("clack:cancel");
|
|
534
|
+
function isCancel(e) {
|
|
535
|
+
return e === CANCEL_SYMBOL;
|
|
536
|
+
}
|
|
537
|
+
function setRawMode(e, r) {
|
|
538
|
+
const o = e;
|
|
539
|
+
o.isTTY && o.setRawMode(r);
|
|
540
|
+
}
|
|
541
|
+
function block({
|
|
542
|
+
input: e = stdin,
|
|
543
|
+
output: r = stdout,
|
|
544
|
+
overwrite: o = true,
|
|
545
|
+
hideCursor: t2 = true
|
|
546
|
+
} = {}) {
|
|
547
|
+
const s = l.createInterface({
|
|
548
|
+
input: e,
|
|
549
|
+
output: r,
|
|
550
|
+
prompt: "",
|
|
551
|
+
tabSize: 1
|
|
552
|
+
});
|
|
553
|
+
l.emitKeypressEvents(e, s), e instanceof ReadStream && e.isTTY && e.setRawMode(true);
|
|
554
|
+
const n = (f, { name: a, sequence: p }) => {
|
|
555
|
+
const c = String(f);
|
|
556
|
+
if (isActionKey([c, a, p], "cancel")) {
|
|
557
|
+
t2 && r.write(import_sisteransi.cursor.show), process.exit(0);
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
if (!o)
|
|
561
|
+
return;
|
|
562
|
+
const i = a === "return" ? 0 : -1, m = a === "return" ? -1 : 0;
|
|
563
|
+
l.moveCursor(r, i, m, () => {
|
|
564
|
+
l.clearLine(r, 1, () => {
|
|
565
|
+
e.once("keypress", n);
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
};
|
|
569
|
+
return t2 && r.write(import_sisteransi.cursor.hide), e.once("keypress", n), () => {
|
|
570
|
+
e.off("keypress", n), t2 && r.write(import_sisteransi.cursor.show), e instanceof ReadStream && e.isTTY && !R && e.setRawMode(false), s.terminal = false, s.close();
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
var getColumns = (e) => ("columns" in e) && typeof e.columns == "number" ? e.columns : 80;
|
|
574
|
+
var getRows = (e) => ("rows" in e) && typeof e.rows == "number" ? e.rows : 20;
|
|
575
|
+
function wrapTextWithPrefix(e, r, o, t2 = o, s = o, n) {
|
|
576
|
+
const f = getColumns(e ?? stdout);
|
|
577
|
+
return wrapAnsi(r, f - o.length, {
|
|
578
|
+
hard: true,
|
|
579
|
+
trim: false
|
|
580
|
+
}).split(`
|
|
581
|
+
`).map((c, i, m) => {
|
|
582
|
+
const d = n ? n(c, i) : c;
|
|
583
|
+
return i === 0 ? `${t2}${d}` : i === m.length - 1 ? `${s}${d}` : `${o}${d}`;
|
|
584
|
+
}).join(`
|
|
585
|
+
`);
|
|
586
|
+
}
|
|
587
|
+
function runValidation(e, n) {
|
|
588
|
+
if ("~standard" in e) {
|
|
589
|
+
const a = e["~standard"].validate(n);
|
|
590
|
+
if (a instanceof Promise)
|
|
591
|
+
throw new TypeError("Schema validation must be synchronous. Update `validate()` and remove any asynchronous logic.");
|
|
592
|
+
return a.issues?.at(0)?.message;
|
|
593
|
+
}
|
|
594
|
+
return e(n);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
class V {
|
|
598
|
+
input;
|
|
599
|
+
output;
|
|
600
|
+
_abortSignal;
|
|
601
|
+
rl;
|
|
602
|
+
opts;
|
|
603
|
+
_render;
|
|
604
|
+
_track = false;
|
|
605
|
+
_prevFrame = "";
|
|
606
|
+
_subscribers = /* @__PURE__ */ new Map;
|
|
607
|
+
_cursor = 0;
|
|
608
|
+
state = "initial";
|
|
609
|
+
error = "";
|
|
610
|
+
value;
|
|
611
|
+
userInput = "";
|
|
612
|
+
constructor(t2, e = true) {
|
|
613
|
+
const { input: i = stdin, output: n = stdout, render: s, signal: r, ...o } = t2;
|
|
614
|
+
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;
|
|
615
|
+
}
|
|
616
|
+
unsubscribe() {
|
|
617
|
+
this._subscribers.clear();
|
|
618
|
+
}
|
|
619
|
+
setSubscriber(t2, e) {
|
|
620
|
+
const i = this._subscribers.get(t2) ?? [];
|
|
621
|
+
i.push(e), this._subscribers.set(t2, i);
|
|
622
|
+
}
|
|
623
|
+
on(t2, e) {
|
|
624
|
+
this.setSubscriber(t2, { cb: e });
|
|
625
|
+
}
|
|
626
|
+
once(t2, e) {
|
|
627
|
+
this.setSubscriber(t2, { cb: e, once: true });
|
|
628
|
+
}
|
|
629
|
+
emit(t2, ...e) {
|
|
630
|
+
const i = this._subscribers.get(t2) ?? [], n = [];
|
|
631
|
+
for (const s of i)
|
|
632
|
+
s.cb(...e), s.once && n.push(() => i.splice(i.indexOf(s), 1));
|
|
633
|
+
for (const s of n)
|
|
634
|
+
s();
|
|
635
|
+
}
|
|
636
|
+
prompt() {
|
|
637
|
+
return new Promise((t2) => {
|
|
638
|
+
if (this._abortSignal) {
|
|
639
|
+
if (this._abortSignal.aborted)
|
|
640
|
+
return this.state = "cancel", this.close(), t2(CANCEL_SYMBOL);
|
|
641
|
+
this._abortSignal.addEventListener("abort", () => {
|
|
642
|
+
this.state = "cancel", this.close();
|
|
643
|
+
}, { once: true });
|
|
644
|
+
}
|
|
645
|
+
this.rl = l__default.createInterface({
|
|
646
|
+
input: this.input,
|
|
647
|
+
tabSize: 2,
|
|
648
|
+
prompt: "",
|
|
649
|
+
escapeCodeTimeout: 50,
|
|
650
|
+
terminal: true
|
|
651
|
+
}), this.rl.prompt(), this.opts.initialUserInput !== undefined && 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", () => {
|
|
652
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t2(this.value);
|
|
653
|
+
}), this.once("cancel", () => {
|
|
654
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t2(CANCEL_SYMBOL);
|
|
655
|
+
});
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
_isActionKey(t2, e) {
|
|
659
|
+
return t2 === "\t";
|
|
660
|
+
}
|
|
661
|
+
_shouldSubmit(t2, e) {
|
|
662
|
+
return true;
|
|
663
|
+
}
|
|
664
|
+
_setValue(t2) {
|
|
665
|
+
this.value = t2, this.emit("value", this.value);
|
|
666
|
+
}
|
|
667
|
+
_setUserInput(t2, e) {
|
|
668
|
+
this.userInput = t2 ?? "", this.emit("userInput", this.userInput), e && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
|
|
669
|
+
}
|
|
670
|
+
_clearUserInput() {
|
|
671
|
+
this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
|
|
672
|
+
}
|
|
673
|
+
onKeypress(t2, e) {
|
|
674
|
+
if (this._track && e.name !== "return" && (e.name && this._isActionKey(t2, 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)), t2 && (t2.toLowerCase() === "y" || t2.toLowerCase() === "n") && this.emit("confirm", t2.toLowerCase() === "y"), this.emit("key", t2, e), e?.name === "return" && this._shouldSubmit(t2, e)) {
|
|
675
|
+
if (this.opts.validate) {
|
|
676
|
+
const i = runValidation(this.opts.validate, this.value);
|
|
677
|
+
i && (this.error = i instanceof Error ? i.message : i, this.state = "error", this.rl?.write(this.userInput));
|
|
678
|
+
}
|
|
679
|
+
this.state !== "error" && (this.state = "submit");
|
|
680
|
+
}
|
|
681
|
+
isActionKey([t2, 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();
|
|
682
|
+
}
|
|
683
|
+
close() {
|
|
684
|
+
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
685
|
+
`), setRawMode(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
|
|
686
|
+
}
|
|
687
|
+
restoreCursor() {
|
|
688
|
+
const t2 = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
|
|
689
|
+
`).length - 1;
|
|
690
|
+
this.output.write(import_sisteransi.cursor.move(-999, t2 * -1));
|
|
691
|
+
}
|
|
692
|
+
render() {
|
|
693
|
+
const t2 = wrapAnsi(this._render(this) ?? "", process.stdout.columns, {
|
|
694
|
+
hard: true,
|
|
695
|
+
trim: false
|
|
696
|
+
});
|
|
697
|
+
if (t2 !== this._prevFrame) {
|
|
698
|
+
if (this.state === "initial")
|
|
699
|
+
this.output.write(import_sisteransi.cursor.hide);
|
|
700
|
+
else {
|
|
701
|
+
const e = diffLines(this._prevFrame, t2), i = getRows(this.output);
|
|
702
|
+
if (this.restoreCursor(), e) {
|
|
703
|
+
const n = Math.max(0, e.numLinesAfter - i), s = Math.max(0, e.numLinesBefore - i);
|
|
704
|
+
let r = e.lines.find((o) => o >= n);
|
|
705
|
+
if (r === undefined) {
|
|
706
|
+
this._prevFrame = t2;
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
if (e.lines.length === 1) {
|
|
710
|
+
this.output.write(import_sisteransi.cursor.move(0, r - s)), this.output.write(import_sisteransi.erase.lines(1));
|
|
711
|
+
const o = t2.split(`
|
|
712
|
+
`);
|
|
713
|
+
this.output.write(o[r]), this._prevFrame = t2, this.output.write(import_sisteransi.cursor.move(0, o.length - r - 1));
|
|
714
|
+
return;
|
|
715
|
+
} else if (e.lines.length > 1) {
|
|
716
|
+
if (n < s)
|
|
717
|
+
r = n;
|
|
718
|
+
else {
|
|
719
|
+
const h = r - s;
|
|
720
|
+
h > 0 && this.output.write(import_sisteransi.cursor.move(0, h));
|
|
721
|
+
}
|
|
722
|
+
this.output.write(import_sisteransi.erase.down());
|
|
723
|
+
const f = t2.split(`
|
|
724
|
+
`).slice(r);
|
|
725
|
+
this.output.write(f.join(`
|
|
726
|
+
`)), this._prevFrame = t2;
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
this.output.write(import_sisteransi.erase.down());
|
|
731
|
+
}
|
|
732
|
+
this.output.write(t2), this.state === "initial" && (this.state = "active"), this._prevFrame = t2;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
function p$1(l2, e) {
|
|
737
|
+
if (l2 === undefined || e.length === 0)
|
|
738
|
+
return 0;
|
|
739
|
+
const i = e.findIndex((s) => s.value === l2);
|
|
740
|
+
return i !== -1 ? i : 0;
|
|
741
|
+
}
|
|
742
|
+
function g(l2, e) {
|
|
743
|
+
return (e.label ?? String(e.value)).toLowerCase().includes(l2.toLowerCase());
|
|
744
|
+
}
|
|
745
|
+
function m(l2, e) {
|
|
746
|
+
if (e)
|
|
747
|
+
return l2 ? e : e[0];
|
|
748
|
+
}
|
|
749
|
+
var T$1 = class T extends V {
|
|
750
|
+
filteredOptions;
|
|
751
|
+
multiple;
|
|
752
|
+
isNavigating = false;
|
|
753
|
+
selectedValues = [];
|
|
754
|
+
focusedValue;
|
|
755
|
+
#e = 0;
|
|
756
|
+
#s = "";
|
|
757
|
+
#t;
|
|
758
|
+
#i;
|
|
759
|
+
#n;
|
|
760
|
+
get cursor() {
|
|
761
|
+
return this.#e;
|
|
762
|
+
}
|
|
763
|
+
get userInputWithCursor() {
|
|
764
|
+
if (!this.userInput)
|
|
765
|
+
return styleText(["inverse", "hidden"], "_");
|
|
766
|
+
if (this._cursor >= this.userInput.length)
|
|
767
|
+
return `${this.userInput}█`;
|
|
768
|
+
const e = this.userInput.slice(0, this.cursor), t2 = this.userInput.slice(this.cursor, this.cursor + 1), i = this.userInput.slice(this.cursor + 1);
|
|
769
|
+
return `${e}${styleText("inverse", t2)}${i}`;
|
|
770
|
+
}
|
|
771
|
+
get options() {
|
|
772
|
+
return typeof this.#i == "function" ? this.#i() : this.#i;
|
|
773
|
+
}
|
|
774
|
+
constructor(e) {
|
|
775
|
+
super(e), this.#i = e.options, this.#n = e.placeholder;
|
|
776
|
+
const t2 = this.options;
|
|
777
|
+
this.filteredOptions = [...t2], this.multiple = e.multiple === true, this.#t = typeof e.options == "function" ? e.filter : e.filter ?? g;
|
|
778
|
+
let i;
|
|
779
|
+
if (e.initialValue && Array.isArray(e.initialValue) ? this.multiple ? i = e.initialValue : i = e.initialValue.slice(0, 1) : !this.multiple && this.options.length > 0 && (i = [this.options[0]?.value]), i)
|
|
780
|
+
for (const s of i) {
|
|
781
|
+
const n = t2.findIndex((o) => o.value === s);
|
|
782
|
+
n !== -1 && (this.toggleSelected(s), this.#e = n);
|
|
783
|
+
}
|
|
784
|
+
this.focusedValue = this.options[this.#e]?.value, this.on("key", (s, n) => this.#l(s, n)), this.on("userInput", (s) => this.#u(s));
|
|
785
|
+
}
|
|
786
|
+
_isActionKey(e, t2) {
|
|
787
|
+
return e === "\t" || this.multiple && this.isNavigating && t2.name === "space" && e !== undefined && e !== "";
|
|
788
|
+
}
|
|
789
|
+
#l(e, t2) {
|
|
790
|
+
const i = t2.name === "up", s = t2.name === "down", n = t2.name === "return", o = this.userInput === "" || this.userInput === "\t", u = this.#n, a = this.options, f = u !== undefined && u !== "" && a.some((r) => !r.disabled && (this.#t ? this.#t(u, r) : true));
|
|
791
|
+
if (t2.name === "tab" && o && f) {
|
|
792
|
+
this.userInput === "\t" && this._clearUserInput(), this._setUserInput(u, true), this.isNavigating = false;
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
i || s ? (this.#e = findCursor(this.#e, i ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#e]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n ? this.value = m(this.multiple, this.selectedValues) : this.multiple ? this.focusedValue !== undefined && (t2.name === "tab" || this.isNavigating && t2.name === "space") ? this.toggleSelected(this.focusedValue) : this.isNavigating = false : (this.focusedValue && (this.selectedValues = [this.focusedValue]), this.isNavigating = false);
|
|
796
|
+
}
|
|
797
|
+
deselectAll() {
|
|
798
|
+
this.selectedValues = [];
|
|
799
|
+
}
|
|
800
|
+
toggleSelected(e) {
|
|
801
|
+
this.filteredOptions.length !== 0 && (this.multiple ? this.selectedValues.includes(e) ? this.selectedValues = this.selectedValues.filter((t2) => t2 !== e) : this.selectedValues = [...this.selectedValues, e] : this.selectedValues = [e]);
|
|
802
|
+
}
|
|
803
|
+
#u(e) {
|
|
804
|
+
if (e !== this.#s) {
|
|
805
|
+
this.#s = e;
|
|
806
|
+
const t2 = this.options;
|
|
807
|
+
e && this.#t ? this.filteredOptions = t2.filter((n) => this.#t?.(e, n)) : this.filteredOptions = [...t2];
|
|
808
|
+
const i = p$1(this.focusedValue, this.filteredOptions);
|
|
809
|
+
this.#e = findCursor(i, 0, this.filteredOptions);
|
|
810
|
+
const s = this.filteredOptions[this.#e];
|
|
811
|
+
s && !s.disabled ? this.focusedValue = s.value : this.focusedValue = undefined, this.multiple || (this.focusedValue !== undefined ? this.toggleSelected(this.focusedValue) : this.deselectAll());
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
|
|
816
|
+
class r extends V {
|
|
817
|
+
get cursor() {
|
|
818
|
+
return this.value ? 0 : 1;
|
|
819
|
+
}
|
|
820
|
+
get _value() {
|
|
821
|
+
return this.cursor === 0;
|
|
822
|
+
}
|
|
823
|
+
constructor(t2) {
|
|
824
|
+
super(t2, false), this.value = !!t2.initialValue, this.on("userInput", () => {
|
|
825
|
+
this.value = this._value;
|
|
826
|
+
}), this.on("confirm", (i) => {
|
|
827
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = i, this.state = "submit", this.close();
|
|
828
|
+
}), this.on("cursor", () => {
|
|
829
|
+
this.value = !this.value;
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
var _ = {
|
|
834
|
+
Y: { type: "year", len: 4 },
|
|
835
|
+
M: { type: "month", len: 2 },
|
|
836
|
+
D: { type: "day", len: 2 }
|
|
837
|
+
};
|
|
838
|
+
function M(r2) {
|
|
839
|
+
return [...r2].map((t2) => _[t2]);
|
|
840
|
+
}
|
|
841
|
+
function P(r2) {
|
|
842
|
+
const i = new Intl.DateTimeFormat(r2, {
|
|
843
|
+
year: "numeric",
|
|
844
|
+
month: "2-digit",
|
|
845
|
+
day: "2-digit"
|
|
846
|
+
}).formatToParts(new Date(2000, 0, 15)), s = [];
|
|
847
|
+
let n = "/";
|
|
848
|
+
for (const e of i)
|
|
849
|
+
e.type === "literal" ? n = e.value.trim() || e.value : (e.type === "year" || e.type === "month" || e.type === "day") && s.push({ type: e.type, len: e.type === "year" ? 4 : 2 });
|
|
850
|
+
return { segments: s, separator: n };
|
|
851
|
+
}
|
|
852
|
+
function p(r2) {
|
|
853
|
+
return Number.parseInt((r2 || "0").replace(/_/g, "0"), 10) || 0;
|
|
854
|
+
}
|
|
855
|
+
function f(r2) {
|
|
856
|
+
return {
|
|
857
|
+
year: p(r2.year),
|
|
858
|
+
month: p(r2.month),
|
|
859
|
+
day: p(r2.day)
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
function c(r2, t2) {
|
|
863
|
+
return new Date(r2 || 2001, t2 || 1, 0).getDate();
|
|
864
|
+
}
|
|
865
|
+
function b(r2) {
|
|
866
|
+
const { year: t2, month: i, day: s } = f(r2);
|
|
867
|
+
if (!t2 || t2 < 0 || t2 > 9999 || !i || i < 1 || i > 12 || !s || s < 1)
|
|
868
|
+
return;
|
|
869
|
+
const n = new Date(Date.UTC(t2, i - 1, s));
|
|
870
|
+
if (!(n.getUTCFullYear() !== t2 || n.getUTCMonth() !== i - 1 || n.getUTCDate() !== s))
|
|
871
|
+
return { year: t2, month: i, day: s };
|
|
872
|
+
}
|
|
873
|
+
function C(r2) {
|
|
874
|
+
const t2 = b(r2);
|
|
875
|
+
return t2 ? new Date(Date.UTC(t2.year, t2.month - 1, t2.day)) : undefined;
|
|
876
|
+
}
|
|
877
|
+
function T2(r2, t2, i, s) {
|
|
878
|
+
const n = i ? {
|
|
879
|
+
year: i.getUTCFullYear(),
|
|
880
|
+
month: i.getUTCMonth() + 1,
|
|
881
|
+
day: i.getUTCDate()
|
|
882
|
+
} : null, e = s ? {
|
|
883
|
+
year: s.getUTCFullYear(),
|
|
884
|
+
month: s.getUTCMonth() + 1,
|
|
885
|
+
day: s.getUTCDate()
|
|
886
|
+
} : null;
|
|
887
|
+
return r2 === "year" ? { min: n?.year ?? 1, max: e?.year ?? 9999 } : r2 === "month" ? {
|
|
888
|
+
min: n && t2.year === n.year ? n.month : 1,
|
|
889
|
+
max: e && t2.year === e.year ? e.month : 12
|
|
890
|
+
} : {
|
|
891
|
+
min: n && t2.year === n.year && t2.month === n.month ? n.day : 1,
|
|
892
|
+
max: e && t2.year === e.year && t2.month === e.month ? e.day : c(t2.year, t2.month)
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
class U extends V {
|
|
897
|
+
#i;
|
|
898
|
+
#o;
|
|
899
|
+
#t;
|
|
900
|
+
#h;
|
|
901
|
+
#u;
|
|
902
|
+
#e = { segmentIndex: 0, positionInSegment: 0 };
|
|
903
|
+
#n = true;
|
|
904
|
+
#s = null;
|
|
905
|
+
inlineError = "";
|
|
906
|
+
get segmentCursor() {
|
|
907
|
+
return { ...this.#e };
|
|
908
|
+
}
|
|
909
|
+
get segmentValues() {
|
|
910
|
+
return { ...this.#t };
|
|
911
|
+
}
|
|
912
|
+
get segments() {
|
|
913
|
+
return this.#i;
|
|
914
|
+
}
|
|
915
|
+
get separator() {
|
|
916
|
+
return this.#o;
|
|
917
|
+
}
|
|
918
|
+
get formattedValue() {
|
|
919
|
+
return this.#l(this.#t);
|
|
920
|
+
}
|
|
921
|
+
#l(t2) {
|
|
922
|
+
return this.#i.map((i) => t2[i.type]).join(this.#o);
|
|
923
|
+
}
|
|
924
|
+
#r() {
|
|
925
|
+
this._setUserInput(this.#l(this.#t)), this._setValue(C(this.#t) ?? undefined);
|
|
926
|
+
}
|
|
927
|
+
constructor(t2) {
|
|
928
|
+
const i = t2.format ? { segments: M(t2.format), separator: t2.separator ?? "/" } : P(t2.locale), s = t2.separator ?? i.separator, n = t2.format ? M(t2.format) : i.segments, e = t2.initialValue ?? t2.defaultValue, m2 = e ? {
|
|
929
|
+
year: String(e.getUTCFullYear()).padStart(4, "0"),
|
|
930
|
+
month: String(e.getUTCMonth() + 1).padStart(2, "0"),
|
|
931
|
+
day: String(e.getUTCDate()).padStart(2, "0")
|
|
932
|
+
} : { year: "____", month: "__", day: "__" }, o = n.map((a) => m2[a.type]).join(s);
|
|
933
|
+
super({ ...t2, initialUserInput: o }, false), this.#i = n, this.#o = s, this.#t = m2, this.#h = t2.minDate, this.#u = t2.maxDate, this.#r(), this.on("cursor", (a) => this.#f(a)), this.on("key", (a, u) => this.#y(a, u)), this.on("finalize", () => this.#p(t2));
|
|
934
|
+
}
|
|
935
|
+
#a() {
|
|
936
|
+
const t2 = Math.max(0, Math.min(this.#e.segmentIndex, this.#i.length - 1)), i = this.#i[t2];
|
|
937
|
+
if (i)
|
|
938
|
+
return this.#e.positionInSegment = Math.max(0, Math.min(this.#e.positionInSegment, i.len - 1)), { segment: i, index: t2 };
|
|
939
|
+
}
|
|
940
|
+
#m(t2) {
|
|
941
|
+
this.inlineError = "", this.#s = null;
|
|
942
|
+
const i = this.#a();
|
|
943
|
+
i && (this.#e.segmentIndex = Math.max(0, Math.min(this.#i.length - 1, i.index + t2)), this.#e.positionInSegment = 0, this.#n = true);
|
|
944
|
+
}
|
|
945
|
+
#d(t2) {
|
|
946
|
+
const i = this.#a();
|
|
947
|
+
if (!i)
|
|
948
|
+
return;
|
|
949
|
+
const { segment: s } = i, n = this.#t[s.type], e = !n || n.replace(/_/g, "") === "", m2 = Number.parseInt((n || "0").replace(/_/g, "0"), 10) || 0, o = T2(s.type, f(this.#t), this.#h, this.#u);
|
|
950
|
+
let a;
|
|
951
|
+
e ? a = t2 === 1 ? o.min : o.max : a = Math.max(Math.min(o.max, m2 + t2), o.min), this.#t = {
|
|
952
|
+
...this.#t,
|
|
953
|
+
[s.type]: a.toString().padStart(s.len, "0")
|
|
954
|
+
}, this.#n = true, this.#s = null, this.#r();
|
|
955
|
+
}
|
|
956
|
+
#f(t2) {
|
|
957
|
+
if (t2)
|
|
958
|
+
switch (t2) {
|
|
959
|
+
case "right":
|
|
960
|
+
return this.#m(1);
|
|
961
|
+
case "left":
|
|
962
|
+
return this.#m(-1);
|
|
963
|
+
case "up":
|
|
964
|
+
return this.#d(1);
|
|
965
|
+
case "down":
|
|
966
|
+
return this.#d(-1);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
#y(t2, i) {
|
|
970
|
+
if (i?.name === "backspace" || i?.sequence === "" || i?.sequence === "\b" || t2 === "" || t2 === "\b") {
|
|
971
|
+
this.inlineError = "";
|
|
972
|
+
const n = this.#a();
|
|
973
|
+
if (!n)
|
|
974
|
+
return;
|
|
975
|
+
if (!this.#t[n.segment.type].replace(/_/g, "")) {
|
|
976
|
+
this.#m(-1);
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
this.#t[n.segment.type] = "_".repeat(n.segment.len), this.#n = true, this.#e.positionInSegment = 0, this.#r();
|
|
980
|
+
return;
|
|
981
|
+
}
|
|
982
|
+
if (i?.name === "tab") {
|
|
983
|
+
this.inlineError = "";
|
|
984
|
+
const n = this.#a();
|
|
985
|
+
if (!n)
|
|
986
|
+
return;
|
|
987
|
+
const e = i.shift ? -1 : 1, m2 = n.index + e;
|
|
988
|
+
m2 >= 0 && m2 < this.#i.length && (this.#e.segmentIndex = m2, this.#e.positionInSegment = 0, this.#n = true);
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
if (t2 && /^[0-9]$/.test(t2)) {
|
|
992
|
+
const n = this.#a();
|
|
993
|
+
if (!n)
|
|
994
|
+
return;
|
|
995
|
+
const { segment: e } = n, m2 = !this.#t[e.type].replace(/_/g, "");
|
|
996
|
+
if (this.#n && this.#s !== null && !m2) {
|
|
997
|
+
const h = this.#s + t2, d = { ...this.#t, [e.type]: h }, g2 = this.#g(d, e);
|
|
998
|
+
if (g2) {
|
|
999
|
+
this.inlineError = g2, this.#s = null, this.#n = false;
|
|
1000
|
+
return;
|
|
1001
|
+
}
|
|
1002
|
+
this.inlineError = "", this.#t[e.type] = h, this.#s = null, this.#n = false, this.#r(), n.index < this.#i.length - 1 && (this.#e.segmentIndex = n.index + 1, this.#e.positionInSegment = 0, this.#n = true);
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
this.#n && !m2 && (this.#t[e.type] = "_".repeat(e.len), this.#e.positionInSegment = 0), this.#n = false, this.#s = null;
|
|
1006
|
+
const o = this.#t[e.type], a = o.indexOf("_"), u = a >= 0 ? a : Math.min(this.#e.positionInSegment, e.len - 1);
|
|
1007
|
+
if (u < 0 || u >= e.len)
|
|
1008
|
+
return;
|
|
1009
|
+
let l2 = o.slice(0, u) + t2 + o.slice(u + 1), D = false;
|
|
1010
|
+
if (u === 0 && o === "__" && (e.type === "month" || e.type === "day")) {
|
|
1011
|
+
const h = Number.parseInt(t2, 10);
|
|
1012
|
+
l2 = `0${t2}`, D = h <= (e.type === "month" ? 1 : 2);
|
|
1013
|
+
}
|
|
1014
|
+
if (e.type === "year" && (l2 = (o.replace(/_/g, "") + t2).padStart(e.len, "_")), !l2.includes("_")) {
|
|
1015
|
+
const h = { ...this.#t, [e.type]: l2 }, d = this.#g(h, e);
|
|
1016
|
+
if (d) {
|
|
1017
|
+
this.inlineError = d;
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
this.inlineError = "", this.#t[e.type] = l2;
|
|
1022
|
+
const y = l2.includes("_") ? undefined : b(this.#t);
|
|
1023
|
+
if (y) {
|
|
1024
|
+
const { year: h, month: d } = y, g2 = c(h, d);
|
|
1025
|
+
this.#t = {
|
|
1026
|
+
year: String(Math.max(0, Math.min(9999, h))).padStart(4, "0"),
|
|
1027
|
+
month: String(Math.max(1, Math.min(12, d))).padStart(2, "0"),
|
|
1028
|
+
day: String(Math.max(1, Math.min(g2, y.day))).padStart(2, "0")
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
this.#r();
|
|
1032
|
+
const S = l2.indexOf("_");
|
|
1033
|
+
D ? (this.#n = true, this.#s = t2) : S >= 0 ? this.#e.positionInSegment = S : a >= 0 && n.index < this.#i.length - 1 ? (this.#e.segmentIndex = n.index + 1, this.#e.positionInSegment = 0, this.#n = true) : this.#e.positionInSegment = Math.min(u + 1, e.len - 1);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
#g(t2, i) {
|
|
1037
|
+
const { month: s, day: n } = f(t2);
|
|
1038
|
+
if (i.type === "month" && (s < 0 || s > 12))
|
|
1039
|
+
return settings.date.messages.invalidMonth;
|
|
1040
|
+
if (i.type === "day" && (n < 0 || n > 31))
|
|
1041
|
+
return settings.date.messages.invalidDay(31, "any month");
|
|
1042
|
+
}
|
|
1043
|
+
#p(t2) {
|
|
1044
|
+
const { year: i, month: s, day: n } = f(this.#t);
|
|
1045
|
+
if (i && s && n) {
|
|
1046
|
+
const e = c(i, s);
|
|
1047
|
+
this.#t = {
|
|
1048
|
+
...this.#t,
|
|
1049
|
+
day: String(Math.min(n, e)).padStart(2, "0")
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
1052
|
+
this.value = C(this.#t) ?? t2.defaultValue ?? undefined;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
var u$2 = class u extends V {
|
|
1056
|
+
options;
|
|
1057
|
+
cursor = 0;
|
|
1058
|
+
#t;
|
|
1059
|
+
getGroupItems(t2) {
|
|
1060
|
+
return this.options.filter((r2) => r2.group === t2);
|
|
1061
|
+
}
|
|
1062
|
+
isGroupSelected(t2) {
|
|
1063
|
+
const r2 = this.getGroupItems(t2), e = this.value;
|
|
1064
|
+
return e === undefined ? false : r2.every((s) => e.includes(s.value));
|
|
1065
|
+
}
|
|
1066
|
+
toggleValue() {
|
|
1067
|
+
const t2 = this.options[this.cursor];
|
|
1068
|
+
if (t2 !== undefined)
|
|
1069
|
+
if (this.value === undefined && (this.value = []), t2.group === true) {
|
|
1070
|
+
const r2 = t2.value, e = this.getGroupItems(r2);
|
|
1071
|
+
this.isGroupSelected(r2) ? this.value = this.value.filter((s) => e.findIndex((i) => i.value === s) === -1) : this.value = [...this.value, ...e.map((s) => s.value)], this.value = Array.from(new Set(this.value));
|
|
1072
|
+
} else {
|
|
1073
|
+
const r2 = this.value.includes(t2.value);
|
|
1074
|
+
this.value = r2 ? this.value.filter((e) => e !== t2.value) : [...this.value, t2.value];
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
constructor(t2) {
|
|
1078
|
+
super(t2, false);
|
|
1079
|
+
const { options: r2 } = t2;
|
|
1080
|
+
this.#t = t2.selectableGroups !== false, this.options = Object.entries(r2).flatMap(([e, s]) => [
|
|
1081
|
+
{ value: e, group: true, label: e },
|
|
1082
|
+
...s.map((i) => ({ ...i, group: e }))
|
|
1083
|
+
]), this.value = [...t2.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: e }) => e === t2.cursorAt), this.#t ? 0 : 1), this.on("cursor", (e) => {
|
|
1084
|
+
switch (e) {
|
|
1085
|
+
case "left":
|
|
1086
|
+
case "up": {
|
|
1087
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
1088
|
+
const s = this.options[this.cursor]?.group === true;
|
|
1089
|
+
!this.#t && s && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
|
|
1090
|
+
break;
|
|
1091
|
+
}
|
|
1092
|
+
case "down":
|
|
1093
|
+
case "right": {
|
|
1094
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
1095
|
+
const s = this.options[this.cursor]?.group === true;
|
|
1096
|
+
!this.#t && s && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
|
|
1097
|
+
break;
|
|
1098
|
+
}
|
|
1099
|
+
case "space":
|
|
1100
|
+
this.toggleValue();
|
|
1101
|
+
break;
|
|
1102
|
+
}
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
1105
|
+
};
|
|
1106
|
+
var o = /* @__PURE__ */ new Set(["up", "down", "left", "right"]);
|
|
1107
|
+
|
|
1108
|
+
class h extends V {
|
|
1109
|
+
#t = false;
|
|
1110
|
+
#s;
|
|
1111
|
+
focused = "editor";
|
|
1112
|
+
get userInputWithCursor() {
|
|
1113
|
+
if (this.state === "submit")
|
|
1114
|
+
return this.userInput;
|
|
1115
|
+
const t2 = this.userInput;
|
|
1116
|
+
if (this.cursor >= t2.length)
|
|
1117
|
+
return `${t2}█`;
|
|
1118
|
+
const s = t2.slice(0, this.cursor), r2 = t2.slice(this.cursor, this.cursor + 1), i = t2.slice(this.cursor + 1);
|
|
1119
|
+
return r2 === `
|
|
1120
|
+
` ? `${s}█
|
|
1121
|
+
${i}` : `${s}${styleText("inverse", r2)}${i}`;
|
|
1122
|
+
}
|
|
1123
|
+
get cursor() {
|
|
1124
|
+
return this._cursor;
|
|
1125
|
+
}
|
|
1126
|
+
#r(t2) {
|
|
1127
|
+
if (this.userInput.length === 0) {
|
|
1128
|
+
this._setUserInput(t2);
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1131
|
+
this._setUserInput(this.userInput.slice(0, this.cursor) + t2 + this.userInput.slice(this.cursor));
|
|
1132
|
+
}
|
|
1133
|
+
#i(t2) {
|
|
1134
|
+
const s = this.value ?? "";
|
|
1135
|
+
switch (t2) {
|
|
1136
|
+
case "up":
|
|
1137
|
+
this._cursor = findTextCursor(this._cursor, 0, -1, s);
|
|
1138
|
+
return;
|
|
1139
|
+
case "down":
|
|
1140
|
+
this._cursor = findTextCursor(this._cursor, 0, 1, s);
|
|
1141
|
+
return;
|
|
1142
|
+
case "left":
|
|
1143
|
+
this._cursor = findTextCursor(this._cursor, -1, 0, s);
|
|
1144
|
+
return;
|
|
1145
|
+
case "right":
|
|
1146
|
+
this._cursor = findTextCursor(this._cursor, 1, 0, s);
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
_shouldSubmit(t2, s) {
|
|
1151
|
+
if (this.#s)
|
|
1152
|
+
return this.focused === "submit" ? true : (this.#r(`
|
|
1153
|
+
`), this._cursor++, false);
|
|
1154
|
+
const r2 = this.#t;
|
|
1155
|
+
return this.#t = true, r2 && this.cursor === this.userInput.length ? (this.userInput[this.cursor - 1] === `
|
|
1156
|
+
` && (this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--), true) : (this.#r(`
|
|
1157
|
+
`), this._cursor++, false);
|
|
1158
|
+
}
|
|
1159
|
+
constructor(t2) {
|
|
1160
|
+
const s = t2.initialUserInput ?? t2.initialValue;
|
|
1161
|
+
super({
|
|
1162
|
+
...t2,
|
|
1163
|
+
initialUserInput: s
|
|
1164
|
+
}, false), s !== undefined && (this._cursor = s.length), this.#s = t2.showSubmit ?? false, this.on("key", (r2, i) => {
|
|
1165
|
+
if (i?.name && o.has(i.name)) {
|
|
1166
|
+
this.#t = false, this.#i(i.name);
|
|
1167
|
+
return;
|
|
1168
|
+
}
|
|
1169
|
+
if (r2 === "\t" && this.#s) {
|
|
1170
|
+
this.focused = this.focused === "editor" ? "submit" : "editor";
|
|
1171
|
+
return;
|
|
1172
|
+
}
|
|
1173
|
+
if (i?.name !== "return") {
|
|
1174
|
+
if (this.#t = false, i?.name === "backspace" && this.cursor > 0) {
|
|
1175
|
+
this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--;
|
|
1176
|
+
return;
|
|
1177
|
+
}
|
|
1178
|
+
if (i?.name === "delete" && this.cursor < this.userInput.length) {
|
|
1179
|
+
this._setUserInput(this.userInput.slice(0, this.cursor) + this.userInput.slice(this.cursor + 1));
|
|
1180
|
+
return;
|
|
1181
|
+
}
|
|
1182
|
+
r2 && (this.#s && this.focused === "submit" && (this.focused = "editor"), this.#r(r2 ?? ""), this._cursor++);
|
|
1183
|
+
}
|
|
1184
|
+
}), this.on("userInput", (r2) => {
|
|
1185
|
+
this._setValue(r2);
|
|
1186
|
+
}), this.on("finalize", () => {
|
|
1187
|
+
this.value || (this.value = t2.defaultValue), this.value === undefined && (this.value = "");
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
class a extends V {
|
|
1193
|
+
options;
|
|
1194
|
+
cursor = 0;
|
|
1195
|
+
get _value() {
|
|
1196
|
+
return this.options[this.cursor]?.value;
|
|
1197
|
+
}
|
|
1198
|
+
get _enabledOptions() {
|
|
1199
|
+
return this.options.filter((e) => e.disabled !== true);
|
|
1200
|
+
}
|
|
1201
|
+
toggleAll() {
|
|
1202
|
+
const e = this._enabledOptions, i = this.value !== undefined && this.value.length === e.length;
|
|
1203
|
+
this.value = i ? [] : e.map((t2) => t2.value);
|
|
1204
|
+
}
|
|
1205
|
+
toggleInvert() {
|
|
1206
|
+
const e = this.value;
|
|
1207
|
+
if (!e)
|
|
1208
|
+
return;
|
|
1209
|
+
const i = this._enabledOptions.filter((t2) => !e.includes(t2.value));
|
|
1210
|
+
this.value = i.map((t2) => t2.value);
|
|
1211
|
+
}
|
|
1212
|
+
toggleValue() {
|
|
1213
|
+
this.value === undefined && (this.value = []);
|
|
1214
|
+
const e = this.value.includes(this._value);
|
|
1215
|
+
this.value = e ? this.value.filter((i) => i !== this._value) : [...this.value, this._value];
|
|
1216
|
+
}
|
|
1217
|
+
constructor(e) {
|
|
1218
|
+
super(e, false), this.options = e.options, this.value = [...e.initialValues ?? []];
|
|
1219
|
+
const i = Math.max(this.options.findIndex(({ value: t2 }) => t2 === e.cursorAt), 0);
|
|
1220
|
+
this.cursor = this.options[i]?.disabled ? findCursor(i, 1, this.options) : i, this.on("key", (t2, l2) => {
|
|
1221
|
+
l2.name === "a" && this.toggleAll(), l2.name === "i" && this.toggleInvert();
|
|
1222
|
+
}), this.on("cursor", (t2) => {
|
|
1223
|
+
switch (t2) {
|
|
1224
|
+
case "left":
|
|
1225
|
+
case "up":
|
|
1226
|
+
this.cursor = findCursor(this.cursor, -1, this.options);
|
|
1227
|
+
break;
|
|
1228
|
+
case "down":
|
|
1229
|
+
case "right":
|
|
1230
|
+
this.cursor = findCursor(this.cursor, 1, this.options);
|
|
1231
|
+
break;
|
|
1232
|
+
case "space":
|
|
1233
|
+
this.toggleValue();
|
|
1234
|
+
break;
|
|
1235
|
+
}
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
var u$1 = class u2 extends V {
|
|
1240
|
+
_mask = "•";
|
|
1241
|
+
get cursor() {
|
|
1242
|
+
return this._cursor;
|
|
1243
|
+
}
|
|
1244
|
+
get masked() {
|
|
1245
|
+
return this.userInput.replaceAll(/./g, this._mask);
|
|
1246
|
+
}
|
|
1247
|
+
get userInputWithCursor() {
|
|
1248
|
+
if (this.state === "submit" || this.state === "cancel")
|
|
1249
|
+
return this.masked;
|
|
1250
|
+
const t2 = this.userInput;
|
|
1251
|
+
if (this.cursor >= t2.length)
|
|
1252
|
+
return `${this.masked}${styleText(["inverse", "hidden"], "_")}`;
|
|
1253
|
+
const s = this.masked, r2 = s.slice(0, this.cursor), i = s.slice(this.cursor, this.cursor + 1), o2 = s.slice(this.cursor + 1);
|
|
1254
|
+
return `${r2}${styleText("inverse", i)}${o2}`;
|
|
1255
|
+
}
|
|
1256
|
+
clear() {
|
|
1257
|
+
this._clearUserInput();
|
|
1258
|
+
}
|
|
1259
|
+
constructor({ mask: t2, ...s }) {
|
|
1260
|
+
super(s), this._mask = t2 ?? "•", this.on("userInput", (r2) => {
|
|
1261
|
+
this._setValue(r2);
|
|
1262
|
+
}), this.on("finalize", () => {
|
|
1263
|
+
this.value === undefined && (this.value = "");
|
|
1264
|
+
});
|
|
1265
|
+
}
|
|
1266
|
+
};
|
|
1267
|
+
var n$1 = class n extends V {
|
|
1268
|
+
options;
|
|
1269
|
+
cursor = 0;
|
|
1270
|
+
get _selectedValue() {
|
|
1271
|
+
return this.options[this.cursor];
|
|
1272
|
+
}
|
|
1273
|
+
changeValue() {
|
|
1274
|
+
const e = this._selectedValue;
|
|
1275
|
+
this.value = e === undefined ? undefined : e.value;
|
|
1276
|
+
}
|
|
1277
|
+
constructor(e) {
|
|
1278
|
+
super(e, false), this.options = e.options;
|
|
1279
|
+
const o2 = this.options.findIndex(({ value: s }) => s === e.initialValue), t2 = o2 === -1 ? 0 : o2;
|
|
1280
|
+
this.cursor = this.options[t2]?.disabled ? findCursor(t2, 1, this.options) : t2, this.changeValue(), this.on("cursor", (s) => {
|
|
1281
|
+
switch (s) {
|
|
1282
|
+
case "left":
|
|
1283
|
+
case "up":
|
|
1284
|
+
this.cursor = findCursor(this.cursor, -1, this.options);
|
|
1285
|
+
break;
|
|
1286
|
+
case "down":
|
|
1287
|
+
case "right":
|
|
1288
|
+
this.cursor = findCursor(this.cursor, 1, this.options);
|
|
1289
|
+
break;
|
|
1290
|
+
}
|
|
1291
|
+
this.changeValue();
|
|
1292
|
+
});
|
|
1293
|
+
}
|
|
1294
|
+
};
|
|
1295
|
+
class n2 extends V {
|
|
1296
|
+
get userInputWithCursor() {
|
|
1297
|
+
if (this.state === "submit")
|
|
1298
|
+
return this.userInput;
|
|
1299
|
+
const t2 = this.userInput;
|
|
1300
|
+
if (this.cursor >= t2.length)
|
|
1301
|
+
return `${this.userInput}█`;
|
|
1302
|
+
const r2 = t2.slice(0, this.cursor), s = t2.slice(this.cursor, this.cursor + 1), e = t2.slice(this.cursor + 1);
|
|
1303
|
+
return `${r2}${styleText("inverse", s)}${e}`;
|
|
1304
|
+
}
|
|
1305
|
+
get cursor() {
|
|
1306
|
+
return this._cursor;
|
|
1307
|
+
}
|
|
1308
|
+
constructor(t2) {
|
|
1309
|
+
super({
|
|
1310
|
+
...t2,
|
|
1311
|
+
initialUserInput: t2.initialUserInput ?? t2.initialValue
|
|
1312
|
+
}), this.on("userInput", (r2) => {
|
|
1313
|
+
this._setValue(r2);
|
|
1314
|
+
}), this.on("finalize", () => {
|
|
1315
|
+
this.value || (this.value = t2.defaultValue), this.value === undefined && (this.value = "");
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
// node_modules/@clack/prompts/dist/index.mjs
|
|
1321
|
+
import { styleText as styleText2, stripVTControlCharacters } from "node:util";
|
|
1322
|
+
import process$1 from "node:process";
|
|
1323
|
+
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
1324
|
+
function isUnicodeSupported() {
|
|
1325
|
+
if (process$1.platform !== "win32") {
|
|
1326
|
+
return process$1.env.TERM !== "linux";
|
|
1327
|
+
}
|
|
1328
|
+
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";
|
|
1329
|
+
}
|
|
1330
|
+
var unicode = isUnicodeSupported();
|
|
1331
|
+
var isCI = () => process.env.CI === "true";
|
|
1332
|
+
var isTTY = (o2) => o2.isTTY === true;
|
|
1333
|
+
var unicodeOr = (o2, e) => unicode ? o2 : e;
|
|
1334
|
+
var S_STEP_ACTIVE = unicodeOr("◆", "*");
|
|
1335
|
+
var S_STEP_CANCEL = unicodeOr("■", "x");
|
|
1336
|
+
var S_STEP_ERROR = unicodeOr("▲", "x");
|
|
1337
|
+
var S_STEP_SUBMIT = unicodeOr("◇", "o");
|
|
1338
|
+
var S_BAR_START = unicodeOr("┌", "T");
|
|
1339
|
+
var S_BAR = unicodeOr("│", "|");
|
|
1340
|
+
var S_BAR_END = unicodeOr("└", "—");
|
|
1341
|
+
var S_BAR_START_RIGHT = unicodeOr("┐", "T");
|
|
1342
|
+
var S_BAR_END_RIGHT = unicodeOr("┘", "—");
|
|
1343
|
+
var S_RADIO_ACTIVE = unicodeOr("●", ">");
|
|
1344
|
+
var S_RADIO_INACTIVE = unicodeOr("○", " ");
|
|
1345
|
+
var S_CHECKBOX_ACTIVE = unicodeOr("◻", "[•]");
|
|
1346
|
+
var S_CHECKBOX_SELECTED = unicodeOr("◼", "[+]");
|
|
1347
|
+
var S_CHECKBOX_INACTIVE = unicodeOr("◻", "[ ]");
|
|
1348
|
+
var S_PASSWORD_MASK = unicodeOr("▪", "•");
|
|
1349
|
+
var S_BAR_H = unicodeOr("─", "-");
|
|
1350
|
+
var S_CORNER_TOP_RIGHT = unicodeOr("╮", "+");
|
|
1351
|
+
var S_CONNECT_LEFT = unicodeOr("├", "+");
|
|
1352
|
+
var S_CORNER_BOTTOM_RIGHT = unicodeOr("╯", "+");
|
|
1353
|
+
var S_CORNER_BOTTOM_LEFT = unicodeOr("╰", "+");
|
|
1354
|
+
var S_CORNER_TOP_LEFT = unicodeOr("╭", "+");
|
|
1355
|
+
var S_INFO = unicodeOr("●", "•");
|
|
1356
|
+
var S_SUCCESS = unicodeOr("◆", "*");
|
|
1357
|
+
var S_WARN = unicodeOr("▲", "!");
|
|
1358
|
+
var S_ERROR = unicodeOr("■", "x");
|
|
1359
|
+
var symbol = (o2) => {
|
|
1360
|
+
switch (o2) {
|
|
1361
|
+
case "initial":
|
|
1362
|
+
case "active":
|
|
1363
|
+
return styleText2("cyan", S_STEP_ACTIVE);
|
|
1364
|
+
case "cancel":
|
|
1365
|
+
return styleText2("red", S_STEP_CANCEL);
|
|
1366
|
+
case "error":
|
|
1367
|
+
return styleText2("yellow", S_STEP_ERROR);
|
|
1368
|
+
case "submit":
|
|
1369
|
+
return styleText2("green", S_STEP_SUBMIT);
|
|
1370
|
+
}
|
|
1371
|
+
};
|
|
1372
|
+
var confirm = (i) => {
|
|
1373
|
+
const a2 = i.active ?? "Yes", s = i.inactive ?? "No";
|
|
1374
|
+
return new r({
|
|
1375
|
+
active: a2,
|
|
1376
|
+
inactive: s,
|
|
1377
|
+
signal: i.signal,
|
|
1378
|
+
input: i.input,
|
|
1379
|
+
output: i.output,
|
|
1380
|
+
initialValue: i.initialValue ?? true,
|
|
1381
|
+
render() {
|
|
1382
|
+
const e = i.withGuide ?? settings.withGuide, u4 = `${symbol(this.state)} `, l2 = e ? `${styleText2("gray", S_BAR)} ` : "", f2 = wrapTextWithPrefix(i.output, i.message, l2, u4), o2 = `${e ? `${styleText2("gray", S_BAR)}
|
|
1383
|
+
` : ""}${f2}
|
|
1384
|
+
`, c2 = this.value ? a2 : s;
|
|
1385
|
+
switch (this.state) {
|
|
1386
|
+
case "submit": {
|
|
1387
|
+
const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
|
|
1388
|
+
return `${o2}${r2}${styleText2("dim", c2)}`;
|
|
1389
|
+
}
|
|
1390
|
+
case "cancel": {
|
|
1391
|
+
const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
|
|
1392
|
+
return `${o2}${r2}${styleText2(["strikethrough", "dim"], c2)}${e ? `
|
|
1393
|
+
${styleText2("gray", S_BAR)}` : ""}`;
|
|
1394
|
+
}
|
|
1395
|
+
default: {
|
|
1396
|
+
const r2 = e ? `${styleText2("cyan", S_BAR)} ` : "", g2 = e ? styleText2("cyan", S_BAR_END) : "";
|
|
1397
|
+
return `${o2}${r2}${this.value ? `${styleText2("green", S_RADIO_ACTIVE)} ${a2}` : `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", a2)}`}${i.vertical ? e ? `
|
|
1398
|
+
${styleText2("cyan", S_BAR)} ` : `
|
|
1399
|
+
` : ` ${styleText2("dim", "/")} `}${this.value ? `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", s)}` : `${styleText2("green", S_RADIO_ACTIVE)} ${s}`}
|
|
1400
|
+
${g2}
|
|
1401
|
+
`;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
}).prompt();
|
|
1406
|
+
};
|
|
1407
|
+
var MULTISELECT_INSTRUCTIONS = [
|
|
1408
|
+
`${styleText2("dim", "↑/↓")} to navigate`,
|
|
1409
|
+
`${styleText2("dim", "Space:")} select`,
|
|
1410
|
+
`${styleText2("dim", "Enter:")} confirm`
|
|
1411
|
+
];
|
|
1412
|
+
var log = {
|
|
1413
|
+
message: (s = [], {
|
|
1414
|
+
symbol: e = styleText2("gray", S_BAR),
|
|
1415
|
+
secondarySymbol: r2 = styleText2("gray", S_BAR),
|
|
1416
|
+
output: m2 = process.stdout,
|
|
1417
|
+
spacing: l2 = 1,
|
|
1418
|
+
withGuide: c2
|
|
1419
|
+
} = {}) => {
|
|
1420
|
+
const t2 = [], o2 = c2 ?? settings.withGuide, f2 = o2 ? r2 : "", O = o2 ? `${e} ` : "", u4 = o2 ? `${r2} ` : "";
|
|
1421
|
+
for (let i = 0;i < l2; i++)
|
|
1422
|
+
t2.push(f2);
|
|
1423
|
+
const g2 = Array.isArray(s) ? s : s.split(`
|
|
1424
|
+
`);
|
|
1425
|
+
if (g2.length > 0) {
|
|
1426
|
+
const [i, ...y] = g2;
|
|
1427
|
+
i.length > 0 ? t2.push(`${O}${i}`) : t2.push(o2 ? e : "");
|
|
1428
|
+
for (const p2 of y)
|
|
1429
|
+
p2.length > 0 ? t2.push(`${u4}${p2}`) : t2.push(o2 ? r2 : "");
|
|
1430
|
+
}
|
|
1431
|
+
m2.write(`${t2.join(`
|
|
1432
|
+
`)}
|
|
1433
|
+
`);
|
|
1434
|
+
},
|
|
1435
|
+
info: (s, e) => {
|
|
1436
|
+
log.message(s, { ...e, symbol: styleText2("blue", S_INFO) });
|
|
1437
|
+
},
|
|
1438
|
+
success: (s, e) => {
|
|
1439
|
+
log.message(s, { ...e, symbol: styleText2("green", S_SUCCESS) });
|
|
1440
|
+
},
|
|
1441
|
+
step: (s, e) => {
|
|
1442
|
+
log.message(s, { ...e, symbol: styleText2("green", S_STEP_SUBMIT) });
|
|
1443
|
+
},
|
|
1444
|
+
warn: (s, e) => {
|
|
1445
|
+
log.message(s, { ...e, symbol: styleText2("yellow", S_WARN) });
|
|
1446
|
+
},
|
|
1447
|
+
warning: (s, e) => {
|
|
1448
|
+
log.warn(s, e);
|
|
1449
|
+
},
|
|
1450
|
+
error: (s, e) => {
|
|
1451
|
+
log.message(s, { ...e, symbol: styleText2("red", S_ERROR) });
|
|
1452
|
+
}
|
|
1453
|
+
};
|
|
1454
|
+
var cancel = (o2 = "", t2) => {
|
|
1455
|
+
const i = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_END)} ` : "";
|
|
1456
|
+
i.write(`${e}${styleText2("red", o2)}
|
|
1457
|
+
|
|
1458
|
+
`);
|
|
1459
|
+
};
|
|
1460
|
+
var intro = (o2 = "", t2) => {
|
|
1461
|
+
const i = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_START)} ` : "";
|
|
1462
|
+
i.write(`${e}${o2}
|
|
1463
|
+
`);
|
|
1464
|
+
};
|
|
1465
|
+
var outro = (o2 = "", t2) => {
|
|
1466
|
+
const i = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR)}
|
|
1467
|
+
${styleText2("gray", S_BAR_END)} ` : "";
|
|
1468
|
+
i.write(`${e}${o2}
|
|
1469
|
+
|
|
1470
|
+
`);
|
|
1471
|
+
};
|
|
1472
|
+
var password = (r2) => new u$1({
|
|
1473
|
+
validate: r2.validate,
|
|
1474
|
+
mask: r2.mask ?? S_PASSWORD_MASK,
|
|
1475
|
+
signal: r2.signal,
|
|
1476
|
+
input: r2.input,
|
|
1477
|
+
output: r2.output,
|
|
1478
|
+
render() {
|
|
1479
|
+
const e = r2.withGuide ?? settings.withGuide, o2 = `${e ? `${styleText2("gray", S_BAR)}
|
|
1480
|
+
` : ""}${symbol(this.state)} ${r2.message}
|
|
1481
|
+
`, c2 = this.userInputWithCursor, i = this.masked;
|
|
1482
|
+
switch (this.state) {
|
|
1483
|
+
case "error": {
|
|
1484
|
+
const s = e ? `${styleText2("yellow", S_BAR)} ` : "", n3 = e ? `${styleText2("yellow", S_BAR_END)} ` : "", l2 = i ?? "";
|
|
1485
|
+
return r2.clearOnError && this.clear(), `${o2.trim()}
|
|
1486
|
+
${s}${l2}
|
|
1487
|
+
${n3}${styleText2("yellow", this.error)}
|
|
1488
|
+
`;
|
|
1489
|
+
}
|
|
1490
|
+
case "submit": {
|
|
1491
|
+
const s = e ? `${styleText2("gray", S_BAR)} ` : "", n3 = i ? styleText2("dim", i) : "";
|
|
1492
|
+
return `${o2}${s}${n3}`;
|
|
1493
|
+
}
|
|
1494
|
+
case "cancel": {
|
|
1495
|
+
const s = e ? `${styleText2("gray", S_BAR)} ` : "", n3 = i ? styleText2(["strikethrough", "dim"], i) : "";
|
|
1496
|
+
return `${o2}${s}${n3}${i && e ? `
|
|
1497
|
+
${styleText2("gray", S_BAR)}` : ""}`;
|
|
1498
|
+
}
|
|
1499
|
+
default: {
|
|
1500
|
+
const s = e ? `${styleText2("cyan", S_BAR)} ` : "", n3 = e ? styleText2("cyan", S_BAR_END) : "";
|
|
1501
|
+
return `${o2}${s}${c2}
|
|
1502
|
+
${n3}
|
|
1503
|
+
`;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
}).prompt();
|
|
1508
|
+
var W = (l2) => styleText2("magenta", l2);
|
|
1509
|
+
var spinner = ({
|
|
1510
|
+
indicator: l2 = "dots",
|
|
1511
|
+
onCancel: h2,
|
|
1512
|
+
output: n3 = process.stdout,
|
|
1513
|
+
cancelMessage: G,
|
|
1514
|
+
errorMessage: O,
|
|
1515
|
+
frames: E = unicode ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"],
|
|
1516
|
+
delay: F = unicode ? 80 : 120,
|
|
1517
|
+
signal: m2,
|
|
1518
|
+
...I
|
|
1519
|
+
} = {}) => {
|
|
1520
|
+
const u4 = isCI();
|
|
1521
|
+
let M2, T3, d = false, S = false, s = "", p2, w = performance.now();
|
|
1522
|
+
const x = getColumns(n3), k = I?.styleFrame ?? W, g2 = (e) => {
|
|
1523
|
+
const r2 = e > 1 ? O ?? settings.messages.error : G ?? settings.messages.cancel;
|
|
1524
|
+
S = e === 1, d && (a2(r2, e), S && typeof h2 == "function" && h2());
|
|
1525
|
+
}, f2 = () => g2(2), i = () => g2(1), A = () => {
|
|
1526
|
+
process.on("uncaughtExceptionMonitor", f2), process.on("unhandledRejection", f2), process.on("SIGINT", i), process.on("SIGTERM", i), process.on("exit", g2), m2 && m2.addEventListener("abort", i);
|
|
1527
|
+
}, H = () => {
|
|
1528
|
+
process.removeListener("uncaughtExceptionMonitor", f2), process.removeListener("unhandledRejection", f2), process.removeListener("SIGINT", i), process.removeListener("SIGTERM", i), process.removeListener("exit", g2), m2 && m2.removeEventListener("abort", i);
|
|
1529
|
+
}, y = () => {
|
|
1530
|
+
if (p2 === undefined)
|
|
1531
|
+
return;
|
|
1532
|
+
u4 && n3.write(`
|
|
1533
|
+
`);
|
|
1534
|
+
const r2 = wrapAnsi(p2, x, {
|
|
1535
|
+
hard: true,
|
|
1536
|
+
trim: false
|
|
1537
|
+
}).split(`
|
|
1538
|
+
`);
|
|
1539
|
+
r2.length > 1 && n3.write(import_sisteransi2.cursor.up(r2.length - 1)), n3.write(import_sisteransi2.cursor.to(0)), n3.write(import_sisteransi2.erase.down());
|
|
1540
|
+
}, C2 = (e) => e.replace(/\.+$/, ""), _2 = (e) => {
|
|
1541
|
+
const r2 = (performance.now() - e) / 1000, t2 = Math.floor(r2 / 60), o2 = Math.floor(r2 % 60);
|
|
1542
|
+
return t2 > 0 ? `[${t2}m ${o2}s]` : `[${o2}s]`;
|
|
1543
|
+
}, N = I.withGuide ?? settings.withGuide, P2 = (e = "") => {
|
|
1544
|
+
d = true, M2 = block({ output: n3 }), s = C2(e), w = performance.now(), N && n3.write(`${styleText2("gray", S_BAR)}
|
|
1545
|
+
`);
|
|
1546
|
+
let r2 = 0, t2 = 0;
|
|
1547
|
+
A(), T3 = setInterval(() => {
|
|
1548
|
+
if (u4 && s === p2)
|
|
1549
|
+
return;
|
|
1550
|
+
y(), p2 = s;
|
|
1551
|
+
const o2 = k(E[r2]);
|
|
1552
|
+
let v;
|
|
1553
|
+
if (u4)
|
|
1554
|
+
v = `${o2} ${s}...`;
|
|
1555
|
+
else if (l2 === "timer")
|
|
1556
|
+
v = `${o2} ${s} ${_2(w)}`;
|
|
1557
|
+
else {
|
|
1558
|
+
const B = ".".repeat(Math.floor(t2)).slice(0, 3);
|
|
1559
|
+
v = `${o2} ${s}${B}`;
|
|
1560
|
+
}
|
|
1561
|
+
const j = wrapAnsi(v, x, {
|
|
1562
|
+
hard: true,
|
|
1563
|
+
trim: false
|
|
1564
|
+
});
|
|
1565
|
+
n3.write(j), r2 = r2 + 1 < E.length ? r2 + 1 : 0, t2 = t2 < 4 ? t2 + 0.125 : 0;
|
|
1566
|
+
}, F);
|
|
1567
|
+
}, a2 = (e = "", r2 = 0, t2 = false) => {
|
|
1568
|
+
if (!d)
|
|
1569
|
+
return;
|
|
1570
|
+
d = false, clearInterval(T3), y();
|
|
1571
|
+
const o2 = r2 === 0 ? styleText2("green", S_STEP_SUBMIT) : r2 === 1 ? styleText2("red", S_STEP_CANCEL) : styleText2("red", S_STEP_ERROR);
|
|
1572
|
+
s = e ?? s, t2 || (l2 === "timer" ? n3.write(`${o2} ${s} ${_2(w)}
|
|
1573
|
+
`) : n3.write(`${o2} ${s}
|
|
1574
|
+
`)), H(), M2();
|
|
1575
|
+
};
|
|
1576
|
+
return {
|
|
1577
|
+
start: P2,
|
|
1578
|
+
stop: (e = "") => a2(e, 0),
|
|
1579
|
+
message: (e = "") => {
|
|
1580
|
+
s = C2(e ?? s);
|
|
1581
|
+
},
|
|
1582
|
+
cancel: (e = "") => a2(e, 1),
|
|
1583
|
+
error: (e = "") => a2(e, 2),
|
|
1584
|
+
clear: () => a2("", 0, true),
|
|
1585
|
+
get isCancelled() {
|
|
1586
|
+
return S;
|
|
1587
|
+
}
|
|
1588
|
+
};
|
|
1589
|
+
};
|
|
1590
|
+
var u4 = {
|
|
1591
|
+
light: unicodeOr("─", "-"),
|
|
1592
|
+
heavy: unicodeOr("━", "="),
|
|
1593
|
+
block: unicodeOr("█", "#")
|
|
1594
|
+
};
|
|
1595
|
+
function progress({
|
|
1596
|
+
style: o2 = "heavy",
|
|
1597
|
+
max: d = 100,
|
|
1598
|
+
size: v = 40,
|
|
1599
|
+
...x
|
|
1600
|
+
} = {}) {
|
|
1601
|
+
const r2 = spinner(x);
|
|
1602
|
+
let a2 = 0, n3 = "";
|
|
1603
|
+
const c2 = Math.max(1, d), l2 = Math.max(1, v), S = (t2) => {
|
|
1604
|
+
switch (t2) {
|
|
1605
|
+
case "initial":
|
|
1606
|
+
case "active":
|
|
1607
|
+
return (e) => styleText2("magenta", e);
|
|
1608
|
+
case "error":
|
|
1609
|
+
case "cancel":
|
|
1610
|
+
return (e) => styleText2("red", e);
|
|
1611
|
+
case "submit":
|
|
1612
|
+
return (e) => styleText2("green", e);
|
|
1613
|
+
default:
|
|
1614
|
+
return (e) => styleText2("magenta", e);
|
|
1615
|
+
}
|
|
1616
|
+
}, p2 = (t2, e) => {
|
|
1617
|
+
const m2 = Math.floor(a2 / c2 * l2);
|
|
1618
|
+
return `${S(t2)(u4[o2].repeat(m2))}${styleText2("dim", u4[o2].repeat(l2 - m2))} ${e}`;
|
|
1619
|
+
}, h2 = (t2 = "") => {
|
|
1620
|
+
n3 = t2, r2.start(p2("initial", t2));
|
|
1621
|
+
}, g2 = (t2 = 1, e) => {
|
|
1622
|
+
a2 = Math.min(c2, t2 + a2), r2.message(p2("active", e ?? n3)), n3 = e ?? n3;
|
|
1623
|
+
};
|
|
1624
|
+
return {
|
|
1625
|
+
start: h2,
|
|
1626
|
+
stop: r2.stop,
|
|
1627
|
+
cancel: r2.cancel,
|
|
1628
|
+
error: r2.error,
|
|
1629
|
+
clear: r2.clear,
|
|
1630
|
+
advance: g2,
|
|
1631
|
+
isCancelled: r2.isCancelled,
|
|
1632
|
+
message: (t2) => g2(0, t2)
|
|
1633
|
+
};
|
|
1634
|
+
}
|
|
1635
|
+
var SELECT_INSTRUCTIONS = [
|
|
1636
|
+
`${styleText2("dim", "↑/↓")} to navigate`,
|
|
1637
|
+
`${styleText2("dim", "Enter:")} confirm`
|
|
1638
|
+
];
|
|
1639
|
+
var i = `${styleText2("gray", S_BAR)} `;
|
|
1640
|
+
var text = (e) => new n2({
|
|
1641
|
+
validate: e.validate,
|
|
1642
|
+
placeholder: e.placeholder,
|
|
1643
|
+
defaultValue: e.defaultValue,
|
|
1644
|
+
initialValue: e.initialValue,
|
|
1645
|
+
output: e.output,
|
|
1646
|
+
signal: e.signal,
|
|
1647
|
+
input: e.input,
|
|
1648
|
+
render() {
|
|
1649
|
+
const i2 = e?.withGuide ?? settings.withGuide, s = `${`${i2 ? `${styleText2("gray", S_BAR)}
|
|
1650
|
+
` : ""}${symbol(this.state)} `}${e.message}
|
|
1651
|
+
`, c2 = e.placeholder && e.placeholder.length > 0 ? styleText2("inverse", e.placeholder[0]) + styleText2("dim", e.placeholder.slice(1)) : styleText2(["inverse", "hidden"], "_"), o2 = this.userInput ? this.userInputWithCursor : c2, l2 = this.value ?? "";
|
|
1652
|
+
switch (this.state) {
|
|
1653
|
+
case "error": {
|
|
1654
|
+
const n3 = this.error ? ` ${styleText2("yellow", this.error)}` : "", r2 = i2 ? `${styleText2("yellow", S_BAR)} ` : "", d = i2 ? styleText2("yellow", S_BAR_END) : "";
|
|
1655
|
+
return `${s.trim()}
|
|
1656
|
+
${r2}${o2}
|
|
1657
|
+
${d}${n3}
|
|
1658
|
+
`;
|
|
1659
|
+
}
|
|
1660
|
+
case "submit": {
|
|
1661
|
+
const n3 = l2 ? ` ${styleText2("dim", l2)}` : "", r2 = i2 ? styleText2("gray", S_BAR) : "";
|
|
1662
|
+
return `${s}${r2}${n3}`;
|
|
1663
|
+
}
|
|
1664
|
+
case "cancel": {
|
|
1665
|
+
const n3 = l2 ? ` ${styleText2(["strikethrough", "dim"], l2)}` : "", r2 = i2 ? styleText2("gray", S_BAR) : "";
|
|
1666
|
+
return `${s}${r2}${n3}${l2.trim() ? `
|
|
1667
|
+
${r2}` : ""}`;
|
|
1668
|
+
}
|
|
1669
|
+
default: {
|
|
1670
|
+
const n3 = i2 ? `${styleText2("cyan", S_BAR)} ` : "", r2 = i2 ? styleText2("cyan", S_BAR_END) : "";
|
|
1671
|
+
return `${s}${n3}${o2}
|
|
1672
|
+
${r2}
|
|
1673
|
+
`;
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
}).prompt();
|
|
3
1678
|
|
|
4
1679
|
// src/cli.ts
|
|
5
|
-
import
|
|
6
|
-
import { mkdir as mkdir5, mkdtemp as mkdtemp2, readFile as readFile6, readdir as readdir2, rename as rename2, rm as
|
|
1680
|
+
import { existsSync, readdirSync, statSync } from "fs";
|
|
1681
|
+
import { mkdir as mkdir5, mkdtemp as mkdtemp2, readFile as readFile6, readdir as readdir2, rename as rename2, rm as rm5, rmdir, stat as stat5 } from "fs/promises";
|
|
7
1682
|
import { createConnection, createServer } from "net";
|
|
8
1683
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
9
|
-
import { dirname as dirname2, join as
|
|
1684
|
+
import { dirname as dirname2, join as join8, relative as relative2, resolve as resolve4, sep } from "path";
|
|
10
1685
|
|
|
11
1686
|
// src/constants.ts
|
|
12
1687
|
var CLI_NAME = "superslate";
|
|
1688
|
+
var LICENSE_KEY_VARIABLE = "SUPERSLATE_LICENSE_KEY";
|
|
13
1689
|
|
|
14
1690
|
// src/constants.ts
|
|
15
1691
|
var CLI_NAME2 = "superslate";
|
|
@@ -18,7 +1694,10 @@ var BUYER_CLI_NAME = "create-app";
|
|
|
18
1694
|
var BUYER_CLI_PACKAGE_NAME = "create-app";
|
|
19
1695
|
var DEFAULT_SCOPE = "@app";
|
|
20
1696
|
var SOURCE_BRAND_NAME = "superslate";
|
|
21
|
-
var
|
|
1697
|
+
var DELIVERY_BASE_URL = "https://dl.superslate.dev";
|
|
1698
|
+
var DELIVERY_URL_VARIABLE = "SUPERSLATE_DELIVERY_URL";
|
|
1699
|
+
var LICENSE_KEY_VARIABLE2 = "SUPERSLATE_LICENSE_KEY";
|
|
1700
|
+
var LICENSE_KEY_PREFIX = "SUPERSLATE-";
|
|
22
1701
|
|
|
23
1702
|
// src/core.ts
|
|
24
1703
|
function validateAppName(value) {
|
|
@@ -55,8 +1734,532 @@ function validateBrandName(value) {
|
|
|
55
1734
|
}
|
|
56
1735
|
var SCOPE_EXTENSIONS = new Set([".json", ".jsonc", ".md", ".ts", ".tsx", ".yaml", ".yml"]);
|
|
57
1736
|
|
|
1737
|
+
// src/delivery.ts
|
|
1738
|
+
var RELEASE_TAG_PATTERN = /^v\d+\.\d+\.\d+(?:-rc\.\d+)?$/;
|
|
1739
|
+
function validateLicenseKey(value) {
|
|
1740
|
+
const key = value.trim();
|
|
1741
|
+
if (!key)
|
|
1742
|
+
return "Enter the licence key from your purchase receipt.";
|
|
1743
|
+
if (/\s/.test(key))
|
|
1744
|
+
return "A licence key does not contain spaces.";
|
|
1745
|
+
if (!key.startsWith(LICENSE_KEY_PREFIX) || key.length === LICENSE_KEY_PREFIX.length) {
|
|
1746
|
+
return `A ${CLI_NAME2} licence key starts with ${LICENSE_KEY_PREFIX}. Copy it from your purchase receipt or the customer portal.`;
|
|
1747
|
+
}
|
|
1748
|
+
return;
|
|
1749
|
+
}
|
|
1750
|
+
function readLicenseKeyFromEnvironment(environment = process.env) {
|
|
1751
|
+
return environment[LICENSE_KEY_VARIABLE2]?.trim() || undefined;
|
|
1752
|
+
}
|
|
1753
|
+
function normalizeSourceVersion(value) {
|
|
1754
|
+
const trimmed = value.trim();
|
|
1755
|
+
const releaseTag = trimmed.startsWith("v") ? trimmed : `v${trimmed}`;
|
|
1756
|
+
if (!RELEASE_TAG_PATTERN.test(releaseTag)) {
|
|
1757
|
+
throw new Error(`Source version must be an immutable release such as 1.2.3: ${value}`);
|
|
1758
|
+
}
|
|
1759
|
+
return releaseTag;
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
// node_modules/@clack/prompts/dist/index.mjs
|
|
1763
|
+
import { styleText as styleText3, stripVTControlCharacters as stripVTControlCharacters2 } from "node:util";
|
|
1764
|
+
import process$12 from "node:process";
|
|
1765
|
+
var import_sisteransi3 = __toESM(require_src(), 1);
|
|
1766
|
+
function isUnicodeSupported2() {
|
|
1767
|
+
if (process$12.platform !== "win32") {
|
|
1768
|
+
return process$12.env.TERM !== "linux";
|
|
1769
|
+
}
|
|
1770
|
+
return Boolean(process$12.env.CI) || Boolean(process$12.env.WT_SESSION) || Boolean(process$12.env.TERMINUS_SUBLIME) || process$12.env.ConEmuTask === "{cmd::Cmder}" || process$12.env.TERM_PROGRAM === "Terminus-Sublime" || process$12.env.TERM_PROGRAM === "vscode" || process$12.env.TERM === "xterm-256color" || process$12.env.TERM === "alacritty" || process$12.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
1771
|
+
}
|
|
1772
|
+
var unicode2 = isUnicodeSupported2();
|
|
1773
|
+
var isCI2 = () => process.env.CI === "true";
|
|
1774
|
+
var unicodeOr2 = (o2, e) => unicode2 ? o2 : e;
|
|
1775
|
+
var S_STEP_ACTIVE2 = unicodeOr2("◆", "*");
|
|
1776
|
+
var S_STEP_CANCEL2 = unicodeOr2("■", "x");
|
|
1777
|
+
var S_STEP_ERROR2 = unicodeOr2("▲", "x");
|
|
1778
|
+
var S_STEP_SUBMIT2 = unicodeOr2("◇", "o");
|
|
1779
|
+
var S_BAR_START2 = unicodeOr2("┌", "T");
|
|
1780
|
+
var S_BAR2 = unicodeOr2("│", "|");
|
|
1781
|
+
var S_BAR_END2 = unicodeOr2("└", "—");
|
|
1782
|
+
var S_BAR_START_RIGHT2 = unicodeOr2("┐", "T");
|
|
1783
|
+
var S_BAR_END_RIGHT2 = unicodeOr2("┘", "—");
|
|
1784
|
+
var S_RADIO_ACTIVE2 = unicodeOr2("●", ">");
|
|
1785
|
+
var S_RADIO_INACTIVE2 = unicodeOr2("○", " ");
|
|
1786
|
+
var S_CHECKBOX_ACTIVE2 = unicodeOr2("◻", "[•]");
|
|
1787
|
+
var S_CHECKBOX_SELECTED2 = unicodeOr2("◼", "[+]");
|
|
1788
|
+
var S_CHECKBOX_INACTIVE2 = unicodeOr2("◻", "[ ]");
|
|
1789
|
+
var S_PASSWORD_MASK2 = unicodeOr2("▪", "•");
|
|
1790
|
+
var S_BAR_H2 = unicodeOr2("─", "-");
|
|
1791
|
+
var S_CORNER_TOP_RIGHT2 = unicodeOr2("╮", "+");
|
|
1792
|
+
var S_CONNECT_LEFT2 = unicodeOr2("├", "+");
|
|
1793
|
+
var S_CORNER_BOTTOM_RIGHT2 = unicodeOr2("╯", "+");
|
|
1794
|
+
var S_CORNER_BOTTOM_LEFT2 = unicodeOr2("╰", "+");
|
|
1795
|
+
var S_CORNER_TOP_LEFT2 = unicodeOr2("╭", "+");
|
|
1796
|
+
var S_INFO2 = unicodeOr2("●", "•");
|
|
1797
|
+
var S_SUCCESS2 = unicodeOr2("◆", "*");
|
|
1798
|
+
var S_WARN2 = unicodeOr2("▲", "!");
|
|
1799
|
+
var S_ERROR2 = unicodeOr2("■", "x");
|
|
1800
|
+
var symbol2 = (o2) => {
|
|
1801
|
+
switch (o2) {
|
|
1802
|
+
case "initial":
|
|
1803
|
+
case "active":
|
|
1804
|
+
return styleText3("cyan", S_STEP_ACTIVE2);
|
|
1805
|
+
case "cancel":
|
|
1806
|
+
return styleText3("red", S_STEP_CANCEL2);
|
|
1807
|
+
case "error":
|
|
1808
|
+
return styleText3("yellow", S_STEP_ERROR2);
|
|
1809
|
+
case "submit":
|
|
1810
|
+
return styleText3("green", S_STEP_SUBMIT2);
|
|
1811
|
+
}
|
|
1812
|
+
};
|
|
1813
|
+
var symbolBar = (o2) => {
|
|
1814
|
+
switch (o2) {
|
|
1815
|
+
case "initial":
|
|
1816
|
+
case "active":
|
|
1817
|
+
return styleText3("cyan", S_BAR2);
|
|
1818
|
+
case "cancel":
|
|
1819
|
+
return styleText3("red", S_BAR2);
|
|
1820
|
+
case "error":
|
|
1821
|
+
return styleText3("yellow", S_BAR2);
|
|
1822
|
+
case "submit":
|
|
1823
|
+
return styleText3("green", S_BAR2);
|
|
1824
|
+
}
|
|
1825
|
+
};
|
|
1826
|
+
function formatInstructionFooter(o2, e) {
|
|
1827
|
+
const r2 = [`${e ? `${styleText3("cyan", S_BAR2)} ` : ""}${o2.join(" • ")}`];
|
|
1828
|
+
return e && r2.push(styleText3("cyan", S_BAR_END2)), r2;
|
|
1829
|
+
}
|
|
1830
|
+
var I = (l2, e, w, p2, b2, C2 = false) => {
|
|
1831
|
+
let r2 = e, O = 0;
|
|
1832
|
+
if (C2)
|
|
1833
|
+
for (let i2 = p2 - 1;i2 >= w; i2--) {
|
|
1834
|
+
const m2 = l2[i2];
|
|
1835
|
+
if (m2 && (r2 -= m2.length), O++, r2 <= b2)
|
|
1836
|
+
break;
|
|
1837
|
+
}
|
|
1838
|
+
else
|
|
1839
|
+
for (let i2 = w;i2 < p2; i2++) {
|
|
1840
|
+
const m2 = l2[i2];
|
|
1841
|
+
if (m2 && (r2 -= m2.length), O++, r2 <= b2)
|
|
1842
|
+
break;
|
|
1843
|
+
}
|
|
1844
|
+
return { lineCount: r2, removals: O };
|
|
1845
|
+
};
|
|
1846
|
+
var limitOptions = ({
|
|
1847
|
+
cursor: l2,
|
|
1848
|
+
options: e,
|
|
1849
|
+
style: w,
|
|
1850
|
+
output: p2 = process.stdout,
|
|
1851
|
+
maxItems: b2 = Number.POSITIVE_INFINITY,
|
|
1852
|
+
columnPadding: C2 = 0,
|
|
1853
|
+
rowPadding: r2 = 4
|
|
1854
|
+
}) => {
|
|
1855
|
+
const i2 = getColumns(p2) - C2, m2 = getRows(p2), M2 = styleText3("dim", "..."), v = Math.max(m2 - r2, 0), a2 = Math.max(Math.min(b2, v), 5);
|
|
1856
|
+
let f2 = 0;
|
|
1857
|
+
l2 >= a2 - 3 && (f2 = Math.max(Math.min(l2 - a2 + 3, e.length - a2), 0));
|
|
1858
|
+
let d = a2 < e.length && f2 > 0, c2 = a2 < e.length && f2 + a2 < e.length;
|
|
1859
|
+
const W2 = Math.min(f2 + a2, e.length), s = [];
|
|
1860
|
+
let g2 = 0;
|
|
1861
|
+
d && g2++, c2 && g2++;
|
|
1862
|
+
const T3 = f2 + (d ? 1 : 0), y = W2 - (c2 ? 1 : 0);
|
|
1863
|
+
for (let t2 = T3;t2 < y; t2++) {
|
|
1864
|
+
const n3 = e[t2], o2 = n3 ? w(n3, t2 === l2) : "", h2 = wrapAnsi(o2, i2, {
|
|
1865
|
+
hard: true,
|
|
1866
|
+
trim: false
|
|
1867
|
+
}).split(`
|
|
1868
|
+
`);
|
|
1869
|
+
s.push(h2), g2 += h2.length;
|
|
1870
|
+
}
|
|
1871
|
+
if (g2 > v) {
|
|
1872
|
+
let t2 = 0, n3 = 0, o2 = g2;
|
|
1873
|
+
const h2 = l2 - T3;
|
|
1874
|
+
let u5 = v;
|
|
1875
|
+
const L = () => I(s, o2, 0, h2, u5), E = () => I(s, o2, h2 + 1, s.length, u5, true);
|
|
1876
|
+
d ? ({ lineCount: o2, removals: t2 } = L(), o2 > u5 && (c2 || (u5 -= 1), { lineCount: o2, removals: n3 } = E())) : (c2 || (u5 -= 1), { lineCount: o2, removals: n3 } = E(), o2 > u5 && (u5 -= 1, { lineCount: o2, removals: t2 } = L())), t2 > 0 && (d = true, s.splice(0, t2)), n3 > 0 && (c2 = true, s.splice(s.length - n3, n3));
|
|
1877
|
+
}
|
|
1878
|
+
const x = [];
|
|
1879
|
+
d && x.push(M2);
|
|
1880
|
+
for (const t2 of s)
|
|
1881
|
+
for (const n3 of t2)
|
|
1882
|
+
x.push(n3);
|
|
1883
|
+
return c2 && x.push(M2), x;
|
|
1884
|
+
};
|
|
1885
|
+
var confirm2 = (i2) => {
|
|
1886
|
+
const a2 = i2.active ?? "Yes", s = i2.inactive ?? "No";
|
|
1887
|
+
return new r({
|
|
1888
|
+
active: a2,
|
|
1889
|
+
inactive: s,
|
|
1890
|
+
signal: i2.signal,
|
|
1891
|
+
input: i2.input,
|
|
1892
|
+
output: i2.output,
|
|
1893
|
+
initialValue: i2.initialValue ?? true,
|
|
1894
|
+
render() {
|
|
1895
|
+
const e = i2.withGuide ?? settings.withGuide, u5 = `${symbol2(this.state)} `, l2 = e ? `${styleText3("gray", S_BAR2)} ` : "", f2 = wrapTextWithPrefix(i2.output, i2.message, l2, u5), o2 = `${e ? `${styleText3("gray", S_BAR2)}
|
|
1896
|
+
` : ""}${f2}
|
|
1897
|
+
`, c2 = this.value ? a2 : s;
|
|
1898
|
+
switch (this.state) {
|
|
1899
|
+
case "submit": {
|
|
1900
|
+
const r2 = e ? `${styleText3("gray", S_BAR2)} ` : "";
|
|
1901
|
+
return `${o2}${r2}${styleText3("dim", c2)}`;
|
|
1902
|
+
}
|
|
1903
|
+
case "cancel": {
|
|
1904
|
+
const r2 = e ? `${styleText3("gray", S_BAR2)} ` : "";
|
|
1905
|
+
return `${o2}${r2}${styleText3(["strikethrough", "dim"], c2)}${e ? `
|
|
1906
|
+
${styleText3("gray", S_BAR2)}` : ""}`;
|
|
1907
|
+
}
|
|
1908
|
+
default: {
|
|
1909
|
+
const r2 = e ? `${styleText3("cyan", S_BAR2)} ` : "", g2 = e ? styleText3("cyan", S_BAR_END2) : "";
|
|
1910
|
+
return `${o2}${r2}${this.value ? `${styleText3("green", S_RADIO_ACTIVE2)} ${a2}` : `${styleText3("dim", S_RADIO_INACTIVE2)} ${styleText3("dim", a2)}`}${i2.vertical ? e ? `
|
|
1911
|
+
${styleText3("cyan", S_BAR2)} ` : `
|
|
1912
|
+
` : ` ${styleText3("dim", "/")} `}${this.value ? `${styleText3("dim", S_RADIO_INACTIVE2)} ${styleText3("dim", s)}` : `${styleText3("green", S_RADIO_ACTIVE2)} ${s}`}
|
|
1913
|
+
${g2}
|
|
1914
|
+
`;
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
}).prompt();
|
|
1919
|
+
};
|
|
1920
|
+
var MULTISELECT_INSTRUCTIONS2 = [
|
|
1921
|
+
`${styleText3("dim", "↑/↓")} to navigate`,
|
|
1922
|
+
`${styleText3("dim", "Space:")} select`,
|
|
1923
|
+
`${styleText3("dim", "Enter:")} confirm`
|
|
1924
|
+
];
|
|
1925
|
+
var m2 = (i2, u5) => i2.split(`
|
|
1926
|
+
`).map((d) => u5(d)).join(`
|
|
1927
|
+
`);
|
|
1928
|
+
var multiselect = (i2) => {
|
|
1929
|
+
const u5 = (t2, a2) => {
|
|
1930
|
+
const r2 = t2.label ?? String(t2.value);
|
|
1931
|
+
return a2 === "disabled" ? `${styleText3("gray", S_CHECKBOX_INACTIVE2)} ${m2(r2, (o2) => styleText3(["strikethrough", "gray"], o2))}${t2.hint ? ` ${styleText3("dim", `(${t2.hint ?? "disabled"})`)}` : ""}` : a2 === "active" ? `${styleText3("cyan", S_CHECKBOX_ACTIVE2)} ${r2}${t2.hint ? ` ${styleText3("dim", `(${t2.hint})`)}` : ""}` : a2 === "selected" ? `${styleText3("green", S_CHECKBOX_SELECTED2)} ${m2(r2, (o2) => styleText3("dim", o2))}${t2.hint ? ` ${styleText3("dim", `(${t2.hint})`)}` : ""}` : a2 === "cancelled" ? `${m2(r2, (o2) => styleText3(["strikethrough", "dim"], o2))}` : a2 === "active-selected" ? `${styleText3("green", S_CHECKBOX_SELECTED2)} ${r2}${t2.hint ? ` ${styleText3("dim", `(${t2.hint})`)}` : ""}` : a2 === "submitted" ? `${m2(r2, (o2) => styleText3("dim", o2))}` : `${styleText3("dim", S_CHECKBOX_INACTIVE2)} ${m2(r2, (o2) => styleText3("dim", o2))}`;
|
|
1932
|
+
}, d = i2.required ?? true, v = i2.showInstructions ?? true;
|
|
1933
|
+
return new a({
|
|
1934
|
+
options: i2.options,
|
|
1935
|
+
signal: i2.signal,
|
|
1936
|
+
input: i2.input,
|
|
1937
|
+
output: i2.output,
|
|
1938
|
+
initialValues: i2.initialValues,
|
|
1939
|
+
required: d,
|
|
1940
|
+
cursorAt: i2.cursorAt,
|
|
1941
|
+
validate(t2) {
|
|
1942
|
+
if (d && (t2 === undefined || t2.length === 0))
|
|
1943
|
+
return `Please select at least one option.
|
|
1944
|
+
${styleText3("reset", styleText3("dim", `Press ${styleText3(["gray", "bgWhite", "inverse"], " space ")} to select, ${styleText3("gray", styleText3("bgWhite", styleText3("inverse", " enter ")))} to submit`))}`;
|
|
1945
|
+
},
|
|
1946
|
+
render() {
|
|
1947
|
+
const t2 = i2.withGuide ?? settings.withGuide, a2 = wrapTextWithPrefix(i2.output, i2.message, t2 ? `${symbolBar(this.state)} ` : "", `${symbol2(this.state)} `), r2 = `${t2 ? `${styleText3("gray", S_BAR2)}
|
|
1948
|
+
` : ""}${a2}
|
|
1949
|
+
`, o2 = this.value ?? [], p2 = (n3, l2) => {
|
|
1950
|
+
if (n3.disabled)
|
|
1951
|
+
return u5(n3, "disabled");
|
|
1952
|
+
const s = o2.includes(n3.value);
|
|
1953
|
+
return l2 && s ? u5(n3, "active-selected") : s ? u5(n3, "selected") : u5(n3, l2 ? "active" : "inactive");
|
|
1954
|
+
};
|
|
1955
|
+
switch (this.state) {
|
|
1956
|
+
case "submit": {
|
|
1957
|
+
const n3 = this.options.filter(({ value: s }) => o2.includes(s)).map((s) => u5(s, "submitted")).join(styleText3("dim", ", ")) || styleText3("dim", "none"), l2 = wrapTextWithPrefix(i2.output, n3, t2 ? `${styleText3("gray", S_BAR2)} ` : "");
|
|
1958
|
+
return `${r2}${l2}`;
|
|
1959
|
+
}
|
|
1960
|
+
case "cancel": {
|
|
1961
|
+
const n3 = this.options.filter(({ value: s }) => o2.includes(s)).map((s) => u5(s, "cancelled")).join(styleText3("dim", ", "));
|
|
1962
|
+
if (n3.trim() === "")
|
|
1963
|
+
return `${r2}${styleText3("gray", S_BAR2)}`;
|
|
1964
|
+
const l2 = wrapTextWithPrefix(i2.output, n3, t2 ? `${styleText3("gray", S_BAR2)} ` : "");
|
|
1965
|
+
return `${r2}${l2}${t2 ? `
|
|
1966
|
+
${styleText3("gray", S_BAR2)}` : ""}`;
|
|
1967
|
+
}
|
|
1968
|
+
case "error": {
|
|
1969
|
+
const n3 = t2 ? `${styleText3("yellow", S_BAR2)} ` : "", l2 = this.error.split(`
|
|
1970
|
+
`).map(($, C2) => C2 === 0 ? `${t2 ? `${styleText3("yellow", S_BAR_END2)} ` : ""}${styleText3("yellow", $)}` : ` ${$}`).join(`
|
|
1971
|
+
`), s = r2.split(`
|
|
1972
|
+
`).length, h2 = l2.split(`
|
|
1973
|
+
`).length + 1;
|
|
1974
|
+
return `${r2}${n3}${limitOptions({
|
|
1975
|
+
output: i2.output,
|
|
1976
|
+
options: this.options,
|
|
1977
|
+
cursor: this.cursor,
|
|
1978
|
+
maxItems: i2.maxItems,
|
|
1979
|
+
columnPadding: n3.length,
|
|
1980
|
+
rowPadding: s + h2,
|
|
1981
|
+
style: p2
|
|
1982
|
+
}).join(`
|
|
1983
|
+
${n3}`)}
|
|
1984
|
+
${l2}
|
|
1985
|
+
`;
|
|
1986
|
+
}
|
|
1987
|
+
default: {
|
|
1988
|
+
const n3 = t2 ? `${styleText3("cyan", S_BAR2)} ` : "", l2 = r2.split(`
|
|
1989
|
+
`).length, s = v ? formatInstructionFooter(MULTISELECT_INSTRUCTIONS2, t2) : t2 ? [styleText3("cyan", S_BAR_END2)] : [], h2 = s.join(`
|
|
1990
|
+
`), $ = s.length + 1;
|
|
1991
|
+
return `${r2}${n3}${limitOptions({
|
|
1992
|
+
output: i2.output,
|
|
1993
|
+
options: this.options,
|
|
1994
|
+
cursor: this.cursor,
|
|
1995
|
+
maxItems: i2.maxItems,
|
|
1996
|
+
columnPadding: n3.length,
|
|
1997
|
+
rowPadding: l2 + $,
|
|
1998
|
+
style: p2
|
|
1999
|
+
}).join(`
|
|
2000
|
+
${n3}`)}
|
|
2001
|
+
${h2}
|
|
2002
|
+
`;
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
}).prompt();
|
|
2007
|
+
};
|
|
2008
|
+
var log2 = {
|
|
2009
|
+
message: (s = [], {
|
|
2010
|
+
symbol: e = styleText3("gray", S_BAR2),
|
|
2011
|
+
secondarySymbol: r2 = styleText3("gray", S_BAR2),
|
|
2012
|
+
output: m3 = process.stdout,
|
|
2013
|
+
spacing: l2 = 1,
|
|
2014
|
+
withGuide: c2
|
|
2015
|
+
} = {}) => {
|
|
2016
|
+
const t2 = [], o2 = c2 ?? settings.withGuide, f2 = o2 ? r2 : "", O = o2 ? `${e} ` : "", u5 = o2 ? `${r2} ` : "";
|
|
2017
|
+
for (let i2 = 0;i2 < l2; i2++)
|
|
2018
|
+
t2.push(f2);
|
|
2019
|
+
const g2 = Array.isArray(s) ? s : s.split(`
|
|
2020
|
+
`);
|
|
2021
|
+
if (g2.length > 0) {
|
|
2022
|
+
const [i2, ...y] = g2;
|
|
2023
|
+
i2.length > 0 ? t2.push(`${O}${i2}`) : t2.push(o2 ? e : "");
|
|
2024
|
+
for (const p2 of y)
|
|
2025
|
+
p2.length > 0 ? t2.push(`${u5}${p2}`) : t2.push(o2 ? r2 : "");
|
|
2026
|
+
}
|
|
2027
|
+
m3.write(`${t2.join(`
|
|
2028
|
+
`)}
|
|
2029
|
+
`);
|
|
2030
|
+
},
|
|
2031
|
+
info: (s, e) => {
|
|
2032
|
+
log2.message(s, { ...e, symbol: styleText3("blue", S_INFO2) });
|
|
2033
|
+
},
|
|
2034
|
+
success: (s, e) => {
|
|
2035
|
+
log2.message(s, { ...e, symbol: styleText3("green", S_SUCCESS2) });
|
|
2036
|
+
},
|
|
2037
|
+
step: (s, e) => {
|
|
2038
|
+
log2.message(s, { ...e, symbol: styleText3("green", S_STEP_SUBMIT2) });
|
|
2039
|
+
},
|
|
2040
|
+
warn: (s, e) => {
|
|
2041
|
+
log2.message(s, { ...e, symbol: styleText3("yellow", S_WARN2) });
|
|
2042
|
+
},
|
|
2043
|
+
warning: (s, e) => {
|
|
2044
|
+
log2.warn(s, e);
|
|
2045
|
+
},
|
|
2046
|
+
error: (s, e) => {
|
|
2047
|
+
log2.message(s, { ...e, symbol: styleText3("red", S_ERROR2) });
|
|
2048
|
+
}
|
|
2049
|
+
};
|
|
2050
|
+
var cancel2 = (o2 = "", t2) => {
|
|
2051
|
+
const i2 = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText3("gray", S_BAR_END2)} ` : "";
|
|
2052
|
+
i2.write(`${e}${styleText3("red", o2)}
|
|
2053
|
+
|
|
2054
|
+
`);
|
|
2055
|
+
};
|
|
2056
|
+
var intro2 = (o2 = "", t2) => {
|
|
2057
|
+
const i2 = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText3("gray", S_BAR_START2)} ` : "";
|
|
2058
|
+
i2.write(`${e}${o2}
|
|
2059
|
+
`);
|
|
2060
|
+
};
|
|
2061
|
+
var outro2 = (o2 = "", t2) => {
|
|
2062
|
+
const i2 = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText3("gray", S_BAR2)}
|
|
2063
|
+
${styleText3("gray", S_BAR_END2)} ` : "";
|
|
2064
|
+
i2.write(`${e}${o2}
|
|
2065
|
+
|
|
2066
|
+
`);
|
|
2067
|
+
};
|
|
2068
|
+
var W2 = (l2) => styleText3("magenta", l2);
|
|
2069
|
+
var spinner2 = ({
|
|
2070
|
+
indicator: l2 = "dots",
|
|
2071
|
+
onCancel: h2,
|
|
2072
|
+
output: n3 = process.stdout,
|
|
2073
|
+
cancelMessage: G,
|
|
2074
|
+
errorMessage: O,
|
|
2075
|
+
frames: E = unicode2 ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"],
|
|
2076
|
+
delay: F = unicode2 ? 80 : 120,
|
|
2077
|
+
signal: m3,
|
|
2078
|
+
...I2
|
|
2079
|
+
} = {}) => {
|
|
2080
|
+
const u5 = isCI2();
|
|
2081
|
+
let M2, T3, d = false, S = false, s = "", p2, w = performance.now();
|
|
2082
|
+
const x = getColumns(n3), k = I2?.styleFrame ?? W2, g2 = (e) => {
|
|
2083
|
+
const r2 = e > 1 ? O ?? settings.messages.error : G ?? settings.messages.cancel;
|
|
2084
|
+
S = e === 1, d && (a2(r2, e), S && typeof h2 == "function" && h2());
|
|
2085
|
+
}, f2 = () => g2(2), i2 = () => g2(1), A = () => {
|
|
2086
|
+
process.on("uncaughtExceptionMonitor", f2), process.on("unhandledRejection", f2), process.on("SIGINT", i2), process.on("SIGTERM", i2), process.on("exit", g2), m3 && m3.addEventListener("abort", i2);
|
|
2087
|
+
}, H = () => {
|
|
2088
|
+
process.removeListener("uncaughtExceptionMonitor", f2), process.removeListener("unhandledRejection", f2), process.removeListener("SIGINT", i2), process.removeListener("SIGTERM", i2), process.removeListener("exit", g2), m3 && m3.removeEventListener("abort", i2);
|
|
2089
|
+
}, y = () => {
|
|
2090
|
+
if (p2 === undefined)
|
|
2091
|
+
return;
|
|
2092
|
+
u5 && n3.write(`
|
|
2093
|
+
`);
|
|
2094
|
+
const r2 = wrapAnsi(p2, x, {
|
|
2095
|
+
hard: true,
|
|
2096
|
+
trim: false
|
|
2097
|
+
}).split(`
|
|
2098
|
+
`);
|
|
2099
|
+
r2.length > 1 && n3.write(import_sisteransi3.cursor.up(r2.length - 1)), n3.write(import_sisteransi3.cursor.to(0)), n3.write(import_sisteransi3.erase.down());
|
|
2100
|
+
}, C2 = (e) => e.replace(/\.+$/, ""), _2 = (e) => {
|
|
2101
|
+
const r2 = (performance.now() - e) / 1000, t2 = Math.floor(r2 / 60), o2 = Math.floor(r2 % 60);
|
|
2102
|
+
return t2 > 0 ? `[${t2}m ${o2}s]` : `[${o2}s]`;
|
|
2103
|
+
}, N = I2.withGuide ?? settings.withGuide, P2 = (e = "") => {
|
|
2104
|
+
d = true, M2 = block({ output: n3 }), s = C2(e), w = performance.now(), N && n3.write(`${styleText3("gray", S_BAR2)}
|
|
2105
|
+
`);
|
|
2106
|
+
let r2 = 0, t2 = 0;
|
|
2107
|
+
A(), T3 = setInterval(() => {
|
|
2108
|
+
if (u5 && s === p2)
|
|
2109
|
+
return;
|
|
2110
|
+
y(), p2 = s;
|
|
2111
|
+
const o2 = k(E[r2]);
|
|
2112
|
+
let v;
|
|
2113
|
+
if (u5)
|
|
2114
|
+
v = `${o2} ${s}...`;
|
|
2115
|
+
else if (l2 === "timer")
|
|
2116
|
+
v = `${o2} ${s} ${_2(w)}`;
|
|
2117
|
+
else {
|
|
2118
|
+
const B = ".".repeat(Math.floor(t2)).slice(0, 3);
|
|
2119
|
+
v = `${o2} ${s}${B}`;
|
|
2120
|
+
}
|
|
2121
|
+
const j = wrapAnsi(v, x, {
|
|
2122
|
+
hard: true,
|
|
2123
|
+
trim: false
|
|
2124
|
+
});
|
|
2125
|
+
n3.write(j), r2 = r2 + 1 < E.length ? r2 + 1 : 0, t2 = t2 < 4 ? t2 + 0.125 : 0;
|
|
2126
|
+
}, F);
|
|
2127
|
+
}, a2 = (e = "", r2 = 0, t2 = false) => {
|
|
2128
|
+
if (!d)
|
|
2129
|
+
return;
|
|
2130
|
+
d = false, clearInterval(T3), y();
|
|
2131
|
+
const o2 = r2 === 0 ? styleText3("green", S_STEP_SUBMIT2) : r2 === 1 ? styleText3("red", S_STEP_CANCEL2) : styleText3("red", S_STEP_ERROR2);
|
|
2132
|
+
s = e ?? s, t2 || (l2 === "timer" ? n3.write(`${o2} ${s} ${_2(w)}
|
|
2133
|
+
`) : n3.write(`${o2} ${s}
|
|
2134
|
+
`)), H(), M2();
|
|
2135
|
+
};
|
|
2136
|
+
return {
|
|
2137
|
+
start: P2,
|
|
2138
|
+
stop: (e = "") => a2(e, 0),
|
|
2139
|
+
message: (e = "") => {
|
|
2140
|
+
s = C2(e ?? s);
|
|
2141
|
+
},
|
|
2142
|
+
cancel: (e = "") => a2(e, 1),
|
|
2143
|
+
error: (e = "") => a2(e, 2),
|
|
2144
|
+
clear: () => a2("", 0, true),
|
|
2145
|
+
get isCancelled() {
|
|
2146
|
+
return S;
|
|
2147
|
+
}
|
|
2148
|
+
};
|
|
2149
|
+
};
|
|
2150
|
+
var u5 = {
|
|
2151
|
+
light: unicodeOr2("─", "-"),
|
|
2152
|
+
heavy: unicodeOr2("━", "="),
|
|
2153
|
+
block: unicodeOr2("█", "#")
|
|
2154
|
+
};
|
|
2155
|
+
var SELECT_INSTRUCTIONS2 = [
|
|
2156
|
+
`${styleText3("dim", "↑/↓")} to navigate`,
|
|
2157
|
+
`${styleText3("dim", "Enter:")} confirm`
|
|
2158
|
+
];
|
|
2159
|
+
var c2 = (t2, o2) => t2.includes(`
|
|
2160
|
+
`) ? t2.split(`
|
|
2161
|
+
`).map((d) => o2(d)).join(`
|
|
2162
|
+
`) : o2(t2);
|
|
2163
|
+
var select = (t2) => {
|
|
2164
|
+
const o2 = (n3, m3) => {
|
|
2165
|
+
if (n3 === undefined)
|
|
2166
|
+
return "";
|
|
2167
|
+
const s = n3.label ?? String(n3.value);
|
|
2168
|
+
switch (m3) {
|
|
2169
|
+
case "disabled":
|
|
2170
|
+
return `${styleText3("gray", S_RADIO_INACTIVE2)} ${c2(s, (i2) => styleText3("gray", i2))}${n3.hint ? ` ${styleText3("dim", `(${n3.hint ?? "disabled"})`)}` : ""}`;
|
|
2171
|
+
case "selected":
|
|
2172
|
+
return `${c2(s, (i2) => styleText3("dim", i2))}`;
|
|
2173
|
+
case "active":
|
|
2174
|
+
return `${styleText3("green", S_RADIO_ACTIVE2)} ${s}${n3.hint ? ` ${styleText3("dim", `(${n3.hint})`)}` : ""}`;
|
|
2175
|
+
case "cancelled":
|
|
2176
|
+
return `${c2(s, (i2) => styleText3(["strikethrough", "dim"], i2))}`;
|
|
2177
|
+
default:
|
|
2178
|
+
return `${styleText3("dim", S_RADIO_INACTIVE2)} ${c2(s, (i2) => styleText3("dim", i2))}`;
|
|
2179
|
+
}
|
|
2180
|
+
}, d = t2.showInstructions ?? true;
|
|
2181
|
+
return new n$1({
|
|
2182
|
+
options: t2.options,
|
|
2183
|
+
signal: t2.signal,
|
|
2184
|
+
input: t2.input,
|
|
2185
|
+
output: t2.output,
|
|
2186
|
+
initialValue: t2.initialValue,
|
|
2187
|
+
render() {
|
|
2188
|
+
const n3 = t2.withGuide ?? settings.withGuide, m3 = `${symbol2(this.state)} `, s = `${symbolBar(this.state)} `, i2 = wrapTextWithPrefix(t2.output, t2.message, s, m3), u6 = `${n3 ? `${styleText3("gray", S_BAR2)}
|
|
2189
|
+
` : ""}${i2}
|
|
2190
|
+
`;
|
|
2191
|
+
switch (this.state) {
|
|
2192
|
+
case "submit": {
|
|
2193
|
+
const r2 = n3 ? `${styleText3("gray", S_BAR2)} ` : "", a2 = wrapTextWithPrefix(t2.output, o2(this.options[this.cursor], "selected"), r2);
|
|
2194
|
+
return `${u6}${a2}`;
|
|
2195
|
+
}
|
|
2196
|
+
case "cancel": {
|
|
2197
|
+
const r2 = n3 ? `${styleText3("gray", S_BAR2)} ` : "", a2 = wrapTextWithPrefix(t2.output, o2(this.options[this.cursor], "cancelled"), r2);
|
|
2198
|
+
return `${u6}${a2}${n3 ? `
|
|
2199
|
+
${styleText3("gray", S_BAR2)}` : ""}`;
|
|
2200
|
+
}
|
|
2201
|
+
default: {
|
|
2202
|
+
const r2 = n3 ? `${styleText3("cyan", S_BAR2)} ` : "", a2 = u6.split(`
|
|
2203
|
+
`).length, p2 = d ? formatInstructionFooter(SELECT_INSTRUCTIONS2, n3) : n3 ? [styleText3("cyan", S_BAR_END2)] : [], b2 = p2.join(`
|
|
2204
|
+
`), f2 = p2.length + 1;
|
|
2205
|
+
return `${u6}${r2}${limitOptions({
|
|
2206
|
+
output: t2.output,
|
|
2207
|
+
cursor: this.cursor,
|
|
2208
|
+
options: this.options,
|
|
2209
|
+
maxItems: t2.maxItems,
|
|
2210
|
+
columnPadding: r2.length,
|
|
2211
|
+
rowPadding: a2 + f2,
|
|
2212
|
+
style: (g2, x) => o2(g2, g2.disabled ? "disabled" : x ? "active" : "inactive")
|
|
2213
|
+
}).join(`
|
|
2214
|
+
${r2}`)}
|
|
2215
|
+
${b2}
|
|
2216
|
+
`;
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
}).prompt();
|
|
2221
|
+
};
|
|
2222
|
+
var i2 = `${styleText3("gray", S_BAR2)} `;
|
|
2223
|
+
var text2 = (e) => new n2({
|
|
2224
|
+
validate: e.validate,
|
|
2225
|
+
placeholder: e.placeholder,
|
|
2226
|
+
defaultValue: e.defaultValue,
|
|
2227
|
+
initialValue: e.initialValue,
|
|
2228
|
+
output: e.output,
|
|
2229
|
+
signal: e.signal,
|
|
2230
|
+
input: e.input,
|
|
2231
|
+
render() {
|
|
2232
|
+
const i3 = e?.withGuide ?? settings.withGuide, s = `${`${i3 ? `${styleText3("gray", S_BAR2)}
|
|
2233
|
+
` : ""}${symbol2(this.state)} `}${e.message}
|
|
2234
|
+
`, c3 = e.placeholder && e.placeholder.length > 0 ? styleText3("inverse", e.placeholder[0]) + styleText3("dim", e.placeholder.slice(1)) : styleText3(["inverse", "hidden"], "_"), o2 = this.userInput ? this.userInputWithCursor : c3, l2 = this.value ?? "";
|
|
2235
|
+
switch (this.state) {
|
|
2236
|
+
case "error": {
|
|
2237
|
+
const n3 = this.error ? ` ${styleText3("yellow", this.error)}` : "", r2 = i3 ? `${styleText3("yellow", S_BAR2)} ` : "", d = i3 ? styleText3("yellow", S_BAR_END2) : "";
|
|
2238
|
+
return `${s.trim()}
|
|
2239
|
+
${r2}${o2}
|
|
2240
|
+
${d}${n3}
|
|
2241
|
+
`;
|
|
2242
|
+
}
|
|
2243
|
+
case "submit": {
|
|
2244
|
+
const n3 = l2 ? ` ${styleText3("dim", l2)}` : "", r2 = i3 ? styleText3("gray", S_BAR2) : "";
|
|
2245
|
+
return `${s}${r2}${n3}`;
|
|
2246
|
+
}
|
|
2247
|
+
case "cancel": {
|
|
2248
|
+
const n3 = l2 ? ` ${styleText3(["strikethrough", "dim"], l2)}` : "", r2 = i3 ? styleText3("gray", S_BAR2) : "";
|
|
2249
|
+
return `${s}${r2}${n3}${l2.trim() ? `
|
|
2250
|
+
${r2}` : ""}`;
|
|
2251
|
+
}
|
|
2252
|
+
default: {
|
|
2253
|
+
const n3 = i3 ? `${styleText3("cyan", S_BAR2)} ` : "", r2 = i3 ? styleText3("cyan", S_BAR_END2) : "";
|
|
2254
|
+
return `${s}${n3}${o2}
|
|
2255
|
+
${r2}
|
|
2256
|
+
`;
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
}).prompt();
|
|
2261
|
+
|
|
58
2262
|
// src/agent-setup.ts
|
|
59
|
-
import * as prompts from "@clack/prompts";
|
|
60
2263
|
import { mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";
|
|
61
2264
|
import { dirname, join as join2, resolve } from "node:path";
|
|
62
2265
|
|
|
@@ -74,19 +2277,19 @@ function runCaptured(command, options) {
|
|
|
74
2277
|
env: options.env ?? process.env,
|
|
75
2278
|
stdio: ["ignore", "pipe", "pipe"]
|
|
76
2279
|
});
|
|
77
|
-
let
|
|
2280
|
+
let stdout2 = "";
|
|
78
2281
|
let stderr = "";
|
|
79
2282
|
child.stdout.setEncoding("utf8");
|
|
80
2283
|
child.stderr.setEncoding("utf8");
|
|
81
2284
|
child.stdout.on("data", (chunk) => {
|
|
82
|
-
|
|
2285
|
+
stdout2 += chunk;
|
|
83
2286
|
});
|
|
84
2287
|
child.stderr.on("data", (chunk) => {
|
|
85
2288
|
stderr += chunk;
|
|
86
2289
|
});
|
|
87
2290
|
child.on("error", reject);
|
|
88
2291
|
child.on("close", (code, signal) => {
|
|
89
|
-
resolve({ exitCode: code ?? (signal ? 1 : 0), stdout, stderr });
|
|
2292
|
+
resolve({ exitCode: code ?? (signal ? 1 : 0), stdout: stdout2, stderr });
|
|
90
2293
|
});
|
|
91
2294
|
});
|
|
92
2295
|
}
|
|
@@ -334,7 +2537,7 @@ async function chooseClients(parsed) {
|
|
|
334
2537
|
if (!process.stdin.isTTY) {
|
|
335
2538
|
throw new Error("Interactive setup needs a terminal. Pass --clients and --yes instead.");
|
|
336
2539
|
}
|
|
337
|
-
const selected = await
|
|
2540
|
+
const selected = await multiselect({
|
|
338
2541
|
message: "Connect which local coding clients?",
|
|
339
2542
|
required: true,
|
|
340
2543
|
options: CLIENTS.map((client) => ({
|
|
@@ -344,8 +2547,8 @@ async function chooseClients(parsed) {
|
|
|
344
2547
|
})),
|
|
345
2548
|
initialValues: detected
|
|
346
2549
|
});
|
|
347
|
-
if (
|
|
348
|
-
|
|
2550
|
+
if (isCancel(selected)) {
|
|
2551
|
+
cancel2("No agent clients were configured.");
|
|
349
2552
|
return;
|
|
350
2553
|
}
|
|
351
2554
|
return selected;
|
|
@@ -379,29 +2582,28 @@ async function runAgentSetup(argv, cliName) {
|
|
|
379
2582
|
const clients = await chooseClients(parsed);
|
|
380
2583
|
if (!clients)
|
|
381
2584
|
return;
|
|
382
|
-
|
|
2585
|
+
intro2("superslate local agent context");
|
|
383
2586
|
if (parsed.dryRun) {
|
|
384
2587
|
for (const client of clients) {
|
|
385
|
-
|
|
2588
|
+
log2.info(`${client}
|
|
386
2589
|
${dryRunDescription(client, root)}`);
|
|
387
2590
|
}
|
|
388
|
-
|
|
2591
|
+
outro2("Dry run complete. No client configuration was changed.");
|
|
389
2592
|
return;
|
|
390
2593
|
}
|
|
391
|
-
const
|
|
392
|
-
|
|
2594
|
+
const progress2 = spinner2();
|
|
2595
|
+
progress2.start("Testing the local MCP server");
|
|
393
2596
|
await smokeServer(root);
|
|
394
|
-
|
|
2597
|
+
progress2.stop("Local MCP server passed its protocol self-check");
|
|
395
2598
|
for (const client of clients) {
|
|
396
2599
|
const result = client === "codex" ? await configureCodex(root) : client === "cursor" ? await configureCursor(root) : await configureClaude(root);
|
|
397
|
-
|
|
2600
|
+
log2.success(`${client}: ${result}`);
|
|
398
2601
|
}
|
|
399
|
-
|
|
400
|
-
|
|
2602
|
+
log2.info("Restart configured clients, then ask: “Use plan_change for my next feature.”");
|
|
2603
|
+
outro2("superslate agent context is ready.");
|
|
401
2604
|
}
|
|
402
2605
|
|
|
403
2606
|
// src/deployment-cli.ts
|
|
404
|
-
import * as prompts3 from "@clack/prompts";
|
|
405
2607
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
406
2608
|
import { resolve as resolve2 } from "node:path";
|
|
407
2609
|
|
|
@@ -616,12 +2818,11 @@ async function applyDeploymentSelection(repositoryRoot, projectName, selection)
|
|
|
616
2818
|
}
|
|
617
2819
|
|
|
618
2820
|
// src/deployment-prompts.ts
|
|
619
|
-
import * as prompts2 from "@clack/prompts";
|
|
620
2821
|
class DeploymentPromptCancelled extends Error {
|
|
621
2822
|
}
|
|
622
2823
|
async function unwrap(value) {
|
|
623
|
-
if (
|
|
624
|
-
|
|
2824
|
+
if (isCancel(value)) {
|
|
2825
|
+
cancel2("Deployment configuration was not changed.");
|
|
625
2826
|
throw new DeploymentPromptCancelled;
|
|
626
2827
|
}
|
|
627
2828
|
return value;
|
|
@@ -642,7 +2843,7 @@ async function collectDeploymentSelection(defaults = {}, nonInteractive = false)
|
|
|
642
2843
|
haEnabled: defaults.haEnabled ?? false
|
|
643
2844
|
};
|
|
644
2845
|
}
|
|
645
|
-
const cloud = defaults.cloud ?? parseDeploymentCloud(await unwrap(await
|
|
2846
|
+
const cloud = defaults.cloud ?? parseDeploymentCloud(await unwrap(await select({
|
|
646
2847
|
message: "Backend cloud",
|
|
647
2848
|
options: [
|
|
648
2849
|
{ value: "aws", label: "AWS", hint: "ECS Fargate + RDS PostgreSQL" },
|
|
@@ -650,7 +2851,7 @@ async function collectDeploymentSelection(defaults = {}, nonInteractive = false)
|
|
|
650
2851
|
{ value: "azure", label: "Azure", hint: "Container Apps + Flexible Server" }
|
|
651
2852
|
]
|
|
652
2853
|
})));
|
|
653
|
-
const frontendTarget = defaults.frontendTarget ?? parseFrontendTarget(await unwrap(await
|
|
2854
|
+
const frontendTarget = defaults.frontendTarget ?? parseFrontendTarget(await unwrap(await select({
|
|
654
2855
|
message: "Frontend host",
|
|
655
2856
|
options: [
|
|
656
2857
|
{ value: "native", label: "Cloud native", hint: "Managed with the backend" },
|
|
@@ -662,7 +2863,7 @@ async function collectDeploymentSelection(defaults = {}, nonInteractive = false)
|
|
|
662
2863
|
}
|
|
663
2864
|
]
|
|
664
2865
|
})));
|
|
665
|
-
const storageProvider = defaults.storageProvider ?? (storageProvidersByCloud[cloud].length === 1 ? storageProvidersByCloud[cloud][0] ?? defaultStorageProviders[cloud] : parseStorageProvider(await unwrap(await
|
|
2866
|
+
const storageProvider = defaults.storageProvider ?? (storageProvidersByCloud[cloud].length === 1 ? storageProvidersByCloud[cloud][0] ?? defaultStorageProviders[cloud] : parseStorageProvider(await unwrap(await select({
|
|
666
2867
|
message: "Object storage",
|
|
667
2868
|
options: storageProvidersByCloud[cloud].map((provider) => ({
|
|
668
2869
|
value: provider,
|
|
@@ -670,29 +2871,29 @@ async function collectDeploymentSelection(defaults = {}, nonInteractive = false)
|
|
|
670
2871
|
hint: provider === defaultStorageProviders[cloud] ? "Cloud-native default" : ""
|
|
671
2872
|
}))
|
|
672
2873
|
}))));
|
|
673
|
-
const environment = defaults.environment ?? await unwrap(await
|
|
2874
|
+
const environment = defaults.environment ?? await unwrap(await text2({
|
|
674
2875
|
message: "Deployment environment",
|
|
675
2876
|
placeholder: "production",
|
|
676
2877
|
defaultValue: "production",
|
|
677
2878
|
validate: (value) => validateDeploymentEnvironment(value || "production")
|
|
678
2879
|
}));
|
|
679
|
-
const region = defaults.region ?? await unwrap(await
|
|
2880
|
+
const region = defaults.region ?? await unwrap(await text2({
|
|
680
2881
|
message: `${cloud.toUpperCase()} region`,
|
|
681
2882
|
placeholder: defaultRegions[cloud],
|
|
682
2883
|
defaultValue: defaultRegions[cloud],
|
|
683
2884
|
validate: (value) => validateRegion(value || defaultRegions[cloud])
|
|
684
2885
|
}));
|
|
685
|
-
const apiDomain = defaults.apiDomain ?? await unwrap(await
|
|
2886
|
+
const apiDomain = defaults.apiDomain ?? await unwrap(await text2({
|
|
686
2887
|
message: "Production API domain",
|
|
687
2888
|
placeholder: "api.example.com",
|
|
688
2889
|
validate: (value) => validateDomain(value ?? "")
|
|
689
2890
|
}));
|
|
690
|
-
const frontendDomain = defaults.frontendDomain ?? await unwrap(await
|
|
2891
|
+
const frontendDomain = defaults.frontendDomain ?? await unwrap(await text2({
|
|
691
2892
|
message: "Production frontend domain",
|
|
692
2893
|
placeholder: "app.example.com",
|
|
693
2894
|
validate: (value) => validateDomain(value ?? "")
|
|
694
2895
|
}));
|
|
695
|
-
const haEnabled = defaults.haEnabled ?? await unwrap(await
|
|
2896
|
+
const haEnabled = defaults.haEnabled ?? await unwrap(await confirm2({
|
|
696
2897
|
message: "Enable the higher-availability profile?",
|
|
697
2898
|
initialValue: false
|
|
698
2899
|
}));
|
|
@@ -750,17 +2951,17 @@ async function runDeploymentConfigure(argv, productName, repositoryRoot = proces
|
|
|
750
2951
|
const rootPackage = JSON.parse(await readFile3(`${root}/package.json`, "utf8"));
|
|
751
2952
|
if (!rootPackage.name)
|
|
752
2953
|
throw new Error("Root package name is required for deployment setup.");
|
|
753
|
-
|
|
2954
|
+
intro2(`${productName} deployment setup`);
|
|
754
2955
|
try {
|
|
755
2956
|
const selection = await collectDeploymentSelection(parsed, parsed.yes);
|
|
756
2957
|
const removed = await applyDeploymentSelection(root, rootPackage.name, selection);
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
2958
|
+
log2.success(`${selection.cloud.toUpperCase()} + ${selection.storageProvider} + ${selection.frontendTarget} is locked for ${selection.environment}.`);
|
|
2959
|
+
log2.info(`${removed.length} unused deployment paths removed.`);
|
|
2960
|
+
log2.step("Next");
|
|
2961
|
+
log2.message(`Review deployment/config.json
|
|
761
2962
|
Configure the protected GitHub environment
|
|
762
2963
|
Dispatch .github/workflows/deploy-cloud.yml`);
|
|
763
|
-
|
|
2964
|
+
outro2("Deployment configuration is ready to commit.");
|
|
764
2965
|
} catch (error) {
|
|
765
2966
|
if (error instanceof DeploymentPromptCancelled)
|
|
766
2967
|
return;
|
|
@@ -783,19 +2984,19 @@ function runCaptured2(command, options) {
|
|
|
783
2984
|
env: options.env ?? process.env,
|
|
784
2985
|
stdio: ["ignore", "pipe", "pipe"]
|
|
785
2986
|
});
|
|
786
|
-
let
|
|
2987
|
+
let stdout2 = "";
|
|
787
2988
|
let stderr = "";
|
|
788
2989
|
child.stdout.setEncoding("utf8");
|
|
789
2990
|
child.stderr.setEncoding("utf8");
|
|
790
2991
|
child.stdout.on("data", (chunk) => {
|
|
791
|
-
|
|
2992
|
+
stdout2 += chunk;
|
|
792
2993
|
});
|
|
793
2994
|
child.stderr.on("data", (chunk) => {
|
|
794
2995
|
stderr += chunk;
|
|
795
2996
|
});
|
|
796
2997
|
child.on("error", reject);
|
|
797
2998
|
child.on("close", (code, signal) => {
|
|
798
|
-
resolve3({ exitCode: code ?? (signal ? 1 : 0), stdout, stderr });
|
|
2999
|
+
resolve3({ exitCode: code ?? (signal ? 1 : 0), stdout: stdout2, stderr });
|
|
799
3000
|
});
|
|
800
3001
|
});
|
|
801
3002
|
}
|
|
@@ -834,12 +3035,11 @@ function isEntrypoint(moduleUrl) {
|
|
|
834
3035
|
}
|
|
835
3036
|
|
|
836
3037
|
// src/deployment-prompts.ts
|
|
837
|
-
import * as prompts4 from "@clack/prompts";
|
|
838
3038
|
class DeploymentPromptCancelled2 extends Error {
|
|
839
3039
|
}
|
|
840
3040
|
async function unwrap2(value) {
|
|
841
|
-
if (
|
|
842
|
-
|
|
3041
|
+
if (isCancel(value)) {
|
|
3042
|
+
cancel2("Deployment configuration was not changed.");
|
|
843
3043
|
throw new DeploymentPromptCancelled2;
|
|
844
3044
|
}
|
|
845
3045
|
return value;
|
|
@@ -860,7 +3060,7 @@ async function collectDeploymentSelection2(defaults = {}, nonInteractive = false
|
|
|
860
3060
|
haEnabled: defaults.haEnabled ?? false
|
|
861
3061
|
};
|
|
862
3062
|
}
|
|
863
|
-
const cloud = defaults.cloud ?? parseDeploymentCloud(await unwrap2(await
|
|
3063
|
+
const cloud = defaults.cloud ?? parseDeploymentCloud(await unwrap2(await select({
|
|
864
3064
|
message: "Backend cloud",
|
|
865
3065
|
options: [
|
|
866
3066
|
{ value: "aws", label: "AWS", hint: "ECS Fargate + RDS PostgreSQL" },
|
|
@@ -868,7 +3068,7 @@ async function collectDeploymentSelection2(defaults = {}, nonInteractive = false
|
|
|
868
3068
|
{ value: "azure", label: "Azure", hint: "Container Apps + Flexible Server" }
|
|
869
3069
|
]
|
|
870
3070
|
})));
|
|
871
|
-
const frontendTarget = defaults.frontendTarget ?? parseFrontendTarget(await unwrap2(await
|
|
3071
|
+
const frontendTarget = defaults.frontendTarget ?? parseFrontendTarget(await unwrap2(await select({
|
|
872
3072
|
message: "Frontend host",
|
|
873
3073
|
options: [
|
|
874
3074
|
{ value: "native", label: "Cloud native", hint: "Managed with the backend" },
|
|
@@ -880,7 +3080,7 @@ async function collectDeploymentSelection2(defaults = {}, nonInteractive = false
|
|
|
880
3080
|
}
|
|
881
3081
|
]
|
|
882
3082
|
})));
|
|
883
|
-
const storageProvider = defaults.storageProvider ?? (storageProvidersByCloud[cloud].length === 1 ? storageProvidersByCloud[cloud][0] ?? defaultStorageProviders[cloud] : parseStorageProvider(await unwrap2(await
|
|
3083
|
+
const storageProvider = defaults.storageProvider ?? (storageProvidersByCloud[cloud].length === 1 ? storageProvidersByCloud[cloud][0] ?? defaultStorageProviders[cloud] : parseStorageProvider(await unwrap2(await select({
|
|
884
3084
|
message: "Object storage",
|
|
885
3085
|
options: storageProvidersByCloud[cloud].map((provider) => ({
|
|
886
3086
|
value: provider,
|
|
@@ -888,29 +3088,29 @@ async function collectDeploymentSelection2(defaults = {}, nonInteractive = false
|
|
|
888
3088
|
hint: provider === defaultStorageProviders[cloud] ? "Cloud-native default" : ""
|
|
889
3089
|
}))
|
|
890
3090
|
}))));
|
|
891
|
-
const environment = defaults.environment ?? await unwrap2(await
|
|
3091
|
+
const environment = defaults.environment ?? await unwrap2(await text2({
|
|
892
3092
|
message: "Deployment environment",
|
|
893
3093
|
placeholder: "production",
|
|
894
3094
|
defaultValue: "production",
|
|
895
3095
|
validate: (value) => validateDeploymentEnvironment(value || "production")
|
|
896
3096
|
}));
|
|
897
|
-
const region = defaults.region ?? await unwrap2(await
|
|
3097
|
+
const region = defaults.region ?? await unwrap2(await text2({
|
|
898
3098
|
message: `${cloud.toUpperCase()} region`,
|
|
899
3099
|
placeholder: defaultRegions[cloud],
|
|
900
3100
|
defaultValue: defaultRegions[cloud],
|
|
901
3101
|
validate: (value) => validateRegion(value || defaultRegions[cloud])
|
|
902
3102
|
}));
|
|
903
|
-
const apiDomain = defaults.apiDomain ?? await unwrap2(await
|
|
3103
|
+
const apiDomain = defaults.apiDomain ?? await unwrap2(await text2({
|
|
904
3104
|
message: "Production API domain",
|
|
905
3105
|
placeholder: "api.example.com",
|
|
906
3106
|
validate: (value) => validateDomain(value ?? "")
|
|
907
3107
|
}));
|
|
908
|
-
const frontendDomain = defaults.frontendDomain ?? await unwrap2(await
|
|
3108
|
+
const frontendDomain = defaults.frontendDomain ?? await unwrap2(await text2({
|
|
909
3109
|
message: "Production frontend domain",
|
|
910
3110
|
placeholder: "app.example.com",
|
|
911
3111
|
validate: (value) => validateDomain(value ?? "")
|
|
912
3112
|
}));
|
|
913
|
-
const haEnabled = defaults.haEnabled ?? await unwrap2(await
|
|
3113
|
+
const haEnabled = defaults.haEnabled ?? await unwrap2(await confirm2({
|
|
914
3114
|
message: "Enable the higher-availability profile?",
|
|
915
3115
|
initialValue: false
|
|
916
3116
|
}));
|
|
@@ -1129,11 +3329,114 @@ async function applyDeploymentSelection2(repositoryRoot, projectName, selection)
|
|
|
1129
3329
|
// src/scaffold.ts
|
|
1130
3330
|
import { execFile } from "node:child_process";
|
|
1131
3331
|
import { createHash } from "node:crypto";
|
|
1132
|
-
import { cp, lstat, mkdir as mkdir4, mkdtemp, readFile as readFile5, readdir, rm as
|
|
3332
|
+
import { cp, lstat, mkdir as mkdir4, mkdtemp, readFile as readFile5, readdir, rm as rm4, stat as stat4, writeFile as writeFile4 } from "node:fs/promises";
|
|
1133
3333
|
import { tmpdir } from "node:os";
|
|
1134
|
-
import { basename, join as
|
|
3334
|
+
import { basename, join as join7, relative, resolve as resolve3 } from "node:path";
|
|
1135
3335
|
import { promisify } from "node:util";
|
|
1136
3336
|
|
|
3337
|
+
// src/delivery.ts
|
|
3338
|
+
import { createWriteStream } from "node:fs";
|
|
3339
|
+
import { rm as rm3 } from "node:fs/promises";
|
|
3340
|
+
import { join as join6 } from "node:path";
|
|
3341
|
+
import { Readable, Transform } from "node:stream";
|
|
3342
|
+
import { pipeline } from "node:stream/promises";
|
|
3343
|
+
var RELEASE_TAG_PATTERN2 = /^v\d+\.\d+\.\d+(?:-rc\.\d+)?$/;
|
|
3344
|
+
var INDEX_TIMEOUT_MS = 15000;
|
|
3345
|
+
var DOWNLOAD_TIMEOUT_MS = 300000;
|
|
3346
|
+
function deliveryBaseUrl(environment = process.env) {
|
|
3347
|
+
const configured = environment[DELIVERY_URL_VARIABLE]?.trim();
|
|
3348
|
+
return (configured || DELIVERY_BASE_URL).replace(/\/+$/, "");
|
|
3349
|
+
}
|
|
3350
|
+
function releaseAssetNames(releaseTag) {
|
|
3351
|
+
const artifact = `foundation-source-${releaseTag}.tar.gz`;
|
|
3352
|
+
return {
|
|
3353
|
+
artifact,
|
|
3354
|
+
checksum: `${artifact}.sha256`,
|
|
3355
|
+
manifest: `foundation-source-${releaseTag}.manifest.json`
|
|
3356
|
+
};
|
|
3357
|
+
}
|
|
3358
|
+
function describeFailure(status, subject) {
|
|
3359
|
+
if (status === 401) {
|
|
3360
|
+
return "That licence key was not accepted. Copy it exactly from your purchase receipt or the customer portal (polar.sh).";
|
|
3361
|
+
}
|
|
3362
|
+
if (status === 429) {
|
|
3363
|
+
return "Too many download requests for this licence key. Wait a minute and try again.";
|
|
3364
|
+
}
|
|
3365
|
+
if (status === 404)
|
|
3366
|
+
return `${subject} is not available for download.`;
|
|
3367
|
+
if (status >= 500) {
|
|
3368
|
+
return "Source delivery is temporarily unavailable. Wait a few minutes and try again.";
|
|
3369
|
+
}
|
|
3370
|
+
return `Source delivery refused the request (HTTP ${status}).`;
|
|
3371
|
+
}
|
|
3372
|
+
async function requestDelivery(url, init, subject) {
|
|
3373
|
+
let response;
|
|
3374
|
+
try {
|
|
3375
|
+
response = await fetch(url, init);
|
|
3376
|
+
} catch {
|
|
3377
|
+
throw new Error("Could not reach source delivery. Check your network connection and try again.");
|
|
3378
|
+
}
|
|
3379
|
+
if (!response.ok)
|
|
3380
|
+
throw new Error(describeFailure(response.status, subject));
|
|
3381
|
+
return response;
|
|
3382
|
+
}
|
|
3383
|
+
async function resolveRelease(licenseKey, baseUrl = deliveryBaseUrl()) {
|
|
3384
|
+
const response = await requestDelivery(`${baseUrl}/v1/releases`, {
|
|
3385
|
+
method: "POST",
|
|
3386
|
+
headers: { "content-type": "application/json" },
|
|
3387
|
+
body: JSON.stringify({ key: licenseKey }),
|
|
3388
|
+
signal: AbortSignal.timeout(INDEX_TIMEOUT_MS)
|
|
3389
|
+
}, "The release index");
|
|
3390
|
+
let index;
|
|
3391
|
+
try {
|
|
3392
|
+
index = await response.json();
|
|
3393
|
+
} catch {
|
|
3394
|
+
index = undefined;
|
|
3395
|
+
}
|
|
3396
|
+
if (!index || !RELEASE_TAG_PATTERN2.test(index.latest) || !Array.isArray(index.versions)) {
|
|
3397
|
+
throw new Error(`Source delivery returned an unreadable release index.`);
|
|
3398
|
+
}
|
|
3399
|
+
return index;
|
|
3400
|
+
}
|
|
3401
|
+
function readContentLength(response) {
|
|
3402
|
+
const header = response.headers.get("content-length");
|
|
3403
|
+
if (!header)
|
|
3404
|
+
return;
|
|
3405
|
+
const total = Number(header);
|
|
3406
|
+
return Number.isSafeInteger(total) && total > 0 ? total : undefined;
|
|
3407
|
+
}
|
|
3408
|
+
function countBytes(total, onBytes) {
|
|
3409
|
+
let received = 0;
|
|
3410
|
+
return new Transform({
|
|
3411
|
+
transform(chunk, _encoding, done) {
|
|
3412
|
+
received += chunk.length;
|
|
3413
|
+
onBytes(received, total);
|
|
3414
|
+
done(null, chunk);
|
|
3415
|
+
}
|
|
3416
|
+
});
|
|
3417
|
+
}
|
|
3418
|
+
async function downloadAsset(licenseKey, releaseTag, assetName, directory, baseUrl = deliveryBaseUrl(), onBytes) {
|
|
3419
|
+
const response = await requestDelivery(`${baseUrl}/v1/source/${encodeURIComponent(releaseTag)}/${encodeURIComponent(assetName)}`, {
|
|
3420
|
+
headers: { authorization: `Bearer ${licenseKey}` },
|
|
3421
|
+
signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS)
|
|
3422
|
+
}, releaseTag);
|
|
3423
|
+
if (!response.body)
|
|
3424
|
+
throw new Error(`Source delivery returned an empty ${assetName}.`);
|
|
3425
|
+
const path = join6(directory, assetName);
|
|
3426
|
+
const source = Readable.fromWeb(response.body);
|
|
3427
|
+
try {
|
|
3428
|
+
if (onBytes) {
|
|
3429
|
+
await pipeline(source, countBytes(readContentLength(response), onBytes), createWriteStream(path));
|
|
3430
|
+
} else {
|
|
3431
|
+
await pipeline(source, createWriteStream(path));
|
|
3432
|
+
}
|
|
3433
|
+
} catch {
|
|
3434
|
+
await rm3(path, { force: true });
|
|
3435
|
+
throw new Error(`Downloading ${assetName} was interrupted. Try again in a few minutes.`);
|
|
3436
|
+
}
|
|
3437
|
+
return path;
|
|
3438
|
+
}
|
|
3439
|
+
|
|
1137
3440
|
// src/core.ts
|
|
1138
3441
|
import { randomBytes } from "node:crypto";
|
|
1139
3442
|
import { extname } from "node:path";
|
|
@@ -1364,7 +3667,49 @@ into this repository.
|
|
|
1364
3667
|
}
|
|
1365
3668
|
return rewritten;
|
|
1366
3669
|
}
|
|
1367
|
-
var
|
|
3670
|
+
var REQUIRED_BUYER_CLI_CONSTANTS = ["CLI_NAME", "CLI_PACKAGE_NAME", "DEFAULT_SCOPE"];
|
|
3671
|
+
function rewriteBuyerCliConstants(content, scope, brandName) {
|
|
3672
|
+
const buyerVariablePrefix = BUYER_CLI_NAME.toUpperCase().replaceAll("-", "_");
|
|
3673
|
+
const buyerConstants = [
|
|
3674
|
+
["CLI_NAME", BUYER_CLI_NAME],
|
|
3675
|
+
["CLI_PACKAGE_NAME", BUYER_CLI_PACKAGE_NAME],
|
|
3676
|
+
["DEFAULT_SCOPE", normalizeScope2(scope)],
|
|
3677
|
+
["SOURCE_BRAND_NAME", brandName],
|
|
3678
|
+
["TEMPLATE_REPOSITORY", "OWNER/REPOSITORY"],
|
|
3679
|
+
["DELIVERY_BASE_URL", "https://releases.example.com"],
|
|
3680
|
+
["DELIVERY_URL_VARIABLE", `${buyerVariablePrefix}_DELIVERY_URL`],
|
|
3681
|
+
["LICENSE_KEY_VARIABLE", `${buyerVariablePrefix}_LICENSE_KEY`],
|
|
3682
|
+
["LICENSE_KEY_PREFIX", "LICENSE-"]
|
|
3683
|
+
];
|
|
3684
|
+
let rewritten = content;
|
|
3685
|
+
for (const [name, value] of buyerConstants) {
|
|
3686
|
+
const declaration = new RegExp(`^export const ${name} = '[^']*'$`, "m");
|
|
3687
|
+
if (!declaration.test(rewritten)) {
|
|
3688
|
+
if (REQUIRED_BUYER_CLI_CONSTANTS.includes(name)) {
|
|
3689
|
+
throw new Error(`Source CLI constants are missing ${name}.`);
|
|
3690
|
+
}
|
|
3691
|
+
continue;
|
|
3692
|
+
}
|
|
3693
|
+
rewritten = rewritten.replace(declaration, `export const ${name} = '${value}'`);
|
|
3694
|
+
}
|
|
3695
|
+
const leaked = [
|
|
3696
|
+
CLI_PACKAGE_NAME,
|
|
3697
|
+
SOURCE_BRAND_NAME,
|
|
3698
|
+
DELIVERY_BASE_URL,
|
|
3699
|
+
DELIVERY_URL_VARIABLE,
|
|
3700
|
+
LICENSE_KEY_VARIABLE2,
|
|
3701
|
+
LICENSE_KEY_PREFIX
|
|
3702
|
+
].filter((identity) => rewritten.includes(identity));
|
|
3703
|
+
if (leaked.length > 0) {
|
|
3704
|
+
throw new Error(`Buyer CLI constants still name the source product: ${leaked.join(", ")}`);
|
|
3705
|
+
}
|
|
3706
|
+
return rewritten;
|
|
3707
|
+
}
|
|
3708
|
+
var SELLER_ONLY_ROOT_SCRIPTS = [
|
|
3709
|
+
"release:distribute",
|
|
3710
|
+
"release:publish-cli",
|
|
3711
|
+
"release:upload"
|
|
3712
|
+
];
|
|
1368
3713
|
function stripSellerOnlyRootScripts(content) {
|
|
1369
3714
|
const manifest = JSON.parse(content);
|
|
1370
3715
|
for (const script of SELLER_ONLY_ROOT_SCRIPTS)
|
|
@@ -1434,14 +3779,14 @@ function isTemplatePathExcluded(relativePath) {
|
|
|
1434
3779
|
return true;
|
|
1435
3780
|
if (normalized === "internal" || normalized.startsWith("internal/"))
|
|
1436
3781
|
return true;
|
|
1437
|
-
if (normalized === ".github/workflows/publish-npm.yml")
|
|
1438
|
-
return true;
|
|
1439
3782
|
if (normalized === ".github/workflows/internal-commercial.yml")
|
|
1440
3783
|
return true;
|
|
1441
3784
|
if (normalized === "apps/worker" || normalized.startsWith("apps/worker/"))
|
|
1442
3785
|
return true;
|
|
1443
3786
|
if (parts.includes("dist") || parts.includes("out"))
|
|
1444
3787
|
return true;
|
|
3788
|
+
if (parts.includes(".next") || parts.includes(".source") || parts.includes(".turbo"))
|
|
3789
|
+
return true;
|
|
1445
3790
|
if (normalized === "bun.lock")
|
|
1446
3791
|
return true;
|
|
1447
3792
|
if (normalized === ".vercelignore")
|
|
@@ -1503,7 +3848,7 @@ async function copyLocalTemplate(source, target) {
|
|
|
1503
3848
|
async function assertNoSymbolicLinks(directory, root = directory, skipExcludedPaths = false) {
|
|
1504
3849
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
1505
3850
|
for (const entry of entries) {
|
|
1506
|
-
const path =
|
|
3851
|
+
const path = join7(directory, entry.name);
|
|
1507
3852
|
const relativePath = relative(root, path);
|
|
1508
3853
|
if (skipExcludedPaths && isTemplatePathExcluded(relativePath))
|
|
1509
3854
|
continue;
|
|
@@ -1526,57 +3871,33 @@ function verifyReleaseMetadata(checksum, manifest, artifactName, digest, templat
|
|
|
1526
3871
|
throw new Error(`${CLI_NAME2} release manifest does not match the downloaded source artifact.`);
|
|
1527
3872
|
}
|
|
1528
3873
|
}
|
|
1529
|
-
async function
|
|
3874
|
+
async function downloadLicensedTemplate(target, licenseKey, sourceVersion, onDownloadProgress) {
|
|
3875
|
+
const baseUrl = deliveryBaseUrl();
|
|
3876
|
+
const releaseTag = sourceVersion ?? (await resolveRelease(licenseKey, baseUrl)).latest;
|
|
3877
|
+
const { artifact, checksum: checksumName, manifest: manifestName } = releaseAssetNames(releaseTag);
|
|
3878
|
+
const temporaryDirectory = await mkdtemp(join7(tmpdir(), `${CLI_NAME2}-`));
|
|
3879
|
+
const extractedPath = join7(temporaryDirectory, "template");
|
|
1530
3880
|
try {
|
|
1531
|
-
await
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
templateRef,
|
|
1535
|
-
"--repo",
|
|
1536
|
-
TEMPLATE_REPOSITORY,
|
|
1537
|
-
"--pattern",
|
|
1538
|
-
fileName,
|
|
1539
|
-
"--dir",
|
|
1540
|
-
directory
|
|
1541
|
-
]);
|
|
1542
|
-
} catch {
|
|
1543
|
-
throw new Error(`Unable to download ${templateRef}. Confirm that GitHub CLI is installed, run ` + `\`gh auth login\`, and accept your ${CLI_NAME2} repository invitation.`);
|
|
1544
|
-
}
|
|
1545
|
-
}
|
|
1546
|
-
async function downloadGitHubTemplate(target, templateRef) {
|
|
1547
|
-
if (!/^v\d+\.\d+\.\d+(?:-rc\.\d+)?$/.test(templateRef)) {
|
|
1548
|
-
throw new Error(`${CLI_NAME2} template reference must be an immutable release tag: ${templateRef}`);
|
|
1549
|
-
}
|
|
1550
|
-
const temporaryDirectory = await mkdtemp(join6(tmpdir(), `${CLI_NAME2}-`));
|
|
1551
|
-
const artifactName = `foundation-source-${templateRef}.tar.gz`;
|
|
1552
|
-
const checksumName = `${artifactName}.sha256`;
|
|
1553
|
-
const manifestName = `foundation-source-${templateRef}.manifest.json`;
|
|
1554
|
-
const archivePath = join6(temporaryDirectory, artifactName);
|
|
1555
|
-
const extractedPath = join6(temporaryDirectory, "template");
|
|
1556
|
-
try {
|
|
1557
|
-
await execFileAsync("gh", ["auth", "status", "--hostname", "github.com"]).catch(() => {
|
|
1558
|
-
throw new Error(`${CLI_NAME2} source access requires GitHub CLI authentication. Run \`gh auth login\` first.`);
|
|
1559
|
-
});
|
|
1560
|
-
await downloadReleaseAsset(templateRef, artifactName, temporaryDirectory);
|
|
1561
|
-
await downloadReleaseAsset(templateRef, checksumName, temporaryDirectory);
|
|
1562
|
-
await downloadReleaseAsset(templateRef, manifestName, temporaryDirectory);
|
|
3881
|
+
const archivePath = await downloadAsset(licenseKey, releaseTag, artifact, temporaryDirectory, baseUrl, onDownloadProgress);
|
|
3882
|
+
await downloadAsset(licenseKey, releaseTag, checksumName, temporaryDirectory, baseUrl);
|
|
3883
|
+
await downloadAsset(licenseKey, releaseTag, manifestName, temporaryDirectory, baseUrl);
|
|
1563
3884
|
const archive = await readFile5(archivePath);
|
|
1564
3885
|
const digest = createHash("sha256").update(archive).digest("hex");
|
|
1565
|
-
const checksum = await readFile5(
|
|
1566
|
-
const manifest = JSON.parse(await readFile5(
|
|
1567
|
-
verifyReleaseMetadata(checksum, manifest,
|
|
3886
|
+
const checksum = await readFile5(join7(temporaryDirectory, checksumName), "utf8");
|
|
3887
|
+
const manifest = JSON.parse(await readFile5(join7(temporaryDirectory, manifestName), "utf8"));
|
|
3888
|
+
verifyReleaseMetadata(checksum, manifest, artifact, digest, releaseTag);
|
|
1568
3889
|
await mkdir4(extractedPath);
|
|
1569
3890
|
await execFileAsync("tar", ["-xzf", archivePath, "-C", extractedPath, "--strip-components=1"]);
|
|
1570
3891
|
await copyLocalTemplate(extractedPath, target);
|
|
1571
3892
|
} finally {
|
|
1572
|
-
await
|
|
3893
|
+
await rm4(temporaryDirectory, { recursive: true, force: true });
|
|
1573
3894
|
}
|
|
1574
3895
|
}
|
|
1575
3896
|
async function walk(directory) {
|
|
1576
3897
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
1577
3898
|
const paths = [];
|
|
1578
3899
|
for (const entry of entries) {
|
|
1579
|
-
const path =
|
|
3900
|
+
const path = join7(directory, entry.name);
|
|
1580
3901
|
if (entry.isSymbolicLink()) {
|
|
1581
3902
|
throw new Error(`Generated template contains a symbolic link: ${path}`);
|
|
1582
3903
|
}
|
|
@@ -1618,7 +3939,7 @@ async function applyScopeRewrite(target, scope) {
|
|
|
1618
3939
|
async function applyBrandRewrite(target, brandName) {
|
|
1619
3940
|
const report = { files: 0, replacements: 0 };
|
|
1620
3941
|
for (const entry of BRAND_MANIFEST) {
|
|
1621
|
-
const path =
|
|
3942
|
+
const path = join7(target, entry.path);
|
|
1622
3943
|
const replacements = await rewriteFile(path, (content) => {
|
|
1623
3944
|
const result = rewriteBrandContent(content, brandName);
|
|
1624
3945
|
if (result.replacements > 0 && path.endsWith(".tsx")) {
|
|
@@ -1633,27 +3954,27 @@ async function applyBrandRewrite(target, brandName) {
|
|
|
1633
3954
|
return report;
|
|
1634
3955
|
}
|
|
1635
3956
|
async function generateEnvironmentFiles(target, databasePort = 5432) {
|
|
1636
|
-
const serverExample = await readFile5(
|
|
1637
|
-
await writeFile4(
|
|
1638
|
-
const webExample = await readFile5(
|
|
1639
|
-
await writeFile4(
|
|
1640
|
-
const docsExample = await readFile5(
|
|
1641
|
-
await writeFile4(
|
|
1642
|
-
await writeFile4(
|
|
3957
|
+
const serverExample = await readFile5(join7(target, "apps/server/.env.example"), "utf8");
|
|
3958
|
+
await writeFile4(join7(target, "apps/server/.env"), generateServerEnv(serverExample, undefined, databasePort));
|
|
3959
|
+
const webExample = await readFile5(join7(target, "apps/web/.env.example"), "utf8");
|
|
3960
|
+
await writeFile4(join7(target, "apps/web/.env"), webExample);
|
|
3961
|
+
const docsExample = await readFile5(join7(target, "apps/docs/.env.example"), "utf8");
|
|
3962
|
+
await writeFile4(join7(target, "apps/docs/.env"), docsExample);
|
|
3963
|
+
await writeFile4(join7(target, ".env"), `POSTGRES_PORT=${databasePort}
|
|
1643
3964
|
`);
|
|
1644
3965
|
}
|
|
1645
3966
|
async function neutralizeAgentInstructions(target) {
|
|
1646
|
-
const agentPath =
|
|
1647
|
-
const claudePath =
|
|
3967
|
+
const agentPath = join7(target, "AGENTS.md");
|
|
3968
|
+
const claudePath = join7(target, "CLAUDE.md");
|
|
1648
3969
|
await writeFile4(agentPath, rewriteBuyerAgentInstructions(await readFile5(agentPath, "utf8")));
|
|
1649
3970
|
await writeFile4(claudePath, rewriteBuyerClaudeInstructions(await readFile5(claudePath, "utf8")));
|
|
1650
|
-
const rootPackagePath =
|
|
3971
|
+
const rootPackagePath = join7(target, "package.json");
|
|
1651
3972
|
await writeFile4(rootPackagePath, stripSellerOnlyRootScripts(await readFile5(rootPackagePath, "utf8")));
|
|
1652
3973
|
}
|
|
1653
3974
|
async function neutralizeSourceCli(target, scope, brandName) {
|
|
1654
3975
|
if (String(CLI_NAME2) === BUYER_CLI_NAME && String(CLI_PACKAGE_NAME) === BUYER_CLI_PACKAGE_NAME)
|
|
1655
3976
|
return;
|
|
1656
|
-
const rootPackagePath =
|
|
3977
|
+
const rootPackagePath = join7(target, "package.json");
|
|
1657
3978
|
const rootPackage = JSON.parse(await readFile5(rootPackagePath, "utf8"));
|
|
1658
3979
|
const sourceScript = rootPackage.scripts?.[CLI_NAME2];
|
|
1659
3980
|
if (!sourceScript)
|
|
@@ -1662,7 +3983,7 @@ async function neutralizeSourceCli(target, scope, brandName) {
|
|
|
1662
3983
|
delete rootPackage.scripts[CLI_NAME2];
|
|
1663
3984
|
await writeFile4(rootPackagePath, `${JSON.stringify(rootPackage, null, 2)}
|
|
1664
3985
|
`);
|
|
1665
|
-
const cliPackagePath =
|
|
3986
|
+
const cliPackagePath = join7(target, "packages/create-app/package.json");
|
|
1666
3987
|
const cliPackage = JSON.parse(await readFile5(cliPackagePath, "utf8"));
|
|
1667
3988
|
if (cliPackage.name !== CLI_PACKAGE_NAME || !cliPackage.bin?.[CLI_NAME2]) {
|
|
1668
3989
|
throw new Error(`Source CLI package must expose ${CLI_PACKAGE_NAME} as ${CLI_NAME2}.`);
|
|
@@ -1670,6 +3991,8 @@ async function neutralizeSourceCli(target, scope, brandName) {
|
|
|
1670
3991
|
cliPackage.bin = { [BUYER_CLI_NAME]: "./src/cli.ts" };
|
|
1671
3992
|
delete cliPackage.description;
|
|
1672
3993
|
delete cliPackage.homepage;
|
|
3994
|
+
delete cliPackage.bugs;
|
|
3995
|
+
delete cliPackage.author;
|
|
1673
3996
|
delete cliPackage.repository;
|
|
1674
3997
|
delete cliPackage.keywords;
|
|
1675
3998
|
delete cliPackage.files;
|
|
@@ -1677,23 +4000,14 @@ async function neutralizeSourceCli(target, scope, brandName) {
|
|
|
1677
4000
|
const { name: _sourceName, version: cliVersion, ...cliPackageRemainder } = cliPackage;
|
|
1678
4001
|
await writeFile4(cliPackagePath, `${JSON.stringify({ name: BUYER_CLI_PACKAGE_NAME, version: cliVersion, private: true, ...cliPackageRemainder }, null, 2)}
|
|
1679
4002
|
`);
|
|
1680
|
-
const constantsPath =
|
|
1681
|
-
|
|
1682
|
-
const
|
|
1683
|
-
const packageDeclaration = `export const CLI_PACKAGE_NAME = '${CLI_PACKAGE_NAME}'`;
|
|
1684
|
-
const scopeDeclaration = `export const DEFAULT_SCOPE = '@app'`;
|
|
1685
|
-
const repositoryDeclaration = `export const TEMPLATE_REPOSITORY = '${TEMPLATE_REPOSITORY}'`;
|
|
1686
|
-
const brandDeclaration = `export const SOURCE_BRAND_NAME = '${SOURCE_BRAND_NAME}'`;
|
|
1687
|
-
if (!constants3.includes(cliDeclaration) || !constants3.includes(packageDeclaration) || !constants3.includes(scopeDeclaration) || !constants3.includes(repositoryDeclaration) || !constants3.includes(brandDeclaration)) {
|
|
1688
|
-
throw new Error("Source CLI constants do not match the package identity.");
|
|
1689
|
-
}
|
|
1690
|
-
await writeFile4(constantsPath, constants3.replace(cliDeclaration, `export const CLI_NAME = '${BUYER_CLI_NAME}'`).replace(packageDeclaration, `export const CLI_PACKAGE_NAME = '${BUYER_CLI_PACKAGE_NAME}'`).replace(scopeDeclaration, `export const DEFAULT_SCOPE = '${normalizeScope2(scope)}'`).replace(repositoryDeclaration, "export const TEMPLATE_REPOSITORY = 'OWNER/REPOSITORY'").replace(brandDeclaration, `export const SOURCE_BRAND_NAME = '${brandName}'`));
|
|
1691
|
-
const brandingPath = join6(target, "docs/golden-paths/customize-branding-design-tokens.md");
|
|
4003
|
+
const constantsPath = join7(target, "packages/create-app/src/constants.ts");
|
|
4004
|
+
await writeFile4(constantsPath, rewriteBuyerCliConstants(await readFile5(constantsPath, "utf8"), scope, brandName));
|
|
4005
|
+
const brandingPath = join7(target, "docs/golden-paths/customize-branding-design-tokens.md");
|
|
1692
4006
|
const branding = await readFile5(brandingPath, "utf8");
|
|
1693
4007
|
await writeFile4(brandingPath, branding.replaceAll(`pnpm ${CLI_NAME2}`, `pnpm ${BUYER_CLI_NAME}`));
|
|
1694
|
-
const setupPath =
|
|
4008
|
+
const setupPath = join7(target, "docs/setup.md");
|
|
1695
4009
|
await writeFile4(setupPath, rewriteBuyerSetupInstructions(await readFile5(setupPath, "utf8")));
|
|
1696
|
-
const releasesPath =
|
|
4010
|
+
const releasesPath = join7(target, "docs/releases.md");
|
|
1697
4011
|
await writeFile4(releasesPath, rewriteBuyerReleaseInstructions(await readFile5(releasesPath, "utf8")));
|
|
1698
4012
|
}
|
|
1699
4013
|
async function initializeRepository(target) {
|
|
@@ -1715,12 +4029,12 @@ async function scaffold(options) {
|
|
|
1715
4029
|
try {
|
|
1716
4030
|
if (options.from)
|
|
1717
4031
|
await copyLocalTemplate(options.from, target);
|
|
1718
|
-
else if (options.
|
|
1719
|
-
await
|
|
1720
|
-
else {
|
|
1721
|
-
throw new Error(`A local source path or
|
|
4032
|
+
else if (options.licenseKey) {
|
|
4033
|
+
await downloadLicensedTemplate(target, options.licenseKey, options.sourceVersion, options.onDownloadProgress);
|
|
4034
|
+
} else {
|
|
4035
|
+
throw new Error(`A local source path or a ${CLI_NAME2} licence key is required.`);
|
|
1722
4036
|
}
|
|
1723
|
-
const packagePath =
|
|
4037
|
+
const packagePath = join7(target, "package.json");
|
|
1724
4038
|
const packageReplacements = await rewriteFile(packagePath, (content) => rewriteRootPackageName(content, options.appName));
|
|
1725
4039
|
const scope = await applyScopeRewrite(target, options.scope);
|
|
1726
4040
|
await neutralizeAgentInstructions(target);
|
|
@@ -1741,7 +4055,7 @@ async function scaffold(options) {
|
|
|
1741
4055
|
}))?.isDirectory()) {
|
|
1742
4056
|
const entries = await readdir(target);
|
|
1743
4057
|
if (entries.length === 0)
|
|
1744
|
-
await
|
|
4058
|
+
await rm4(target, { recursive: true, force: true });
|
|
1745
4059
|
}
|
|
1746
4060
|
throw error;
|
|
1747
4061
|
}
|
|
@@ -1758,6 +4072,8 @@ function usage() {
|
|
|
1758
4072
|
Create a buyer-owned SaaS application from your licensed ${suggestBrandName(CLI_NAME)} release.
|
|
1759
4073
|
|
|
1760
4074
|
Options:
|
|
4075
|
+
--license-key <key> Licence key from your purchase (or set ${LICENSE_KEY_VARIABLE})
|
|
4076
|
+
--source-version <version> Pin an immutable release (default: the latest you are entitled to)
|
|
1761
4077
|
--from <path> Use a local source checkout (maintainer/testing)
|
|
1762
4078
|
--scope <namespace> Advanced workspace namespace override (default: derived from brand)
|
|
1763
4079
|
--brand <name> Display name (default: derived from app name)
|
|
@@ -1802,7 +4118,11 @@ function parseArguments(argv) {
|
|
|
1802
4118
|
const argument = argv[index];
|
|
1803
4119
|
if (argument === "--from")
|
|
1804
4120
|
parsed.from = takeValue3(argv, index++, argument);
|
|
1805
|
-
else if (argument === "--
|
|
4121
|
+
else if (argument === "--license-key")
|
|
4122
|
+
parsed.licenseKey = takeValue3(argv, index++, argument);
|
|
4123
|
+
else if (argument === "--source-version") {
|
|
4124
|
+
parsed.sourceVersion = normalizeSourceVersion(takeValue3(argv, index++, argument));
|
|
4125
|
+
} else if (argument === "--scope")
|
|
1806
4126
|
parsed.scope = takeValue3(argv, index++, argument);
|
|
1807
4127
|
else if (argument === "--brand")
|
|
1808
4128
|
parsed.brandName = takeValue3(argv, index++, argument);
|
|
@@ -1870,28 +4190,60 @@ function suggestScope(brandName, fallbackAppName) {
|
|
|
1870
4190
|
return namespace || fallbackAppName;
|
|
1871
4191
|
}
|
|
1872
4192
|
async function unwrapPrompt(value) {
|
|
1873
|
-
if (
|
|
1874
|
-
|
|
4193
|
+
if (isCancel(value)) {
|
|
4194
|
+
cancel("No project was created.");
|
|
1875
4195
|
throw new CliCancelled;
|
|
1876
4196
|
}
|
|
1877
4197
|
return value;
|
|
1878
4198
|
}
|
|
4199
|
+
function describeTargetConflict(appName) {
|
|
4200
|
+
const target = resolve4(process.cwd(), appName);
|
|
4201
|
+
if (!existsSync(target))
|
|
4202
|
+
return;
|
|
4203
|
+
if (!statSync(target).isDirectory())
|
|
4204
|
+
return `./${appName} already exists as a file.`;
|
|
4205
|
+
if (readdirSync(target).length > 0) {
|
|
4206
|
+
return `./${appName} already exists and is not empty. Pick another name, or remove it first.`;
|
|
4207
|
+
}
|
|
4208
|
+
return;
|
|
4209
|
+
}
|
|
4210
|
+
async function collectLicenseKey(parsed) {
|
|
4211
|
+
const supplied = parsed.licenseKey?.trim() ?? readLicenseKeyFromEnvironment();
|
|
4212
|
+
if (supplied) {
|
|
4213
|
+
const error = validateLicenseKey(supplied);
|
|
4214
|
+
if (error)
|
|
4215
|
+
throw new Error(error);
|
|
4216
|
+
return supplied.trim();
|
|
4217
|
+
}
|
|
4218
|
+
if (parsed.yes || !process.stdin.isTTY) {
|
|
4219
|
+
throw new Error(`A licence key is required. Pass --license-key or set ${LICENSE_KEY_VARIABLE}.`);
|
|
4220
|
+
}
|
|
4221
|
+
const entered = await unwrapPrompt(await password({
|
|
4222
|
+
message: "Licence key",
|
|
4223
|
+
validate: (value) => validateLicenseKey(value ?? "")
|
|
4224
|
+
}));
|
|
4225
|
+
return entered.trim();
|
|
4226
|
+
}
|
|
1879
4227
|
async function collectOptions(parsed) {
|
|
1880
4228
|
if (parsed.yes && !parsed.appName)
|
|
1881
4229
|
throw new Error("Pass an app name when using --yes.");
|
|
1882
4230
|
if (!parsed.yes && !process.stdin.isTTY && !parsed.appName) {
|
|
1883
4231
|
throw new Error("Interactive prompts need a terminal. Pass an app name and --yes instead.");
|
|
1884
4232
|
}
|
|
1885
|
-
const appName = parsed.appName ?? await unwrapPrompt(await
|
|
4233
|
+
const appName = parsed.appName ?? await unwrapPrompt(await text({
|
|
1886
4234
|
message: "App name",
|
|
1887
4235
|
placeholder: "my-saas",
|
|
1888
|
-
validate: (value) => validateAppName(value ?? "")
|
|
4236
|
+
validate: (value) => validateAppName(value ?? "") ?? describeTargetConflict(value ?? "")
|
|
1889
4237
|
}));
|
|
1890
4238
|
const appNameError = validateAppName(appName);
|
|
1891
4239
|
if (appNameError)
|
|
1892
4240
|
throw new Error(appNameError);
|
|
4241
|
+
const targetConflict = describeTargetConflict(appName);
|
|
4242
|
+
if (targetConflict)
|
|
4243
|
+
throw new Error(targetConflict);
|
|
4244
|
+
const licenseKey = parsed.from ? undefined : await collectLicenseKey(parsed);
|
|
1893
4245
|
const suggestedBrand = suggestBrandName(appName);
|
|
1894
|
-
const brandName = parsed.brandName ?? (parsed.yes ? suggestedBrand : await unwrapPrompt(await
|
|
4246
|
+
const brandName = parsed.brandName ?? (parsed.yes ? suggestedBrand : await unwrapPrompt(await text({
|
|
1895
4247
|
message: "Brand name",
|
|
1896
4248
|
placeholder: suggestedBrand,
|
|
1897
4249
|
defaultValue: suggestedBrand,
|
|
@@ -1901,22 +4253,22 @@ async function collectOptions(parsed) {
|
|
|
1901
4253
|
if (brandError)
|
|
1902
4254
|
throw new Error(brandError);
|
|
1903
4255
|
const scope = normalizeScope(parsed.scope ?? suggestScope(brandName, appName));
|
|
1904
|
-
const initializeGit = parsed.initializeGit ?? (parsed.yes ? true : await unwrapPrompt(await
|
|
4256
|
+
const initializeGit = parsed.initializeGit ?? (parsed.yes ? true : await unwrapPrompt(await confirm({
|
|
1905
4257
|
message: "Initialize a Git repository?",
|
|
1906
4258
|
initialValue: true
|
|
1907
4259
|
})));
|
|
1908
|
-
const installDependencies = parsed.installDependencies ?? (parsed.yes ? true : await unwrapPrompt(await
|
|
4260
|
+
const installDependencies = parsed.installDependencies ?? (parsed.yes ? true : await unwrapPrompt(await confirm({
|
|
1909
4261
|
message: "Install dependencies with pnpm?",
|
|
1910
4262
|
initialValue: true
|
|
1911
4263
|
})));
|
|
1912
4264
|
if (parsed.startDevelopment && !installDependencies) {
|
|
1913
4265
|
throw new Error("--start requires dependency installation. Remove --no-install.");
|
|
1914
4266
|
}
|
|
1915
|
-
const startDevelopment = parsed.startDevelopment ?? (parsed.yes || !installDependencies ? false : await unwrapPrompt(await
|
|
4267
|
+
const startDevelopment = parsed.startDevelopment ?? (parsed.yes || !installDependencies ? false : await unwrapPrompt(await confirm({
|
|
1916
4268
|
message: "Start local development now?",
|
|
1917
4269
|
initialValue: true
|
|
1918
4270
|
})));
|
|
1919
|
-
const setupDeployment = parsed.setupDeployment ?? (parsed.yes ? false : await unwrapPrompt(await
|
|
4271
|
+
const setupDeployment = parsed.setupDeployment ?? (parsed.yes ? false : await unwrapPrompt(await confirm({
|
|
1920
4272
|
message: "Set up cloud deployment now?",
|
|
1921
4273
|
initialValue: false
|
|
1922
4274
|
})));
|
|
@@ -1924,6 +4276,8 @@ async function collectOptions(parsed) {
|
|
|
1924
4276
|
return {
|
|
1925
4277
|
appName,
|
|
1926
4278
|
from: parsed.from ? resolve4(parsed.from) : undefined,
|
|
4279
|
+
licenseKey,
|
|
4280
|
+
sourceVersion: parsed.sourceVersion,
|
|
1927
4281
|
scope,
|
|
1928
4282
|
brandName,
|
|
1929
4283
|
initializeGit,
|
|
@@ -1938,15 +4292,6 @@ async function readCliVersion() {
|
|
|
1938
4292
|
throw new Error(`${CLI_NAME} package version is missing.`);
|
|
1939
4293
|
return packageJson.version;
|
|
1940
4294
|
}
|
|
1941
|
-
function templateRefForVersion(version) {
|
|
1942
|
-
if (!/^\d+\.\d+\.\d+(?:-rc\.\d+)?$/.test(version)) {
|
|
1943
|
-
throw new Error(`${CLI_NAME} package version is not release-compatible: ${version}`);
|
|
1944
|
-
}
|
|
1945
|
-
if (version === "0.0.0") {
|
|
1946
|
-
throw new Error(`This pre-release ${CLI_NAME} checkout requires --from <local-source-path>.`);
|
|
1947
|
-
}
|
|
1948
|
-
return `v${version}`;
|
|
1949
|
-
}
|
|
1950
4295
|
async function assertTargetAvailable(target) {
|
|
1951
4296
|
const targetStat = await stat5(target).catch(() => {
|
|
1952
4297
|
return;
|
|
@@ -2008,8 +4353,8 @@ function assertSiblingTarget(source, target) {
|
|
|
2008
4353
|
throw new Error(`Create the new app beside the ${CLI_NAME} source checkout, not inside it.`);
|
|
2009
4354
|
}
|
|
2010
4355
|
}
|
|
2011
|
-
function commandFailureOutput(
|
|
2012
|
-
const output = (stderr.trim() ||
|
|
4356
|
+
function commandFailureOutput(stdout2, stderr) {
|
|
4357
|
+
const output = (stderr.trim() || stdout2.trim()).split(`
|
|
2013
4358
|
`).slice(-12).join(`
|
|
2014
4359
|
`);
|
|
2015
4360
|
return output ? `
|
|
@@ -2017,73 +4362,109 @@ function commandFailureOutput(stdout, stderr) {
|
|
|
2017
4362
|
${output}` : "";
|
|
2018
4363
|
}
|
|
2019
4364
|
async function installDependencies(target) {
|
|
2020
|
-
const { stdout, stderr, exitCode } = await runCaptured2(["pnpm", "install", "--frozen-lockfile"], {
|
|
4365
|
+
const { stdout: stdout2, stderr, exitCode } = await runCaptured2(["pnpm", "install", "--frozen-lockfile"], {
|
|
2021
4366
|
cwd: target,
|
|
2022
4367
|
env: { ...process.env, CI: "1" }
|
|
2023
4368
|
});
|
|
2024
4369
|
if (exitCode !== 0) {
|
|
2025
|
-
throw new Error(`Dependency installation failed.${commandFailureOutput(
|
|
4370
|
+
throw new Error(`Dependency installation failed.${commandFailureOutput(stdout2, stderr)}`);
|
|
2026
4371
|
}
|
|
2027
4372
|
}
|
|
2028
|
-
async function
|
|
2029
|
-
const
|
|
2030
|
-
|
|
2031
|
-
throw new Error(`${command.join(" ")} failed.${commandFailureOutput(stdout, stderr)}`);
|
|
2032
|
-
}
|
|
4373
|
+
async function occupiedDevelopmentPorts() {
|
|
4374
|
+
const results = await Promise.all([5173, 8000].map(async (port) => ({ port, available: await isPortAvailable(port) })));
|
|
4375
|
+
return results.filter((result) => !result.available).map((result) => result.port);
|
|
2033
4376
|
}
|
|
2034
4377
|
async function startDevelopment(target) {
|
|
2035
|
-
|
|
2036
|
-
port,
|
|
2037
|
-
available: await isPortAvailable(port)
|
|
2038
|
-
})))).filter((result) => !result.available).map((result) => result.port);
|
|
2039
|
-
if (occupiedPorts.length > 0) {
|
|
2040
|
-
throw new Error(`Cannot start development because port ${occupiedPorts.join(", ")} is in use.`);
|
|
2041
|
-
}
|
|
2042
|
-
await runStep("Starting local Postgres", "Local Postgres is ready", () => runCapturedCommand(["docker", "compose", "up", "-d", "--wait", "postgres"], target));
|
|
2043
|
-
prompts5.log.info(`Web http://localhost:5173
|
|
4378
|
+
log.info(`Web http://localhost:5173
|
|
2044
4379
|
API http://localhost:8000`);
|
|
2045
|
-
|
|
2046
|
-
const exitCode = await runInherited(["
|
|
4380
|
+
outro("Development servers are starting. Ctrl+C stops app servers; Postgres stays running.");
|
|
4381
|
+
const exitCode = await runInherited(["pnpm", "run", "dev"], { cwd: target });
|
|
2047
4382
|
if (exitCode !== 0 && exitCode !== 130) {
|
|
2048
4383
|
throw new Error(`Development servers exited with code ${exitCode}.`);
|
|
2049
4384
|
}
|
|
2050
4385
|
}
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
4386
|
+
var BYTE_UNITS = ["B", "KB", "MB", "GB"];
|
|
4387
|
+
var BYTE_SCALE = 1024;
|
|
4388
|
+
var PROGRESS_MAX = 100;
|
|
4389
|
+
var PROGRESS_BAR_WIDTH = 40;
|
|
4390
|
+
var PROGRESS_MIN_INTERVAL_MS = 80;
|
|
4391
|
+
var PROGRESS_MIN_DELTA = 0.5;
|
|
4392
|
+
function formatBytes(bytes) {
|
|
4393
|
+
let value = bytes;
|
|
4394
|
+
let unit = 0;
|
|
4395
|
+
while (value >= BYTE_SCALE && unit < BYTE_UNITS.length - 1) {
|
|
4396
|
+
value /= BYTE_SCALE;
|
|
4397
|
+
unit += 1;
|
|
4398
|
+
}
|
|
4399
|
+
return `${unit === 0 ? value : value.toFixed(1)} ${BYTE_UNITS[unit]}`;
|
|
4400
|
+
}
|
|
4401
|
+
function supportsAnimation() {
|
|
4402
|
+
return isTTY(process.stdout) && !isCI();
|
|
4403
|
+
}
|
|
4404
|
+
function createScaffoldReporter(pending, expectsDownload) {
|
|
4405
|
+
if (!expectsDownload || !supportsAnimation())
|
|
4406
|
+
return { handle: spinner() };
|
|
4407
|
+
const bar = progress({
|
|
4408
|
+
style: "heavy",
|
|
4409
|
+
size: PROGRESS_BAR_WIDTH,
|
|
4410
|
+
max: PROGRESS_MAX
|
|
4411
|
+
});
|
|
4412
|
+
let shown = 0;
|
|
4413
|
+
let emittedAt = 0;
|
|
4414
|
+
return {
|
|
4415
|
+
handle: bar,
|
|
4416
|
+
onDownloadProgress: (received, total) => {
|
|
4417
|
+
const percent = total ? Math.min(PROGRESS_MAX, received / total * PROGRESS_MAX) : shown;
|
|
4418
|
+
const finished = total !== undefined && received >= total;
|
|
4419
|
+
const now = performance.now();
|
|
4420
|
+
if (!finished && now - emittedAt < PROGRESS_MIN_INTERVAL_MS && percent - shown < PROGRESS_MIN_DELTA) {
|
|
4421
|
+
return;
|
|
4422
|
+
}
|
|
4423
|
+
emittedAt = now;
|
|
4424
|
+
const label = finished ? pending : total === undefined ? `Downloading source ${formatBytes(received)}` : `Downloading source ${formatBytes(received)} / ${formatBytes(total)}`;
|
|
4425
|
+
bar.advance(percent - shown, label);
|
|
4426
|
+
shown = percent;
|
|
4427
|
+
}
|
|
4428
|
+
};
|
|
4429
|
+
}
|
|
4430
|
+
async function runStep(pending, complete, action, handle) {
|
|
4431
|
+
handle.start(pending);
|
|
2054
4432
|
try {
|
|
2055
4433
|
const result = await action();
|
|
2056
|
-
|
|
4434
|
+
handle.stop(complete);
|
|
2057
4435
|
return result;
|
|
2058
4436
|
} catch (error) {
|
|
2059
|
-
|
|
4437
|
+
handle.error(`${pending} failed`);
|
|
2060
4438
|
throw error;
|
|
2061
4439
|
}
|
|
2062
4440
|
}
|
|
2063
|
-
async function createApplication(options
|
|
4441
|
+
async function createApplication(options) {
|
|
2064
4442
|
const target = resolve4(process.cwd(), options.appName);
|
|
2065
4443
|
await assertTargetAvailable(target);
|
|
2066
4444
|
assertSiblingTarget(options.from, target);
|
|
2067
4445
|
const databasePort = await findAvailablePort();
|
|
2068
4446
|
await mkdir5(dirname2(target), { recursive: true });
|
|
2069
|
-
const staging = await mkdtemp2(
|
|
4447
|
+
const staging = await mkdtemp2(join8(dirname2(target), `.${options.appName}-${CLI_NAME}-`));
|
|
4448
|
+
const preparing = "Preparing your application";
|
|
4449
|
+
const reporter = createScaffoldReporter(preparing, Boolean(options.licenseKey));
|
|
2070
4450
|
try {
|
|
2071
|
-
|
|
2072
|
-
await runStep("Preparing your application", "Application source prepared", () => scaffold({
|
|
4451
|
+
await runStep(preparing, "Application source prepared", () => scaffold({
|
|
2073
4452
|
appName: options.appName,
|
|
2074
4453
|
scope: options.scope,
|
|
2075
4454
|
brandName: options.brandName,
|
|
2076
4455
|
targetDirectory: staging,
|
|
2077
4456
|
from: options.from,
|
|
2078
|
-
|
|
4457
|
+
licenseKey: options.licenseKey,
|
|
4458
|
+
sourceVersion: options.sourceVersion,
|
|
2079
4459
|
initializeGit: options.initializeGit,
|
|
2080
|
-
databasePort
|
|
2081
|
-
|
|
4460
|
+
databasePort,
|
|
4461
|
+
onDownloadProgress: reporter.onDownloadProgress
|
|
4462
|
+
}), reporter.handle);
|
|
2082
4463
|
if (options.deployment) {
|
|
2083
|
-
await runStep("Configuring deployment", "Deployment target locked", () => applyDeploymentSelection2(staging, options.appName, options.deployment));
|
|
4464
|
+
await runStep("Configuring deployment", "Deployment target locked", () => applyDeploymentSelection2(staging, options.appName, options.deployment), spinner());
|
|
2084
4465
|
}
|
|
2085
4466
|
if (options.installDependencies) {
|
|
2086
|
-
await runStep("Installing dependencies with pnpm", "Dependencies installed with pnpm", () => installDependencies(staging), "timer");
|
|
4467
|
+
await runStep("Installing dependencies with pnpm", "Dependencies installed with pnpm", () => installDependencies(staging), spinner({ indicator: "timer" }));
|
|
2087
4468
|
}
|
|
2088
4469
|
if (await stat5(target).catch(() => {
|
|
2089
4470
|
return;
|
|
@@ -2092,7 +4473,7 @@ async function createApplication(options, version) {
|
|
|
2092
4473
|
await rename2(staging, target);
|
|
2093
4474
|
return { target, databasePort };
|
|
2094
4475
|
} catch (error) {
|
|
2095
|
-
await
|
|
4476
|
+
await rm5(staging, { recursive: true, force: true });
|
|
2096
4477
|
throw error;
|
|
2097
4478
|
}
|
|
2098
4479
|
}
|
|
@@ -2101,16 +4482,16 @@ function completionDetails(target, options, databasePort) {
|
|
|
2101
4482
|
const install = options.installDependencies ? [] : ["vp install --frozen-lockfile"];
|
|
2102
4483
|
return {
|
|
2103
4484
|
directory: `./${targetName}`,
|
|
2104
|
-
commands: [
|
|
2105
|
-
`cd ${targetName}`,
|
|
2106
|
-
...install,
|
|
2107
|
-
"docker compose up -d postgres",
|
|
2108
|
-
"vp run -r --parallel dev"
|
|
2109
|
-
].join(`
|
|
4485
|
+
commands: [`cd ${targetName}`, ...install, "pnpm dev"].join(`
|
|
2110
4486
|
`),
|
|
2111
4487
|
database: `Postgres localhost:${databasePort}`
|
|
2112
4488
|
};
|
|
2113
4489
|
}
|
|
4490
|
+
function printRunnableCommands(commands) {
|
|
4491
|
+
console.log(`
|
|
4492
|
+
${commands}
|
|
4493
|
+
`);
|
|
4494
|
+
}
|
|
2114
4495
|
async function main() {
|
|
2115
4496
|
const argv = process.argv.slice(2);
|
|
2116
4497
|
if (argv[0] === "agent") {
|
|
@@ -2135,32 +4516,40 @@ async function main() {
|
|
|
2135
4516
|
console.log(version);
|
|
2136
4517
|
return;
|
|
2137
4518
|
}
|
|
2138
|
-
|
|
4519
|
+
intro(`${suggestBrandName(CLI_NAME)} ${version} \xB7 production SaaS foundation`);
|
|
2139
4520
|
const options = await collectOptions(parsed);
|
|
2140
|
-
const { target, databasePort } = await createApplication(options
|
|
4521
|
+
const { target, databasePort } = await createApplication(options);
|
|
2141
4522
|
const completion = completionDetails(target, options, databasePort);
|
|
2142
|
-
|
|
4523
|
+
log.success(`Created ${completion.directory}`);
|
|
2143
4524
|
if (!options.startDevelopment) {
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
prompts5.log.info(`Web http://localhost:5173
|
|
4525
|
+
log.step("Run locally");
|
|
4526
|
+
log.info(`Web http://localhost:5173
|
|
2147
4527
|
API http://localhost:8000
|
|
2148
4528
|
${completion.database}`);
|
|
2149
4529
|
if (options.deployment) {
|
|
2150
|
-
|
|
4530
|
+
log.info(`Deployment ${options.deployment.cloud.toUpperCase()} + ${options.deployment.storageProvider} + ${options.deployment.frontendTarget} locked. Review deployment/README.md.`);
|
|
2151
4531
|
} else {
|
|
2152
|
-
|
|
4532
|
+
log.info("Deployment deferred. Run `pnpm deploy:configure` when you are ready.");
|
|
2153
4533
|
}
|
|
2154
|
-
|
|
4534
|
+
outro(`${options.brandName} is ready.`);
|
|
4535
|
+
printRunnableCommands(completion.commands);
|
|
4536
|
+
return;
|
|
4537
|
+
}
|
|
4538
|
+
const occupiedPorts = await occupiedDevelopmentPorts();
|
|
4539
|
+
if (occupiedPorts.length > 0) {
|
|
4540
|
+
log.warn(`Port ${occupiedPorts.join(" and ")} already in use, so the development servers were not started.`);
|
|
4541
|
+
log.step("Free the port, then run");
|
|
4542
|
+
outro(`${options.brandName} is ready at ${completion.directory}.`);
|
|
4543
|
+
printRunnableCommands(completion.commands);
|
|
2155
4544
|
return;
|
|
2156
4545
|
}
|
|
2157
4546
|
try {
|
|
2158
4547
|
await startDevelopment(target);
|
|
2159
4548
|
} catch (error) {
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
4549
|
+
log.error(error instanceof Error ? error.message : String(error));
|
|
4550
|
+
log.step("Start it manually");
|
|
4551
|
+
outro(`${options.brandName} is ready at ${completion.directory}.`);
|
|
4552
|
+
printRunnableCommands(completion.commands);
|
|
2164
4553
|
process.exitCode = 1;
|
|
2165
4554
|
}
|
|
2166
4555
|
}
|
|
@@ -2168,16 +4557,20 @@ if (isEntrypoint(import.meta.url)) {
|
|
|
2168
4557
|
main().catch((error) => {
|
|
2169
4558
|
if (error instanceof CliCancelled)
|
|
2170
4559
|
return;
|
|
2171
|
-
|
|
2172
|
-
|
|
4560
|
+
log.error(error instanceof Error ? error.message : String(error));
|
|
4561
|
+
outro("No project was created.");
|
|
2173
4562
|
process.exitCode = 1;
|
|
2174
4563
|
});
|
|
2175
4564
|
}
|
|
2176
4565
|
export {
|
|
2177
4566
|
usage,
|
|
2178
|
-
templateRefForVersion,
|
|
2179
4567
|
suggestScope,
|
|
2180
4568
|
suggestBrandName,
|
|
4569
|
+
printRunnableCommands,
|
|
2181
4570
|
parseArguments,
|
|
2182
|
-
|
|
4571
|
+
occupiedDevelopmentPorts,
|
|
4572
|
+
formatBytes,
|
|
4573
|
+
findAvailablePort,
|
|
4574
|
+
describeTargetConflict,
|
|
4575
|
+
collectLicenseKey
|
|
2183
4576
|
};
|