amina 3.3.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/dist/index.js +2430 -0
- package/package.json +42 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2430 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
12
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
+
var cached = cache.get(mod);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
20
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
21
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
22
|
+
for (let key of __getOwnPropNames(mod))
|
|
23
|
+
if (!__hasOwnProp.call(to, key))
|
|
24
|
+
__defProp(to, key, {
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
26
|
+
enumerable: true
|
|
27
|
+
});
|
|
28
|
+
if (canCache)
|
|
29
|
+
cache.set(mod, to);
|
|
30
|
+
return to;
|
|
31
|
+
};
|
|
32
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
33
|
+
|
|
34
|
+
// ../node_modules/.bun/sisteransi@1.0.5/node_modules/sisteransi/src/index.js
|
|
35
|
+
var require_src = __commonJS((exports, module) => {
|
|
36
|
+
var ESC = "\x1B";
|
|
37
|
+
var CSI = `${ESC}[`;
|
|
38
|
+
var beep = "\x07";
|
|
39
|
+
var cursor = {
|
|
40
|
+
to(x, y) {
|
|
41
|
+
if (!y)
|
|
42
|
+
return `${CSI}${x + 1}G`;
|
|
43
|
+
return `${CSI}${y + 1};${x + 1}H`;
|
|
44
|
+
},
|
|
45
|
+
move(x, y) {
|
|
46
|
+
let ret = "";
|
|
47
|
+
if (x < 0)
|
|
48
|
+
ret += `${CSI}${-x}D`;
|
|
49
|
+
else if (x > 0)
|
|
50
|
+
ret += `${CSI}${x}C`;
|
|
51
|
+
if (y < 0)
|
|
52
|
+
ret += `${CSI}${-y}A`;
|
|
53
|
+
else if (y > 0)
|
|
54
|
+
ret += `${CSI}${y}B`;
|
|
55
|
+
return ret;
|
|
56
|
+
},
|
|
57
|
+
up: (count = 1) => `${CSI}${count}A`,
|
|
58
|
+
down: (count = 1) => `${CSI}${count}B`,
|
|
59
|
+
forward: (count = 1) => `${CSI}${count}C`,
|
|
60
|
+
backward: (count = 1) => `${CSI}${count}D`,
|
|
61
|
+
nextLine: (count = 1) => `${CSI}E`.repeat(count),
|
|
62
|
+
prevLine: (count = 1) => `${CSI}F`.repeat(count),
|
|
63
|
+
left: `${CSI}G`,
|
|
64
|
+
hide: `${CSI}?25l`,
|
|
65
|
+
show: `${CSI}?25h`,
|
|
66
|
+
save: `${ESC}7`,
|
|
67
|
+
restore: `${ESC}8`
|
|
68
|
+
};
|
|
69
|
+
var scroll = {
|
|
70
|
+
up: (count = 1) => `${CSI}S`.repeat(count),
|
|
71
|
+
down: (count = 1) => `${CSI}T`.repeat(count)
|
|
72
|
+
};
|
|
73
|
+
var erase = {
|
|
74
|
+
screen: `${CSI}2J`,
|
|
75
|
+
up: (count = 1) => `${CSI}1J`.repeat(count),
|
|
76
|
+
down: (count = 1) => `${CSI}J`.repeat(count),
|
|
77
|
+
line: `${CSI}2K`,
|
|
78
|
+
lineEnd: `${CSI}K`,
|
|
79
|
+
lineStart: `${CSI}1K`,
|
|
80
|
+
lines(count) {
|
|
81
|
+
let clear = "";
|
|
82
|
+
for (let i = 0;i < count; i++)
|
|
83
|
+
clear += this.line + (i < count - 1 ? cursor.up() : "");
|
|
84
|
+
if (count)
|
|
85
|
+
clear += cursor.left;
|
|
86
|
+
return clear;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
module.exports = { cursor, scroll, erase, beep };
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// src/index.ts
|
|
93
|
+
import { fileURLToPath } from "node:url";
|
|
94
|
+
|
|
95
|
+
// src/check.ts
|
|
96
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
97
|
+
import path from "node:path";
|
|
98
|
+
var RELEASE_API_URL = "https://api.github.com/repos/iamvikshan/amina/releases/latest";
|
|
99
|
+
var GITHUB_RELEASE_URL = "https://github.com/iamvikshan/amina/releases/latest";
|
|
100
|
+
var GITLAB_RELEASE_URL = "https://gitlab.com/vikshan/amina/-/releases";
|
|
101
|
+
var GHCR_IMAGE = "ghcr.io/iamvikshan/amina";
|
|
102
|
+
var GITLAB_IMAGE = "registry.gitlab.com/vikshan/amina";
|
|
103
|
+
var PACKAGE_NAME = "amina";
|
|
104
|
+
function normalizeVersion(version) {
|
|
105
|
+
return version.trim().replace(/^v/, "");
|
|
106
|
+
}
|
|
107
|
+
function compareVersions(left, right) {
|
|
108
|
+
const leftParts = parseVersion(left);
|
|
109
|
+
const rightParts = parseVersion(right);
|
|
110
|
+
for (let index = 0;index < 3; index++) {
|
|
111
|
+
const difference = leftParts.core[index] - rightParts.core[index];
|
|
112
|
+
if (difference !== 0) {
|
|
113
|
+
return difference;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (leftParts.prerelease.length === 0 && rightParts.prerelease.length === 0) {
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
if (leftParts.prerelease.length === 0) {
|
|
120
|
+
return 1;
|
|
121
|
+
}
|
|
122
|
+
if (rightParts.prerelease.length === 0) {
|
|
123
|
+
return -1;
|
|
124
|
+
}
|
|
125
|
+
const sharedLength = Math.max(leftParts.prerelease.length, rightParts.prerelease.length);
|
|
126
|
+
for (let index = 0;index < sharedLength; index++) {
|
|
127
|
+
const leftIdentifier = leftParts.prerelease[index];
|
|
128
|
+
const rightIdentifier = rightParts.prerelease[index];
|
|
129
|
+
if (leftIdentifier === undefined) {
|
|
130
|
+
return -1;
|
|
131
|
+
}
|
|
132
|
+
if (rightIdentifier === undefined) {
|
|
133
|
+
return 1;
|
|
134
|
+
}
|
|
135
|
+
const leftNumber = toNumericIdentifier(leftIdentifier);
|
|
136
|
+
const rightNumber = toNumericIdentifier(rightIdentifier);
|
|
137
|
+
if (leftNumber !== null && rightNumber !== null) {
|
|
138
|
+
const difference = leftNumber - rightNumber;
|
|
139
|
+
if (difference !== 0) {
|
|
140
|
+
return difference;
|
|
141
|
+
}
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (leftNumber !== null) {
|
|
145
|
+
return -1;
|
|
146
|
+
}
|
|
147
|
+
if (rightNumber !== null) {
|
|
148
|
+
return 1;
|
|
149
|
+
}
|
|
150
|
+
if (leftIdentifier < rightIdentifier) {
|
|
151
|
+
return -1;
|
|
152
|
+
}
|
|
153
|
+
if (leftIdentifier > rightIdentifier) {
|
|
154
|
+
return 1;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return 0;
|
|
158
|
+
}
|
|
159
|
+
function findLocalVersion(startDirectory, dependencies = {}) {
|
|
160
|
+
const fileExists = dependencies.fileExists ?? existsSync;
|
|
161
|
+
const readFile = dependencies.readFile ?? readFileSyncUtf8;
|
|
162
|
+
let currentDirectory = path.resolve(startDirectory);
|
|
163
|
+
while (true) {
|
|
164
|
+
const packageJsonPath = path.join(currentDirectory, "package.json");
|
|
165
|
+
if (fileExists(packageJsonPath)) {
|
|
166
|
+
let packageJson = null;
|
|
167
|
+
try {
|
|
168
|
+
packageJson = parsePackageJson(readFile(packageJsonPath));
|
|
169
|
+
} catch (caughtError) {
|
|
170
|
+
if (!(caughtError instanceof SyntaxError)) {
|
|
171
|
+
throw caughtError;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (packageJson?.name === PACKAGE_NAME && typeof packageJson.version === "string" && packageJson.version.trim() !== "") {
|
|
175
|
+
return normalizeVersion(packageJson.version);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const parentDirectory = path.dirname(currentDirectory);
|
|
179
|
+
if (parentDirectory === currentDirectory) {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
currentDirectory = parentDirectory;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
async function fetchLatestRelease(fetchImpl = fetch) {
|
|
186
|
+
const response = await fetchImpl(RELEASE_API_URL, {
|
|
187
|
+
headers: {
|
|
188
|
+
accept: "application/vnd.github+json",
|
|
189
|
+
"user-agent": "amina"
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
if (!response.ok) {
|
|
193
|
+
throw new Error(`GitHub latest release request failed with ${response.status} ${response.statusText}`.trim());
|
|
194
|
+
}
|
|
195
|
+
const payload = await response.json();
|
|
196
|
+
if (typeof payload.tag_name !== "string" || payload.tag_name.trim() === "") {
|
|
197
|
+
throw new Error("GitHub latest release response did not include tag_name");
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
latestTag: payload.tag_name,
|
|
201
|
+
latestVersion: normalizeVersion(payload.tag_name),
|
|
202
|
+
releaseUrl: typeof payload.html_url === "string" && payload.html_url.trim() !== "" ? payload.html_url : GITHUB_RELEASE_URL
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function formatCliOutput(latestRelease, localVersion) {
|
|
206
|
+
if (!localVersion) {
|
|
207
|
+
return [
|
|
208
|
+
`Latest Amina release: ${latestRelease.latestVersion}`,
|
|
209
|
+
"Local Amina version could not be detected.",
|
|
210
|
+
...createUpgradeInstructions(latestRelease.releaseUrl)
|
|
211
|
+
];
|
|
212
|
+
}
|
|
213
|
+
const comparison = compareVersions(localVersion, latestRelease.latestVersion);
|
|
214
|
+
if (comparison === 0) {
|
|
215
|
+
return [
|
|
216
|
+
"Amina is up to date.",
|
|
217
|
+
`Current version: ${localVersion}`,
|
|
218
|
+
`Latest release: ${latestRelease.latestVersion}`
|
|
219
|
+
];
|
|
220
|
+
}
|
|
221
|
+
if (comparison > 0) {
|
|
222
|
+
return [
|
|
223
|
+
"Local version is newer than the latest published release.",
|
|
224
|
+
`Current version: ${localVersion}`,
|
|
225
|
+
`Latest release: ${latestRelease.latestVersion}`
|
|
226
|
+
];
|
|
227
|
+
}
|
|
228
|
+
return [
|
|
229
|
+
`Update available: ${localVersion} -> ${latestRelease.latestVersion}`,
|
|
230
|
+
...createUpgradeInstructions(latestRelease.releaseUrl)
|
|
231
|
+
];
|
|
232
|
+
}
|
|
233
|
+
async function runCheck(dependencies = {}) {
|
|
234
|
+
const cwd = dependencies.cwd ?? process.cwd();
|
|
235
|
+
const log = dependencies.log ?? console.log;
|
|
236
|
+
const error = dependencies.error ?? console.error;
|
|
237
|
+
try {
|
|
238
|
+
const latestRelease = await fetchLatestRelease(dependencies.fetchImpl);
|
|
239
|
+
const localVersion = findLocalVersion(cwd, dependencies);
|
|
240
|
+
for (const line of formatCliOutput(latestRelease, localVersion)) {
|
|
241
|
+
log(line);
|
|
242
|
+
}
|
|
243
|
+
return 0;
|
|
244
|
+
} catch (caughtError) {
|
|
245
|
+
const message = caughtError instanceof Error ? caughtError.message : "Unknown error";
|
|
246
|
+
error(`Failed to check the latest Amina release: ${message}`);
|
|
247
|
+
return 1;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function createUpgradeInstructions(releaseUrl) {
|
|
251
|
+
return [
|
|
252
|
+
"Source releases (GitHub/GitLab source archives only):",
|
|
253
|
+
`- GitHub: ${releaseUrl}`,
|
|
254
|
+
`- GitLab: ${GITLAB_RELEASE_URL}`,
|
|
255
|
+
"Container images:",
|
|
256
|
+
`- GHCR: docker pull ${GHCR_IMAGE}:latest`,
|
|
257
|
+
`- GitLab Registry: docker pull ${GITLAB_IMAGE}:latest`,
|
|
258
|
+
"After updating the source or image, restart Amina with your usual deployment process."
|
|
259
|
+
];
|
|
260
|
+
}
|
|
261
|
+
function parseVersion(version) {
|
|
262
|
+
const normalizedVersion = normalizeVersion(version);
|
|
263
|
+
const [mainPart, prereleasePart = ""] = normalizedVersion.split("-", 2);
|
|
264
|
+
const core = mainPart.split(".");
|
|
265
|
+
if (core.length !== 3 || core.some((part) => !/^\d+$/.test(part))) {
|
|
266
|
+
throw new Error(`Invalid semantic version: ${version}`);
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
core: [Number(core[0]), Number(core[1]), Number(core[2])],
|
|
270
|
+
prerelease: prereleasePart === "" ? [] : prereleasePart.split(".").filter((part) => part !== "")
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
function parsePackageJson(contents) {
|
|
274
|
+
return JSON.parse(contents);
|
|
275
|
+
}
|
|
276
|
+
function readFileSyncUtf8(filePath) {
|
|
277
|
+
return readFileSync(filePath, "utf8");
|
|
278
|
+
}
|
|
279
|
+
function toNumericIdentifier(identifier) {
|
|
280
|
+
return /^\d+$/.test(identifier) ? Number(identifier) : null;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// src/install.ts
|
|
284
|
+
import {
|
|
285
|
+
existsSync as existsSync2,
|
|
286
|
+
writeFileSync,
|
|
287
|
+
chmodSync,
|
|
288
|
+
mkdirSync,
|
|
289
|
+
rmSync,
|
|
290
|
+
copyFileSync
|
|
291
|
+
} from "node:fs";
|
|
292
|
+
import path2 from "node:path";
|
|
293
|
+
|
|
294
|
+
// src/shared.ts
|
|
295
|
+
import { spawnSync } from "node:child_process";
|
|
296
|
+
|
|
297
|
+
// ../node_modules/.bun/@clack+core@1.1.0/node_modules/@clack/core/dist/index.mjs
|
|
298
|
+
var import_sisteransi = __toESM(require_src(), 1);
|
|
299
|
+
import { styleText as D } from "node:util";
|
|
300
|
+
import { stdout as R, stdin as q } from "node:process";
|
|
301
|
+
import * as k from "node:readline";
|
|
302
|
+
import ot from "node:readline";
|
|
303
|
+
import { ReadStream as J } from "node:tty";
|
|
304
|
+
function x(t, e, s) {
|
|
305
|
+
if (!s.some((u) => !u.disabled))
|
|
306
|
+
return t;
|
|
307
|
+
const i = t + e, r = Math.max(s.length - 1, 0), n = i < 0 ? r : i > r ? 0 : i;
|
|
308
|
+
return s[n].disabled ? x(n, e < 0 ? -1 : 1, s) : n;
|
|
309
|
+
}
|
|
310
|
+
var at = (t) => t === 161 || t === 164 || t === 167 || t === 168 || t === 170 || t === 173 || t === 174 || t >= 176 && t <= 180 || t >= 182 && t <= 186 || t >= 188 && t <= 191 || t === 198 || t === 208 || t === 215 || t === 216 || t >= 222 && t <= 225 || t === 230 || t >= 232 && t <= 234 || t === 236 || t === 237 || t === 240 || t === 242 || t === 243 || t >= 247 && t <= 250 || t === 252 || t === 254 || t === 257 || t === 273 || t === 275 || t === 283 || t === 294 || t === 295 || t === 299 || t >= 305 && t <= 307 || t === 312 || t >= 319 && t <= 322 || t === 324 || t >= 328 && t <= 331 || t === 333 || t === 338 || t === 339 || t === 358 || t === 359 || t === 363 || t === 462 || t === 464 || t === 466 || t === 468 || t === 470 || t === 472 || t === 474 || t === 476 || t === 593 || t === 609 || t === 708 || t === 711 || t >= 713 && t <= 715 || t === 717 || t === 720 || t >= 728 && t <= 731 || t === 733 || t === 735 || t >= 768 && t <= 879 || t >= 913 && t <= 929 || t >= 931 && t <= 937 || t >= 945 && t <= 961 || t >= 963 && t <= 969 || t === 1025 || t >= 1040 && t <= 1103 || t === 1105 || t === 8208 || t >= 8211 && t <= 8214 || t === 8216 || t === 8217 || t === 8220 || t === 8221 || t >= 8224 && t <= 8226 || t >= 8228 && t <= 8231 || t === 8240 || t === 8242 || t === 8243 || t === 8245 || t === 8251 || t === 8254 || t === 8308 || t === 8319 || t >= 8321 && t <= 8324 || t === 8364 || t === 8451 || t === 8453 || t === 8457 || t === 8467 || t === 8470 || t === 8481 || t === 8482 || t === 8486 || t === 8491 || t === 8531 || t === 8532 || t >= 8539 && t <= 8542 || t >= 8544 && t <= 8555 || t >= 8560 && t <= 8569 || t === 8585 || t >= 8592 && t <= 8601 || t === 8632 || t === 8633 || t === 8658 || t === 8660 || t === 8679 || t === 8704 || t === 8706 || t === 8707 || t === 8711 || t === 8712 || t === 8715 || t === 8719 || t === 8721 || t === 8725 || t === 8730 || t >= 8733 && t <= 8736 || t === 8739 || t === 8741 || t >= 8743 && t <= 8748 || t === 8750 || t >= 8756 && t <= 8759 || t === 8764 || t === 8765 || t === 8776 || t === 8780 || t === 8786 || t === 8800 || t === 8801 || t >= 8804 && t <= 8807 || t === 8810 || t === 8811 || t === 8814 || t === 8815 || t === 8834 || t === 8835 || t === 8838 || t === 8839 || t === 8853 || t === 8857 || t === 8869 || t === 8895 || t === 8978 || t >= 9312 && t <= 9449 || t >= 9451 && t <= 9547 || t >= 9552 && t <= 9587 || t >= 9600 && t <= 9615 || t >= 9618 && t <= 9621 || t === 9632 || t === 9633 || t >= 9635 && t <= 9641 || t === 9650 || t === 9651 || t === 9654 || t === 9655 || t === 9660 || t === 9661 || t === 9664 || t === 9665 || t >= 9670 && t <= 9672 || t === 9675 || t >= 9678 && t <= 9681 || t >= 9698 && t <= 9701 || t === 9711 || t === 9733 || t === 9734 || t === 9737 || t === 9742 || t === 9743 || t === 9756 || t === 9758 || t === 9792 || t === 9794 || t === 9824 || t === 9825 || t >= 9827 && t <= 9829 || t >= 9831 && t <= 9834 || t === 9836 || t === 9837 || t === 9839 || t === 9886 || t === 9887 || t === 9919 || t >= 9926 && t <= 9933 || t >= 9935 && t <= 9939 || t >= 9941 && t <= 9953 || t === 9955 || t === 9960 || t === 9961 || t >= 9963 && t <= 9969 || t === 9972 || t >= 9974 && t <= 9977 || t === 9979 || t === 9980 || t === 9982 || t === 9983 || t === 10045 || t >= 10102 && t <= 10111 || t >= 11094 && t <= 11097 || t >= 12872 && t <= 12879 || t >= 57344 && t <= 63743 || t >= 65024 && t <= 65039 || t === 65533 || t >= 127232 && t <= 127242 || t >= 127248 && t <= 127277 || t >= 127280 && t <= 127337 || t >= 127344 && t <= 127373 || t === 127375 || t === 127376 || t >= 127387 && t <= 127404 || t >= 917760 && t <= 917999 || t >= 983040 && t <= 1048573 || t >= 1048576 && t <= 1114109;
|
|
311
|
+
var lt = (t) => t === 12288 || t >= 65281 && t <= 65376 || t >= 65504 && t <= 65510;
|
|
312
|
+
var ht = (t) => t >= 4352 && t <= 4447 || t === 8986 || t === 8987 || t === 9001 || t === 9002 || t >= 9193 && t <= 9196 || t === 9200 || t === 9203 || t === 9725 || t === 9726 || t === 9748 || t === 9749 || t >= 9800 && t <= 9811 || t === 9855 || t === 9875 || t === 9889 || t === 9898 || t === 9899 || t === 9917 || t === 9918 || t === 9924 || t === 9925 || t === 9934 || t === 9940 || t === 9962 || t === 9970 || t === 9971 || t === 9973 || t === 9978 || t === 9981 || t === 9989 || t === 9994 || t === 9995 || t === 10024 || t === 10060 || t === 10062 || t >= 10067 && t <= 10069 || t === 10071 || t >= 10133 && t <= 10135 || t === 10160 || t === 10175 || t === 11035 || t === 11036 || t === 11088 || t === 11093 || t >= 11904 && t <= 11929 || t >= 11931 && t <= 12019 || t >= 12032 && t <= 12245 || t >= 12272 && t <= 12287 || t >= 12289 && t <= 12350 || t >= 12353 && t <= 12438 || t >= 12441 && t <= 12543 || t >= 12549 && t <= 12591 || t >= 12593 && t <= 12686 || t >= 12688 && t <= 12771 || t >= 12783 && t <= 12830 || t >= 12832 && t <= 12871 || t >= 12880 && t <= 19903 || t >= 19968 && t <= 42124 || t >= 42128 && t <= 42182 || t >= 43360 && t <= 43388 || t >= 44032 && t <= 55203 || t >= 63744 && t <= 64255 || t >= 65040 && t <= 65049 || t >= 65072 && t <= 65106 || t >= 65108 && t <= 65126 || t >= 65128 && t <= 65131 || t >= 94176 && t <= 94180 || t === 94192 || t === 94193 || t >= 94208 && t <= 100343 || t >= 100352 && t <= 101589 || t >= 101632 && t <= 101640 || t >= 110576 && t <= 110579 || t >= 110581 && t <= 110587 || t === 110589 || t === 110590 || t >= 110592 && t <= 110882 || t === 110898 || t >= 110928 && t <= 110930 || t === 110933 || t >= 110948 && t <= 110951 || t >= 110960 && t <= 111355 || t === 126980 || t === 127183 || t === 127374 || t >= 127377 && t <= 127386 || t >= 127488 && t <= 127490 || t >= 127504 && t <= 127547 || t >= 127552 && t <= 127560 || t === 127568 || t === 127569 || t >= 127584 && t <= 127589 || t >= 127744 && t <= 127776 || t >= 127789 && t <= 127797 || t >= 127799 && t <= 127868 || t >= 127870 && t <= 127891 || t >= 127904 && t <= 127946 || t >= 127951 && t <= 127955 || t >= 127968 && t <= 127984 || t === 127988 || t >= 127992 && t <= 128062 || t === 128064 || t >= 128066 && t <= 128252 || t >= 128255 && t <= 128317 || t >= 128331 && t <= 128334 || t >= 128336 && t <= 128359 || t === 128378 || t === 128405 || t === 128406 || t === 128420 || t >= 128507 && t <= 128591 || t >= 128640 && t <= 128709 || t === 128716 || t >= 128720 && t <= 128722 || t >= 128725 && t <= 128727 || t >= 128732 && t <= 128735 || t === 128747 || t === 128748 || t >= 128756 && t <= 128764 || t >= 128992 && t <= 129003 || t === 129008 || t >= 129292 && t <= 129338 || t >= 129340 && t <= 129349 || t >= 129351 && t <= 129535 || t >= 129648 && t <= 129660 || t >= 129664 && t <= 129672 || t >= 129680 && t <= 129725 || t >= 129727 && t <= 129733 || t >= 129742 && t <= 129755 || t >= 129760 && t <= 129768 || t >= 129776 && t <= 129784 || t >= 131072 && t <= 196605 || t >= 196608 && t <= 262141;
|
|
313
|
+
var O = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/y;
|
|
314
|
+
var y = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
315
|
+
var L = /\t{1,1000}/y;
|
|
316
|
+
var P = /[\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;
|
|
317
|
+
var M = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
|
|
318
|
+
var ct = /\p{M}+/gu;
|
|
319
|
+
var ft = { limit: 1 / 0, ellipsis: "" };
|
|
320
|
+
var X = (t, e = {}, s = {}) => {
|
|
321
|
+
const i = e.limit ?? 1 / 0, r = e.ellipsis ?? "", n = e?.ellipsisWidth ?? (r ? X(r, ft, s).width : 0), u = s.ansiWidth ?? 0, a = s.controlWidth ?? 0, l = s.tabWidth ?? 8, E = s.ambiguousWidth ?? 1, g = s.emojiWidth ?? 2, m = s.fullWidthWidth ?? 2, A = s.regularWidth ?? 1, V = s.wideWidth ?? 2;
|
|
322
|
+
let h = 0, o = 0, p = t.length, v = 0, F = false, d = p, b = Math.max(0, i - n), C = 0, w = 0, c = 0, f = 0;
|
|
323
|
+
t:
|
|
324
|
+
for (;; ) {
|
|
325
|
+
if (w > C || o >= p && o > h) {
|
|
326
|
+
const ut = t.slice(C, w) || t.slice(h, o);
|
|
327
|
+
v = 0;
|
|
328
|
+
for (const Y of ut.replaceAll(ct, "")) {
|
|
329
|
+
const $ = Y.codePointAt(0) || 0;
|
|
330
|
+
if (lt($) ? f = m : ht($) ? f = V : E !== A && at($) ? f = E : f = A, c + f > b && (d = Math.min(d, Math.max(C, h) + v)), c + f > i) {
|
|
331
|
+
F = true;
|
|
332
|
+
break t;
|
|
333
|
+
}
|
|
334
|
+
v += Y.length, c += f;
|
|
335
|
+
}
|
|
336
|
+
C = w = 0;
|
|
337
|
+
}
|
|
338
|
+
if (o >= p)
|
|
339
|
+
break;
|
|
340
|
+
if (M.lastIndex = o, M.test(t)) {
|
|
341
|
+
if (v = M.lastIndex - o, f = v * A, c + f > b && (d = Math.min(d, o + Math.floor((b - c) / A))), c + f > i) {
|
|
342
|
+
F = true;
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
c += f, C = h, w = o, o = h = M.lastIndex;
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
if (O.lastIndex = o, O.test(t)) {
|
|
349
|
+
if (c + u > b && (d = Math.min(d, o)), c + u > i) {
|
|
350
|
+
F = true;
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
c += u, C = h, w = o, o = h = O.lastIndex;
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
if (y.lastIndex = o, y.test(t)) {
|
|
357
|
+
if (v = y.lastIndex - o, f = v * a, c + f > b && (d = Math.min(d, o + Math.floor((b - c) / a))), c + f > i) {
|
|
358
|
+
F = true;
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
c += f, C = h, w = o, o = h = y.lastIndex;
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
if (L.lastIndex = o, L.test(t)) {
|
|
365
|
+
if (v = L.lastIndex - o, f = v * l, c + f > b && (d = Math.min(d, o + Math.floor((b - c) / l))), c + f > i) {
|
|
366
|
+
F = true;
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
c += f, C = h, w = o, o = h = L.lastIndex;
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
if (P.lastIndex = o, P.test(t)) {
|
|
373
|
+
if (c + g > b && (d = Math.min(d, o)), c + g > i) {
|
|
374
|
+
F = true;
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
377
|
+
c += g, C = h, w = o, o = h = P.lastIndex;
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
o += 1;
|
|
381
|
+
}
|
|
382
|
+
return { width: F ? b : c, index: F ? d : p, truncated: F, ellipsed: F && i >= n };
|
|
383
|
+
};
|
|
384
|
+
var pt = { limit: 1 / 0, ellipsis: "", ellipsisWidth: 0 };
|
|
385
|
+
var S = (t, e = {}) => X(t, pt, e).width;
|
|
386
|
+
var T = "\x1B";
|
|
387
|
+
var Z = "";
|
|
388
|
+
var Ft = 39;
|
|
389
|
+
var j = "\x07";
|
|
390
|
+
var Q = "[";
|
|
391
|
+
var dt = "]";
|
|
392
|
+
var tt = "m";
|
|
393
|
+
var U = `${dt}8;;`;
|
|
394
|
+
var et = new RegExp(`(?:\\${Q}(?<code>\\d+)m|\\${U}(?<uri>.*)${j})`, "y");
|
|
395
|
+
var mt = (t) => {
|
|
396
|
+
if (t >= 30 && t <= 37 || t >= 90 && t <= 97)
|
|
397
|
+
return 39;
|
|
398
|
+
if (t >= 40 && t <= 47 || t >= 100 && t <= 107)
|
|
399
|
+
return 49;
|
|
400
|
+
if (t === 1 || t === 2)
|
|
401
|
+
return 22;
|
|
402
|
+
if (t === 3)
|
|
403
|
+
return 23;
|
|
404
|
+
if (t === 4)
|
|
405
|
+
return 24;
|
|
406
|
+
if (t === 7)
|
|
407
|
+
return 27;
|
|
408
|
+
if (t === 8)
|
|
409
|
+
return 28;
|
|
410
|
+
if (t === 9)
|
|
411
|
+
return 29;
|
|
412
|
+
if (t === 0)
|
|
413
|
+
return 0;
|
|
414
|
+
};
|
|
415
|
+
var st = (t) => `${T}${Q}${t}${tt}`;
|
|
416
|
+
var it = (t) => `${T}${U}${t}${j}`;
|
|
417
|
+
var gt = (t) => t.map((e) => S(e));
|
|
418
|
+
var G = (t, e, s) => {
|
|
419
|
+
const i = e[Symbol.iterator]();
|
|
420
|
+
let r = false, n = false, u = t.at(-1), a = u === undefined ? 0 : S(u), l = i.next(), E = i.next(), g = 0;
|
|
421
|
+
for (;!l.done; ) {
|
|
422
|
+
const m = l.value, A = S(m);
|
|
423
|
+
a + A <= s ? t[t.length - 1] += m : (t.push(m), a = 0), (m === T || m === Z) && (r = true, n = e.startsWith(U, g + 1)), r ? n ? m === j && (r = false, n = false) : m === tt && (r = false) : (a += A, a === s && !E.done && (t.push(""), a = 0)), l = E, E = i.next(), g += m.length;
|
|
424
|
+
}
|
|
425
|
+
u = t.at(-1), !a && u !== undefined && u.length > 0 && t.length > 1 && (t[t.length - 2] += t.pop());
|
|
426
|
+
};
|
|
427
|
+
var vt = (t) => {
|
|
428
|
+
const e = t.split(" ");
|
|
429
|
+
let s = e.length;
|
|
430
|
+
for (;s > 0 && !(S(e[s - 1]) > 0); )
|
|
431
|
+
s--;
|
|
432
|
+
return s === e.length ? t : e.slice(0, s).join(" ") + e.slice(s).join("");
|
|
433
|
+
};
|
|
434
|
+
var Et = (t, e, s = {}) => {
|
|
435
|
+
if (s.trim !== false && t.trim() === "")
|
|
436
|
+
return "";
|
|
437
|
+
let i = "", r, n;
|
|
438
|
+
const u = t.split(" "), a = gt(u);
|
|
439
|
+
let l = [""];
|
|
440
|
+
for (const [h, o] of u.entries()) {
|
|
441
|
+
s.trim !== false && (l[l.length - 1] = (l.at(-1) ?? "").trimStart());
|
|
442
|
+
let p = S(l.at(-1) ?? "");
|
|
443
|
+
if (h !== 0 && (p >= e && (s.wordWrap === false || s.trim === false) && (l.push(""), p = 0), (p > 0 || s.trim === false) && (l[l.length - 1] += " ", p++)), s.hard && a[h] > e) {
|
|
444
|
+
const v = e - p, F = 1 + Math.floor((a[h] - v - 1) / e);
|
|
445
|
+
Math.floor((a[h] - 1) / e) < F && l.push(""), G(l, o, e);
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
if (p + a[h] > e && p > 0 && a[h] > 0) {
|
|
449
|
+
if (s.wordWrap === false && p < e) {
|
|
450
|
+
G(l, o, e);
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
l.push("");
|
|
454
|
+
}
|
|
455
|
+
if (p + a[h] > e && s.wordWrap === false) {
|
|
456
|
+
G(l, o, e);
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
l[l.length - 1] += o;
|
|
460
|
+
}
|
|
461
|
+
s.trim !== false && (l = l.map((h) => vt(h)));
|
|
462
|
+
const E = l.join(`
|
|
463
|
+
`), g = E[Symbol.iterator]();
|
|
464
|
+
let m = g.next(), A = g.next(), V = 0;
|
|
465
|
+
for (;!m.done; ) {
|
|
466
|
+
const h = m.value, o = A.value;
|
|
467
|
+
if (i += h, h === T || h === Z) {
|
|
468
|
+
et.lastIndex = V + 1;
|
|
469
|
+
const F = et.exec(E)?.groups;
|
|
470
|
+
if (F?.code !== undefined) {
|
|
471
|
+
const d = Number.parseFloat(F.code);
|
|
472
|
+
r = d === Ft ? undefined : d;
|
|
473
|
+
} else
|
|
474
|
+
F?.uri !== undefined && (n = F.uri.length === 0 ? undefined : F.uri);
|
|
475
|
+
}
|
|
476
|
+
const p = r ? mt(r) : undefined;
|
|
477
|
+
o === `
|
|
478
|
+
` ? (n && (i += it("")), r && p && (i += st(p))) : h === `
|
|
479
|
+
` && (r && p && (i += st(r)), n && (i += it(n))), V += h.length, m = A, A = g.next();
|
|
480
|
+
}
|
|
481
|
+
return i;
|
|
482
|
+
};
|
|
483
|
+
function K(t, e, s) {
|
|
484
|
+
return String(t).normalize().replaceAll(`\r
|
|
485
|
+
`, `
|
|
486
|
+
`).split(`
|
|
487
|
+
`).map((i) => Et(i, e, s)).join(`
|
|
488
|
+
`);
|
|
489
|
+
}
|
|
490
|
+
var At = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
491
|
+
var _ = { actions: new Set(At), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]), messages: { cancel: "Canceled", error: "Something went wrong" }, withGuide: true };
|
|
492
|
+
function H(t, e) {
|
|
493
|
+
if (typeof t == "string")
|
|
494
|
+
return _.aliases.get(t) === e;
|
|
495
|
+
for (const s of t)
|
|
496
|
+
if (s !== undefined && H(s, e))
|
|
497
|
+
return true;
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
function _t(t, e) {
|
|
501
|
+
if (t === e)
|
|
502
|
+
return;
|
|
503
|
+
const s = t.split(`
|
|
504
|
+
`), i = e.split(`
|
|
505
|
+
`), r = Math.max(s.length, i.length), n = [];
|
|
506
|
+
for (let u = 0;u < r; u++)
|
|
507
|
+
s[u] !== i[u] && n.push(u);
|
|
508
|
+
return { lines: n, numLinesBefore: s.length, numLinesAfter: i.length, numLines: r };
|
|
509
|
+
}
|
|
510
|
+
var bt = globalThis.process.platform.startsWith("win");
|
|
511
|
+
var z = Symbol("clack:cancel");
|
|
512
|
+
function Ct(t) {
|
|
513
|
+
return t === z;
|
|
514
|
+
}
|
|
515
|
+
function W(t, e) {
|
|
516
|
+
const s = t;
|
|
517
|
+
s.isTTY && s.setRawMode(e);
|
|
518
|
+
}
|
|
519
|
+
function xt({ input: t = q, output: e = R, overwrite: s = true, hideCursor: i = true } = {}) {
|
|
520
|
+
const r = k.createInterface({ input: t, output: e, prompt: "", tabSize: 1 });
|
|
521
|
+
k.emitKeypressEvents(t, r), t instanceof J && t.isTTY && t.setRawMode(true);
|
|
522
|
+
const n = (u, { name: a, sequence: l }) => {
|
|
523
|
+
const E = String(u);
|
|
524
|
+
if (H([E, a, l], "cancel")) {
|
|
525
|
+
i && e.write(import_sisteransi.cursor.show), process.exit(0);
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
if (!s)
|
|
529
|
+
return;
|
|
530
|
+
const g = a === "return" ? 0 : -1, m = a === "return" ? -1 : 0;
|
|
531
|
+
k.moveCursor(e, g, m, () => {
|
|
532
|
+
k.clearLine(e, 1, () => {
|
|
533
|
+
t.once("keypress", n);
|
|
534
|
+
});
|
|
535
|
+
});
|
|
536
|
+
};
|
|
537
|
+
return i && e.write(import_sisteransi.cursor.hide), t.once("keypress", n), () => {
|
|
538
|
+
t.off("keypress", n), i && e.write(import_sisteransi.cursor.show), t instanceof J && t.isTTY && !bt && t.setRawMode(false), r.terminal = false, r.close();
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
var rt = (t) => ("columns" in t) && typeof t.columns == "number" ? t.columns : 80;
|
|
542
|
+
var nt = (t) => ("rows" in t) && typeof t.rows == "number" ? t.rows : 20;
|
|
543
|
+
function Bt(t, e, s, i = s) {
|
|
544
|
+
const r = rt(t ?? R);
|
|
545
|
+
return K(e, r - s.length, { hard: true, trim: false }).split(`
|
|
546
|
+
`).map((n, u) => `${u === 0 ? i : s}${n}`).join(`
|
|
547
|
+
`);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
class B {
|
|
551
|
+
input;
|
|
552
|
+
output;
|
|
553
|
+
_abortSignal;
|
|
554
|
+
rl;
|
|
555
|
+
opts;
|
|
556
|
+
_render;
|
|
557
|
+
_track = false;
|
|
558
|
+
_prevFrame = "";
|
|
559
|
+
_subscribers = new Map;
|
|
560
|
+
_cursor = 0;
|
|
561
|
+
state = "initial";
|
|
562
|
+
error = "";
|
|
563
|
+
value;
|
|
564
|
+
userInput = "";
|
|
565
|
+
constructor(e, s = true) {
|
|
566
|
+
const { input: i = q, output: r = R, render: n, signal: u, ...a } = e;
|
|
567
|
+
this.opts = a, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = n.bind(this), this._track = s, this._abortSignal = u, this.input = i, this.output = r;
|
|
568
|
+
}
|
|
569
|
+
unsubscribe() {
|
|
570
|
+
this._subscribers.clear();
|
|
571
|
+
}
|
|
572
|
+
setSubscriber(e, s) {
|
|
573
|
+
const i = this._subscribers.get(e) ?? [];
|
|
574
|
+
i.push(s), this._subscribers.set(e, i);
|
|
575
|
+
}
|
|
576
|
+
on(e, s) {
|
|
577
|
+
this.setSubscriber(e, { cb: s });
|
|
578
|
+
}
|
|
579
|
+
once(e, s) {
|
|
580
|
+
this.setSubscriber(e, { cb: s, once: true });
|
|
581
|
+
}
|
|
582
|
+
emit(e, ...s) {
|
|
583
|
+
const i = this._subscribers.get(e) ?? [], r = [];
|
|
584
|
+
for (const n of i)
|
|
585
|
+
n.cb(...s), n.once && r.push(() => i.splice(i.indexOf(n), 1));
|
|
586
|
+
for (const n of r)
|
|
587
|
+
n();
|
|
588
|
+
}
|
|
589
|
+
prompt() {
|
|
590
|
+
return new Promise((e) => {
|
|
591
|
+
if (this._abortSignal) {
|
|
592
|
+
if (this._abortSignal.aborted)
|
|
593
|
+
return this.state = "cancel", this.close(), e(z);
|
|
594
|
+
this._abortSignal.addEventListener("abort", () => {
|
|
595
|
+
this.state = "cancel", this.close();
|
|
596
|
+
}, { once: true });
|
|
597
|
+
}
|
|
598
|
+
this.rl = ot.createInterface({ input: this.input, tabSize: 2, prompt: "", escapeCodeTimeout: 50, terminal: true }), this.rl.prompt(), this.opts.initialUserInput !== undefined && this._setUserInput(this.opts.initialUserInput, true), this.input.on("keypress", this.onKeypress), W(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
|
|
599
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), W(this.input, false), e(this.value);
|
|
600
|
+
}), this.once("cancel", () => {
|
|
601
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), W(this.input, false), e(z);
|
|
602
|
+
});
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
_isActionKey(e, s) {
|
|
606
|
+
return e === "\t";
|
|
607
|
+
}
|
|
608
|
+
_setValue(e) {
|
|
609
|
+
this.value = e, this.emit("value", this.value);
|
|
610
|
+
}
|
|
611
|
+
_setUserInput(e, s) {
|
|
612
|
+
this.userInput = e ?? "", this.emit("userInput", this.userInput), s && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
|
|
613
|
+
}
|
|
614
|
+
_clearUserInput() {
|
|
615
|
+
this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
|
|
616
|
+
}
|
|
617
|
+
onKeypress(e, s) {
|
|
618
|
+
if (this._track && s.name !== "return" && (s.name && this._isActionKey(e, s) && 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"), s?.name && (!this._track && _.aliases.has(s.name) && this.emit("cursor", _.aliases.get(s.name)), _.actions.has(s.name) && this.emit("cursor", s.name)), e && (e.toLowerCase() === "y" || e.toLowerCase() === "n") && this.emit("confirm", e.toLowerCase() === "y"), this.emit("key", e?.toLowerCase(), s), s?.name === "return") {
|
|
619
|
+
if (this.opts.validate) {
|
|
620
|
+
const i = this.opts.validate(this.value);
|
|
621
|
+
i && (this.error = i instanceof Error ? i.message : i, this.state = "error", this.rl?.write(this.userInput));
|
|
622
|
+
}
|
|
623
|
+
this.state !== "error" && (this.state = "submit");
|
|
624
|
+
}
|
|
625
|
+
H([e, s?.name, s?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
|
|
626
|
+
}
|
|
627
|
+
close() {
|
|
628
|
+
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
629
|
+
`), W(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
|
|
630
|
+
}
|
|
631
|
+
restoreCursor() {
|
|
632
|
+
const e = K(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
|
|
633
|
+
`).length - 1;
|
|
634
|
+
this.output.write(import_sisteransi.cursor.move(-999, e * -1));
|
|
635
|
+
}
|
|
636
|
+
render() {
|
|
637
|
+
const e = K(this._render(this) ?? "", process.stdout.columns, { hard: true, trim: false });
|
|
638
|
+
if (e !== this._prevFrame) {
|
|
639
|
+
if (this.state === "initial")
|
|
640
|
+
this.output.write(import_sisteransi.cursor.hide);
|
|
641
|
+
else {
|
|
642
|
+
const s = _t(this._prevFrame, e), i = nt(this.output);
|
|
643
|
+
if (this.restoreCursor(), s) {
|
|
644
|
+
const r = Math.max(0, s.numLinesAfter - i), n = Math.max(0, s.numLinesBefore - i);
|
|
645
|
+
let u = s.lines.find((a) => a >= r);
|
|
646
|
+
if (u === undefined) {
|
|
647
|
+
this._prevFrame = e;
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
if (s.lines.length === 1) {
|
|
651
|
+
this.output.write(import_sisteransi.cursor.move(0, u - n)), this.output.write(import_sisteransi.erase.lines(1));
|
|
652
|
+
const a = e.split(`
|
|
653
|
+
`);
|
|
654
|
+
this.output.write(a[u]), this._prevFrame = e, this.output.write(import_sisteransi.cursor.move(0, a.length - u - 1));
|
|
655
|
+
return;
|
|
656
|
+
} else if (s.lines.length > 1) {
|
|
657
|
+
if (r < n)
|
|
658
|
+
u = r;
|
|
659
|
+
else {
|
|
660
|
+
const l = u - n;
|
|
661
|
+
l > 0 && this.output.write(import_sisteransi.cursor.move(0, l));
|
|
662
|
+
}
|
|
663
|
+
this.output.write(import_sisteransi.erase.down());
|
|
664
|
+
const a = e.split(`
|
|
665
|
+
`).slice(u);
|
|
666
|
+
this.output.write(a.join(`
|
|
667
|
+
`)), this._prevFrame = e;
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
this.output.write(import_sisteransi.erase.down());
|
|
672
|
+
}
|
|
673
|
+
this.output.write(e), this.state === "initial" && (this.state = "active"), this._prevFrame = e;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
function wt(t, e) {
|
|
678
|
+
if (t === undefined || e.length === 0)
|
|
679
|
+
return 0;
|
|
680
|
+
const s = e.findIndex((i) => i.value === t);
|
|
681
|
+
return s !== -1 ? s : 0;
|
|
682
|
+
}
|
|
683
|
+
function Dt(t, e) {
|
|
684
|
+
return (e.label ?? String(e.value)).toLowerCase().includes(t.toLowerCase());
|
|
685
|
+
}
|
|
686
|
+
function St(t, e) {
|
|
687
|
+
if (e)
|
|
688
|
+
return t ? e : e[0];
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
class Vt extends B {
|
|
692
|
+
filteredOptions;
|
|
693
|
+
multiple;
|
|
694
|
+
isNavigating = false;
|
|
695
|
+
selectedValues = [];
|
|
696
|
+
focusedValue;
|
|
697
|
+
#t = 0;
|
|
698
|
+
#s = "";
|
|
699
|
+
#i;
|
|
700
|
+
#e;
|
|
701
|
+
get cursor() {
|
|
702
|
+
return this.#t;
|
|
703
|
+
}
|
|
704
|
+
get userInputWithCursor() {
|
|
705
|
+
if (!this.userInput)
|
|
706
|
+
return D(["inverse", "hidden"], "_");
|
|
707
|
+
if (this._cursor >= this.userInput.length)
|
|
708
|
+
return `${this.userInput}█`;
|
|
709
|
+
const e = this.userInput.slice(0, this._cursor), [s, ...i] = this.userInput.slice(this._cursor);
|
|
710
|
+
return `${e}${D("inverse", s)}${i.join("")}`;
|
|
711
|
+
}
|
|
712
|
+
get options() {
|
|
713
|
+
return typeof this.#e == "function" ? this.#e() : this.#e;
|
|
714
|
+
}
|
|
715
|
+
constructor(e) {
|
|
716
|
+
super(e), this.#e = e.options;
|
|
717
|
+
const s = this.options;
|
|
718
|
+
this.filteredOptions = [...s], this.multiple = e.multiple === true, this.#i = e.filter ?? Dt;
|
|
719
|
+
let i;
|
|
720
|
+
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)
|
|
721
|
+
for (const r of i) {
|
|
722
|
+
const n = s.findIndex((u) => u.value === r);
|
|
723
|
+
n !== -1 && (this.toggleSelected(r), this.#t = n);
|
|
724
|
+
}
|
|
725
|
+
this.focusedValue = this.options[this.#t]?.value, this.on("key", (r, n) => this.#r(r, n)), this.on("userInput", (r) => this.#n(r));
|
|
726
|
+
}
|
|
727
|
+
_isActionKey(e, s) {
|
|
728
|
+
return e === "\t" || this.multiple && this.isNavigating && s.name === "space" && e !== undefined && e !== "";
|
|
729
|
+
}
|
|
730
|
+
#r(e, s) {
|
|
731
|
+
const i = s.name === "up", r = s.name === "down", n = s.name === "return";
|
|
732
|
+
i || r ? (this.#t = x(this.#t, i ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#t]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n ? this.value = St(this.multiple, this.selectedValues) : this.multiple ? this.focusedValue !== undefined && (s.name === "tab" || this.isNavigating && s.name === "space") ? this.toggleSelected(this.focusedValue) : this.isNavigating = false : (this.focusedValue && (this.selectedValues = [this.focusedValue]), this.isNavigating = false);
|
|
733
|
+
}
|
|
734
|
+
deselectAll() {
|
|
735
|
+
this.selectedValues = [];
|
|
736
|
+
}
|
|
737
|
+
toggleSelected(e) {
|
|
738
|
+
this.filteredOptions.length !== 0 && (this.multiple ? this.selectedValues.includes(e) ? this.selectedValues = this.selectedValues.filter((s) => s !== e) : this.selectedValues = [...this.selectedValues, e] : this.selectedValues = [e]);
|
|
739
|
+
}
|
|
740
|
+
#n(e) {
|
|
741
|
+
if (e !== this.#s) {
|
|
742
|
+
this.#s = e;
|
|
743
|
+
const s = this.options;
|
|
744
|
+
e ? this.filteredOptions = s.filter((n) => this.#i(e, n)) : this.filteredOptions = [...s];
|
|
745
|
+
const i = wt(this.focusedValue, this.filteredOptions);
|
|
746
|
+
this.#t = x(i, 0, this.filteredOptions);
|
|
747
|
+
const r = this.filteredOptions[this.#t];
|
|
748
|
+
r && !r.disabled ? this.focusedValue = r.value : this.focusedValue = undefined, this.multiple || (this.focusedValue !== undefined ? this.toggleSelected(this.focusedValue) : this.deselectAll());
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
class kt extends B {
|
|
754
|
+
get cursor() {
|
|
755
|
+
return this.value ? 0 : 1;
|
|
756
|
+
}
|
|
757
|
+
get _value() {
|
|
758
|
+
return this.cursor === 0;
|
|
759
|
+
}
|
|
760
|
+
constructor(e) {
|
|
761
|
+
super(e, false), this.value = !!e.initialValue, this.on("userInput", () => {
|
|
762
|
+
this.value = this._value;
|
|
763
|
+
}), this.on("confirm", (s) => {
|
|
764
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = s, this.state = "submit", this.close();
|
|
765
|
+
}), this.on("cursor", () => {
|
|
766
|
+
this.value = !this.value;
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
class yt extends B {
|
|
772
|
+
options;
|
|
773
|
+
cursor = 0;
|
|
774
|
+
#t;
|
|
775
|
+
getGroupItems(e) {
|
|
776
|
+
return this.options.filter((s) => s.group === e);
|
|
777
|
+
}
|
|
778
|
+
isGroupSelected(e) {
|
|
779
|
+
const s = this.getGroupItems(e), i = this.value;
|
|
780
|
+
return i === undefined ? false : s.every((r) => i.includes(r.value));
|
|
781
|
+
}
|
|
782
|
+
toggleValue() {
|
|
783
|
+
const e = this.options[this.cursor];
|
|
784
|
+
if (this.value === undefined && (this.value = []), e.group === true) {
|
|
785
|
+
const s = e.value, i = this.getGroupItems(s);
|
|
786
|
+
this.isGroupSelected(s) ? this.value = this.value.filter((r) => i.findIndex((n) => n.value === r) === -1) : this.value = [...this.value, ...i.map((r) => r.value)], this.value = Array.from(new Set(this.value));
|
|
787
|
+
} else {
|
|
788
|
+
const s = this.value.includes(e.value);
|
|
789
|
+
this.value = s ? this.value.filter((i) => i !== e.value) : [...this.value, e.value];
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
constructor(e) {
|
|
793
|
+
super(e, false);
|
|
794
|
+
const { options: s } = e;
|
|
795
|
+
this.#t = e.selectableGroups !== false, this.options = Object.entries(s).flatMap(([i, r]) => [{ value: i, group: true, label: i }, ...r.map((n) => ({ ...n, group: i }))]), this.value = [...e.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: i }) => i === e.cursorAt), this.#t ? 0 : 1), this.on("cursor", (i) => {
|
|
796
|
+
switch (i) {
|
|
797
|
+
case "left":
|
|
798
|
+
case "up": {
|
|
799
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
800
|
+
const r = this.options[this.cursor]?.group === true;
|
|
801
|
+
!this.#t && r && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
804
|
+
case "down":
|
|
805
|
+
case "right": {
|
|
806
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
807
|
+
const r = this.options[this.cursor]?.group === true;
|
|
808
|
+
!this.#t && r && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
|
|
809
|
+
break;
|
|
810
|
+
}
|
|
811
|
+
case "space":
|
|
812
|
+
this.toggleValue();
|
|
813
|
+
break;
|
|
814
|
+
}
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
class Mt extends B {
|
|
819
|
+
_mask = "•";
|
|
820
|
+
get cursor() {
|
|
821
|
+
return this._cursor;
|
|
822
|
+
}
|
|
823
|
+
get masked() {
|
|
824
|
+
return this.userInput.replaceAll(/./g, this._mask);
|
|
825
|
+
}
|
|
826
|
+
get userInputWithCursor() {
|
|
827
|
+
if (this.state === "submit" || this.state === "cancel")
|
|
828
|
+
return this.masked;
|
|
829
|
+
const e = this.userInput;
|
|
830
|
+
if (this.cursor >= e.length)
|
|
831
|
+
return `${this.masked}${D(["inverse", "hidden"], "_")}`;
|
|
832
|
+
const s = this.masked, i = s.slice(0, this.cursor), r = s.slice(this.cursor);
|
|
833
|
+
return `${i}${D("inverse", r[0])}${r.slice(1)}`;
|
|
834
|
+
}
|
|
835
|
+
clear() {
|
|
836
|
+
this._clearUserInput();
|
|
837
|
+
}
|
|
838
|
+
constructor({ mask: e, ...s }) {
|
|
839
|
+
super(s), this._mask = e ?? "•", this.on("userInput", (i) => {
|
|
840
|
+
this._setValue(i);
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
class Tt extends B {
|
|
846
|
+
options;
|
|
847
|
+
cursor = 0;
|
|
848
|
+
get _selectedValue() {
|
|
849
|
+
return this.options[this.cursor];
|
|
850
|
+
}
|
|
851
|
+
changeValue() {
|
|
852
|
+
this.value = this._selectedValue.value;
|
|
853
|
+
}
|
|
854
|
+
constructor(e) {
|
|
855
|
+
super(e, false), this.options = e.options;
|
|
856
|
+
const s = this.options.findIndex(({ value: r }) => r === e.initialValue), i = s === -1 ? 0 : s;
|
|
857
|
+
this.cursor = this.options[i].disabled ? x(i, 1, this.options) : i, this.changeValue(), this.on("cursor", (r) => {
|
|
858
|
+
switch (r) {
|
|
859
|
+
case "left":
|
|
860
|
+
case "up":
|
|
861
|
+
this.cursor = x(this.cursor, -1, this.options);
|
|
862
|
+
break;
|
|
863
|
+
case "down":
|
|
864
|
+
case "right":
|
|
865
|
+
this.cursor = x(this.cursor, 1, this.options);
|
|
866
|
+
break;
|
|
867
|
+
}
|
|
868
|
+
this.changeValue();
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
class $t extends B {
|
|
873
|
+
get userInputWithCursor() {
|
|
874
|
+
if (this.state === "submit")
|
|
875
|
+
return this.userInput;
|
|
876
|
+
const e = this.userInput;
|
|
877
|
+
if (this.cursor >= e.length)
|
|
878
|
+
return `${this.userInput}█`;
|
|
879
|
+
const s = e.slice(0, this.cursor), [i, ...r] = e.slice(this.cursor);
|
|
880
|
+
return `${s}${D("inverse", i)}${r.join("")}`;
|
|
881
|
+
}
|
|
882
|
+
get cursor() {
|
|
883
|
+
return this._cursor;
|
|
884
|
+
}
|
|
885
|
+
constructor(e) {
|
|
886
|
+
super({ ...e, initialUserInput: e.initialUserInput ?? e.initialValue }), this.on("userInput", (s) => {
|
|
887
|
+
this._setValue(s);
|
|
888
|
+
}), this.on("finalize", () => {
|
|
889
|
+
this.value || (this.value = e.defaultValue), this.value === undefined && (this.value = "");
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
// ../node_modules/.bun/@clack+prompts@1.1.0/node_modules/@clack/prompts/dist/index.mjs
|
|
895
|
+
import { styleText as t, stripVTControlCharacters as ue } from "node:util";
|
|
896
|
+
import N2 from "node:process";
|
|
897
|
+
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
898
|
+
function pt2() {
|
|
899
|
+
return N2.platform !== "win32" ? N2.env.TERM !== "linux" : !!N2.env.CI || !!N2.env.WT_SESSION || !!N2.env.TERMINUS_SUBLIME || N2.env.ConEmuTask === "{cmd::Cmder}" || N2.env.TERM_PROGRAM === "Terminus-Sublime" || N2.env.TERM_PROGRAM === "vscode" || N2.env.TERM === "xterm-256color" || N2.env.TERM === "alacritty" || N2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
900
|
+
}
|
|
901
|
+
var ee = pt2();
|
|
902
|
+
var ce = () => process.env.CI === "true";
|
|
903
|
+
var I2 = (e, r) => ee ? e : r;
|
|
904
|
+
var Re = I2("◆", "*");
|
|
905
|
+
var $e = I2("■", "x");
|
|
906
|
+
var de = I2("▲", "x");
|
|
907
|
+
var V = I2("◇", "o");
|
|
908
|
+
var he = I2("┌", "T");
|
|
909
|
+
var h = I2("│", "|");
|
|
910
|
+
var x2 = I2("└", "—");
|
|
911
|
+
var Oe = I2("┐", "T");
|
|
912
|
+
var Pe = I2("┘", "—");
|
|
913
|
+
var z2 = I2("●", ">");
|
|
914
|
+
var H2 = I2("○", " ");
|
|
915
|
+
var te = I2("◻", "[•]");
|
|
916
|
+
var U2 = I2("◼", "[+]");
|
|
917
|
+
var q2 = I2("◻", "[ ]");
|
|
918
|
+
var Ne = I2("▪", "•");
|
|
919
|
+
var se = I2("─", "-");
|
|
920
|
+
var pe = I2("╮", "+");
|
|
921
|
+
var We = I2("├", "+");
|
|
922
|
+
var me = I2("╯", "+");
|
|
923
|
+
var ge = I2("╰", "+");
|
|
924
|
+
var Ge = I2("╭", "+");
|
|
925
|
+
var fe = I2("●", "•");
|
|
926
|
+
var Fe = I2("◆", "*");
|
|
927
|
+
var ye = I2("▲", "!");
|
|
928
|
+
var Ee = I2("■", "x");
|
|
929
|
+
var W2 = (e) => {
|
|
930
|
+
switch (e) {
|
|
931
|
+
case "initial":
|
|
932
|
+
case "active":
|
|
933
|
+
return t("cyan", Re);
|
|
934
|
+
case "cancel":
|
|
935
|
+
return t("red", $e);
|
|
936
|
+
case "error":
|
|
937
|
+
return t("yellow", de);
|
|
938
|
+
case "submit":
|
|
939
|
+
return t("green", V);
|
|
940
|
+
}
|
|
941
|
+
};
|
|
942
|
+
var ve = (e) => {
|
|
943
|
+
switch (e) {
|
|
944
|
+
case "initial":
|
|
945
|
+
case "active":
|
|
946
|
+
return t("cyan", h);
|
|
947
|
+
case "cancel":
|
|
948
|
+
return t("red", h);
|
|
949
|
+
case "error":
|
|
950
|
+
return t("yellow", h);
|
|
951
|
+
case "submit":
|
|
952
|
+
return t("green", h);
|
|
953
|
+
}
|
|
954
|
+
};
|
|
955
|
+
var mt2 = (e) => e === 161 || e === 164 || e === 167 || e === 168 || e === 170 || e === 173 || e === 174 || e >= 176 && e <= 180 || e >= 182 && e <= 186 || e >= 188 && e <= 191 || e === 198 || e === 208 || e === 215 || e === 216 || e >= 222 && e <= 225 || e === 230 || e >= 232 && e <= 234 || e === 236 || e === 237 || e === 240 || e === 242 || e === 243 || e >= 247 && e <= 250 || e === 252 || e === 254 || e === 257 || e === 273 || e === 275 || e === 283 || e === 294 || e === 295 || e === 299 || e >= 305 && e <= 307 || e === 312 || e >= 319 && e <= 322 || e === 324 || e >= 328 && e <= 331 || e === 333 || e === 338 || e === 339 || e === 358 || e === 359 || e === 363 || e === 462 || e === 464 || e === 466 || e === 468 || e === 470 || e === 472 || e === 474 || e === 476 || e === 593 || e === 609 || e === 708 || e === 711 || e >= 713 && e <= 715 || e === 717 || e === 720 || e >= 728 && e <= 731 || e === 733 || e === 735 || e >= 768 && e <= 879 || e >= 913 && e <= 929 || e >= 931 && e <= 937 || e >= 945 && e <= 961 || e >= 963 && e <= 969 || e === 1025 || e >= 1040 && e <= 1103 || e === 1105 || e === 8208 || e >= 8211 && e <= 8214 || e === 8216 || e === 8217 || e === 8220 || e === 8221 || e >= 8224 && e <= 8226 || e >= 8228 && e <= 8231 || e === 8240 || e === 8242 || e === 8243 || e === 8245 || e === 8251 || e === 8254 || e === 8308 || e === 8319 || e >= 8321 && e <= 8324 || e === 8364 || e === 8451 || e === 8453 || e === 8457 || e === 8467 || e === 8470 || e === 8481 || e === 8482 || e === 8486 || e === 8491 || e === 8531 || e === 8532 || e >= 8539 && e <= 8542 || e >= 8544 && e <= 8555 || e >= 8560 && e <= 8569 || e === 8585 || e >= 8592 && e <= 8601 || e === 8632 || e === 8633 || e === 8658 || e === 8660 || e === 8679 || e === 8704 || e === 8706 || e === 8707 || e === 8711 || e === 8712 || e === 8715 || e === 8719 || e === 8721 || e === 8725 || e === 8730 || e >= 8733 && e <= 8736 || e === 8739 || e === 8741 || e >= 8743 && e <= 8748 || e === 8750 || e >= 8756 && e <= 8759 || e === 8764 || e === 8765 || e === 8776 || e === 8780 || e === 8786 || e === 8800 || e === 8801 || e >= 8804 && e <= 8807 || e === 8810 || e === 8811 || e === 8814 || e === 8815 || e === 8834 || e === 8835 || e === 8838 || e === 8839 || e === 8853 || e === 8857 || e === 8869 || e === 8895 || e === 8978 || e >= 9312 && e <= 9449 || e >= 9451 && e <= 9547 || e >= 9552 && e <= 9587 || e >= 9600 && e <= 9615 || e >= 9618 && e <= 9621 || e === 9632 || e === 9633 || e >= 9635 && e <= 9641 || e === 9650 || e === 9651 || e === 9654 || e === 9655 || e === 9660 || e === 9661 || e === 9664 || e === 9665 || e >= 9670 && e <= 9672 || e === 9675 || e >= 9678 && e <= 9681 || e >= 9698 && e <= 9701 || e === 9711 || e === 9733 || e === 9734 || e === 9737 || e === 9742 || e === 9743 || e === 9756 || e === 9758 || e === 9792 || e === 9794 || e === 9824 || e === 9825 || e >= 9827 && e <= 9829 || e >= 9831 && e <= 9834 || e === 9836 || e === 9837 || e === 9839 || e === 9886 || e === 9887 || e === 9919 || e >= 9926 && e <= 9933 || e >= 9935 && e <= 9939 || e >= 9941 && e <= 9953 || e === 9955 || e === 9960 || e === 9961 || e >= 9963 && e <= 9969 || e === 9972 || e >= 9974 && e <= 9977 || e === 9979 || e === 9980 || e === 9982 || e === 9983 || e === 10045 || e >= 10102 && e <= 10111 || e >= 11094 && e <= 11097 || e >= 12872 && e <= 12879 || e >= 57344 && e <= 63743 || e >= 65024 && e <= 65039 || e === 65533 || e >= 127232 && e <= 127242 || e >= 127248 && e <= 127277 || e >= 127280 && e <= 127337 || e >= 127344 && e <= 127373 || e === 127375 || e === 127376 || e >= 127387 && e <= 127404 || e >= 917760 && e <= 917999 || e >= 983040 && e <= 1048573 || e >= 1048576 && e <= 1114109;
|
|
956
|
+
var gt2 = (e) => e === 12288 || e >= 65281 && e <= 65376 || e >= 65504 && e <= 65510;
|
|
957
|
+
var ft2 = (e) => e >= 4352 && e <= 4447 || e === 8986 || e === 8987 || e === 9001 || e === 9002 || e >= 9193 && e <= 9196 || e === 9200 || e === 9203 || e === 9725 || e === 9726 || e === 9748 || e === 9749 || e >= 9800 && e <= 9811 || e === 9855 || e === 9875 || e === 9889 || e === 9898 || e === 9899 || e === 9917 || e === 9918 || e === 9924 || e === 9925 || e === 9934 || e === 9940 || e === 9962 || e === 9970 || e === 9971 || e === 9973 || e === 9978 || e === 9981 || e === 9989 || e === 9994 || e === 9995 || e === 10024 || e === 10060 || e === 10062 || e >= 10067 && e <= 10069 || e === 10071 || e >= 10133 && e <= 10135 || e === 10160 || e === 10175 || e === 11035 || e === 11036 || e === 11088 || e === 11093 || e >= 11904 && e <= 11929 || e >= 11931 && e <= 12019 || e >= 12032 && e <= 12245 || e >= 12272 && e <= 12287 || e >= 12289 && e <= 12350 || e >= 12353 && e <= 12438 || e >= 12441 && e <= 12543 || e >= 12549 && e <= 12591 || e >= 12593 && e <= 12686 || e >= 12688 && e <= 12771 || e >= 12783 && e <= 12830 || e >= 12832 && e <= 12871 || e >= 12880 && e <= 19903 || e >= 19968 && e <= 42124 || e >= 42128 && e <= 42182 || e >= 43360 && e <= 43388 || e >= 44032 && e <= 55203 || e >= 63744 && e <= 64255 || e >= 65040 && e <= 65049 || e >= 65072 && e <= 65106 || e >= 65108 && e <= 65126 || e >= 65128 && e <= 65131 || e >= 94176 && e <= 94180 || e === 94192 || e === 94193 || e >= 94208 && e <= 100343 || e >= 100352 && e <= 101589 || e >= 101632 && e <= 101640 || e >= 110576 && e <= 110579 || e >= 110581 && e <= 110587 || e === 110589 || e === 110590 || e >= 110592 && e <= 110882 || e === 110898 || e >= 110928 && e <= 110930 || e === 110933 || e >= 110948 && e <= 110951 || e >= 110960 && e <= 111355 || e === 126980 || e === 127183 || e === 127374 || e >= 127377 && e <= 127386 || e >= 127488 && e <= 127490 || e >= 127504 && e <= 127547 || e >= 127552 && e <= 127560 || e === 127568 || e === 127569 || e >= 127584 && e <= 127589 || e >= 127744 && e <= 127776 || e >= 127789 && e <= 127797 || e >= 127799 && e <= 127868 || e >= 127870 && e <= 127891 || e >= 127904 && e <= 127946 || e >= 127951 && e <= 127955 || e >= 127968 && e <= 127984 || e === 127988 || e >= 127992 && e <= 128062 || e === 128064 || e >= 128066 && e <= 128252 || e >= 128255 && e <= 128317 || e >= 128331 && e <= 128334 || e >= 128336 && e <= 128359 || e === 128378 || e === 128405 || e === 128406 || e === 128420 || e >= 128507 && e <= 128591 || e >= 128640 && e <= 128709 || e === 128716 || e >= 128720 && e <= 128722 || e >= 128725 && e <= 128727 || e >= 128732 && e <= 128735 || e === 128747 || e === 128748 || e >= 128756 && e <= 128764 || e >= 128992 && e <= 129003 || e === 129008 || e >= 129292 && e <= 129338 || e >= 129340 && e <= 129349 || e >= 129351 && e <= 129535 || e >= 129648 && e <= 129660 || e >= 129664 && e <= 129672 || e >= 129680 && e <= 129725 || e >= 129727 && e <= 129733 || e >= 129742 && e <= 129755 || e >= 129760 && e <= 129768 || e >= 129776 && e <= 129784 || e >= 131072 && e <= 196605 || e >= 196608 && e <= 262141;
|
|
958
|
+
var we = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/y;
|
|
959
|
+
var re = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
960
|
+
var ie = /\t{1,1000}/y;
|
|
961
|
+
var Ae = /[\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;
|
|
962
|
+
var ne = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
|
|
963
|
+
var Ft2 = /\p{M}+/gu;
|
|
964
|
+
var yt2 = { limit: 1 / 0, ellipsis: "" };
|
|
965
|
+
var Le = (e, r = {}, s = {}) => {
|
|
966
|
+
const i = r.limit ?? 1 / 0, a = r.ellipsis ?? "", o = r?.ellipsisWidth ?? (a ? Le(a, yt2, s).width : 0), u = s.ansiWidth ?? 0, l = s.controlWidth ?? 0, n = s.tabWidth ?? 8, c = s.ambiguousWidth ?? 1, p = s.emojiWidth ?? 2, f = s.fullWidthWidth ?? 2, g = s.regularWidth ?? 1, E = s.wideWidth ?? 2;
|
|
967
|
+
let $ = 0, m = 0, d = e.length, F = 0, y2 = false, v = d, C = Math.max(0, i - o), A = 0, b = 0, w = 0, S2 = 0;
|
|
968
|
+
e:
|
|
969
|
+
for (;; ) {
|
|
970
|
+
if (b > A || m >= d && m > $) {
|
|
971
|
+
const T2 = e.slice(A, b) || e.slice($, m);
|
|
972
|
+
F = 0;
|
|
973
|
+
for (const M2 of T2.replaceAll(Ft2, "")) {
|
|
974
|
+
const O2 = M2.codePointAt(0) || 0;
|
|
975
|
+
if (gt2(O2) ? S2 = f : ft2(O2) ? S2 = E : c !== g && mt2(O2) ? S2 = c : S2 = g, w + S2 > C && (v = Math.min(v, Math.max(A, $) + F)), w + S2 > i) {
|
|
976
|
+
y2 = true;
|
|
977
|
+
break e;
|
|
978
|
+
}
|
|
979
|
+
F += M2.length, w += S2;
|
|
980
|
+
}
|
|
981
|
+
A = b = 0;
|
|
982
|
+
}
|
|
983
|
+
if (m >= d)
|
|
984
|
+
break;
|
|
985
|
+
if (ne.lastIndex = m, ne.test(e)) {
|
|
986
|
+
if (F = ne.lastIndex - m, S2 = F * g, w + S2 > C && (v = Math.min(v, m + Math.floor((C - w) / g))), w + S2 > i) {
|
|
987
|
+
y2 = true;
|
|
988
|
+
break;
|
|
989
|
+
}
|
|
990
|
+
w += S2, A = $, b = m, m = $ = ne.lastIndex;
|
|
991
|
+
continue;
|
|
992
|
+
}
|
|
993
|
+
if (we.lastIndex = m, we.test(e)) {
|
|
994
|
+
if (w + u > C && (v = Math.min(v, m)), w + u > i) {
|
|
995
|
+
y2 = true;
|
|
996
|
+
break;
|
|
997
|
+
}
|
|
998
|
+
w += u, A = $, b = m, m = $ = we.lastIndex;
|
|
999
|
+
continue;
|
|
1000
|
+
}
|
|
1001
|
+
if (re.lastIndex = m, re.test(e)) {
|
|
1002
|
+
if (F = re.lastIndex - m, S2 = F * l, w + S2 > C && (v = Math.min(v, m + Math.floor((C - w) / l))), w + S2 > i) {
|
|
1003
|
+
y2 = true;
|
|
1004
|
+
break;
|
|
1005
|
+
}
|
|
1006
|
+
w += S2, A = $, b = m, m = $ = re.lastIndex;
|
|
1007
|
+
continue;
|
|
1008
|
+
}
|
|
1009
|
+
if (ie.lastIndex = m, ie.test(e)) {
|
|
1010
|
+
if (F = ie.lastIndex - m, S2 = F * n, w + S2 > C && (v = Math.min(v, m + Math.floor((C - w) / n))), w + S2 > i) {
|
|
1011
|
+
y2 = true;
|
|
1012
|
+
break;
|
|
1013
|
+
}
|
|
1014
|
+
w += S2, A = $, b = m, m = $ = ie.lastIndex;
|
|
1015
|
+
continue;
|
|
1016
|
+
}
|
|
1017
|
+
if (Ae.lastIndex = m, Ae.test(e)) {
|
|
1018
|
+
if (w + p > C && (v = Math.min(v, m)), w + p > i) {
|
|
1019
|
+
y2 = true;
|
|
1020
|
+
break;
|
|
1021
|
+
}
|
|
1022
|
+
w += p, A = $, b = m, m = $ = Ae.lastIndex;
|
|
1023
|
+
continue;
|
|
1024
|
+
}
|
|
1025
|
+
m += 1;
|
|
1026
|
+
}
|
|
1027
|
+
return { width: y2 ? C : w, index: y2 ? v : d, truncated: y2, ellipsed: y2 && i >= o };
|
|
1028
|
+
};
|
|
1029
|
+
var Et2 = { limit: 1 / 0, ellipsis: "", ellipsisWidth: 0 };
|
|
1030
|
+
var D2 = (e, r = {}) => Le(e, Et2, r).width;
|
|
1031
|
+
var ae = "\x1B";
|
|
1032
|
+
var je = "";
|
|
1033
|
+
var vt2 = 39;
|
|
1034
|
+
var Ce = "\x07";
|
|
1035
|
+
var ke = "[";
|
|
1036
|
+
var wt2 = "]";
|
|
1037
|
+
var Ve = "m";
|
|
1038
|
+
var Se = `${wt2}8;;`;
|
|
1039
|
+
var He = new RegExp(`(?:\\${ke}(?<code>\\d+)m|\\${Se}(?<uri>.*)${Ce})`, "y");
|
|
1040
|
+
var At2 = (e) => {
|
|
1041
|
+
if (e >= 30 && e <= 37 || e >= 90 && e <= 97)
|
|
1042
|
+
return 39;
|
|
1043
|
+
if (e >= 40 && e <= 47 || e >= 100 && e <= 107)
|
|
1044
|
+
return 49;
|
|
1045
|
+
if (e === 1 || e === 2)
|
|
1046
|
+
return 22;
|
|
1047
|
+
if (e === 3)
|
|
1048
|
+
return 23;
|
|
1049
|
+
if (e === 4)
|
|
1050
|
+
return 24;
|
|
1051
|
+
if (e === 7)
|
|
1052
|
+
return 27;
|
|
1053
|
+
if (e === 8)
|
|
1054
|
+
return 28;
|
|
1055
|
+
if (e === 9)
|
|
1056
|
+
return 29;
|
|
1057
|
+
if (e === 0)
|
|
1058
|
+
return 0;
|
|
1059
|
+
};
|
|
1060
|
+
var Ue = (e) => `${ae}${ke}${e}${Ve}`;
|
|
1061
|
+
var Ke = (e) => `${ae}${Se}${e}${Ce}`;
|
|
1062
|
+
var Ct2 = (e) => e.map((r) => D2(r));
|
|
1063
|
+
var Ie = (e, r, s) => {
|
|
1064
|
+
const i = r[Symbol.iterator]();
|
|
1065
|
+
let a = false, o = false, u = e.at(-1), l = u === undefined ? 0 : D2(u), n = i.next(), c = i.next(), p = 0;
|
|
1066
|
+
for (;!n.done; ) {
|
|
1067
|
+
const f = n.value, g = D2(f);
|
|
1068
|
+
l + g <= s ? e[e.length - 1] += f : (e.push(f), l = 0), (f === ae || f === je) && (a = true, o = r.startsWith(Se, p + 1)), a ? o ? f === Ce && (a = false, o = false) : f === Ve && (a = false) : (l += g, l === s && !c.done && (e.push(""), l = 0)), n = c, c = i.next(), p += f.length;
|
|
1069
|
+
}
|
|
1070
|
+
u = e.at(-1), !l && u !== undefined && u.length > 0 && e.length > 1 && (e[e.length - 2] += e.pop());
|
|
1071
|
+
};
|
|
1072
|
+
var St2 = (e) => {
|
|
1073
|
+
const r = e.split(" ");
|
|
1074
|
+
let s = r.length;
|
|
1075
|
+
for (;s > 0 && !(D2(r[s - 1]) > 0); )
|
|
1076
|
+
s--;
|
|
1077
|
+
return s === r.length ? e : r.slice(0, s).join(" ") + r.slice(s).join("");
|
|
1078
|
+
};
|
|
1079
|
+
var It2 = (e, r, s = {}) => {
|
|
1080
|
+
if (s.trim !== false && e.trim() === "")
|
|
1081
|
+
return "";
|
|
1082
|
+
let i = "", a, o;
|
|
1083
|
+
const u = e.split(" "), l = Ct2(u);
|
|
1084
|
+
let n = [""];
|
|
1085
|
+
for (const [$, m] of u.entries()) {
|
|
1086
|
+
s.trim !== false && (n[n.length - 1] = (n.at(-1) ?? "").trimStart());
|
|
1087
|
+
let d = D2(n.at(-1) ?? "");
|
|
1088
|
+
if ($ !== 0 && (d >= r && (s.wordWrap === false || s.trim === false) && (n.push(""), d = 0), (d > 0 || s.trim === false) && (n[n.length - 1] += " ", d++)), s.hard && l[$] > r) {
|
|
1089
|
+
const F = r - d, y2 = 1 + Math.floor((l[$] - F - 1) / r);
|
|
1090
|
+
Math.floor((l[$] - 1) / r) < y2 && n.push(""), Ie(n, m, r);
|
|
1091
|
+
continue;
|
|
1092
|
+
}
|
|
1093
|
+
if (d + l[$] > r && d > 0 && l[$] > 0) {
|
|
1094
|
+
if (s.wordWrap === false && d < r) {
|
|
1095
|
+
Ie(n, m, r);
|
|
1096
|
+
continue;
|
|
1097
|
+
}
|
|
1098
|
+
n.push("");
|
|
1099
|
+
}
|
|
1100
|
+
if (d + l[$] > r && s.wordWrap === false) {
|
|
1101
|
+
Ie(n, m, r);
|
|
1102
|
+
continue;
|
|
1103
|
+
}
|
|
1104
|
+
n[n.length - 1] += m;
|
|
1105
|
+
}
|
|
1106
|
+
s.trim !== false && (n = n.map(($) => St2($)));
|
|
1107
|
+
const c = n.join(`
|
|
1108
|
+
`), p = c[Symbol.iterator]();
|
|
1109
|
+
let f = p.next(), g = p.next(), E = 0;
|
|
1110
|
+
for (;!f.done; ) {
|
|
1111
|
+
const $ = f.value, m = g.value;
|
|
1112
|
+
if (i += $, $ === ae || $ === je) {
|
|
1113
|
+
He.lastIndex = E + 1;
|
|
1114
|
+
const y2 = He.exec(c)?.groups;
|
|
1115
|
+
if (y2?.code !== undefined) {
|
|
1116
|
+
const v = Number.parseFloat(y2.code);
|
|
1117
|
+
a = v === vt2 ? undefined : v;
|
|
1118
|
+
} else
|
|
1119
|
+
y2?.uri !== undefined && (o = y2.uri.length === 0 ? undefined : y2.uri);
|
|
1120
|
+
}
|
|
1121
|
+
const d = a ? At2(a) : undefined;
|
|
1122
|
+
m === `
|
|
1123
|
+
` ? (o && (i += Ke("")), a && d && (i += Ue(d))) : $ === `
|
|
1124
|
+
` && (a && d && (i += Ue(a)), o && (i += Ke(o))), E += $.length, f = g, g = p.next();
|
|
1125
|
+
}
|
|
1126
|
+
return i;
|
|
1127
|
+
};
|
|
1128
|
+
function J2(e, r, s) {
|
|
1129
|
+
return String(e).normalize().replaceAll(`\r
|
|
1130
|
+
`, `
|
|
1131
|
+
`).split(`
|
|
1132
|
+
`).map((i) => It2(i, r, s)).join(`
|
|
1133
|
+
`);
|
|
1134
|
+
}
|
|
1135
|
+
var bt2 = (e, r, s, i, a) => {
|
|
1136
|
+
let o = r, u = 0;
|
|
1137
|
+
for (let l = s;l < i; l++) {
|
|
1138
|
+
const n = e[l];
|
|
1139
|
+
if (o = o - n.length, u++, o <= a)
|
|
1140
|
+
break;
|
|
1141
|
+
}
|
|
1142
|
+
return { lineCount: o, removals: u };
|
|
1143
|
+
};
|
|
1144
|
+
var X2 = ({ cursor: e, options: r, style: s, output: i = process.stdout, maxItems: a = Number.POSITIVE_INFINITY, columnPadding: o = 0, rowPadding: u = 4 }) => {
|
|
1145
|
+
const l = rt(i) - o, n = nt(i), c = t("dim", "..."), p = Math.max(n - u, 0), f = Math.max(Math.min(a, p), 5);
|
|
1146
|
+
let g = 0;
|
|
1147
|
+
e >= f - 3 && (g = Math.max(Math.min(e - f + 3, r.length - f), 0));
|
|
1148
|
+
let E = f < r.length && g > 0, $ = f < r.length && g + f < r.length;
|
|
1149
|
+
const m = Math.min(g + f, r.length), d = [];
|
|
1150
|
+
let F = 0;
|
|
1151
|
+
E && F++, $ && F++;
|
|
1152
|
+
const y2 = g + (E ? 1 : 0), v = m - ($ ? 1 : 0);
|
|
1153
|
+
for (let A = y2;A < v; A++) {
|
|
1154
|
+
const b = J2(s(r[A], A === e), l, { hard: true, trim: false }).split(`
|
|
1155
|
+
`);
|
|
1156
|
+
d.push(b), F += b.length;
|
|
1157
|
+
}
|
|
1158
|
+
if (F > p) {
|
|
1159
|
+
let A = 0, b = 0, w = F;
|
|
1160
|
+
const S2 = e - y2, T2 = (M2, O2) => bt2(d, w, M2, O2, p);
|
|
1161
|
+
E ? ({ lineCount: w, removals: A } = T2(0, S2), w > p && ({ lineCount: w, removals: b } = T2(S2 + 1, d.length))) : ({ lineCount: w, removals: b } = T2(S2 + 1, d.length), w > p && ({ lineCount: w, removals: A } = T2(0, S2))), A > 0 && (E = true, d.splice(0, A)), b > 0 && ($ = true, d.splice(d.length - b, b));
|
|
1162
|
+
}
|
|
1163
|
+
const C = [];
|
|
1164
|
+
E && C.push(c);
|
|
1165
|
+
for (const A of d)
|
|
1166
|
+
for (const b of A)
|
|
1167
|
+
C.push(b);
|
|
1168
|
+
return $ && C.push(c), C;
|
|
1169
|
+
};
|
|
1170
|
+
var Rt = (e) => {
|
|
1171
|
+
const r = e.active ?? "Yes", s = e.inactive ?? "No";
|
|
1172
|
+
return new kt({ active: r, inactive: s, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue ?? true, render() {
|
|
1173
|
+
const i = e.withGuide ?? _.withGuide, a = `${i ? `${t("gray", h)}
|
|
1174
|
+
` : ""}${W2(this.state)} ${e.message}
|
|
1175
|
+
`, o = this.value ? r : s;
|
|
1176
|
+
switch (this.state) {
|
|
1177
|
+
case "submit": {
|
|
1178
|
+
const u = i ? `${t("gray", h)} ` : "";
|
|
1179
|
+
return `${a}${u}${t("dim", o)}`;
|
|
1180
|
+
}
|
|
1181
|
+
case "cancel": {
|
|
1182
|
+
const u = i ? `${t("gray", h)} ` : "";
|
|
1183
|
+
return `${a}${u}${t(["strikethrough", "dim"], o)}${i ? `
|
|
1184
|
+
${t("gray", h)}` : ""}`;
|
|
1185
|
+
}
|
|
1186
|
+
default: {
|
|
1187
|
+
const u = i ? `${t("cyan", h)} ` : "", l = i ? t("cyan", x2) : "";
|
|
1188
|
+
return `${a}${u}${this.value ? `${t("green", z2)} ${r}` : `${t("dim", H2)} ${t("dim", r)}`}${e.vertical ? i ? `
|
|
1189
|
+
${t("cyan", h)} ` : `
|
|
1190
|
+
` : ` ${t("dim", "/")} `}${this.value ? `${t("dim", H2)} ${t("dim", s)}` : `${t("green", z2)} ${s}`}
|
|
1191
|
+
${l}
|
|
1192
|
+
`;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
} }).prompt();
|
|
1196
|
+
};
|
|
1197
|
+
var R2 = { message: (e = [], { symbol: r = t("gray", h), secondarySymbol: s = t("gray", h), output: i = process.stdout, spacing: a = 1, withGuide: o } = {}) => {
|
|
1198
|
+
const u = [], l = o ?? _.withGuide, n = l ? s : "", c = l ? `${r} ` : "", p = l ? `${s} ` : "";
|
|
1199
|
+
for (let g = 0;g < a; g++)
|
|
1200
|
+
u.push(n);
|
|
1201
|
+
const f = Array.isArray(e) ? e : e.split(`
|
|
1202
|
+
`);
|
|
1203
|
+
if (f.length > 0) {
|
|
1204
|
+
const [g, ...E] = f;
|
|
1205
|
+
g.length > 0 ? u.push(`${c}${g}`) : u.push(l ? r : "");
|
|
1206
|
+
for (const $ of E)
|
|
1207
|
+
$.length > 0 ? u.push(`${p}${$}`) : u.push(l ? s : "");
|
|
1208
|
+
}
|
|
1209
|
+
i.write(`${u.join(`
|
|
1210
|
+
`)}
|
|
1211
|
+
`);
|
|
1212
|
+
}, info: (e, r) => {
|
|
1213
|
+
R2.message(e, { ...r, symbol: t("blue", fe) });
|
|
1214
|
+
}, success: (e, r) => {
|
|
1215
|
+
R2.message(e, { ...r, symbol: t("green", Fe) });
|
|
1216
|
+
}, step: (e, r) => {
|
|
1217
|
+
R2.message(e, { ...r, symbol: t("green", V) });
|
|
1218
|
+
}, warn: (e, r) => {
|
|
1219
|
+
R2.message(e, { ...r, symbol: t("yellow", ye) });
|
|
1220
|
+
}, warning: (e, r) => {
|
|
1221
|
+
R2.warn(e, r);
|
|
1222
|
+
}, error: (e, r) => {
|
|
1223
|
+
R2.message(e, { ...r, symbol: t("red", Ee) });
|
|
1224
|
+
} };
|
|
1225
|
+
var Nt = (e = "", r) => {
|
|
1226
|
+
const s = r?.output ?? process.stdout, i = r?.withGuide ?? _.withGuide ? `${t("gray", x2)} ` : "";
|
|
1227
|
+
s.write(`${i}${t("red", e)}
|
|
1228
|
+
|
|
1229
|
+
`);
|
|
1230
|
+
};
|
|
1231
|
+
var Wt2 = (e = "", r) => {
|
|
1232
|
+
const s = r?.output ?? process.stdout, i = r?.withGuide ?? _.withGuide ? `${t("gray", he)} ` : "";
|
|
1233
|
+
s.write(`${i}${e}
|
|
1234
|
+
`);
|
|
1235
|
+
};
|
|
1236
|
+
var Gt = (e = "", r) => {
|
|
1237
|
+
const s = r?.output ?? process.stdout, i = r?.withGuide ?? _.withGuide ? `${t("gray", h)}
|
|
1238
|
+
${t("gray", x2)} ` : "";
|
|
1239
|
+
s.write(`${i}${e}
|
|
1240
|
+
|
|
1241
|
+
`);
|
|
1242
|
+
};
|
|
1243
|
+
var Ht = (e) => new Mt({ validate: e.validate, mask: e.mask ?? Ne, signal: e.signal, input: e.input, output: e.output, render() {
|
|
1244
|
+
const r = e.withGuide ?? _.withGuide, s = `${r ? `${t("gray", h)}
|
|
1245
|
+
` : ""}${W2(this.state)} ${e.message}
|
|
1246
|
+
`, i = this.userInputWithCursor, a = this.masked;
|
|
1247
|
+
switch (this.state) {
|
|
1248
|
+
case "error": {
|
|
1249
|
+
const o = r ? `${t("yellow", h)} ` : "", u = r ? `${t("yellow", x2)} ` : "", l = a ?? "";
|
|
1250
|
+
return e.clearOnError && this.clear(), `${s.trim()}
|
|
1251
|
+
${o}${l}
|
|
1252
|
+
${u}${t("yellow", this.error)}
|
|
1253
|
+
`;
|
|
1254
|
+
}
|
|
1255
|
+
case "submit": {
|
|
1256
|
+
const o = r ? `${t("gray", h)} ` : "", u = a ? t("dim", a) : "";
|
|
1257
|
+
return `${s}${o}${u}`;
|
|
1258
|
+
}
|
|
1259
|
+
case "cancel": {
|
|
1260
|
+
const o = r ? `${t("gray", h)} ` : "", u = a ? t(["strikethrough", "dim"], a) : "";
|
|
1261
|
+
return `${s}${o}${u}${a && r ? `
|
|
1262
|
+
${t("gray", h)}` : ""}`;
|
|
1263
|
+
}
|
|
1264
|
+
default: {
|
|
1265
|
+
const o = r ? `${t("cyan", h)} ` : "", u = r ? t("cyan", x2) : "";
|
|
1266
|
+
return `${s}${o}${i}
|
|
1267
|
+
${u}
|
|
1268
|
+
`;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
} }).prompt();
|
|
1272
|
+
var Kt = (e) => t("magenta", e);
|
|
1273
|
+
var be = ({ indicator: e = "dots", onCancel: r, output: s = process.stdout, cancelMessage: i, errorMessage: a, frames: o = ee ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], delay: u = ee ? 80 : 120, signal: l, ...n } = {}) => {
|
|
1274
|
+
const c = ce();
|
|
1275
|
+
let p, f, g = false, E = false, $ = "", m, d = performance.now();
|
|
1276
|
+
const F = rt(s), y2 = n?.styleFrame ?? Kt, v = (B2) => {
|
|
1277
|
+
const P2 = B2 > 1 ? a ?? _.messages.error : i ?? _.messages.cancel;
|
|
1278
|
+
E = B2 === 1, g && (k2(P2, B2), E && typeof r == "function" && r());
|
|
1279
|
+
}, C = () => v(2), A = () => v(1), b = () => {
|
|
1280
|
+
process.on("uncaughtExceptionMonitor", C), process.on("unhandledRejection", C), process.on("SIGINT", A), process.on("SIGTERM", A), process.on("exit", v), l && l.addEventListener("abort", A);
|
|
1281
|
+
}, w = () => {
|
|
1282
|
+
process.removeListener("uncaughtExceptionMonitor", C), process.removeListener("unhandledRejection", C), process.removeListener("SIGINT", A), process.removeListener("SIGTERM", A), process.removeListener("exit", v), l && l.removeEventListener("abort", A);
|
|
1283
|
+
}, S2 = () => {
|
|
1284
|
+
if (m === undefined)
|
|
1285
|
+
return;
|
|
1286
|
+
c && s.write(`
|
|
1287
|
+
`);
|
|
1288
|
+
const B2 = J2(m, F, { hard: true, trim: false }).split(`
|
|
1289
|
+
`);
|
|
1290
|
+
B2.length > 1 && s.write(import_sisteransi2.cursor.up(B2.length - 1)), s.write(import_sisteransi2.cursor.to(0)), s.write(import_sisteransi2.erase.down());
|
|
1291
|
+
}, T2 = (B2) => B2.replace(/\.+$/, ""), M2 = (B2) => {
|
|
1292
|
+
const P2 = (performance.now() - B2) / 1000, G2 = Math.floor(P2 / 60), L2 = Math.floor(P2 % 60);
|
|
1293
|
+
return G2 > 0 ? `[${G2}m ${L2}s]` : `[${L2}s]`;
|
|
1294
|
+
}, O2 = n.withGuide ?? _.withGuide, le = (B2 = "") => {
|
|
1295
|
+
g = true, p = xt({ output: s }), $ = T2(B2), d = performance.now(), O2 && s.write(`${t("gray", h)}
|
|
1296
|
+
`);
|
|
1297
|
+
let P2 = 0, G2 = 0;
|
|
1298
|
+
b(), f = setInterval(() => {
|
|
1299
|
+
if (c && $ === m)
|
|
1300
|
+
return;
|
|
1301
|
+
S2(), m = $;
|
|
1302
|
+
const L2 = y2(o[P2]);
|
|
1303
|
+
let Z2;
|
|
1304
|
+
if (c)
|
|
1305
|
+
Z2 = `${L2} ${$}...`;
|
|
1306
|
+
else if (e === "timer")
|
|
1307
|
+
Z2 = `${L2} ${$} ${M2(d)}`;
|
|
1308
|
+
else {
|
|
1309
|
+
const et2 = ".".repeat(Math.floor(G2)).slice(0, 3);
|
|
1310
|
+
Z2 = `${L2} ${$}${et2}`;
|
|
1311
|
+
}
|
|
1312
|
+
const Ze = J2(Z2, F, { hard: true, trim: false });
|
|
1313
|
+
s.write(Ze), P2 = P2 + 1 < o.length ? P2 + 1 : 0, G2 = G2 < 4 ? G2 + 0.125 : 0;
|
|
1314
|
+
}, u);
|
|
1315
|
+
}, k2 = (B2 = "", P2 = 0, G2 = false) => {
|
|
1316
|
+
if (!g)
|
|
1317
|
+
return;
|
|
1318
|
+
g = false, clearInterval(f), S2();
|
|
1319
|
+
const L2 = P2 === 0 ? t("green", V) : P2 === 1 ? t("red", $e) : t("red", de);
|
|
1320
|
+
$ = B2 ?? $, G2 || (e === "timer" ? s.write(`${L2} ${$} ${M2(d)}
|
|
1321
|
+
`) : s.write(`${L2} ${$}
|
|
1322
|
+
`)), w(), p();
|
|
1323
|
+
};
|
|
1324
|
+
return { start: le, stop: (B2 = "") => k2(B2, 0), message: (B2 = "") => {
|
|
1325
|
+
$ = T2(B2 ?? $);
|
|
1326
|
+
}, cancel: (B2 = "") => k2(B2, 1), error: (B2 = "") => k2(B2, 2), clear: () => k2("", 0, true), get isCancelled() {
|
|
1327
|
+
return E;
|
|
1328
|
+
} };
|
|
1329
|
+
};
|
|
1330
|
+
var ze = { light: I2("─", "-"), heavy: I2("━", "="), block: I2("█", "#") };
|
|
1331
|
+
var oe = (e, r) => e.includes(`
|
|
1332
|
+
`) ? e.split(`
|
|
1333
|
+
`).map((s) => r(s)).join(`
|
|
1334
|
+
`) : r(e);
|
|
1335
|
+
var Jt = (e) => {
|
|
1336
|
+
const r = (s, i) => {
|
|
1337
|
+
const a = s.label ?? String(s.value);
|
|
1338
|
+
switch (i) {
|
|
1339
|
+
case "disabled":
|
|
1340
|
+
return `${t("gray", H2)} ${oe(a, (o) => t("gray", o))}${s.hint ? ` ${t("dim", `(${s.hint ?? "disabled"})`)}` : ""}`;
|
|
1341
|
+
case "selected":
|
|
1342
|
+
return `${oe(a, (o) => t("dim", o))}`;
|
|
1343
|
+
case "active":
|
|
1344
|
+
return `${t("green", z2)} ${a}${s.hint ? ` ${t("dim", `(${s.hint})`)}` : ""}`;
|
|
1345
|
+
case "cancelled":
|
|
1346
|
+
return `${oe(a, (o) => t(["strikethrough", "dim"], o))}`;
|
|
1347
|
+
default:
|
|
1348
|
+
return `${t("dim", H2)} ${oe(a, (o) => t("dim", o))}`;
|
|
1349
|
+
}
|
|
1350
|
+
};
|
|
1351
|
+
return new Tt({ options: e.options, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue, render() {
|
|
1352
|
+
const s = e.withGuide ?? _.withGuide, i = `${W2(this.state)} `, a = `${ve(this.state)} `, o = Bt(e.output, e.message, a, i), u = `${s ? `${t("gray", h)}
|
|
1353
|
+
` : ""}${o}
|
|
1354
|
+
`;
|
|
1355
|
+
switch (this.state) {
|
|
1356
|
+
case "submit": {
|
|
1357
|
+
const l = s ? `${t("gray", h)} ` : "", n = Bt(e.output, r(this.options[this.cursor], "selected"), l);
|
|
1358
|
+
return `${u}${n}`;
|
|
1359
|
+
}
|
|
1360
|
+
case "cancel": {
|
|
1361
|
+
const l = s ? `${t("gray", h)} ` : "", n = Bt(e.output, r(this.options[this.cursor], "cancelled"), l);
|
|
1362
|
+
return `${u}${n}${s ? `
|
|
1363
|
+
${t("gray", h)}` : ""}`;
|
|
1364
|
+
}
|
|
1365
|
+
default: {
|
|
1366
|
+
const l = s ? `${t("cyan", h)} ` : "", n = s ? t("cyan", x2) : "", c = u.split(`
|
|
1367
|
+
`).length, p = s ? 2 : 1;
|
|
1368
|
+
return `${u}${l}${X2({ output: e.output, cursor: this.cursor, options: this.options, maxItems: e.maxItems, columnPadding: l.length, rowPadding: c + p, style: (f, g) => r(f, f.disabled ? "disabled" : g ? "active" : "inactive") }).join(`
|
|
1369
|
+
${l}`)}
|
|
1370
|
+
${n}
|
|
1371
|
+
`;
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
} }).prompt();
|
|
1375
|
+
};
|
|
1376
|
+
var Qe = `${t("gray", h)} `;
|
|
1377
|
+
var Zt = (e) => new $t({ validate: e.validate, placeholder: e.placeholder, defaultValue: e.defaultValue, initialValue: e.initialValue, output: e.output, signal: e.signal, input: e.input, render() {
|
|
1378
|
+
const r = e?.withGuide ?? _.withGuide, s = `${`${r ? `${t("gray", h)}
|
|
1379
|
+
` : ""}${W2(this.state)} `}${e.message}
|
|
1380
|
+
`, i = e.placeholder ? t("inverse", e.placeholder[0]) + t("dim", e.placeholder.slice(1)) : t(["inverse", "hidden"], "_"), a = this.userInput ? this.userInputWithCursor : i, o = this.value ?? "";
|
|
1381
|
+
switch (this.state) {
|
|
1382
|
+
case "error": {
|
|
1383
|
+
const u = this.error ? ` ${t("yellow", this.error)}` : "", l = r ? `${t("yellow", h)} ` : "", n = r ? t("yellow", x2) : "";
|
|
1384
|
+
return `${s.trim()}
|
|
1385
|
+
${l}${a}
|
|
1386
|
+
${n}${u}
|
|
1387
|
+
`;
|
|
1388
|
+
}
|
|
1389
|
+
case "submit": {
|
|
1390
|
+
const u = o ? ` ${t("dim", o)}` : "", l = r ? t("gray", h) : "";
|
|
1391
|
+
return `${s}${l}${u}`;
|
|
1392
|
+
}
|
|
1393
|
+
case "cancel": {
|
|
1394
|
+
const u = o ? ` ${t(["strikethrough", "dim"], o)}` : "", l = r ? t("gray", h) : "";
|
|
1395
|
+
return `${s}${l}${u}${o.trim() ? `
|
|
1396
|
+
${l}` : ""}`;
|
|
1397
|
+
}
|
|
1398
|
+
default: {
|
|
1399
|
+
const u = r ? `${t("cyan", h)} ` : "", l = r ? t("cyan", x2) : "";
|
|
1400
|
+
return `${s}${u}${a}
|
|
1401
|
+
${l}
|
|
1402
|
+
`;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
} }).prompt();
|
|
1406
|
+
|
|
1407
|
+
// src/shared.ts
|
|
1408
|
+
var RESET = "\x1B[0m";
|
|
1409
|
+
var RED = "\x1B[31m";
|
|
1410
|
+
var GREEN = "\x1B[32m";
|
|
1411
|
+
var YELLOW = "\x1B[33m";
|
|
1412
|
+
var BLUE = "\x1B[34m";
|
|
1413
|
+
function log(message) {
|
|
1414
|
+
console.log(`${BLUE}[*]${RESET} ${message}`);
|
|
1415
|
+
}
|
|
1416
|
+
function warn(message) {
|
|
1417
|
+
console.warn(`${YELLOW}[!]${RESET} ${message}`);
|
|
1418
|
+
}
|
|
1419
|
+
function error(message) {
|
|
1420
|
+
console.error(`${RED}[x]${RESET} ${message}`);
|
|
1421
|
+
}
|
|
1422
|
+
function success(message) {
|
|
1423
|
+
console.log(`${GREEN}[+]${RESET} ${message}`);
|
|
1424
|
+
}
|
|
1425
|
+
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
1426
|
+
function spawn(args, options) {
|
|
1427
|
+
const result = spawnSync(args[0], args.slice(1), {
|
|
1428
|
+
cwd: options?.cwd,
|
|
1429
|
+
encoding: "utf8"
|
|
1430
|
+
});
|
|
1431
|
+
return {
|
|
1432
|
+
success: result.status === 0,
|
|
1433
|
+
stdout: (result.stdout ?? "").trim(),
|
|
1434
|
+
stderr: (result.stderr ?? "").trim()
|
|
1435
|
+
};
|
|
1436
|
+
}
|
|
1437
|
+
function commandExists(cmd) {
|
|
1438
|
+
const bin = process.platform === "win32" ? "where" : "which";
|
|
1439
|
+
return spawn([bin, cmd]).success;
|
|
1440
|
+
}
|
|
1441
|
+
function defaultPrompts() {
|
|
1442
|
+
return {
|
|
1443
|
+
text: Zt,
|
|
1444
|
+
password: Ht,
|
|
1445
|
+
select: Jt,
|
|
1446
|
+
confirm: Rt,
|
|
1447
|
+
spinner: be,
|
|
1448
|
+
intro: Wt2,
|
|
1449
|
+
outro: Gt,
|
|
1450
|
+
cancel: Nt,
|
|
1451
|
+
isCancel: Ct,
|
|
1452
|
+
log: R2
|
|
1453
|
+
};
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
// src/env.ts
|
|
1457
|
+
import { createInterface as createInterface2 } from "node:readline";
|
|
1458
|
+
import { randomUUID } from "node:crypto";
|
|
1459
|
+
import { accessSync, readFileSync as readFileSync2 } from "node:fs";
|
|
1460
|
+
var ENV_CATEGORIES = [
|
|
1461
|
+
{
|
|
1462
|
+
name: "Required",
|
|
1463
|
+
description: "Bot will not start without these",
|
|
1464
|
+
vars: [
|
|
1465
|
+
{
|
|
1466
|
+
key: "BOT_TOKEN",
|
|
1467
|
+
prompt: "Discord Bot Token from Developer Portal",
|
|
1468
|
+
secret: true,
|
|
1469
|
+
required: true
|
|
1470
|
+
},
|
|
1471
|
+
{
|
|
1472
|
+
key: "MONGO_CONNECTION",
|
|
1473
|
+
prompt: "MongoDB connection string (e.g., mongodb+srv://...)",
|
|
1474
|
+
secret: true,
|
|
1475
|
+
required: true
|
|
1476
|
+
}
|
|
1477
|
+
]
|
|
1478
|
+
},
|
|
1479
|
+
{
|
|
1480
|
+
name: "Lavalink",
|
|
1481
|
+
description: "Music System",
|
|
1482
|
+
optional: true,
|
|
1483
|
+
vars: [
|
|
1484
|
+
{
|
|
1485
|
+
key: "LAVALINK_PASS",
|
|
1486
|
+
prompt: "Lavalink password (leave empty to auto-generate)",
|
|
1487
|
+
secret: true
|
|
1488
|
+
},
|
|
1489
|
+
{ key: "LAVALINK_1_HOST", prompt: "Primary node host" },
|
|
1490
|
+
{ key: "LAVALINK_1_PORT", prompt: "Primary node port" },
|
|
1491
|
+
{ key: "LAVALINK_1_ID", prompt: "Primary node identifier" },
|
|
1492
|
+
{
|
|
1493
|
+
key: "LAVALINK_2_HOST",
|
|
1494
|
+
prompt: "Secondary node host (leave empty to skip)"
|
|
1495
|
+
},
|
|
1496
|
+
{ key: "LAVALINK_2_PORT", prompt: "Secondary node port" },
|
|
1497
|
+
{ key: "LAVALINK_2_ID", prompt: "Secondary node identifier" }
|
|
1498
|
+
]
|
|
1499
|
+
},
|
|
1500
|
+
{
|
|
1501
|
+
name: "Music Services",
|
|
1502
|
+
description: "Spotify (requires local Lavalink)",
|
|
1503
|
+
optional: true,
|
|
1504
|
+
vars: [
|
|
1505
|
+
{ key: "SPOTIFY_CLIENT_ID", prompt: "Spotify API client ID" },
|
|
1506
|
+
{ key: "SPOTIFY_CLIENT_SECRET", prompt: "Spotify API client secret" }
|
|
1507
|
+
]
|
|
1508
|
+
},
|
|
1509
|
+
{
|
|
1510
|
+
name: "Optional Features",
|
|
1511
|
+
description: "Webhooks and AI keys",
|
|
1512
|
+
optional: true,
|
|
1513
|
+
vars: [
|
|
1514
|
+
{ key: "WEBHOOK_SECRET", prompt: "Dashboard webhook auth secret" },
|
|
1515
|
+
{ key: "LOGS_WEBHOOK", prompt: "Discord webhook for bot logs" },
|
|
1516
|
+
{ key: "MISTRAL", prompt: "Mistral AI API key" },
|
|
1517
|
+
{ key: "GROQ", prompt: "Groq API key" }
|
|
1518
|
+
]
|
|
1519
|
+
},
|
|
1520
|
+
{
|
|
1521
|
+
name: "Utility Commands",
|
|
1522
|
+
description: "Weather, image, GitHub",
|
|
1523
|
+
optional: true,
|
|
1524
|
+
vars: [
|
|
1525
|
+
{ key: "WEATHERSTACK_KEY", prompt: "Weather command API key" },
|
|
1526
|
+
{ key: "STRANGE_API_KEY", prompt: "Image manipulation API key" }
|
|
1527
|
+
]
|
|
1528
|
+
},
|
|
1529
|
+
{
|
|
1530
|
+
name: "Monitoring",
|
|
1531
|
+
description: "Error tracking",
|
|
1532
|
+
optional: true,
|
|
1533
|
+
vars: [
|
|
1534
|
+
{
|
|
1535
|
+
key: "HONEYBADGER_API_KEY",
|
|
1536
|
+
prompt: "Honeybadger error tracking API key"
|
|
1537
|
+
}
|
|
1538
|
+
]
|
|
1539
|
+
}
|
|
1540
|
+
];
|
|
1541
|
+
var REQUIRED_KEYS = ["BOT_TOKEN", "MONGO_CONNECTION"];
|
|
1542
|
+
var ALL_KEYS = ENV_CATEGORIES.flatMap((c) => c.vars.map((v) => v.key));
|
|
1543
|
+
function parseEnv(content) {
|
|
1544
|
+
const map = new Map;
|
|
1545
|
+
for (const line of content.split(`
|
|
1546
|
+
`)) {
|
|
1547
|
+
const trimmed = line.trim();
|
|
1548
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
1549
|
+
continue;
|
|
1550
|
+
const eqIdx = trimmed.indexOf("=");
|
|
1551
|
+
if (eqIdx === -1)
|
|
1552
|
+
continue;
|
|
1553
|
+
let value = trimmed.slice(eqIdx + 1).trim();
|
|
1554
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
1555
|
+
value = value.slice(1, -1);
|
|
1556
|
+
}
|
|
1557
|
+
map.set(trimmed.slice(0, eqIdx).trim(), value);
|
|
1558
|
+
}
|
|
1559
|
+
return map;
|
|
1560
|
+
}
|
|
1561
|
+
function validateEnv(content) {
|
|
1562
|
+
const parsed = parseEnv(content);
|
|
1563
|
+
const errors = [];
|
|
1564
|
+
const warnings = [];
|
|
1565
|
+
for (const key of REQUIRED_KEYS) {
|
|
1566
|
+
if (!parsed.has(key) || !parsed.get(key)) {
|
|
1567
|
+
errors.push(`Missing required variable: ${key}`);
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
for (const key of ALL_KEYS) {
|
|
1571
|
+
if (REQUIRED_KEYS.includes(key))
|
|
1572
|
+
continue;
|
|
1573
|
+
if (!parsed.has(key) || !parsed.get(key)) {
|
|
1574
|
+
warnings.push(`Missing optional variable: ${key}`);
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
return { ok: errors.length === 0, errors, warnings };
|
|
1578
|
+
}
|
|
1579
|
+
async function envGuidedMode(prompts) {
|
|
1580
|
+
const lines = [];
|
|
1581
|
+
for (const category of ENV_CATEGORIES) {
|
|
1582
|
+
if (category.optional) {
|
|
1583
|
+
const configure = await prompts.confirm({
|
|
1584
|
+
message: `Configure ${category.name}? (${category.description})`
|
|
1585
|
+
});
|
|
1586
|
+
if (prompts.isCancel(configure)) {
|
|
1587
|
+
prompts.cancel("Configuration cancelled.");
|
|
1588
|
+
throw new Error("User cancelled");
|
|
1589
|
+
}
|
|
1590
|
+
if (!configure) {
|
|
1591
|
+
for (const v of category.vars)
|
|
1592
|
+
lines.push(`${v.key}=`);
|
|
1593
|
+
continue;
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
for (const v of category.vars) {
|
|
1597
|
+
const fn = v.secret ? prompts.password : prompts.text;
|
|
1598
|
+
const value = await fn({ message: v.prompt });
|
|
1599
|
+
if (prompts.isCancel(value)) {
|
|
1600
|
+
prompts.cancel("Configuration cancelled.");
|
|
1601
|
+
throw new Error("User cancelled");
|
|
1602
|
+
}
|
|
1603
|
+
let resolved = String(value);
|
|
1604
|
+
if (v.key === "LAVALINK_PASS" && !resolved) {
|
|
1605
|
+
resolved = randomUUID().replace(/-/g, "").slice(0, 24);
|
|
1606
|
+
}
|
|
1607
|
+
lines.push(`${v.key}=${resolved}`);
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
return lines.join(`
|
|
1611
|
+
`);
|
|
1612
|
+
}
|
|
1613
|
+
async function envPasteMode(prompts) {
|
|
1614
|
+
prompts.log.info("Paste your .env content below. Enter an empty line to finish.");
|
|
1615
|
+
const lines = [];
|
|
1616
|
+
const rl = createInterface2({ input: process.stdin, output: process.stdout });
|
|
1617
|
+
return new Promise((resolve) => {
|
|
1618
|
+
rl.on("line", (line) => {
|
|
1619
|
+
if (line.trim() === "") {
|
|
1620
|
+
rl.close();
|
|
1621
|
+
resolve(lines.join(`
|
|
1622
|
+
`));
|
|
1623
|
+
} else {
|
|
1624
|
+
lines.push(line);
|
|
1625
|
+
}
|
|
1626
|
+
});
|
|
1627
|
+
rl.on("close", () => resolve(lines.join(`
|
|
1628
|
+
`)));
|
|
1629
|
+
});
|
|
1630
|
+
}
|
|
1631
|
+
async function envImportMode(prompts, deps = {}) {
|
|
1632
|
+
const fileExists = deps.fileExists ?? ((p) => {
|
|
1633
|
+
try {
|
|
1634
|
+
accessSync(p);
|
|
1635
|
+
return true;
|
|
1636
|
+
} catch {
|
|
1637
|
+
return false;
|
|
1638
|
+
}
|
|
1639
|
+
});
|
|
1640
|
+
const readFile = deps.readFile ?? ((p) => readFileSync2(p, "utf8"));
|
|
1641
|
+
const filePath = await prompts.text({
|
|
1642
|
+
message: "Path to .env file",
|
|
1643
|
+
placeholder: "./path/to/.env"
|
|
1644
|
+
});
|
|
1645
|
+
if (prompts.isCancel(filePath)) {
|
|
1646
|
+
prompts.cancel("Configuration cancelled.");
|
|
1647
|
+
throw new Error("User cancelled");
|
|
1648
|
+
}
|
|
1649
|
+
const resolved = String(filePath);
|
|
1650
|
+
if (!fileExists(resolved)) {
|
|
1651
|
+
throw new Error(`File not found: ${resolved}`);
|
|
1652
|
+
}
|
|
1653
|
+
return readFile(resolved);
|
|
1654
|
+
}
|
|
1655
|
+
async function configureEnv(prompts, mode, deps) {
|
|
1656
|
+
switch (mode) {
|
|
1657
|
+
case "guided":
|
|
1658
|
+
return envGuidedMode(prompts);
|
|
1659
|
+
case "paste":
|
|
1660
|
+
return envPasteMode(prompts);
|
|
1661
|
+
case "import":
|
|
1662
|
+
return envImportMode(prompts, deps);
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
// src/health.ts
|
|
1667
|
+
var SERVICES = [
|
|
1668
|
+
"amina",
|
|
1669
|
+
"lavalink",
|
|
1670
|
+
"cloudflared",
|
|
1671
|
+
"watchtower"
|
|
1672
|
+
];
|
|
1673
|
+
var DEFAULT_TIMEOUT = 120000;
|
|
1674
|
+
var DEFAULT_INTERVAL = 5000;
|
|
1675
|
+
function checkService(spawnFn, name) {
|
|
1676
|
+
const format = name === "watchtower" ? "{{.State.Status}}" : "{{.State.Health.Status}}";
|
|
1677
|
+
const result = spawnFn(["docker", "inspect", `--format=${format}`, name]);
|
|
1678
|
+
return result.success ? result.stdout : "not found";
|
|
1679
|
+
}
|
|
1680
|
+
function isTerminal(statuses) {
|
|
1681
|
+
const values = Object.values(statuses);
|
|
1682
|
+
const allReady = values.every((s) => s === "healthy" || s === "running");
|
|
1683
|
+
const anyUnhealthy = values.some((s) => s === "unhealthy");
|
|
1684
|
+
return allReady || anyUnhealthy;
|
|
1685
|
+
}
|
|
1686
|
+
async function pollHealth(spawnFn, prompts, opts) {
|
|
1687
|
+
const timeout = opts?.timeout ?? DEFAULT_TIMEOUT;
|
|
1688
|
+
const interval = opts?.interval ?? DEFAULT_INTERVAL;
|
|
1689
|
+
const spin = prompts.spinner();
|
|
1690
|
+
spin.start("Waiting for services to become healthy...");
|
|
1691
|
+
const deadline = Date.now() + timeout;
|
|
1692
|
+
let statuses = {};
|
|
1693
|
+
while (Date.now() < deadline) {
|
|
1694
|
+
statuses = {};
|
|
1695
|
+
for (const name of SERVICES) {
|
|
1696
|
+
statuses[name] = checkService(spawnFn, name);
|
|
1697
|
+
}
|
|
1698
|
+
const summary = Object.entries(statuses).map(([k2, v]) => `${k2}: ${v}`).join(" | ");
|
|
1699
|
+
spin.message(summary);
|
|
1700
|
+
if (isTerminal(statuses))
|
|
1701
|
+
break;
|
|
1702
|
+
await sleep(interval);
|
|
1703
|
+
}
|
|
1704
|
+
const values = Object.values(statuses);
|
|
1705
|
+
const allReady = values.length > 0 && values.every((s) => s === "healthy" || s === "running");
|
|
1706
|
+
const anyUnhealthy = values.some((s) => s === "unhealthy");
|
|
1707
|
+
if (allReady) {
|
|
1708
|
+
spin.stop("All services are ready.");
|
|
1709
|
+
} else if (anyUnhealthy) {
|
|
1710
|
+
spin.stop("Some services are unhealthy.");
|
|
1711
|
+
} else {
|
|
1712
|
+
spin.stop("Timed out waiting for services.");
|
|
1713
|
+
}
|
|
1714
|
+
return statuses;
|
|
1715
|
+
}
|
|
1716
|
+
function formatDashboard(statuses, deployPath) {
|
|
1717
|
+
const lines = ["", "=== Amina Deployment Status ===", ""];
|
|
1718
|
+
for (const [name, status] of Object.entries(statuses)) {
|
|
1719
|
+
const icon = status === "healthy" || status === "running" ? "[+]" : "[x]";
|
|
1720
|
+
lines.push(` ${icon} ${name}: ${status}`);
|
|
1721
|
+
}
|
|
1722
|
+
lines.push("", "--- Useful Commands ---", ` View logs: docker compose -f ${deployPath}/docker-compose.yml logs -f`, ` Restart: docker compose -f ${deployPath}/docker-compose.yml restart`, ` Stop: docker compose -f ${deployPath}/docker-compose.yml down`, ` Update: amina update`, ` Uninstall: rm -rf ${deployPath}`, "");
|
|
1723
|
+
return lines;
|
|
1724
|
+
}
|
|
1725
|
+
function showDashboard(statuses, deployPath, prompts) {
|
|
1726
|
+
const lines = formatDashboard(statuses, deployPath);
|
|
1727
|
+
const anyBad = Object.values(statuses).some((s) => s !== "healthy" && s !== "running");
|
|
1728
|
+
for (const line of lines) {
|
|
1729
|
+
if (anyBad) {
|
|
1730
|
+
prompts.log.warn(line);
|
|
1731
|
+
} else {
|
|
1732
|
+
prompts.log.success(line);
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
// src/install.ts
|
|
1738
|
+
var REPO_URL = "https://github.com/iamvikshan/amina.git";
|
|
1739
|
+
var DEFAULT_DEPLOY_DIR = "amina";
|
|
1740
|
+
async function ensurePrerequisites(deps) {
|
|
1741
|
+
const cmdExists = deps.commandExistsFn ?? commandExists;
|
|
1742
|
+
const spawnFn = deps.spawnFn ?? spawn;
|
|
1743
|
+
const prompts = deps.prompts ?? defaultPrompts();
|
|
1744
|
+
const mode = deps.mode ?? "deploy";
|
|
1745
|
+
const dryRun = deps.dryRun ?? false;
|
|
1746
|
+
const force = deps.force ?? false;
|
|
1747
|
+
const isDebian = deps.isDebian ?? (() => existsSync2("/etc/debian_version"));
|
|
1748
|
+
const missing = [];
|
|
1749
|
+
if (!cmdExists("git"))
|
|
1750
|
+
missing.push("git");
|
|
1751
|
+
if (mode === "deploy") {
|
|
1752
|
+
if (!cmdExists("docker"))
|
|
1753
|
+
missing.push("docker");
|
|
1754
|
+
const composeCheck = spawnFn(["docker", "compose", "version"]);
|
|
1755
|
+
if (!composeCheck.success)
|
|
1756
|
+
missing.push("docker compose (v2 plugin)");
|
|
1757
|
+
}
|
|
1758
|
+
if (missing.length === 0)
|
|
1759
|
+
return { ok: true, missing: [] };
|
|
1760
|
+
if (!isDebian())
|
|
1761
|
+
return { ok: false, missing };
|
|
1762
|
+
if (dryRun) {
|
|
1763
|
+
log("[DRY-RUN] Would auto-install: " + missing.join(", "));
|
|
1764
|
+
return { ok: true, missing: [] };
|
|
1765
|
+
}
|
|
1766
|
+
if (!force) {
|
|
1767
|
+
const install = await prompts.confirm({
|
|
1768
|
+
message: `Missing: ${missing.join(", ")}. Auto-install on Debian/Ubuntu?`
|
|
1769
|
+
});
|
|
1770
|
+
if (prompts.isCancel(install) || !install)
|
|
1771
|
+
return { ok: false, missing };
|
|
1772
|
+
}
|
|
1773
|
+
const needsGit = missing.includes("git");
|
|
1774
|
+
const needsDocker = missing.includes("docker") || missing.includes("docker compose (v2 plugin)");
|
|
1775
|
+
if (needsGit) {
|
|
1776
|
+
const update = spawnFn(["sudo", "apt-get", "update"]);
|
|
1777
|
+
if (!update.success)
|
|
1778
|
+
return { ok: false, missing };
|
|
1779
|
+
const inst = spawnFn(["sudo", "apt-get", "install", "-y", "git", "curl"]);
|
|
1780
|
+
if (!inst.success)
|
|
1781
|
+
return { ok: false, missing };
|
|
1782
|
+
}
|
|
1783
|
+
if (needsDocker) {
|
|
1784
|
+
const result = spawnFn([
|
|
1785
|
+
"sh",
|
|
1786
|
+
"-c",
|
|
1787
|
+
"curl -fsSL https://get.docker.com | sh"
|
|
1788
|
+
]);
|
|
1789
|
+
if (!result.success)
|
|
1790
|
+
return { ok: false, missing };
|
|
1791
|
+
}
|
|
1792
|
+
const stillMissing = [];
|
|
1793
|
+
if (!cmdExists("git"))
|
|
1794
|
+
stillMissing.push("git");
|
|
1795
|
+
if (mode === "deploy") {
|
|
1796
|
+
if (!cmdExists("docker"))
|
|
1797
|
+
stillMissing.push("docker");
|
|
1798
|
+
const recheck = spawnFn(["docker", "compose", "version"]);
|
|
1799
|
+
if (!recheck.success)
|
|
1800
|
+
stillMissing.push("docker compose (v2 plugin)");
|
|
1801
|
+
}
|
|
1802
|
+
return stillMissing.length === 0 ? { ok: true, missing: [] } : { ok: false, missing: stillMissing };
|
|
1803
|
+
}
|
|
1804
|
+
async function checkExistingDeployment(deps) {
|
|
1805
|
+
const home = process.env.HOME ?? "/root";
|
|
1806
|
+
const deployPath = deps.deployPath ?? path2.join(home, DEFAULT_DEPLOY_DIR);
|
|
1807
|
+
const fileExists = deps.fileExists ?? existsSync2;
|
|
1808
|
+
const spawnFn = deps.spawnFn ?? spawn;
|
|
1809
|
+
const prompts = deps.prompts ?? defaultPrompts();
|
|
1810
|
+
const mode = deps.mode ?? "deploy";
|
|
1811
|
+
const dryRun = deps.dryRun ?? false;
|
|
1812
|
+
const force = deps.force ?? false;
|
|
1813
|
+
if (mode === "dev") {
|
|
1814
|
+
if (fileExists(path2.join(deployPath, ".git"))) {
|
|
1815
|
+
warn("Use 'amina update' to update an existing clone.");
|
|
1816
|
+
return "abort";
|
|
1817
|
+
}
|
|
1818
|
+
return "proceed";
|
|
1819
|
+
}
|
|
1820
|
+
const hasCompose = fileExists(path2.join(deployPath, "docker-compose.yml"));
|
|
1821
|
+
const hasEnv = fileExists(path2.join(deployPath, ".env"));
|
|
1822
|
+
if (!hasCompose && !hasEnv)
|
|
1823
|
+
return "proceed";
|
|
1824
|
+
if (hasCompose !== hasEnv) {
|
|
1825
|
+
warn("Partial deployment detected. Proceeding with fresh install.");
|
|
1826
|
+
return "proceed";
|
|
1827
|
+
}
|
|
1828
|
+
if (dryRun) {
|
|
1829
|
+
log("[DRY-RUN] Would show existing deployment menu.");
|
|
1830
|
+
return "proceed";
|
|
1831
|
+
}
|
|
1832
|
+
if (force)
|
|
1833
|
+
return "update";
|
|
1834
|
+
spawnFn(["docker", "compose", "ps", "-q"], { cwd: deployPath });
|
|
1835
|
+
const action = await prompts.select({
|
|
1836
|
+
message: "Existing deployment detected. What would you like to do?",
|
|
1837
|
+
options: [
|
|
1838
|
+
{ value: "restart", label: "Restart services" },
|
|
1839
|
+
{ value: "update", label: "Update & restart" },
|
|
1840
|
+
{ value: "reconfigure", label: "Full reconfigure" },
|
|
1841
|
+
{ value: "abort", label: "Cancel" }
|
|
1842
|
+
]
|
|
1843
|
+
});
|
|
1844
|
+
if (prompts.isCancel(action))
|
|
1845
|
+
return "abort";
|
|
1846
|
+
return action;
|
|
1847
|
+
}
|
|
1848
|
+
async function runInstall(deps = {}) {
|
|
1849
|
+
const home = process.env.HOME ?? "/root";
|
|
1850
|
+
const deployPath = deps.deployPath ?? path2.join(home, DEFAULT_DEPLOY_DIR);
|
|
1851
|
+
const spawnFn = deps.spawnFn ?? spawn;
|
|
1852
|
+
const fileExists = deps.fileExists ?? existsSync2;
|
|
1853
|
+
const writeFile = deps.writeFile ?? writeFileSync;
|
|
1854
|
+
const chmod = deps.chmod ?? chmodSync;
|
|
1855
|
+
const mkdir = deps.mkdir ?? mkdirSync;
|
|
1856
|
+
const rmdir = deps.rmdir ?? rmSync;
|
|
1857
|
+
const copyFile = deps.copyFile ?? copyFileSync;
|
|
1858
|
+
const prompts = deps.prompts ?? defaultPrompts();
|
|
1859
|
+
const dryRun = deps.dryRun ?? false;
|
|
1860
|
+
const mode = deps.mode ?? "deploy";
|
|
1861
|
+
const tmpdir = deps.tmpdir ?? path2.join(deployPath, ".amina-tmp");
|
|
1862
|
+
const resolved = {
|
|
1863
|
+
...deps,
|
|
1864
|
+
deployPath,
|
|
1865
|
+
spawnFn,
|
|
1866
|
+
fileExists,
|
|
1867
|
+
writeFile,
|
|
1868
|
+
chmod,
|
|
1869
|
+
mkdir,
|
|
1870
|
+
rmdir,
|
|
1871
|
+
prompts,
|
|
1872
|
+
dryRun,
|
|
1873
|
+
mode,
|
|
1874
|
+
tmpdir
|
|
1875
|
+
};
|
|
1876
|
+
prompts.intro("Amina Install");
|
|
1877
|
+
const prereqs = await ensurePrerequisites(resolved);
|
|
1878
|
+
if (!prereqs.ok) {
|
|
1879
|
+
error("Missing prerequisites:");
|
|
1880
|
+
for (const m of prereqs.missing)
|
|
1881
|
+
error(` - ${m}`);
|
|
1882
|
+
warn("Install the missing tools and try again.");
|
|
1883
|
+
return 1;
|
|
1884
|
+
}
|
|
1885
|
+
const existing = await checkExistingDeployment(resolved);
|
|
1886
|
+
switch (existing) {
|
|
1887
|
+
case "restart": {
|
|
1888
|
+
if (dryRun) {
|
|
1889
|
+
log("[DRY-RUN] Would restart services.");
|
|
1890
|
+
} else {
|
|
1891
|
+
const restart = spawnFn(["docker", "compose", "restart"], {
|
|
1892
|
+
cwd: deployPath
|
|
1893
|
+
});
|
|
1894
|
+
if (!restart.success) {
|
|
1895
|
+
error(`docker compose restart failed: ${restart.stderr}`);
|
|
1896
|
+
return 1;
|
|
1897
|
+
}
|
|
1898
|
+
const statuses = await pollHealth(spawnFn, prompts);
|
|
1899
|
+
showDashboard(statuses, deployPath, prompts);
|
|
1900
|
+
}
|
|
1901
|
+
return 0;
|
|
1902
|
+
}
|
|
1903
|
+
case "update": {
|
|
1904
|
+
if (dryRun) {
|
|
1905
|
+
log("[DRY-RUN] Would pull and restart services.");
|
|
1906
|
+
} else {
|
|
1907
|
+
const pull = spawnFn(["docker", "compose", "pull"], { cwd: deployPath });
|
|
1908
|
+
if (!pull.success) {
|
|
1909
|
+
error(`docker compose pull failed: ${pull.stderr}`);
|
|
1910
|
+
return 1;
|
|
1911
|
+
}
|
|
1912
|
+
const up = spawnFn(["docker", "compose", "up", "-d"], {
|
|
1913
|
+
cwd: deployPath
|
|
1914
|
+
});
|
|
1915
|
+
if (!up.success) {
|
|
1916
|
+
error(`docker compose up failed: ${up.stderr}`);
|
|
1917
|
+
return 1;
|
|
1918
|
+
}
|
|
1919
|
+
const statuses = await pollHealth(spawnFn, prompts);
|
|
1920
|
+
showDashboard(statuses, deployPath, prompts);
|
|
1921
|
+
}
|
|
1922
|
+
return 0;
|
|
1923
|
+
}
|
|
1924
|
+
case "reconfigure":
|
|
1925
|
+
break;
|
|
1926
|
+
case "abort":
|
|
1927
|
+
return 0;
|
|
1928
|
+
case "proceed":
|
|
1929
|
+
break;
|
|
1930
|
+
}
|
|
1931
|
+
if (mode === "dev") {
|
|
1932
|
+
if (dryRun) {
|
|
1933
|
+
log(`[DRY-RUN] Would clone ${REPO_URL} to ${deployPath}`);
|
|
1934
|
+
} else {
|
|
1935
|
+
const clone = spawnFn(["git", "clone", REPO_URL, deployPath]);
|
|
1936
|
+
if (!clone.success) {
|
|
1937
|
+
error(`Failed to clone repository: ${clone.stderr}`);
|
|
1938
|
+
return 1;
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
prompts.outro("Source cloned. Run bun install and bun run dev to get started.");
|
|
1942
|
+
return 0;
|
|
1943
|
+
}
|
|
1944
|
+
if (dryRun) {
|
|
1945
|
+
log(`[DRY-RUN] Would clone ${REPO_URL} to ${tmpdir}`);
|
|
1946
|
+
} else {
|
|
1947
|
+
mkdir(tmpdir, { recursive: true });
|
|
1948
|
+
const clone = spawnFn(["git", "clone", "--depth", "1", REPO_URL, tmpdir]);
|
|
1949
|
+
if (!clone.success) {
|
|
1950
|
+
error(`Failed to clone repository: ${clone.stderr}`);
|
|
1951
|
+
rmdir(tmpdir, { recursive: true, force: true });
|
|
1952
|
+
return 1;
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
if (dryRun) {
|
|
1956
|
+
log("[DRY-RUN] Would create deploy directory and copy config files.");
|
|
1957
|
+
} else {
|
|
1958
|
+
mkdir(deployPath, { recursive: true });
|
|
1959
|
+
mkdir(path2.join(deployPath, "lavalink"), { recursive: true });
|
|
1960
|
+
const composeSrc = path2.join(tmpdir, "docker-compose.prod.yml");
|
|
1961
|
+
const lavalinkSrc = path2.join(tmpdir, "lavalink", "application.yml");
|
|
1962
|
+
if (!fileExists(composeSrc)) {
|
|
1963
|
+
error("docker-compose.prod.yml not found in cloned repository.");
|
|
1964
|
+
rmdir(tmpdir, { recursive: true, force: true });
|
|
1965
|
+
return 1;
|
|
1966
|
+
}
|
|
1967
|
+
try {
|
|
1968
|
+
copyFile(composeSrc, path2.join(deployPath, "docker-compose.yml"));
|
|
1969
|
+
if (fileExists(lavalinkSrc)) {
|
|
1970
|
+
copyFile(lavalinkSrc, path2.join(deployPath, "lavalink", "application.yml"));
|
|
1971
|
+
}
|
|
1972
|
+
} catch (e) {
|
|
1973
|
+
error(`Failed to copy config files: ${e instanceof Error ? e.message : e}`);
|
|
1974
|
+
rmdir(tmpdir, { recursive: true, force: true });
|
|
1975
|
+
return 1;
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
let envContent = "";
|
|
1979
|
+
let retries = 0;
|
|
1980
|
+
const maxRetries = 3;
|
|
1981
|
+
while (retries < maxRetries) {
|
|
1982
|
+
const envMode = await prompts.select({
|
|
1983
|
+
message: "How would you like to configure environment variables?",
|
|
1984
|
+
options: [
|
|
1985
|
+
{ value: "guided", label: "Guided setup", hint: "Interactive prompts" },
|
|
1986
|
+
{ value: "paste", label: "Paste .env content" },
|
|
1987
|
+
{ value: "import", label: "Import from file" }
|
|
1988
|
+
]
|
|
1989
|
+
});
|
|
1990
|
+
if (prompts.isCancel(envMode)) {
|
|
1991
|
+
if (!dryRun)
|
|
1992
|
+
rmdir(tmpdir, { recursive: true, force: true });
|
|
1993
|
+
return 1;
|
|
1994
|
+
}
|
|
1995
|
+
try {
|
|
1996
|
+
envContent = await (deps.configureEnvFn ?? configureEnv)(prompts, envMode);
|
|
1997
|
+
} catch {
|
|
1998
|
+
if (!dryRun)
|
|
1999
|
+
rmdir(tmpdir, { recursive: true, force: true });
|
|
2000
|
+
return 1;
|
|
2001
|
+
}
|
|
2002
|
+
const validation = (deps.validateEnvFn ?? validateEnv)(envContent);
|
|
2003
|
+
if (validation.ok) {
|
|
2004
|
+
for (const w of validation.warnings)
|
|
2005
|
+
warn(w);
|
|
2006
|
+
break;
|
|
2007
|
+
}
|
|
2008
|
+
for (const e of validation.errors)
|
|
2009
|
+
error(e);
|
|
2010
|
+
for (const w of validation.warnings)
|
|
2011
|
+
warn(w);
|
|
2012
|
+
retries++;
|
|
2013
|
+
if (retries < maxRetries)
|
|
2014
|
+
warn("Please try again.");
|
|
2015
|
+
}
|
|
2016
|
+
if (retries >= maxRetries) {
|
|
2017
|
+
error("Failed to configure valid environment after 3 attempts.");
|
|
2018
|
+
if (!dryRun)
|
|
2019
|
+
rmdir(tmpdir, { recursive: true, force: true });
|
|
2020
|
+
return 1;
|
|
2021
|
+
}
|
|
2022
|
+
const envPath = path2.join(deployPath, ".env");
|
|
2023
|
+
if (dryRun) {
|
|
2024
|
+
log("[DRY-RUN] Would write .env file.");
|
|
2025
|
+
} else {
|
|
2026
|
+
writeFile(envPath, envContent);
|
|
2027
|
+
chmod(envPath, 384);
|
|
2028
|
+
}
|
|
2029
|
+
if (dryRun) {
|
|
2030
|
+
log("[DRY-RUN] Would run docker compose up -d.");
|
|
2031
|
+
} else {
|
|
2032
|
+
const up = spawnFn(["docker", "compose", "up", "-d"], { cwd: deployPath });
|
|
2033
|
+
if (!up.success) {
|
|
2034
|
+
error(`docker compose up failed: ${up.stderr}`);
|
|
2035
|
+
rmdir(tmpdir, { recursive: true, force: true });
|
|
2036
|
+
return 1;
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
if (!dryRun) {
|
|
2040
|
+
const statuses = await pollHealth(spawnFn, prompts);
|
|
2041
|
+
showDashboard(statuses, deployPath, prompts);
|
|
2042
|
+
}
|
|
2043
|
+
if (!dryRun) {
|
|
2044
|
+
rmdir(tmpdir, { recursive: true, force: true });
|
|
2045
|
+
}
|
|
2046
|
+
prompts.outro("Installation complete!");
|
|
2047
|
+
return 0;
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
// src/status.ts
|
|
2051
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
2052
|
+
import path3 from "node:path";
|
|
2053
|
+
function detectMode(deployPath, fileExists) {
|
|
2054
|
+
if (fileExists(path3.join(deployPath, "docker-compose.yml")))
|
|
2055
|
+
return "deploy";
|
|
2056
|
+
if (fileExists(path3.join(deployPath, ".git")))
|
|
2057
|
+
return "dev";
|
|
2058
|
+
return null;
|
|
2059
|
+
}
|
|
2060
|
+
async function runStatus(deps = {}) {
|
|
2061
|
+
const home = process.env.HOME ?? "/root";
|
|
2062
|
+
const deployPath = deps.deployPath ?? path3.join(home, "amina");
|
|
2063
|
+
const fileExists = deps.fileExists ?? existsSync3;
|
|
2064
|
+
const spawnFn = deps.spawnFn ?? spawn;
|
|
2065
|
+
const prompts = deps.prompts ?? defaultPrompts();
|
|
2066
|
+
const mode = detectMode(deployPath, fileExists);
|
|
2067
|
+
if (!mode) {
|
|
2068
|
+
error(`No deployment found at ${deployPath}`);
|
|
2069
|
+
warn('Run "amina install" to set up a fresh deployment.');
|
|
2070
|
+
return 1;
|
|
2071
|
+
}
|
|
2072
|
+
if (mode === "deploy") {
|
|
2073
|
+
const statuses = await pollHealth(spawnFn, prompts, {
|
|
2074
|
+
timeout: 1e4,
|
|
2075
|
+
interval: 2000
|
|
2076
|
+
});
|
|
2077
|
+
showDashboard(statuses, deployPath, prompts);
|
|
2078
|
+
return 0;
|
|
2079
|
+
}
|
|
2080
|
+
const branch = spawnFn(["git", "branch", "--show-current"], {
|
|
2081
|
+
cwd: deployPath
|
|
2082
|
+
});
|
|
2083
|
+
const lastCommit = spawnFn(["git", "log", "--oneline", "-1"], {
|
|
2084
|
+
cwd: deployPath
|
|
2085
|
+
});
|
|
2086
|
+
if (!branch.success || !lastCommit.success) {
|
|
2087
|
+
error("Failed to read git repository status.");
|
|
2088
|
+
return 1;
|
|
2089
|
+
}
|
|
2090
|
+
const status = spawnFn(["git", "status", "--short"], { cwd: deployPath });
|
|
2091
|
+
prompts.log.info(`Branch: ${branch.stdout || "unknown"}`);
|
|
2092
|
+
prompts.log.info(`Last commit: ${lastCommit.stdout || "unknown"}`);
|
|
2093
|
+
if (status.stdout) {
|
|
2094
|
+
prompts.log.warn("Uncommitted changes:");
|
|
2095
|
+
prompts.log.info(status.stdout);
|
|
2096
|
+
} else {
|
|
2097
|
+
prompts.log.success("Working tree is clean.");
|
|
2098
|
+
}
|
|
2099
|
+
return 0;
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2102
|
+
// src/uninstall.ts
|
|
2103
|
+
import { existsSync as existsSync4, rmSync as rmSync2 } from "node:fs";
|
|
2104
|
+
import path4 from "node:path";
|
|
2105
|
+
function detectMode2(deployPath, fileExists) {
|
|
2106
|
+
if (fileExists(path4.join(deployPath, "docker-compose.yml")))
|
|
2107
|
+
return "deploy";
|
|
2108
|
+
if (fileExists(path4.join(deployPath, ".git")))
|
|
2109
|
+
return "dev";
|
|
2110
|
+
return null;
|
|
2111
|
+
}
|
|
2112
|
+
async function runUninstall(deps = {}) {
|
|
2113
|
+
const home = process.env.HOME ?? "/root";
|
|
2114
|
+
const deployPath = deps.deployPath ?? path4.join(home, "amina");
|
|
2115
|
+
const fileExists = deps.fileExists ?? existsSync4;
|
|
2116
|
+
const spawnFn = deps.spawnFn ?? spawn;
|
|
2117
|
+
const rmdir = deps.rmdir ?? rmSync2;
|
|
2118
|
+
const prompts = deps.prompts ?? defaultPrompts();
|
|
2119
|
+
const dryRun = deps.dryRun ?? false;
|
|
2120
|
+
const force = deps.force ?? false;
|
|
2121
|
+
const mode = detectMode2(deployPath, fileExists);
|
|
2122
|
+
if (!mode) {
|
|
2123
|
+
error(`No deployment found at ${deployPath}`);
|
|
2124
|
+
warn("Nothing to uninstall.");
|
|
2125
|
+
return 1;
|
|
2126
|
+
}
|
|
2127
|
+
log(`Found ${mode} deployment at ${deployPath}`);
|
|
2128
|
+
if (dryRun) {
|
|
2129
|
+
log("[DRY-RUN] Would stop and remove all services.");
|
|
2130
|
+
log(`[DRY-RUN] Would remove directory: ${deployPath}`);
|
|
2131
|
+
return 0;
|
|
2132
|
+
}
|
|
2133
|
+
if (!force) {
|
|
2134
|
+
const confirmed = await prompts.confirm({
|
|
2135
|
+
message: `Are you sure you want to remove the ${mode} deployment at ${deployPath}?`
|
|
2136
|
+
});
|
|
2137
|
+
if (prompts.isCancel(confirmed) || !confirmed) {
|
|
2138
|
+
warn("Uninstall cancelled.");
|
|
2139
|
+
return 0;
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
if (mode === "deploy") {
|
|
2143
|
+
if (!force) {
|
|
2144
|
+
const removeVolumes = await prompts.confirm({
|
|
2145
|
+
message: "Also remove Docker volumes (database data, etc.)?"
|
|
2146
|
+
});
|
|
2147
|
+
if (prompts.isCancel(removeVolumes)) {
|
|
2148
|
+
warn("Uninstall cancelled.");
|
|
2149
|
+
return 0;
|
|
2150
|
+
}
|
|
2151
|
+
const downArgs = ["docker", "compose", "down", "--remove-orphans"];
|
|
2152
|
+
if (removeVolumes)
|
|
2153
|
+
downArgs.push("-v");
|
|
2154
|
+
const down = spawnFn(downArgs, { cwd: deployPath });
|
|
2155
|
+
if (!down.success) {
|
|
2156
|
+
error(`docker compose down failed: ${down.stderr}`);
|
|
2157
|
+
return 1;
|
|
2158
|
+
}
|
|
2159
|
+
} else {
|
|
2160
|
+
const down = spawnFn(["docker", "compose", "down", "--remove-orphans", "-v"], { cwd: deployPath });
|
|
2161
|
+
if (!down.success) {
|
|
2162
|
+
error(`docker compose down failed: ${down.stderr}`);
|
|
2163
|
+
return 1;
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
rmdir(deployPath, { recursive: true, force: true });
|
|
2168
|
+
success(`Removed ${mode} deployment at ${deployPath}`);
|
|
2169
|
+
return 0;
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
// src/update.ts
|
|
2173
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
2174
|
+
import path5 from "node:path";
|
|
2175
|
+
var REPO_URL2 = "https://github.com/iamvikshan/amina.git";
|
|
2176
|
+
function detectMode3(deployPath, fileExists) {
|
|
2177
|
+
if (fileExists(path5.join(deployPath, "docker-compose.yml")))
|
|
2178
|
+
return "deploy";
|
|
2179
|
+
if (fileExists(path5.join(deployPath, ".git")))
|
|
2180
|
+
return "dev";
|
|
2181
|
+
return null;
|
|
2182
|
+
}
|
|
2183
|
+
function parseImageIds(stdout) {
|
|
2184
|
+
const ids = {};
|
|
2185
|
+
if (!stdout.trim())
|
|
2186
|
+
return ids;
|
|
2187
|
+
try {
|
|
2188
|
+
for (const line of stdout.trim().split(`
|
|
2189
|
+
`)) {
|
|
2190
|
+
const entry = JSON.parse(line);
|
|
2191
|
+
if (entry.Service && entry.ID)
|
|
2192
|
+
ids[entry.Service] = entry.ID;
|
|
2193
|
+
}
|
|
2194
|
+
} catch {}
|
|
2195
|
+
return ids;
|
|
2196
|
+
}
|
|
2197
|
+
function changedServices(before, after) {
|
|
2198
|
+
const changed = [];
|
|
2199
|
+
for (const [service, id] of Object.entries(after)) {
|
|
2200
|
+
if (before[service] !== id)
|
|
2201
|
+
changed.push(service);
|
|
2202
|
+
}
|
|
2203
|
+
return changed;
|
|
2204
|
+
}
|
|
2205
|
+
async function updateDeploy(opts) {
|
|
2206
|
+
const { deployPath, spawnFn, prompts, dryRun } = opts;
|
|
2207
|
+
if (dryRun) {
|
|
2208
|
+
log("[DRY-RUN] Would pull latest images.");
|
|
2209
|
+
log("[DRY-RUN] Would restart changed services.");
|
|
2210
|
+
log("[DRY-RUN] Would prune old images.");
|
|
2211
|
+
return 0;
|
|
2212
|
+
}
|
|
2213
|
+
const beforeResult = spawnFn(["docker", "compose", "images", "--format", "json"], { cwd: deployPath });
|
|
2214
|
+
const beforeIds = parseImageIds(beforeResult.stdout);
|
|
2215
|
+
log("Pulling latest images...");
|
|
2216
|
+
const pull = spawnFn(["docker", "compose", "pull"], { cwd: deployPath });
|
|
2217
|
+
if (!pull.success) {
|
|
2218
|
+
error(`docker compose pull failed: ${pull.stderr}`);
|
|
2219
|
+
return 1;
|
|
2220
|
+
}
|
|
2221
|
+
const afterResult = spawnFn(["docker", "compose", "images", "--format", "json"], { cwd: deployPath });
|
|
2222
|
+
const afterIds = parseImageIds(afterResult.stdout);
|
|
2223
|
+
const changed = changedServices(beforeIds, afterIds);
|
|
2224
|
+
if (changed.length === 0) {
|
|
2225
|
+
success("All images are already up to date.");
|
|
2226
|
+
} else {
|
|
2227
|
+
log(`Restarting changed services: ${changed.join(", ")}`);
|
|
2228
|
+
const up = spawnFn(["docker", "compose", "up", "-d", ...changed], {
|
|
2229
|
+
cwd: deployPath
|
|
2230
|
+
});
|
|
2231
|
+
if (!up.success) {
|
|
2232
|
+
error(`docker compose up failed: ${up.stderr}`);
|
|
2233
|
+
return 1;
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
const statuses = await pollHealth(spawnFn, prompts);
|
|
2237
|
+
showDashboard(statuses, deployPath, prompts);
|
|
2238
|
+
spawnFn(["docker", "image", "prune", "-f"]);
|
|
2239
|
+
success("Amina deployment updated successfully.");
|
|
2240
|
+
return 0;
|
|
2241
|
+
}
|
|
2242
|
+
async function updateDev(opts) {
|
|
2243
|
+
const { deployPath, spawnFn, prompts, dryRun, force } = opts;
|
|
2244
|
+
if (dryRun) {
|
|
2245
|
+
log("[DRY-RUN] Would fetch and pull latest changes.");
|
|
2246
|
+
return 0;
|
|
2247
|
+
}
|
|
2248
|
+
const fetch2 = spawnFn(["git", "fetch", "--prune"], { cwd: deployPath });
|
|
2249
|
+
if (!fetch2.success) {
|
|
2250
|
+
error(`git fetch failed: ${fetch2.stderr}`);
|
|
2251
|
+
return 1;
|
|
2252
|
+
}
|
|
2253
|
+
const status = spawnFn(["git", "status", "--porcelain"], { cwd: deployPath });
|
|
2254
|
+
const isDirty = status.stdout.trim().length > 0;
|
|
2255
|
+
if (!isDirty) {
|
|
2256
|
+
log("Working tree is clean. Pulling latest...");
|
|
2257
|
+
const pull = spawnFn(["git", "pull", "--ff-only"], { cwd: deployPath });
|
|
2258
|
+
if (!pull.success) {
|
|
2259
|
+
error(`git pull failed: ${pull.stderr}`);
|
|
2260
|
+
return 1;
|
|
2261
|
+
}
|
|
2262
|
+
success("Updated successfully.");
|
|
2263
|
+
return 0;
|
|
2264
|
+
}
|
|
2265
|
+
if (force) {
|
|
2266
|
+
log("Force mode: stashing local changes...");
|
|
2267
|
+
spawnFn(["git", "stash", "push", "-u"], { cwd: deployPath });
|
|
2268
|
+
const pull = spawnFn(["git", "pull", "--ff-only"], { cwd: deployPath });
|
|
2269
|
+
if (!pull.success) {
|
|
2270
|
+
error(`git pull failed: ${pull.stderr}`);
|
|
2271
|
+
spawnFn(["git", "stash", "pop"], { cwd: deployPath });
|
|
2272
|
+
warn("Local changes have been restored.");
|
|
2273
|
+
return 1;
|
|
2274
|
+
}
|
|
2275
|
+
spawnFn(["git", "stash", "drop"], { cwd: deployPath });
|
|
2276
|
+
success("Updated successfully (local changes were stashed and dropped).");
|
|
2277
|
+
return 0;
|
|
2278
|
+
}
|
|
2279
|
+
const action = await prompts.select({
|
|
2280
|
+
message: "Local changes detected. How would you like to proceed?",
|
|
2281
|
+
options: [
|
|
2282
|
+
{
|
|
2283
|
+
value: "overwrite",
|
|
2284
|
+
label: "Overwrite local changes",
|
|
2285
|
+
hint: "stash, pull, drop stash"
|
|
2286
|
+
},
|
|
2287
|
+
{
|
|
2288
|
+
value: "versioned",
|
|
2289
|
+
label: "Pull to versioned folder",
|
|
2290
|
+
hint: "clone alongside current dir"
|
|
2291
|
+
},
|
|
2292
|
+
{ value: "cancel", label: "Cancel" }
|
|
2293
|
+
]
|
|
2294
|
+
});
|
|
2295
|
+
if (prompts.isCancel(action) || action === "cancel") {
|
|
2296
|
+
warn("Update cancelled.");
|
|
2297
|
+
return 0;
|
|
2298
|
+
}
|
|
2299
|
+
if (action === "overwrite") {
|
|
2300
|
+
spawnFn(["git", "stash", "push", "-u"], { cwd: deployPath });
|
|
2301
|
+
const pull = spawnFn(["git", "pull", "--ff-only"], { cwd: deployPath });
|
|
2302
|
+
if (!pull.success) {
|
|
2303
|
+
error(`git pull failed: ${pull.stderr}`);
|
|
2304
|
+
spawnFn(["git", "stash", "pop"], { cwd: deployPath });
|
|
2305
|
+
warn("Local changes have been restored.");
|
|
2306
|
+
return 1;
|
|
2307
|
+
}
|
|
2308
|
+
spawnFn(["git", "stash", "drop"], { cwd: deployPath });
|
|
2309
|
+
success("Updated successfully.");
|
|
2310
|
+
return 0;
|
|
2311
|
+
}
|
|
2312
|
+
const confirmed = await prompts.confirm({
|
|
2313
|
+
message: "This will clone the latest version into a new folder alongside the current one. Continue?"
|
|
2314
|
+
});
|
|
2315
|
+
if (prompts.isCancel(confirmed) || !confirmed) {
|
|
2316
|
+
warn("Update cancelled.");
|
|
2317
|
+
return 0;
|
|
2318
|
+
}
|
|
2319
|
+
const tagResult = spawnFn(["git", "describe", "--tags", "--abbrev=0"], {
|
|
2320
|
+
cwd: deployPath
|
|
2321
|
+
});
|
|
2322
|
+
const version = tagResult.success ? tagResult.stdout.replace(/^v/, "") : "latest";
|
|
2323
|
+
const parentDir = path5.dirname(deployPath);
|
|
2324
|
+
const versionedPath = path5.join(parentDir, `amina-v${version}`);
|
|
2325
|
+
const clone = spawnFn(["git", "clone", REPO_URL2, versionedPath]);
|
|
2326
|
+
if (!clone.success) {
|
|
2327
|
+
error(`Failed to clone to ${versionedPath}: ${clone.stderr}`);
|
|
2328
|
+
return 1;
|
|
2329
|
+
}
|
|
2330
|
+
success(`Cloned latest to ${versionedPath}`);
|
|
2331
|
+
return 0;
|
|
2332
|
+
}
|
|
2333
|
+
async function runUpdate(dependencies = {}) {
|
|
2334
|
+
const home = process.env.HOME ?? "/root";
|
|
2335
|
+
const deployPath = dependencies.deployPath ?? path5.join(home, "amina");
|
|
2336
|
+
const fileExists = dependencies.fileExists ?? existsSync5;
|
|
2337
|
+
const spawnFn = dependencies.spawnFn ?? spawn;
|
|
2338
|
+
const prompts = dependencies.prompts ?? defaultPrompts();
|
|
2339
|
+
const dryRun = dependencies.dryRun ?? false;
|
|
2340
|
+
const force = dependencies.force ?? false;
|
|
2341
|
+
const mode = dependencies.mode ?? detectMode3(deployPath, fileExists);
|
|
2342
|
+
if (!mode) {
|
|
2343
|
+
error(`No deployment found at ${deployPath}`);
|
|
2344
|
+
warn('Run "amina install" to set up a fresh deployment.');
|
|
2345
|
+
return 1;
|
|
2346
|
+
}
|
|
2347
|
+
log(`Updating Amina (${mode} mode) in ${deployPath}...`);
|
|
2348
|
+
if (mode === "deploy") {
|
|
2349
|
+
return updateDeploy({ deployPath, spawnFn, prompts, dryRun });
|
|
2350
|
+
}
|
|
2351
|
+
return updateDev({ deployPath, spawnFn, prompts, dryRun, force });
|
|
2352
|
+
}
|
|
2353
|
+
|
|
2354
|
+
// src/index.ts
|
|
2355
|
+
function parseFlags(args) {
|
|
2356
|
+
const flags = { dryRun: false, force: false, mode: "deploy" };
|
|
2357
|
+
for (let i = 3;i < args.length; i++) {
|
|
2358
|
+
const arg = args[i];
|
|
2359
|
+
if (arg === "--dry-run")
|
|
2360
|
+
flags.dryRun = true;
|
|
2361
|
+
else if (arg === "--force" || arg === "-f" || arg === "-y")
|
|
2362
|
+
flags.force = true;
|
|
2363
|
+
else if (arg === "--mode" && i + 1 < args.length) {
|
|
2364
|
+
const val = args[++i];
|
|
2365
|
+
if (val === "deploy" || val === "dev")
|
|
2366
|
+
flags.mode = val;
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
return flags;
|
|
2370
|
+
}
|
|
2371
|
+
var HELP_TEXT = `amina - Amina deployment CLI
|
|
2372
|
+
|
|
2373
|
+
Usage: amina <command> [options]
|
|
2374
|
+
|
|
2375
|
+
Commands:
|
|
2376
|
+
check Check for new Amina releases
|
|
2377
|
+
install Deploy a fresh Amina instance
|
|
2378
|
+
update Update an existing deployment
|
|
2379
|
+
uninstall Remove an Amina deployment
|
|
2380
|
+
status Show deployment status
|
|
2381
|
+
help Show this help message
|
|
2382
|
+
|
|
2383
|
+
Options:
|
|
2384
|
+
--dry-run Preview changes without executing
|
|
2385
|
+
--force Skip confirmations (auto-approve)
|
|
2386
|
+
--mode Set mode: deploy (default) or dev
|
|
2387
|
+
-f, -y Alias for --force
|
|
2388
|
+
`;
|
|
2389
|
+
async function main(args = process.argv) {
|
|
2390
|
+
const subcommand = args[2] ?? "help";
|
|
2391
|
+
const flags = parseFlags(args);
|
|
2392
|
+
switch (subcommand) {
|
|
2393
|
+
case "check":
|
|
2394
|
+
return runCheck();
|
|
2395
|
+
case "install":
|
|
2396
|
+
return runInstall({
|
|
2397
|
+
dryRun: flags.dryRun,
|
|
2398
|
+
force: flags.force,
|
|
2399
|
+
mode: flags.mode
|
|
2400
|
+
});
|
|
2401
|
+
case "update":
|
|
2402
|
+
return runUpdate({
|
|
2403
|
+
dryRun: flags.dryRun,
|
|
2404
|
+
force: flags.force,
|
|
2405
|
+
mode: flags.mode
|
|
2406
|
+
});
|
|
2407
|
+
case "uninstall":
|
|
2408
|
+
return runUninstall({ dryRun: flags.dryRun, force: flags.force });
|
|
2409
|
+
case "status":
|
|
2410
|
+
return runStatus();
|
|
2411
|
+
case "help":
|
|
2412
|
+
case "--help":
|
|
2413
|
+
case "-h":
|
|
2414
|
+
console.log(HELP_TEXT);
|
|
2415
|
+
return 0;
|
|
2416
|
+
default:
|
|
2417
|
+
console.error(`Unknown command: ${subcommand}
|
|
2418
|
+
`);
|
|
2419
|
+
console.log(HELP_TEXT);
|
|
2420
|
+
return 1;
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
var isMain = process.argv[1] === fileURLToPath(import.meta.url);
|
|
2424
|
+
if (isMain) {
|
|
2425
|
+
process.exitCode = await main();
|
|
2426
|
+
}
|
|
2427
|
+
export {
|
|
2428
|
+
parseFlags,
|
|
2429
|
+
main
|
|
2430
|
+
};
|