@saidulbadhon/jssm-cli 1.5.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 +4372 -0
- package/package.json +50 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,4372 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
9
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
10
|
+
}) : x)(function(x) {
|
|
11
|
+
if (typeof require !== "undefined")
|
|
12
|
+
return require.apply(this, arguments);
|
|
13
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
14
|
+
});
|
|
15
|
+
var __esm = (fn, res) => function __init() {
|
|
16
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
17
|
+
};
|
|
18
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
19
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
20
|
+
};
|
|
21
|
+
var __export = (target, all) => {
|
|
22
|
+
for (var name in all)
|
|
23
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
24
|
+
};
|
|
25
|
+
var __copyProps = (to, from, except, desc) => {
|
|
26
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
27
|
+
for (let key of __getOwnPropNames(from))
|
|
28
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
29
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
30
|
+
}
|
|
31
|
+
return to;
|
|
32
|
+
};
|
|
33
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
34
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
35
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
36
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
37
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
38
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
39
|
+
mod
|
|
40
|
+
));
|
|
41
|
+
|
|
42
|
+
// node_modules/cli-width/index.js
|
|
43
|
+
var require_cli_width = __commonJS({
|
|
44
|
+
"node_modules/cli-width/index.js"(exports, module) {
|
|
45
|
+
"use strict";
|
|
46
|
+
module.exports = cliWidth2;
|
|
47
|
+
function normalizeOpts(options) {
|
|
48
|
+
const defaultOpts = {
|
|
49
|
+
defaultWidth: 0,
|
|
50
|
+
output: process.stdout,
|
|
51
|
+
tty: __require("tty")
|
|
52
|
+
};
|
|
53
|
+
if (!options) {
|
|
54
|
+
return defaultOpts;
|
|
55
|
+
}
|
|
56
|
+
Object.keys(defaultOpts).forEach(function(key) {
|
|
57
|
+
if (!options[key]) {
|
|
58
|
+
options[key] = defaultOpts[key];
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
return options;
|
|
62
|
+
}
|
|
63
|
+
function cliWidth2(options) {
|
|
64
|
+
const opts = normalizeOpts(options);
|
|
65
|
+
if (opts.output.getWindowSize) {
|
|
66
|
+
return opts.output.getWindowSize()[0] || opts.defaultWidth;
|
|
67
|
+
}
|
|
68
|
+
if (opts.tty.getWindowSize) {
|
|
69
|
+
return opts.tty.getWindowSize()[1] || opts.defaultWidth;
|
|
70
|
+
}
|
|
71
|
+
if (opts.output.columns) {
|
|
72
|
+
return opts.output.columns;
|
|
73
|
+
}
|
|
74
|
+
if (process.env.CLI_WIDTH) {
|
|
75
|
+
const width = parseInt(process.env.CLI_WIDTH, 10);
|
|
76
|
+
if (!isNaN(width) && width !== 0) {
|
|
77
|
+
return width;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return opts.defaultWidth;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// node_modules/emoji-regex/index.js
|
|
86
|
+
var require_emoji_regex = __commonJS({
|
|
87
|
+
"node_modules/emoji-regex/index.js"(exports, module) {
|
|
88
|
+
module.exports = () => {
|
|
89
|
+
return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E-\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED8\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])))?))?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3C-\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC2\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF]|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// node_modules/mute-stream/lib/index.js
|
|
95
|
+
var require_lib = __commonJS({
|
|
96
|
+
"node_modules/mute-stream/lib/index.js"(exports, module) {
|
|
97
|
+
var Stream = __require("stream");
|
|
98
|
+
var MuteStream2 = class extends Stream {
|
|
99
|
+
#isTTY = null;
|
|
100
|
+
constructor(opts = {}) {
|
|
101
|
+
super(opts);
|
|
102
|
+
this.writable = this.readable = true;
|
|
103
|
+
this.muted = false;
|
|
104
|
+
this.on("pipe", this._onpipe);
|
|
105
|
+
this.replace = opts.replace;
|
|
106
|
+
this._prompt = opts.prompt || null;
|
|
107
|
+
this._hadControl = false;
|
|
108
|
+
}
|
|
109
|
+
#destSrc(key, def) {
|
|
110
|
+
if (this._dest) {
|
|
111
|
+
return this._dest[key];
|
|
112
|
+
}
|
|
113
|
+
if (this._src) {
|
|
114
|
+
return this._src[key];
|
|
115
|
+
}
|
|
116
|
+
return def;
|
|
117
|
+
}
|
|
118
|
+
#proxy(method, ...args2) {
|
|
119
|
+
if (typeof this._dest?.[method] === "function") {
|
|
120
|
+
this._dest[method](...args2);
|
|
121
|
+
}
|
|
122
|
+
if (typeof this._src?.[method] === "function") {
|
|
123
|
+
this._src[method](...args2);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
get isTTY() {
|
|
127
|
+
if (this.#isTTY !== null) {
|
|
128
|
+
return this.#isTTY;
|
|
129
|
+
}
|
|
130
|
+
return this.#destSrc("isTTY", false);
|
|
131
|
+
}
|
|
132
|
+
// basically just get replace the getter/setter with a regular value
|
|
133
|
+
set isTTY(val) {
|
|
134
|
+
this.#isTTY = val;
|
|
135
|
+
}
|
|
136
|
+
get rows() {
|
|
137
|
+
return this.#destSrc("rows");
|
|
138
|
+
}
|
|
139
|
+
get columns() {
|
|
140
|
+
return this.#destSrc("columns");
|
|
141
|
+
}
|
|
142
|
+
mute() {
|
|
143
|
+
this.muted = true;
|
|
144
|
+
}
|
|
145
|
+
unmute() {
|
|
146
|
+
this.muted = false;
|
|
147
|
+
}
|
|
148
|
+
_onpipe(src) {
|
|
149
|
+
this._src = src;
|
|
150
|
+
}
|
|
151
|
+
pipe(dest, options) {
|
|
152
|
+
this._dest = dest;
|
|
153
|
+
return super.pipe(dest, options);
|
|
154
|
+
}
|
|
155
|
+
pause() {
|
|
156
|
+
if (this._src) {
|
|
157
|
+
return this._src.pause();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
resume() {
|
|
161
|
+
if (this._src) {
|
|
162
|
+
return this._src.resume();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
write(c) {
|
|
166
|
+
if (this.muted) {
|
|
167
|
+
if (!this.replace) {
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
if (c.match(/^\u001b/)) {
|
|
171
|
+
if (c.indexOf(this._prompt) === 0) {
|
|
172
|
+
c = c.slice(this._prompt.length);
|
|
173
|
+
c = c.replace(/./g, this.replace);
|
|
174
|
+
c = this._prompt + c;
|
|
175
|
+
}
|
|
176
|
+
this._hadControl = true;
|
|
177
|
+
return this.emit("data", c);
|
|
178
|
+
} else {
|
|
179
|
+
if (this._prompt && this._hadControl && c.indexOf(this._prompt) === 0) {
|
|
180
|
+
this._hadControl = false;
|
|
181
|
+
this.emit("data", this._prompt);
|
|
182
|
+
c = c.slice(this._prompt.length);
|
|
183
|
+
}
|
|
184
|
+
c = c.toString().replace(/./g, this.replace);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
this.emit("data", c);
|
|
188
|
+
}
|
|
189
|
+
end(c) {
|
|
190
|
+
if (this.muted) {
|
|
191
|
+
if (c && this.replace) {
|
|
192
|
+
c = c.toString().replace(/./g, this.replace);
|
|
193
|
+
} else {
|
|
194
|
+
c = null;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (c) {
|
|
198
|
+
this.emit("data", c);
|
|
199
|
+
}
|
|
200
|
+
this.emit("end");
|
|
201
|
+
}
|
|
202
|
+
destroy(...args2) {
|
|
203
|
+
return this.#proxy("destroy", ...args2);
|
|
204
|
+
}
|
|
205
|
+
destroySoon(...args2) {
|
|
206
|
+
return this.#proxy("destroySoon", ...args2);
|
|
207
|
+
}
|
|
208
|
+
close(...args2) {
|
|
209
|
+
return this.#proxy("close", ...args2);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
module.exports = MuteStream2;
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// src/auth.ts
|
|
217
|
+
var auth_exports = {};
|
|
218
|
+
__export(auth_exports, {
|
|
219
|
+
clearAuthData: () => clearAuthData,
|
|
220
|
+
getAuthData: () => getAuthData,
|
|
221
|
+
getAuthToken: () => getAuthToken,
|
|
222
|
+
isAuthenticated: () => isAuthenticated,
|
|
223
|
+
loadAuthData: () => loadAuthData,
|
|
224
|
+
login: () => login,
|
|
225
|
+
register: () => register,
|
|
226
|
+
saveAuthData: () => saveAuthData
|
|
227
|
+
});
|
|
228
|
+
import { homedir } from "os";
|
|
229
|
+
import { join } from "path";
|
|
230
|
+
import { mkdir, readFile, writeFile, unlink } from "fs/promises";
|
|
231
|
+
async function loadAuthData() {
|
|
232
|
+
try {
|
|
233
|
+
const data = await readFile(AUTH_FILE, "utf-8");
|
|
234
|
+
const authData = JSON.parse(data);
|
|
235
|
+
if (authData.expiresAt && Date.now() > authData.expiresAt) {
|
|
236
|
+
console.log("\u26A0\uFE0F Authentication token has expired. Please login again.");
|
|
237
|
+
await clearAuthData();
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
return authData;
|
|
241
|
+
} catch (error) {
|
|
242
|
+
if (error.code === "ENOENT") {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
throw error;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
async function saveAuthData(authData) {
|
|
249
|
+
try {
|
|
250
|
+
await mkdir(AUTH_DIR, { recursive: true });
|
|
251
|
+
await writeFile(AUTH_FILE, JSON.stringify(authData, null, 2), "utf-8");
|
|
252
|
+
} catch (error) {
|
|
253
|
+
console.error("Failed to save authentication data:", error);
|
|
254
|
+
throw error;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
async function clearAuthData() {
|
|
258
|
+
try {
|
|
259
|
+
await unlink(AUTH_FILE);
|
|
260
|
+
} catch (error) {
|
|
261
|
+
if (error.code !== "ENOENT") {
|
|
262
|
+
throw error;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async function isAuthenticated() {
|
|
267
|
+
const authData = await loadAuthData();
|
|
268
|
+
return authData !== null;
|
|
269
|
+
}
|
|
270
|
+
async function getAuthToken() {
|
|
271
|
+
const authData = await loadAuthData();
|
|
272
|
+
return authData?.token || null;
|
|
273
|
+
}
|
|
274
|
+
async function getAuthData() {
|
|
275
|
+
try {
|
|
276
|
+
const data = await readFile(AUTH_FILE, "utf-8");
|
|
277
|
+
return JSON.parse(data);
|
|
278
|
+
} catch (error) {
|
|
279
|
+
if (error.code === "ENOENT") {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
throw error;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
async function login(host, email, password) {
|
|
286
|
+
try {
|
|
287
|
+
const response = await fetch(`${host}/auth/login`, {
|
|
288
|
+
method: "POST",
|
|
289
|
+
headers: {
|
|
290
|
+
"Content-Type": "application/json"
|
|
291
|
+
},
|
|
292
|
+
body: JSON.stringify({ email, password })
|
|
293
|
+
});
|
|
294
|
+
if (!response.ok) {
|
|
295
|
+
const error = await response.json();
|
|
296
|
+
return { success: false, error: error.error || "Login failed" };
|
|
297
|
+
}
|
|
298
|
+
const data = await response.json();
|
|
299
|
+
const expiresAt = Date.now() + 7 * 24 * 60 * 60 * 1e3;
|
|
300
|
+
await saveAuthData({
|
|
301
|
+
token: data.token,
|
|
302
|
+
user: data.user,
|
|
303
|
+
expiresAt
|
|
304
|
+
});
|
|
305
|
+
return { success: true };
|
|
306
|
+
} catch (error) {
|
|
307
|
+
return { success: false, error: error.message || "Network error" };
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
async function register(host, email, password, name) {
|
|
311
|
+
try {
|
|
312
|
+
const response = await fetch(`${host}/auth/register`, {
|
|
313
|
+
method: "POST",
|
|
314
|
+
headers: {
|
|
315
|
+
"Content-Type": "application/json"
|
|
316
|
+
},
|
|
317
|
+
body: JSON.stringify({ email, password, name })
|
|
318
|
+
});
|
|
319
|
+
if (!response.ok) {
|
|
320
|
+
const error = await response.json();
|
|
321
|
+
return { success: false, error: error.error || "Registration failed" };
|
|
322
|
+
}
|
|
323
|
+
const data = await response.json();
|
|
324
|
+
const expiresAt = Date.now() + 7 * 24 * 60 * 60 * 1e3;
|
|
325
|
+
await saveAuthData({
|
|
326
|
+
token: data.token,
|
|
327
|
+
user: data.user,
|
|
328
|
+
expiresAt
|
|
329
|
+
});
|
|
330
|
+
return { success: true };
|
|
331
|
+
} catch (error) {
|
|
332
|
+
return { success: false, error: error.message || "Network error" };
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
var AUTH_DIR, AUTH_FILE;
|
|
336
|
+
var init_auth = __esm({
|
|
337
|
+
"src/auth.ts"() {
|
|
338
|
+
"use strict";
|
|
339
|
+
AUTH_DIR = join(homedir(), ".jssm");
|
|
340
|
+
AUTH_FILE = join(AUTH_DIR, "auth");
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
// node_modules/@inquirer/core/dist/lib/key.js
|
|
345
|
+
var isUpKey = (key, keybindings = []) => (
|
|
346
|
+
// The up key
|
|
347
|
+
key.name === "up" || // Vim keybinding: hjkl keys map to left/down/up/right
|
|
348
|
+
keybindings.includes("vim") && key.name === "k" || // Emacs keybinding: Ctrl+P means "previous" in Emacs navigation conventions
|
|
349
|
+
keybindings.includes("emacs") && key.ctrl && key.name === "p"
|
|
350
|
+
);
|
|
351
|
+
var isDownKey = (key, keybindings = []) => (
|
|
352
|
+
// The down key
|
|
353
|
+
key.name === "down" || // Vim keybinding: hjkl keys map to left/down/up/right
|
|
354
|
+
keybindings.includes("vim") && key.name === "j" || // Emacs keybinding: Ctrl+N means "next" in Emacs navigation conventions
|
|
355
|
+
keybindings.includes("emacs") && key.ctrl && key.name === "n"
|
|
356
|
+
);
|
|
357
|
+
var isSpaceKey = (key) => key.name === "space";
|
|
358
|
+
var isBackspaceKey = (key) => key.name === "backspace";
|
|
359
|
+
var isTabKey = (key) => key.name === "tab";
|
|
360
|
+
var isNumberKey = (key) => "1234567890".includes(key.name);
|
|
361
|
+
var isEnterKey = (key) => key.name === "enter" || key.name === "return";
|
|
362
|
+
|
|
363
|
+
// node_modules/@inquirer/core/dist/lib/errors.js
|
|
364
|
+
var AbortPromptError = class extends Error {
|
|
365
|
+
name = "AbortPromptError";
|
|
366
|
+
message = "Prompt was aborted";
|
|
367
|
+
constructor(options) {
|
|
368
|
+
super();
|
|
369
|
+
this.cause = options?.cause;
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
var CancelPromptError = class extends Error {
|
|
373
|
+
name = "CancelPromptError";
|
|
374
|
+
message = "Prompt was canceled";
|
|
375
|
+
};
|
|
376
|
+
var ExitPromptError = class extends Error {
|
|
377
|
+
name = "ExitPromptError";
|
|
378
|
+
};
|
|
379
|
+
var HookError = class extends Error {
|
|
380
|
+
name = "HookError";
|
|
381
|
+
};
|
|
382
|
+
var ValidationError = class extends Error {
|
|
383
|
+
name = "ValidationError";
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
// node_modules/@inquirer/core/dist/lib/use-state.js
|
|
387
|
+
import { AsyncResource as AsyncResource2 } from "node:async_hooks";
|
|
388
|
+
|
|
389
|
+
// node_modules/@inquirer/core/dist/lib/hook-engine.js
|
|
390
|
+
import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
|
|
391
|
+
var hookStorage = new AsyncLocalStorage();
|
|
392
|
+
function createStore(rl) {
|
|
393
|
+
const store = {
|
|
394
|
+
rl,
|
|
395
|
+
hooks: [],
|
|
396
|
+
hooksCleanup: [],
|
|
397
|
+
hooksEffect: [],
|
|
398
|
+
index: 0,
|
|
399
|
+
handleChange() {
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
return store;
|
|
403
|
+
}
|
|
404
|
+
function withHooks(rl, cb) {
|
|
405
|
+
const store = createStore(rl);
|
|
406
|
+
return hookStorage.run(store, () => {
|
|
407
|
+
function cycle(render) {
|
|
408
|
+
store.handleChange = () => {
|
|
409
|
+
store.index = 0;
|
|
410
|
+
render();
|
|
411
|
+
};
|
|
412
|
+
store.handleChange();
|
|
413
|
+
}
|
|
414
|
+
return cb(cycle);
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
function getStore() {
|
|
418
|
+
const store = hookStorage.getStore();
|
|
419
|
+
if (!store) {
|
|
420
|
+
throw new HookError("[Inquirer] Hook functions can only be called from within a prompt");
|
|
421
|
+
}
|
|
422
|
+
return store;
|
|
423
|
+
}
|
|
424
|
+
function readline() {
|
|
425
|
+
return getStore().rl;
|
|
426
|
+
}
|
|
427
|
+
function withUpdates(fn) {
|
|
428
|
+
const wrapped = (...args2) => {
|
|
429
|
+
const store = getStore();
|
|
430
|
+
let shouldUpdate = false;
|
|
431
|
+
const oldHandleChange = store.handleChange;
|
|
432
|
+
store.handleChange = () => {
|
|
433
|
+
shouldUpdate = true;
|
|
434
|
+
};
|
|
435
|
+
const returnValue = fn(...args2);
|
|
436
|
+
if (shouldUpdate) {
|
|
437
|
+
oldHandleChange();
|
|
438
|
+
}
|
|
439
|
+
store.handleChange = oldHandleChange;
|
|
440
|
+
return returnValue;
|
|
441
|
+
};
|
|
442
|
+
return AsyncResource.bind(wrapped);
|
|
443
|
+
}
|
|
444
|
+
function withPointer(cb) {
|
|
445
|
+
const store = getStore();
|
|
446
|
+
const { index } = store;
|
|
447
|
+
const pointer = {
|
|
448
|
+
get() {
|
|
449
|
+
return store.hooks[index];
|
|
450
|
+
},
|
|
451
|
+
set(value) {
|
|
452
|
+
store.hooks[index] = value;
|
|
453
|
+
},
|
|
454
|
+
initialized: index in store.hooks
|
|
455
|
+
};
|
|
456
|
+
const returnValue = cb(pointer);
|
|
457
|
+
store.index++;
|
|
458
|
+
return returnValue;
|
|
459
|
+
}
|
|
460
|
+
function handleChange() {
|
|
461
|
+
getStore().handleChange();
|
|
462
|
+
}
|
|
463
|
+
var effectScheduler = {
|
|
464
|
+
queue(cb) {
|
|
465
|
+
const store = getStore();
|
|
466
|
+
const { index } = store;
|
|
467
|
+
store.hooksEffect.push(() => {
|
|
468
|
+
store.hooksCleanup[index]?.();
|
|
469
|
+
const cleanFn = cb(readline());
|
|
470
|
+
if (cleanFn != null && typeof cleanFn !== "function") {
|
|
471
|
+
throw new ValidationError("useEffect return value must be a cleanup function or nothing.");
|
|
472
|
+
}
|
|
473
|
+
store.hooksCleanup[index] = cleanFn;
|
|
474
|
+
});
|
|
475
|
+
},
|
|
476
|
+
run() {
|
|
477
|
+
const store = getStore();
|
|
478
|
+
withUpdates(() => {
|
|
479
|
+
store.hooksEffect.forEach((effect) => {
|
|
480
|
+
effect();
|
|
481
|
+
});
|
|
482
|
+
store.hooksEffect.length = 0;
|
|
483
|
+
})();
|
|
484
|
+
},
|
|
485
|
+
clearAll() {
|
|
486
|
+
const store = getStore();
|
|
487
|
+
store.hooksCleanup.forEach((cleanFn) => {
|
|
488
|
+
cleanFn?.();
|
|
489
|
+
});
|
|
490
|
+
store.hooksEffect.length = 0;
|
|
491
|
+
store.hooksCleanup.length = 0;
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
// node_modules/@inquirer/core/dist/lib/use-state.js
|
|
496
|
+
function useState(defaultValue) {
|
|
497
|
+
return withPointer((pointer) => {
|
|
498
|
+
const setState = AsyncResource2.bind(function setState2(newValue) {
|
|
499
|
+
if (pointer.get() !== newValue) {
|
|
500
|
+
pointer.set(newValue);
|
|
501
|
+
handleChange();
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
if (pointer.initialized) {
|
|
505
|
+
return [pointer.get(), setState];
|
|
506
|
+
}
|
|
507
|
+
const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
|
|
508
|
+
pointer.set(value);
|
|
509
|
+
return [value, setState];
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// node_modules/@inquirer/core/dist/lib/use-effect.js
|
|
514
|
+
function useEffect(cb, depArray) {
|
|
515
|
+
withPointer((pointer) => {
|
|
516
|
+
const oldDeps = pointer.get();
|
|
517
|
+
const hasChanged = !Array.isArray(oldDeps) || depArray.some((dep, i) => !Object.is(dep, oldDeps[i]));
|
|
518
|
+
if (hasChanged) {
|
|
519
|
+
effectScheduler.queue(cb);
|
|
520
|
+
}
|
|
521
|
+
pointer.set(depArray);
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// node_modules/@inquirer/core/dist/lib/theme.js
|
|
526
|
+
import { styleText } from "node:util";
|
|
527
|
+
|
|
528
|
+
// node_modules/@inquirer/figures/dist/index.js
|
|
529
|
+
import process2 from "node:process";
|
|
530
|
+
function isUnicodeSupported() {
|
|
531
|
+
if (process2.platform !== "win32") {
|
|
532
|
+
return process2.env["TERM"] !== "linux";
|
|
533
|
+
}
|
|
534
|
+
return Boolean(process2.env["WT_SESSION"]) || // Windows Terminal
|
|
535
|
+
Boolean(process2.env["TERMINUS_SUBLIME"]) || // Terminus (<0.2.27)
|
|
536
|
+
process2.env["ConEmuTask"] === "{cmd::Cmder}" || // ConEmu and cmder
|
|
537
|
+
process2.env["TERM_PROGRAM"] === "Terminus-Sublime" || process2.env["TERM_PROGRAM"] === "vscode" || process2.env["TERM"] === "xterm-256color" || process2.env["TERM"] === "alacritty" || process2.env["TERMINAL_EMULATOR"] === "JetBrains-JediTerm";
|
|
538
|
+
}
|
|
539
|
+
var common = {
|
|
540
|
+
circleQuestionMark: "(?)",
|
|
541
|
+
questionMarkPrefix: "(?)",
|
|
542
|
+
square: "\u2588",
|
|
543
|
+
squareDarkShade: "\u2593",
|
|
544
|
+
squareMediumShade: "\u2592",
|
|
545
|
+
squareLightShade: "\u2591",
|
|
546
|
+
squareTop: "\u2580",
|
|
547
|
+
squareBottom: "\u2584",
|
|
548
|
+
squareLeft: "\u258C",
|
|
549
|
+
squareRight: "\u2590",
|
|
550
|
+
squareCenter: "\u25A0",
|
|
551
|
+
bullet: "\u25CF",
|
|
552
|
+
dot: "\u2024",
|
|
553
|
+
ellipsis: "\u2026",
|
|
554
|
+
pointerSmall: "\u203A",
|
|
555
|
+
triangleUp: "\u25B2",
|
|
556
|
+
triangleUpSmall: "\u25B4",
|
|
557
|
+
triangleDown: "\u25BC",
|
|
558
|
+
triangleDownSmall: "\u25BE",
|
|
559
|
+
triangleLeftSmall: "\u25C2",
|
|
560
|
+
triangleRightSmall: "\u25B8",
|
|
561
|
+
home: "\u2302",
|
|
562
|
+
heart: "\u2665",
|
|
563
|
+
musicNote: "\u266A",
|
|
564
|
+
musicNoteBeamed: "\u266B",
|
|
565
|
+
arrowUp: "\u2191",
|
|
566
|
+
arrowDown: "\u2193",
|
|
567
|
+
arrowLeft: "\u2190",
|
|
568
|
+
arrowRight: "\u2192",
|
|
569
|
+
arrowLeftRight: "\u2194",
|
|
570
|
+
arrowUpDown: "\u2195",
|
|
571
|
+
almostEqual: "\u2248",
|
|
572
|
+
notEqual: "\u2260",
|
|
573
|
+
lessOrEqual: "\u2264",
|
|
574
|
+
greaterOrEqual: "\u2265",
|
|
575
|
+
identical: "\u2261",
|
|
576
|
+
infinity: "\u221E",
|
|
577
|
+
subscriptZero: "\u2080",
|
|
578
|
+
subscriptOne: "\u2081",
|
|
579
|
+
subscriptTwo: "\u2082",
|
|
580
|
+
subscriptThree: "\u2083",
|
|
581
|
+
subscriptFour: "\u2084",
|
|
582
|
+
subscriptFive: "\u2085",
|
|
583
|
+
subscriptSix: "\u2086",
|
|
584
|
+
subscriptSeven: "\u2087",
|
|
585
|
+
subscriptEight: "\u2088",
|
|
586
|
+
subscriptNine: "\u2089",
|
|
587
|
+
oneHalf: "\xBD",
|
|
588
|
+
oneThird: "\u2153",
|
|
589
|
+
oneQuarter: "\xBC",
|
|
590
|
+
oneFifth: "\u2155",
|
|
591
|
+
oneSixth: "\u2159",
|
|
592
|
+
oneEighth: "\u215B",
|
|
593
|
+
twoThirds: "\u2154",
|
|
594
|
+
twoFifths: "\u2156",
|
|
595
|
+
threeQuarters: "\xBE",
|
|
596
|
+
threeFifths: "\u2157",
|
|
597
|
+
threeEighths: "\u215C",
|
|
598
|
+
fourFifths: "\u2158",
|
|
599
|
+
fiveSixths: "\u215A",
|
|
600
|
+
fiveEighths: "\u215D",
|
|
601
|
+
sevenEighths: "\u215E",
|
|
602
|
+
line: "\u2500",
|
|
603
|
+
lineBold: "\u2501",
|
|
604
|
+
lineDouble: "\u2550",
|
|
605
|
+
lineDashed0: "\u2504",
|
|
606
|
+
lineDashed1: "\u2505",
|
|
607
|
+
lineDashed2: "\u2508",
|
|
608
|
+
lineDashed3: "\u2509",
|
|
609
|
+
lineDashed4: "\u254C",
|
|
610
|
+
lineDashed5: "\u254D",
|
|
611
|
+
lineDashed6: "\u2574",
|
|
612
|
+
lineDashed7: "\u2576",
|
|
613
|
+
lineDashed8: "\u2578",
|
|
614
|
+
lineDashed9: "\u257A",
|
|
615
|
+
lineDashed10: "\u257C",
|
|
616
|
+
lineDashed11: "\u257E",
|
|
617
|
+
lineDashed12: "\u2212",
|
|
618
|
+
lineDashed13: "\u2013",
|
|
619
|
+
lineDashed14: "\u2010",
|
|
620
|
+
lineDashed15: "\u2043",
|
|
621
|
+
lineVertical: "\u2502",
|
|
622
|
+
lineVerticalBold: "\u2503",
|
|
623
|
+
lineVerticalDouble: "\u2551",
|
|
624
|
+
lineVerticalDashed0: "\u2506",
|
|
625
|
+
lineVerticalDashed1: "\u2507",
|
|
626
|
+
lineVerticalDashed2: "\u250A",
|
|
627
|
+
lineVerticalDashed3: "\u250B",
|
|
628
|
+
lineVerticalDashed4: "\u254E",
|
|
629
|
+
lineVerticalDashed5: "\u254F",
|
|
630
|
+
lineVerticalDashed6: "\u2575",
|
|
631
|
+
lineVerticalDashed7: "\u2577",
|
|
632
|
+
lineVerticalDashed8: "\u2579",
|
|
633
|
+
lineVerticalDashed9: "\u257B",
|
|
634
|
+
lineVerticalDashed10: "\u257D",
|
|
635
|
+
lineVerticalDashed11: "\u257F",
|
|
636
|
+
lineDownLeft: "\u2510",
|
|
637
|
+
lineDownLeftArc: "\u256E",
|
|
638
|
+
lineDownBoldLeftBold: "\u2513",
|
|
639
|
+
lineDownBoldLeft: "\u2512",
|
|
640
|
+
lineDownLeftBold: "\u2511",
|
|
641
|
+
lineDownDoubleLeftDouble: "\u2557",
|
|
642
|
+
lineDownDoubleLeft: "\u2556",
|
|
643
|
+
lineDownLeftDouble: "\u2555",
|
|
644
|
+
lineDownRight: "\u250C",
|
|
645
|
+
lineDownRightArc: "\u256D",
|
|
646
|
+
lineDownBoldRightBold: "\u250F",
|
|
647
|
+
lineDownBoldRight: "\u250E",
|
|
648
|
+
lineDownRightBold: "\u250D",
|
|
649
|
+
lineDownDoubleRightDouble: "\u2554",
|
|
650
|
+
lineDownDoubleRight: "\u2553",
|
|
651
|
+
lineDownRightDouble: "\u2552",
|
|
652
|
+
lineUpLeft: "\u2518",
|
|
653
|
+
lineUpLeftArc: "\u256F",
|
|
654
|
+
lineUpBoldLeftBold: "\u251B",
|
|
655
|
+
lineUpBoldLeft: "\u251A",
|
|
656
|
+
lineUpLeftBold: "\u2519",
|
|
657
|
+
lineUpDoubleLeftDouble: "\u255D",
|
|
658
|
+
lineUpDoubleLeft: "\u255C",
|
|
659
|
+
lineUpLeftDouble: "\u255B",
|
|
660
|
+
lineUpRight: "\u2514",
|
|
661
|
+
lineUpRightArc: "\u2570",
|
|
662
|
+
lineUpBoldRightBold: "\u2517",
|
|
663
|
+
lineUpBoldRight: "\u2516",
|
|
664
|
+
lineUpRightBold: "\u2515",
|
|
665
|
+
lineUpDoubleRightDouble: "\u255A",
|
|
666
|
+
lineUpDoubleRight: "\u2559",
|
|
667
|
+
lineUpRightDouble: "\u2558",
|
|
668
|
+
lineUpDownLeft: "\u2524",
|
|
669
|
+
lineUpBoldDownBoldLeftBold: "\u252B",
|
|
670
|
+
lineUpBoldDownBoldLeft: "\u2528",
|
|
671
|
+
lineUpDownLeftBold: "\u2525",
|
|
672
|
+
lineUpBoldDownLeftBold: "\u2529",
|
|
673
|
+
lineUpDownBoldLeftBold: "\u252A",
|
|
674
|
+
lineUpDownBoldLeft: "\u2527",
|
|
675
|
+
lineUpBoldDownLeft: "\u2526",
|
|
676
|
+
lineUpDoubleDownDoubleLeftDouble: "\u2563",
|
|
677
|
+
lineUpDoubleDownDoubleLeft: "\u2562",
|
|
678
|
+
lineUpDownLeftDouble: "\u2561",
|
|
679
|
+
lineUpDownRight: "\u251C",
|
|
680
|
+
lineUpBoldDownBoldRightBold: "\u2523",
|
|
681
|
+
lineUpBoldDownBoldRight: "\u2520",
|
|
682
|
+
lineUpDownRightBold: "\u251D",
|
|
683
|
+
lineUpBoldDownRightBold: "\u2521",
|
|
684
|
+
lineUpDownBoldRightBold: "\u2522",
|
|
685
|
+
lineUpDownBoldRight: "\u251F",
|
|
686
|
+
lineUpBoldDownRight: "\u251E",
|
|
687
|
+
lineUpDoubleDownDoubleRightDouble: "\u2560",
|
|
688
|
+
lineUpDoubleDownDoubleRight: "\u255F",
|
|
689
|
+
lineUpDownRightDouble: "\u255E",
|
|
690
|
+
lineDownLeftRight: "\u252C",
|
|
691
|
+
lineDownBoldLeftBoldRightBold: "\u2533",
|
|
692
|
+
lineDownLeftBoldRightBold: "\u252F",
|
|
693
|
+
lineDownBoldLeftRight: "\u2530",
|
|
694
|
+
lineDownBoldLeftBoldRight: "\u2531",
|
|
695
|
+
lineDownBoldLeftRightBold: "\u2532",
|
|
696
|
+
lineDownLeftRightBold: "\u252E",
|
|
697
|
+
lineDownLeftBoldRight: "\u252D",
|
|
698
|
+
lineDownDoubleLeftDoubleRightDouble: "\u2566",
|
|
699
|
+
lineDownDoubleLeftRight: "\u2565",
|
|
700
|
+
lineDownLeftDoubleRightDouble: "\u2564",
|
|
701
|
+
lineUpLeftRight: "\u2534",
|
|
702
|
+
lineUpBoldLeftBoldRightBold: "\u253B",
|
|
703
|
+
lineUpLeftBoldRightBold: "\u2537",
|
|
704
|
+
lineUpBoldLeftRight: "\u2538",
|
|
705
|
+
lineUpBoldLeftBoldRight: "\u2539",
|
|
706
|
+
lineUpBoldLeftRightBold: "\u253A",
|
|
707
|
+
lineUpLeftRightBold: "\u2536",
|
|
708
|
+
lineUpLeftBoldRight: "\u2535",
|
|
709
|
+
lineUpDoubleLeftDoubleRightDouble: "\u2569",
|
|
710
|
+
lineUpDoubleLeftRight: "\u2568",
|
|
711
|
+
lineUpLeftDoubleRightDouble: "\u2567",
|
|
712
|
+
lineUpDownLeftRight: "\u253C",
|
|
713
|
+
lineUpBoldDownBoldLeftBoldRightBold: "\u254B",
|
|
714
|
+
lineUpDownBoldLeftBoldRightBold: "\u2548",
|
|
715
|
+
lineUpBoldDownLeftBoldRightBold: "\u2547",
|
|
716
|
+
lineUpBoldDownBoldLeftRightBold: "\u254A",
|
|
717
|
+
lineUpBoldDownBoldLeftBoldRight: "\u2549",
|
|
718
|
+
lineUpBoldDownLeftRight: "\u2540",
|
|
719
|
+
lineUpDownBoldLeftRight: "\u2541",
|
|
720
|
+
lineUpDownLeftBoldRight: "\u253D",
|
|
721
|
+
lineUpDownLeftRightBold: "\u253E",
|
|
722
|
+
lineUpBoldDownBoldLeftRight: "\u2542",
|
|
723
|
+
lineUpDownLeftBoldRightBold: "\u253F",
|
|
724
|
+
lineUpBoldDownLeftBoldRight: "\u2543",
|
|
725
|
+
lineUpBoldDownLeftRightBold: "\u2544",
|
|
726
|
+
lineUpDownBoldLeftBoldRight: "\u2545",
|
|
727
|
+
lineUpDownBoldLeftRightBold: "\u2546",
|
|
728
|
+
lineUpDoubleDownDoubleLeftDoubleRightDouble: "\u256C",
|
|
729
|
+
lineUpDoubleDownDoubleLeftRight: "\u256B",
|
|
730
|
+
lineUpDownLeftDoubleRightDouble: "\u256A",
|
|
731
|
+
lineCross: "\u2573",
|
|
732
|
+
lineBackslash: "\u2572",
|
|
733
|
+
lineSlash: "\u2571"
|
|
734
|
+
};
|
|
735
|
+
var specialMainSymbols = {
|
|
736
|
+
tick: "\u2714",
|
|
737
|
+
info: "\u2139",
|
|
738
|
+
warning: "\u26A0",
|
|
739
|
+
cross: "\u2718",
|
|
740
|
+
squareSmall: "\u25FB",
|
|
741
|
+
squareSmallFilled: "\u25FC",
|
|
742
|
+
circle: "\u25EF",
|
|
743
|
+
circleFilled: "\u25C9",
|
|
744
|
+
circleDotted: "\u25CC",
|
|
745
|
+
circleDouble: "\u25CE",
|
|
746
|
+
circleCircle: "\u24DE",
|
|
747
|
+
circleCross: "\u24E7",
|
|
748
|
+
circlePipe: "\u24BE",
|
|
749
|
+
radioOn: "\u25C9",
|
|
750
|
+
radioOff: "\u25EF",
|
|
751
|
+
checkboxOn: "\u2612",
|
|
752
|
+
checkboxOff: "\u2610",
|
|
753
|
+
checkboxCircleOn: "\u24E7",
|
|
754
|
+
checkboxCircleOff: "\u24BE",
|
|
755
|
+
pointer: "\u276F",
|
|
756
|
+
triangleUpOutline: "\u25B3",
|
|
757
|
+
triangleLeft: "\u25C0",
|
|
758
|
+
triangleRight: "\u25B6",
|
|
759
|
+
lozenge: "\u25C6",
|
|
760
|
+
lozengeOutline: "\u25C7",
|
|
761
|
+
hamburger: "\u2630",
|
|
762
|
+
smiley: "\u32E1",
|
|
763
|
+
mustache: "\u0DF4",
|
|
764
|
+
star: "\u2605",
|
|
765
|
+
play: "\u25B6",
|
|
766
|
+
nodejs: "\u2B22",
|
|
767
|
+
oneSeventh: "\u2150",
|
|
768
|
+
oneNinth: "\u2151",
|
|
769
|
+
oneTenth: "\u2152"
|
|
770
|
+
};
|
|
771
|
+
var specialFallbackSymbols = {
|
|
772
|
+
tick: "\u221A",
|
|
773
|
+
info: "i",
|
|
774
|
+
warning: "\u203C",
|
|
775
|
+
cross: "\xD7",
|
|
776
|
+
squareSmall: "\u25A1",
|
|
777
|
+
squareSmallFilled: "\u25A0",
|
|
778
|
+
circle: "( )",
|
|
779
|
+
circleFilled: "(*)",
|
|
780
|
+
circleDotted: "( )",
|
|
781
|
+
circleDouble: "( )",
|
|
782
|
+
circleCircle: "(\u25CB)",
|
|
783
|
+
circleCross: "(\xD7)",
|
|
784
|
+
circlePipe: "(\u2502)",
|
|
785
|
+
radioOn: "(*)",
|
|
786
|
+
radioOff: "( )",
|
|
787
|
+
checkboxOn: "[\xD7]",
|
|
788
|
+
checkboxOff: "[ ]",
|
|
789
|
+
checkboxCircleOn: "(\xD7)",
|
|
790
|
+
checkboxCircleOff: "( )",
|
|
791
|
+
pointer: ">",
|
|
792
|
+
triangleUpOutline: "\u2206",
|
|
793
|
+
triangleLeft: "\u25C4",
|
|
794
|
+
triangleRight: "\u25BA",
|
|
795
|
+
lozenge: "\u2666",
|
|
796
|
+
lozengeOutline: "\u25CA",
|
|
797
|
+
hamburger: "\u2261",
|
|
798
|
+
smiley: "\u263A",
|
|
799
|
+
mustache: "\u250C\u2500\u2510",
|
|
800
|
+
star: "\u2736",
|
|
801
|
+
play: "\u25BA",
|
|
802
|
+
nodejs: "\u2666",
|
|
803
|
+
oneSeventh: "1/7",
|
|
804
|
+
oneNinth: "1/9",
|
|
805
|
+
oneTenth: "1/10"
|
|
806
|
+
};
|
|
807
|
+
var mainSymbols = {
|
|
808
|
+
...common,
|
|
809
|
+
...specialMainSymbols
|
|
810
|
+
};
|
|
811
|
+
var fallbackSymbols = {
|
|
812
|
+
...common,
|
|
813
|
+
...specialFallbackSymbols
|
|
814
|
+
};
|
|
815
|
+
var shouldUseMain = isUnicodeSupported();
|
|
816
|
+
var figures = shouldUseMain ? mainSymbols : fallbackSymbols;
|
|
817
|
+
var dist_default = figures;
|
|
818
|
+
var replacements = Object.entries(specialMainSymbols);
|
|
819
|
+
|
|
820
|
+
// node_modules/@inquirer/core/dist/lib/theme.js
|
|
821
|
+
var defaultTheme = {
|
|
822
|
+
prefix: {
|
|
823
|
+
idle: styleText("blue", "?"),
|
|
824
|
+
done: styleText("green", dist_default.tick)
|
|
825
|
+
},
|
|
826
|
+
spinner: {
|
|
827
|
+
interval: 80,
|
|
828
|
+
frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"].map((frame) => styleText("yellow", frame))
|
|
829
|
+
},
|
|
830
|
+
style: {
|
|
831
|
+
answer: (text) => styleText("cyan", text),
|
|
832
|
+
message: (text) => styleText("bold", text),
|
|
833
|
+
error: (text) => styleText("red", `> ${text}`),
|
|
834
|
+
defaultAnswer: (text) => styleText("dim", `(${text})`),
|
|
835
|
+
help: (text) => styleText("dim", text),
|
|
836
|
+
highlight: (text) => styleText("cyan", text),
|
|
837
|
+
key: (text) => styleText("cyan", styleText("bold", `<${text}>`))
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
|
|
841
|
+
// node_modules/@inquirer/core/dist/lib/make-theme.js
|
|
842
|
+
function isPlainObject(value) {
|
|
843
|
+
if (typeof value !== "object" || value === null)
|
|
844
|
+
return false;
|
|
845
|
+
let proto = value;
|
|
846
|
+
while (Object.getPrototypeOf(proto) !== null) {
|
|
847
|
+
proto = Object.getPrototypeOf(proto);
|
|
848
|
+
}
|
|
849
|
+
return Object.getPrototypeOf(value) === proto;
|
|
850
|
+
}
|
|
851
|
+
function deepMerge(...objects) {
|
|
852
|
+
const output = {};
|
|
853
|
+
for (const obj of objects) {
|
|
854
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
855
|
+
const prevValue = output[key];
|
|
856
|
+
output[key] = isPlainObject(prevValue) && isPlainObject(value) ? deepMerge(prevValue, value) : value;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
return output;
|
|
860
|
+
}
|
|
861
|
+
function makeTheme(...themes) {
|
|
862
|
+
const themesToMerge = [
|
|
863
|
+
defaultTheme,
|
|
864
|
+
...themes.filter((theme) => theme != null)
|
|
865
|
+
];
|
|
866
|
+
return deepMerge(...themesToMerge);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
// node_modules/@inquirer/core/dist/lib/use-prefix.js
|
|
870
|
+
function usePrefix({ status = "idle", theme }) {
|
|
871
|
+
const [showLoader, setShowLoader] = useState(false);
|
|
872
|
+
const [tick, setTick] = useState(0);
|
|
873
|
+
const { prefix, spinner } = makeTheme(theme);
|
|
874
|
+
useEffect(() => {
|
|
875
|
+
if (status === "loading") {
|
|
876
|
+
let tickInterval;
|
|
877
|
+
let inc = -1;
|
|
878
|
+
const delayTimeout = setTimeout(() => {
|
|
879
|
+
setShowLoader(true);
|
|
880
|
+
tickInterval = setInterval(() => {
|
|
881
|
+
inc = inc + 1;
|
|
882
|
+
setTick(inc % spinner.frames.length);
|
|
883
|
+
}, spinner.interval);
|
|
884
|
+
}, 300);
|
|
885
|
+
return () => {
|
|
886
|
+
clearTimeout(delayTimeout);
|
|
887
|
+
clearInterval(tickInterval);
|
|
888
|
+
};
|
|
889
|
+
} else {
|
|
890
|
+
setShowLoader(false);
|
|
891
|
+
}
|
|
892
|
+
}, [status]);
|
|
893
|
+
if (showLoader) {
|
|
894
|
+
return spinner.frames[tick];
|
|
895
|
+
}
|
|
896
|
+
const iconName = status === "loading" ? "idle" : status;
|
|
897
|
+
return typeof prefix === "string" ? prefix : prefix[iconName] ?? prefix["idle"];
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
// node_modules/@inquirer/core/dist/lib/use-memo.js
|
|
901
|
+
function useMemo(fn, dependencies) {
|
|
902
|
+
return withPointer((pointer) => {
|
|
903
|
+
const prev = pointer.get();
|
|
904
|
+
if (!prev || prev.dependencies.length !== dependencies.length || prev.dependencies.some((dep, i) => dep !== dependencies[i])) {
|
|
905
|
+
const value = fn();
|
|
906
|
+
pointer.set({ value, dependencies });
|
|
907
|
+
return value;
|
|
908
|
+
}
|
|
909
|
+
return prev.value;
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
// node_modules/@inquirer/core/dist/lib/use-ref.js
|
|
914
|
+
function useRef(val) {
|
|
915
|
+
return useState({ current: val })[0];
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// node_modules/@inquirer/core/dist/lib/use-keypress.js
|
|
919
|
+
function useKeypress(userHandler) {
|
|
920
|
+
const signal = useRef(userHandler);
|
|
921
|
+
signal.current = userHandler;
|
|
922
|
+
useEffect((rl) => {
|
|
923
|
+
let ignore = false;
|
|
924
|
+
const handler = withUpdates((_input, event) => {
|
|
925
|
+
if (ignore)
|
|
926
|
+
return;
|
|
927
|
+
void signal.current(event, rl);
|
|
928
|
+
});
|
|
929
|
+
rl.input.on("keypress", handler);
|
|
930
|
+
return () => {
|
|
931
|
+
ignore = true;
|
|
932
|
+
rl.input.removeListener("keypress", handler);
|
|
933
|
+
};
|
|
934
|
+
}, []);
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
// node_modules/@inquirer/core/dist/lib/utils.js
|
|
938
|
+
var import_cli_width = __toESM(require_cli_width(), 1);
|
|
939
|
+
|
|
940
|
+
// node_modules/ansi-regex/index.js
|
|
941
|
+
function ansiRegex({ onlyFirst = false } = {}) {
|
|
942
|
+
const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
|
|
943
|
+
const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
|
|
944
|
+
const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
|
|
945
|
+
const pattern = `${osc}|${csi}`;
|
|
946
|
+
return new RegExp(pattern, onlyFirst ? void 0 : "g");
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
// node_modules/strip-ansi/index.js
|
|
950
|
+
var regex = ansiRegex();
|
|
951
|
+
function stripAnsi(string) {
|
|
952
|
+
if (typeof string !== "string") {
|
|
953
|
+
throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
|
|
954
|
+
}
|
|
955
|
+
return string.replace(regex, "");
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
// node_modules/get-east-asian-width/lookup.js
|
|
959
|
+
function isAmbiguous(x) {
|
|
960
|
+
return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 || x === 242 || x === 243 || x >= 247 && x <= 250 || x === 252 || x === 254 || x === 257 || x === 273 || x === 275 || x === 283 || x === 294 || x === 295 || x === 299 || x >= 305 && x <= 307 || x === 312 || x >= 319 && x <= 322 || x === 324 || x >= 328 && x <= 331 || x === 333 || x === 338 || x === 339 || x === 358 || x === 359 || x === 363 || x === 462 || x === 464 || x === 466 || x === 468 || x === 470 || x === 472 || x === 474 || x === 476 || x === 593 || x === 609 || x === 708 || x === 711 || x >= 713 && x <= 715 || x === 717 || x === 720 || x >= 728 && x <= 731 || x === 733 || x === 735 || x >= 768 && x <= 879 || x >= 913 && x <= 929 || x >= 931 && x <= 937 || x >= 945 && x <= 961 || x >= 963 && x <= 969 || x === 1025 || x >= 1040 && x <= 1103 || x === 1105 || x === 8208 || x >= 8211 && x <= 8214 || x === 8216 || x === 8217 || x === 8220 || x === 8221 || x >= 8224 && x <= 8226 || x >= 8228 && x <= 8231 || x === 8240 || x === 8242 || x === 8243 || x === 8245 || x === 8251 || x === 8254 || x === 8308 || x === 8319 || x >= 8321 && x <= 8324 || x === 8364 || x === 8451 || x === 8453 || x === 8457 || x === 8467 || x === 8470 || x === 8481 || x === 8482 || x === 8486 || x === 8491 || x === 8531 || x === 8532 || x >= 8539 && x <= 8542 || x >= 8544 && x <= 8555 || x >= 8560 && x <= 8569 || x === 8585 || x >= 8592 && x <= 8601 || x === 8632 || x === 8633 || x === 8658 || x === 8660 || x === 8679 || x === 8704 || x === 8706 || x === 8707 || x === 8711 || x === 8712 || x === 8715 || x === 8719 || x === 8721 || x === 8725 || x === 8730 || x >= 8733 && x <= 8736 || x === 8739 || x === 8741 || x >= 8743 && x <= 8748 || x === 8750 || x >= 8756 && x <= 8759 || x === 8764 || x === 8765 || x === 8776 || x === 8780 || x === 8786 || x === 8800 || x === 8801 || x >= 8804 && x <= 8807 || x === 8810 || x === 8811 || x === 8814 || x === 8815 || x === 8834 || x === 8835 || x === 8838 || x === 8839 || x === 8853 || x === 8857 || x === 8869 || x === 8895 || x === 8978 || x >= 9312 && x <= 9449 || x >= 9451 && x <= 9547 || x >= 9552 && x <= 9587 || x >= 9600 && x <= 9615 || x >= 9618 && x <= 9621 || x === 9632 || x === 9633 || x >= 9635 && x <= 9641 || x === 9650 || x === 9651 || x === 9654 || x === 9655 || x === 9660 || x === 9661 || x === 9664 || x === 9665 || x >= 9670 && x <= 9672 || x === 9675 || x >= 9678 && x <= 9681 || x >= 9698 && x <= 9701 || x === 9711 || x === 9733 || x === 9734 || x === 9737 || x === 9742 || x === 9743 || x === 9756 || x === 9758 || x === 9792 || x === 9794 || x === 9824 || x === 9825 || x >= 9827 && x <= 9829 || x >= 9831 && x <= 9834 || x === 9836 || x === 9837 || x === 9839 || x === 9886 || x === 9887 || x === 9919 || x >= 9926 && x <= 9933 || x >= 9935 && x <= 9939 || x >= 9941 && x <= 9953 || x === 9955 || x === 9960 || x === 9961 || x >= 9963 && x <= 9969 || x === 9972 || x >= 9974 && x <= 9977 || x === 9979 || x === 9980 || x === 9982 || x === 9983 || x === 10045 || x >= 10102 && x <= 10111 || x >= 11094 && x <= 11097 || x >= 12872 && x <= 12879 || x >= 57344 && x <= 63743 || x >= 65024 && x <= 65039 || x === 65533 || x >= 127232 && x <= 127242 || x >= 127248 && x <= 127277 || x >= 127280 && x <= 127337 || x >= 127344 && x <= 127373 || x === 127375 || x === 127376 || x >= 127387 && x <= 127404 || x >= 917760 && x <= 917999 || x >= 983040 && x <= 1048573 || x >= 1048576 && x <= 1114109;
|
|
961
|
+
}
|
|
962
|
+
function isFullWidth(x) {
|
|
963
|
+
return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
|
|
964
|
+
}
|
|
965
|
+
function isWide(x) {
|
|
966
|
+
return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9776 && x <= 9783 || x >= 9800 && x <= 9811 || x === 9855 || x >= 9866 && x <= 9871 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12773 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x >= 94192 && x <= 94198 || x >= 94208 && x <= 101589 || x >= 101631 && x <= 101662 || x >= 101760 && x <= 101874 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x >= 119552 && x <= 119638 || x >= 119648 && x <= 119670 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128728 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129674 || x >= 129678 && x <= 129734 || x === 129736 || x >= 129741 && x <= 129756 || x >= 129759 && x <= 129770 || x >= 129775 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
// node_modules/get-east-asian-width/index.js
|
|
970
|
+
function validate(codePoint) {
|
|
971
|
+
if (!Number.isSafeInteger(codePoint)) {
|
|
972
|
+
throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
|
|
976
|
+
validate(codePoint);
|
|
977
|
+
if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) {
|
|
978
|
+
return 2;
|
|
979
|
+
}
|
|
980
|
+
return 1;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
// node_modules/string-width/index.js
|
|
984
|
+
var import_emoji_regex = __toESM(require_emoji_regex(), 1);
|
|
985
|
+
var segmenter = new Intl.Segmenter();
|
|
986
|
+
var defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u;
|
|
987
|
+
function stringWidth(string, options = {}) {
|
|
988
|
+
if (typeof string !== "string" || string.length === 0) {
|
|
989
|
+
return 0;
|
|
990
|
+
}
|
|
991
|
+
const {
|
|
992
|
+
ambiguousIsNarrow = true,
|
|
993
|
+
countAnsiEscapeCodes = false
|
|
994
|
+
} = options;
|
|
995
|
+
if (!countAnsiEscapeCodes) {
|
|
996
|
+
string = stripAnsi(string);
|
|
997
|
+
}
|
|
998
|
+
if (string.length === 0) {
|
|
999
|
+
return 0;
|
|
1000
|
+
}
|
|
1001
|
+
let width = 0;
|
|
1002
|
+
const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
|
|
1003
|
+
for (const { segment: character } of segmenter.segment(string)) {
|
|
1004
|
+
const codePoint = character.codePointAt(0);
|
|
1005
|
+
if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) {
|
|
1006
|
+
continue;
|
|
1007
|
+
}
|
|
1008
|
+
if (codePoint >= 8203 && codePoint <= 8207 || codePoint === 65279) {
|
|
1009
|
+
continue;
|
|
1010
|
+
}
|
|
1011
|
+
if (codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071) {
|
|
1012
|
+
continue;
|
|
1013
|
+
}
|
|
1014
|
+
if (codePoint >= 55296 && codePoint <= 57343) {
|
|
1015
|
+
continue;
|
|
1016
|
+
}
|
|
1017
|
+
if (codePoint >= 65024 && codePoint <= 65039) {
|
|
1018
|
+
continue;
|
|
1019
|
+
}
|
|
1020
|
+
if (defaultIgnorableCodePointRegex.test(character)) {
|
|
1021
|
+
continue;
|
|
1022
|
+
}
|
|
1023
|
+
if ((0, import_emoji_regex.default)().test(character)) {
|
|
1024
|
+
width += 2;
|
|
1025
|
+
continue;
|
|
1026
|
+
}
|
|
1027
|
+
width += eastAsianWidth(codePoint, eastAsianWidthOptions);
|
|
1028
|
+
}
|
|
1029
|
+
return width;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
// node_modules/ansi-styles/index.js
|
|
1033
|
+
var ANSI_BACKGROUND_OFFSET = 10;
|
|
1034
|
+
var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
|
|
1035
|
+
var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
|
|
1036
|
+
var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
|
|
1037
|
+
var styles = {
|
|
1038
|
+
modifier: {
|
|
1039
|
+
reset: [0, 0],
|
|
1040
|
+
// 21 isn't widely supported and 22 does the same thing
|
|
1041
|
+
bold: [1, 22],
|
|
1042
|
+
dim: [2, 22],
|
|
1043
|
+
italic: [3, 23],
|
|
1044
|
+
underline: [4, 24],
|
|
1045
|
+
overline: [53, 55],
|
|
1046
|
+
inverse: [7, 27],
|
|
1047
|
+
hidden: [8, 28],
|
|
1048
|
+
strikethrough: [9, 29]
|
|
1049
|
+
},
|
|
1050
|
+
color: {
|
|
1051
|
+
black: [30, 39],
|
|
1052
|
+
red: [31, 39],
|
|
1053
|
+
green: [32, 39],
|
|
1054
|
+
yellow: [33, 39],
|
|
1055
|
+
blue: [34, 39],
|
|
1056
|
+
magenta: [35, 39],
|
|
1057
|
+
cyan: [36, 39],
|
|
1058
|
+
white: [37, 39],
|
|
1059
|
+
// Bright color
|
|
1060
|
+
blackBright: [90, 39],
|
|
1061
|
+
gray: [90, 39],
|
|
1062
|
+
// Alias of `blackBright`
|
|
1063
|
+
grey: [90, 39],
|
|
1064
|
+
// Alias of `blackBright`
|
|
1065
|
+
redBright: [91, 39],
|
|
1066
|
+
greenBright: [92, 39],
|
|
1067
|
+
yellowBright: [93, 39],
|
|
1068
|
+
blueBright: [94, 39],
|
|
1069
|
+
magentaBright: [95, 39],
|
|
1070
|
+
cyanBright: [96, 39],
|
|
1071
|
+
whiteBright: [97, 39]
|
|
1072
|
+
},
|
|
1073
|
+
bgColor: {
|
|
1074
|
+
bgBlack: [40, 49],
|
|
1075
|
+
bgRed: [41, 49],
|
|
1076
|
+
bgGreen: [42, 49],
|
|
1077
|
+
bgYellow: [43, 49],
|
|
1078
|
+
bgBlue: [44, 49],
|
|
1079
|
+
bgMagenta: [45, 49],
|
|
1080
|
+
bgCyan: [46, 49],
|
|
1081
|
+
bgWhite: [47, 49],
|
|
1082
|
+
// Bright color
|
|
1083
|
+
bgBlackBright: [100, 49],
|
|
1084
|
+
bgGray: [100, 49],
|
|
1085
|
+
// Alias of `bgBlackBright`
|
|
1086
|
+
bgGrey: [100, 49],
|
|
1087
|
+
// Alias of `bgBlackBright`
|
|
1088
|
+
bgRedBright: [101, 49],
|
|
1089
|
+
bgGreenBright: [102, 49],
|
|
1090
|
+
bgYellowBright: [103, 49],
|
|
1091
|
+
bgBlueBright: [104, 49],
|
|
1092
|
+
bgMagentaBright: [105, 49],
|
|
1093
|
+
bgCyanBright: [106, 49],
|
|
1094
|
+
bgWhiteBright: [107, 49]
|
|
1095
|
+
}
|
|
1096
|
+
};
|
|
1097
|
+
var modifierNames = Object.keys(styles.modifier);
|
|
1098
|
+
var foregroundColorNames = Object.keys(styles.color);
|
|
1099
|
+
var backgroundColorNames = Object.keys(styles.bgColor);
|
|
1100
|
+
var colorNames = [...foregroundColorNames, ...backgroundColorNames];
|
|
1101
|
+
function assembleStyles() {
|
|
1102
|
+
const codes = /* @__PURE__ */ new Map();
|
|
1103
|
+
for (const [groupName, group] of Object.entries(styles)) {
|
|
1104
|
+
for (const [styleName, style] of Object.entries(group)) {
|
|
1105
|
+
styles[styleName] = {
|
|
1106
|
+
open: `\x1B[${style[0]}m`,
|
|
1107
|
+
close: `\x1B[${style[1]}m`
|
|
1108
|
+
};
|
|
1109
|
+
group[styleName] = styles[styleName];
|
|
1110
|
+
codes.set(style[0], style[1]);
|
|
1111
|
+
}
|
|
1112
|
+
Object.defineProperty(styles, groupName, {
|
|
1113
|
+
value: group,
|
|
1114
|
+
enumerable: false
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
Object.defineProperty(styles, "codes", {
|
|
1118
|
+
value: codes,
|
|
1119
|
+
enumerable: false
|
|
1120
|
+
});
|
|
1121
|
+
styles.color.close = "\x1B[39m";
|
|
1122
|
+
styles.bgColor.close = "\x1B[49m";
|
|
1123
|
+
styles.color.ansi = wrapAnsi16();
|
|
1124
|
+
styles.color.ansi256 = wrapAnsi256();
|
|
1125
|
+
styles.color.ansi16m = wrapAnsi16m();
|
|
1126
|
+
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
|
|
1127
|
+
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
|
|
1128
|
+
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
|
|
1129
|
+
Object.defineProperties(styles, {
|
|
1130
|
+
rgbToAnsi256: {
|
|
1131
|
+
value(red, green, blue) {
|
|
1132
|
+
if (red === green && green === blue) {
|
|
1133
|
+
if (red < 8) {
|
|
1134
|
+
return 16;
|
|
1135
|
+
}
|
|
1136
|
+
if (red > 248) {
|
|
1137
|
+
return 231;
|
|
1138
|
+
}
|
|
1139
|
+
return Math.round((red - 8) / 247 * 24) + 232;
|
|
1140
|
+
}
|
|
1141
|
+
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
|
|
1142
|
+
},
|
|
1143
|
+
enumerable: false
|
|
1144
|
+
},
|
|
1145
|
+
hexToRgb: {
|
|
1146
|
+
value(hex) {
|
|
1147
|
+
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
|
|
1148
|
+
if (!matches) {
|
|
1149
|
+
return [0, 0, 0];
|
|
1150
|
+
}
|
|
1151
|
+
let [colorString] = matches;
|
|
1152
|
+
if (colorString.length === 3) {
|
|
1153
|
+
colorString = [...colorString].map((character) => character + character).join("");
|
|
1154
|
+
}
|
|
1155
|
+
const integer = Number.parseInt(colorString, 16);
|
|
1156
|
+
return [
|
|
1157
|
+
/* eslint-disable no-bitwise */
|
|
1158
|
+
integer >> 16 & 255,
|
|
1159
|
+
integer >> 8 & 255,
|
|
1160
|
+
integer & 255
|
|
1161
|
+
/* eslint-enable no-bitwise */
|
|
1162
|
+
];
|
|
1163
|
+
},
|
|
1164
|
+
enumerable: false
|
|
1165
|
+
},
|
|
1166
|
+
hexToAnsi256: {
|
|
1167
|
+
value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
|
|
1168
|
+
enumerable: false
|
|
1169
|
+
},
|
|
1170
|
+
ansi256ToAnsi: {
|
|
1171
|
+
value(code) {
|
|
1172
|
+
if (code < 8) {
|
|
1173
|
+
return 30 + code;
|
|
1174
|
+
}
|
|
1175
|
+
if (code < 16) {
|
|
1176
|
+
return 90 + (code - 8);
|
|
1177
|
+
}
|
|
1178
|
+
let red;
|
|
1179
|
+
let green;
|
|
1180
|
+
let blue;
|
|
1181
|
+
if (code >= 232) {
|
|
1182
|
+
red = ((code - 232) * 10 + 8) / 255;
|
|
1183
|
+
green = red;
|
|
1184
|
+
blue = red;
|
|
1185
|
+
} else {
|
|
1186
|
+
code -= 16;
|
|
1187
|
+
const remainder = code % 36;
|
|
1188
|
+
red = Math.floor(code / 36) / 5;
|
|
1189
|
+
green = Math.floor(remainder / 6) / 5;
|
|
1190
|
+
blue = remainder % 6 / 5;
|
|
1191
|
+
}
|
|
1192
|
+
const value = Math.max(red, green, blue) * 2;
|
|
1193
|
+
if (value === 0) {
|
|
1194
|
+
return 30;
|
|
1195
|
+
}
|
|
1196
|
+
let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
|
|
1197
|
+
if (value === 2) {
|
|
1198
|
+
result += 60;
|
|
1199
|
+
}
|
|
1200
|
+
return result;
|
|
1201
|
+
},
|
|
1202
|
+
enumerable: false
|
|
1203
|
+
},
|
|
1204
|
+
rgbToAnsi: {
|
|
1205
|
+
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
|
|
1206
|
+
enumerable: false
|
|
1207
|
+
},
|
|
1208
|
+
hexToAnsi: {
|
|
1209
|
+
value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
|
|
1210
|
+
enumerable: false
|
|
1211
|
+
}
|
|
1212
|
+
});
|
|
1213
|
+
return styles;
|
|
1214
|
+
}
|
|
1215
|
+
var ansiStyles = assembleStyles();
|
|
1216
|
+
var ansi_styles_default = ansiStyles;
|
|
1217
|
+
|
|
1218
|
+
// node_modules/wrap-ansi/index.js
|
|
1219
|
+
var ESCAPES = /* @__PURE__ */ new Set([
|
|
1220
|
+
"\x1B",
|
|
1221
|
+
"\x9B"
|
|
1222
|
+
]);
|
|
1223
|
+
var END_CODE = 39;
|
|
1224
|
+
var ANSI_ESCAPE_BELL = "\x07";
|
|
1225
|
+
var ANSI_CSI = "[";
|
|
1226
|
+
var ANSI_OSC = "]";
|
|
1227
|
+
var ANSI_SGR_TERMINATOR = "m";
|
|
1228
|
+
var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
1229
|
+
var wrapAnsiCode = (code) => `${ESCAPES.values().next().value}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
|
|
1230
|
+
var wrapAnsiHyperlink = (url) => `${ESCAPES.values().next().value}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
|
|
1231
|
+
var wordLengths = (string) => string.split(" ").map((character) => stringWidth(character));
|
|
1232
|
+
var wrapWord = (rows, word, columns) => {
|
|
1233
|
+
const characters = [...word];
|
|
1234
|
+
let isInsideEscape = false;
|
|
1235
|
+
let isInsideLinkEscape = false;
|
|
1236
|
+
let visible = stringWidth(stripAnsi(rows.at(-1)));
|
|
1237
|
+
for (const [index, character] of characters.entries()) {
|
|
1238
|
+
const characterLength = stringWidth(character);
|
|
1239
|
+
if (visible + characterLength <= columns) {
|
|
1240
|
+
rows[rows.length - 1] += character;
|
|
1241
|
+
} else {
|
|
1242
|
+
rows.push(character);
|
|
1243
|
+
visible = 0;
|
|
1244
|
+
}
|
|
1245
|
+
if (ESCAPES.has(character)) {
|
|
1246
|
+
isInsideEscape = true;
|
|
1247
|
+
const ansiEscapeLinkCandidate = characters.slice(index + 1, index + 1 + ANSI_ESCAPE_LINK.length).join("");
|
|
1248
|
+
isInsideLinkEscape = ansiEscapeLinkCandidate === ANSI_ESCAPE_LINK;
|
|
1249
|
+
}
|
|
1250
|
+
if (isInsideEscape) {
|
|
1251
|
+
if (isInsideLinkEscape) {
|
|
1252
|
+
if (character === ANSI_ESCAPE_BELL) {
|
|
1253
|
+
isInsideEscape = false;
|
|
1254
|
+
isInsideLinkEscape = false;
|
|
1255
|
+
}
|
|
1256
|
+
} else if (character === ANSI_SGR_TERMINATOR) {
|
|
1257
|
+
isInsideEscape = false;
|
|
1258
|
+
}
|
|
1259
|
+
continue;
|
|
1260
|
+
}
|
|
1261
|
+
visible += characterLength;
|
|
1262
|
+
if (visible === columns && index < characters.length - 1) {
|
|
1263
|
+
rows.push("");
|
|
1264
|
+
visible = 0;
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
if (!visible && rows.at(-1).length > 0 && rows.length > 1) {
|
|
1268
|
+
rows[rows.length - 2] += rows.pop();
|
|
1269
|
+
}
|
|
1270
|
+
};
|
|
1271
|
+
var stringVisibleTrimSpacesRight = (string) => {
|
|
1272
|
+
const words = string.split(" ");
|
|
1273
|
+
let last = words.length;
|
|
1274
|
+
while (last > 0) {
|
|
1275
|
+
if (stringWidth(words[last - 1]) > 0) {
|
|
1276
|
+
break;
|
|
1277
|
+
}
|
|
1278
|
+
last--;
|
|
1279
|
+
}
|
|
1280
|
+
if (last === words.length) {
|
|
1281
|
+
return string;
|
|
1282
|
+
}
|
|
1283
|
+
return words.slice(0, last).join(" ") + words.slice(last).join("");
|
|
1284
|
+
};
|
|
1285
|
+
var exec = (string, columns, options = {}) => {
|
|
1286
|
+
if (options.trim !== false && string.trim() === "") {
|
|
1287
|
+
return "";
|
|
1288
|
+
}
|
|
1289
|
+
let returnValue = "";
|
|
1290
|
+
let escapeCode;
|
|
1291
|
+
let escapeUrl;
|
|
1292
|
+
const lengths = wordLengths(string);
|
|
1293
|
+
let rows = [""];
|
|
1294
|
+
for (const [index, word] of string.split(" ").entries()) {
|
|
1295
|
+
if (options.trim !== false) {
|
|
1296
|
+
rows[rows.length - 1] = rows.at(-1).trimStart();
|
|
1297
|
+
}
|
|
1298
|
+
let rowLength = stringWidth(rows.at(-1));
|
|
1299
|
+
if (index !== 0) {
|
|
1300
|
+
if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
|
|
1301
|
+
rows.push("");
|
|
1302
|
+
rowLength = 0;
|
|
1303
|
+
}
|
|
1304
|
+
if (rowLength > 0 || options.trim === false) {
|
|
1305
|
+
rows[rows.length - 1] += " ";
|
|
1306
|
+
rowLength++;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
if (options.hard && lengths[index] > columns) {
|
|
1310
|
+
const remainingColumns = columns - rowLength;
|
|
1311
|
+
const breaksStartingThisLine = 1 + Math.floor((lengths[index] - remainingColumns - 1) / columns);
|
|
1312
|
+
const breaksStartingNextLine = Math.floor((lengths[index] - 1) / columns);
|
|
1313
|
+
if (breaksStartingNextLine < breaksStartingThisLine) {
|
|
1314
|
+
rows.push("");
|
|
1315
|
+
}
|
|
1316
|
+
wrapWord(rows, word, columns);
|
|
1317
|
+
continue;
|
|
1318
|
+
}
|
|
1319
|
+
if (rowLength + lengths[index] > columns && rowLength > 0 && lengths[index] > 0) {
|
|
1320
|
+
if (options.wordWrap === false && rowLength < columns) {
|
|
1321
|
+
wrapWord(rows, word, columns);
|
|
1322
|
+
continue;
|
|
1323
|
+
}
|
|
1324
|
+
rows.push("");
|
|
1325
|
+
}
|
|
1326
|
+
if (rowLength + lengths[index] > columns && options.wordWrap === false) {
|
|
1327
|
+
wrapWord(rows, word, columns);
|
|
1328
|
+
continue;
|
|
1329
|
+
}
|
|
1330
|
+
rows[rows.length - 1] += word;
|
|
1331
|
+
}
|
|
1332
|
+
if (options.trim !== false) {
|
|
1333
|
+
rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
|
|
1334
|
+
}
|
|
1335
|
+
const preString = rows.join("\n");
|
|
1336
|
+
const pre = [...preString];
|
|
1337
|
+
let preStringIndex = 0;
|
|
1338
|
+
for (const [index, character] of pre.entries()) {
|
|
1339
|
+
returnValue += character;
|
|
1340
|
+
if (ESCAPES.has(character)) {
|
|
1341
|
+
const { groups } = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`).exec(preString.slice(preStringIndex)) || { groups: {} };
|
|
1342
|
+
if (groups.code !== void 0) {
|
|
1343
|
+
const code2 = Number.parseFloat(groups.code);
|
|
1344
|
+
escapeCode = code2 === END_CODE ? void 0 : code2;
|
|
1345
|
+
} else if (groups.uri !== void 0) {
|
|
1346
|
+
escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri;
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
const code = ansi_styles_default.codes.get(Number(escapeCode));
|
|
1350
|
+
if (pre[index + 1] === "\n") {
|
|
1351
|
+
if (escapeUrl) {
|
|
1352
|
+
returnValue += wrapAnsiHyperlink("");
|
|
1353
|
+
}
|
|
1354
|
+
if (escapeCode && code) {
|
|
1355
|
+
returnValue += wrapAnsiCode(code);
|
|
1356
|
+
}
|
|
1357
|
+
} else if (character === "\n") {
|
|
1358
|
+
if (escapeCode && code) {
|
|
1359
|
+
returnValue += wrapAnsiCode(escapeCode);
|
|
1360
|
+
}
|
|
1361
|
+
if (escapeUrl) {
|
|
1362
|
+
returnValue += wrapAnsiHyperlink(escapeUrl);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
preStringIndex += character.length;
|
|
1366
|
+
}
|
|
1367
|
+
return returnValue;
|
|
1368
|
+
};
|
|
1369
|
+
function wrapAnsi(string, columns, options) {
|
|
1370
|
+
return String(string).normalize().replaceAll("\r\n", "\n").split("\n").map((line) => exec(line, columns, options)).join("\n");
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
// node_modules/@inquirer/core/dist/lib/utils.js
|
|
1374
|
+
function breakLines(content, width) {
|
|
1375
|
+
return content.split("\n").flatMap((line) => wrapAnsi(line, width, { trim: false, hard: true }).split("\n").map((str) => str.trimEnd())).join("\n");
|
|
1376
|
+
}
|
|
1377
|
+
function readlineWidth() {
|
|
1378
|
+
return (0, import_cli_width.default)({ defaultWidth: 80, output: readline().output });
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
// node_modules/@inquirer/core/dist/lib/pagination/use-pagination.js
|
|
1382
|
+
function usePointerPosition({ active, renderedItems, pageSize, loop }) {
|
|
1383
|
+
const state = useRef({
|
|
1384
|
+
lastPointer: active,
|
|
1385
|
+
lastActive: void 0
|
|
1386
|
+
});
|
|
1387
|
+
const { lastPointer, lastActive } = state.current;
|
|
1388
|
+
const middle = Math.floor(pageSize / 2);
|
|
1389
|
+
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
|
1390
|
+
const defaultPointerPosition = renderedItems.slice(0, active).reduce((acc, item) => acc + item.length, 0);
|
|
1391
|
+
let pointer = defaultPointerPosition;
|
|
1392
|
+
if (renderedLength > pageSize) {
|
|
1393
|
+
if (loop) {
|
|
1394
|
+
pointer = lastPointer;
|
|
1395
|
+
if (
|
|
1396
|
+
// First render, skip this logic.
|
|
1397
|
+
lastActive != null && // Only move the pointer down when the user moves down.
|
|
1398
|
+
lastActive < active && // Check user didn't move up across page boundary.
|
|
1399
|
+
active - lastActive < pageSize
|
|
1400
|
+
) {
|
|
1401
|
+
pointer = Math.min(
|
|
1402
|
+
// Furthest allowed position for the pointer is the middle of the list
|
|
1403
|
+
middle,
|
|
1404
|
+
Math.abs(active - lastActive) === 1 ? Math.min(
|
|
1405
|
+
// Move the pointer at most the height of the last active item.
|
|
1406
|
+
lastPointer + (renderedItems[lastActive]?.length ?? 0),
|
|
1407
|
+
// If the user moved by one item, move the pointer to the natural position of the active item as
|
|
1408
|
+
// long as it doesn't move the cursor up.
|
|
1409
|
+
Math.max(defaultPointerPosition, lastPointer)
|
|
1410
|
+
) : (
|
|
1411
|
+
// Otherwise, move the pointer down by the difference between the active and last active item.
|
|
1412
|
+
lastPointer + active - lastActive
|
|
1413
|
+
)
|
|
1414
|
+
);
|
|
1415
|
+
}
|
|
1416
|
+
} else {
|
|
1417
|
+
const spaceUnderActive = renderedItems.slice(active).reduce((acc, item) => acc + item.length, 0);
|
|
1418
|
+
pointer = spaceUnderActive < pageSize - middle ? (
|
|
1419
|
+
// If the active item is near the end of the list, progressively move the cursor towards the end.
|
|
1420
|
+
pageSize - spaceUnderActive
|
|
1421
|
+
) : (
|
|
1422
|
+
// Otherwise, progressively move the pointer to the middle of the list.
|
|
1423
|
+
Math.min(defaultPointerPosition, middle)
|
|
1424
|
+
);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
state.current.lastPointer = pointer;
|
|
1428
|
+
state.current.lastActive = active;
|
|
1429
|
+
return pointer;
|
|
1430
|
+
}
|
|
1431
|
+
function usePagination({ items, active, renderItem, pageSize, loop = true }) {
|
|
1432
|
+
const width = readlineWidth();
|
|
1433
|
+
const bound = (num) => (num % items.length + items.length) % items.length;
|
|
1434
|
+
const renderedItems = items.map((item, index) => {
|
|
1435
|
+
if (item == null)
|
|
1436
|
+
return [];
|
|
1437
|
+
return breakLines(renderItem({ item, index, isActive: index === active }), width).split("\n");
|
|
1438
|
+
});
|
|
1439
|
+
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
|
1440
|
+
const renderItemAtIndex = (index) => renderedItems[index] ?? [];
|
|
1441
|
+
const pointer = usePointerPosition({ active, renderedItems, pageSize, loop });
|
|
1442
|
+
const activeItem = renderItemAtIndex(active).slice(0, pageSize);
|
|
1443
|
+
const activeItemPosition = pointer + activeItem.length <= pageSize ? pointer : pageSize - activeItem.length;
|
|
1444
|
+
const pageBuffer = Array.from({ length: pageSize });
|
|
1445
|
+
pageBuffer.splice(activeItemPosition, activeItem.length, ...activeItem);
|
|
1446
|
+
const itemVisited = /* @__PURE__ */ new Set([active]);
|
|
1447
|
+
let bufferPointer = activeItemPosition + activeItem.length;
|
|
1448
|
+
let itemPointer = bound(active + 1);
|
|
1449
|
+
while (bufferPointer < pageSize && !itemVisited.has(itemPointer) && (loop && renderedLength > pageSize ? itemPointer !== active : itemPointer > active)) {
|
|
1450
|
+
const lines = renderItemAtIndex(itemPointer);
|
|
1451
|
+
const linesToAdd = lines.slice(0, pageSize - bufferPointer);
|
|
1452
|
+
pageBuffer.splice(bufferPointer, linesToAdd.length, ...linesToAdd);
|
|
1453
|
+
itemVisited.add(itemPointer);
|
|
1454
|
+
bufferPointer += linesToAdd.length;
|
|
1455
|
+
itemPointer = bound(itemPointer + 1);
|
|
1456
|
+
}
|
|
1457
|
+
bufferPointer = activeItemPosition - 1;
|
|
1458
|
+
itemPointer = bound(active - 1);
|
|
1459
|
+
while (bufferPointer >= 0 && !itemVisited.has(itemPointer) && (loop && renderedLength > pageSize ? itemPointer !== active : itemPointer < active)) {
|
|
1460
|
+
const lines = renderItemAtIndex(itemPointer);
|
|
1461
|
+
const linesToAdd = lines.slice(Math.max(0, lines.length - bufferPointer - 1));
|
|
1462
|
+
pageBuffer.splice(bufferPointer - linesToAdd.length + 1, linesToAdd.length, ...linesToAdd);
|
|
1463
|
+
itemVisited.add(itemPointer);
|
|
1464
|
+
bufferPointer -= linesToAdd.length;
|
|
1465
|
+
itemPointer = bound(itemPointer - 1);
|
|
1466
|
+
}
|
|
1467
|
+
return pageBuffer.filter((line) => typeof line === "string").join("\n");
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
// node_modules/@inquirer/core/dist/lib/create-prompt.js
|
|
1471
|
+
var import_mute_stream = __toESM(require_lib(), 1);
|
|
1472
|
+
import * as readline2 from "node:readline";
|
|
1473
|
+
import { AsyncResource as AsyncResource3 } from "node:async_hooks";
|
|
1474
|
+
|
|
1475
|
+
// node_modules/signal-exit/dist/mjs/signals.js
|
|
1476
|
+
var signals = [];
|
|
1477
|
+
signals.push("SIGHUP", "SIGINT", "SIGTERM");
|
|
1478
|
+
if (process.platform !== "win32") {
|
|
1479
|
+
signals.push(
|
|
1480
|
+
"SIGALRM",
|
|
1481
|
+
"SIGABRT",
|
|
1482
|
+
"SIGVTALRM",
|
|
1483
|
+
"SIGXCPU",
|
|
1484
|
+
"SIGXFSZ",
|
|
1485
|
+
"SIGUSR2",
|
|
1486
|
+
"SIGTRAP",
|
|
1487
|
+
"SIGSYS",
|
|
1488
|
+
"SIGQUIT",
|
|
1489
|
+
"SIGIOT"
|
|
1490
|
+
// should detect profiler and enable/disable accordingly.
|
|
1491
|
+
// see #21
|
|
1492
|
+
// 'SIGPROF'
|
|
1493
|
+
);
|
|
1494
|
+
}
|
|
1495
|
+
if (process.platform === "linux") {
|
|
1496
|
+
signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
// node_modules/signal-exit/dist/mjs/index.js
|
|
1500
|
+
var processOk = (process4) => !!process4 && typeof process4 === "object" && typeof process4.removeListener === "function" && typeof process4.emit === "function" && typeof process4.reallyExit === "function" && typeof process4.listeners === "function" && typeof process4.kill === "function" && typeof process4.pid === "number" && typeof process4.on === "function";
|
|
1501
|
+
var kExitEmitter = Symbol.for("signal-exit emitter");
|
|
1502
|
+
var global = globalThis;
|
|
1503
|
+
var ObjectDefineProperty = Object.defineProperty.bind(Object);
|
|
1504
|
+
var Emitter = class {
|
|
1505
|
+
emitted = {
|
|
1506
|
+
afterExit: false,
|
|
1507
|
+
exit: false
|
|
1508
|
+
};
|
|
1509
|
+
listeners = {
|
|
1510
|
+
afterExit: [],
|
|
1511
|
+
exit: []
|
|
1512
|
+
};
|
|
1513
|
+
count = 0;
|
|
1514
|
+
id = Math.random();
|
|
1515
|
+
constructor() {
|
|
1516
|
+
if (global[kExitEmitter]) {
|
|
1517
|
+
return global[kExitEmitter];
|
|
1518
|
+
}
|
|
1519
|
+
ObjectDefineProperty(global, kExitEmitter, {
|
|
1520
|
+
value: this,
|
|
1521
|
+
writable: false,
|
|
1522
|
+
enumerable: false,
|
|
1523
|
+
configurable: false
|
|
1524
|
+
});
|
|
1525
|
+
}
|
|
1526
|
+
on(ev, fn) {
|
|
1527
|
+
this.listeners[ev].push(fn);
|
|
1528
|
+
}
|
|
1529
|
+
removeListener(ev, fn) {
|
|
1530
|
+
const list = this.listeners[ev];
|
|
1531
|
+
const i = list.indexOf(fn);
|
|
1532
|
+
if (i === -1) {
|
|
1533
|
+
return;
|
|
1534
|
+
}
|
|
1535
|
+
if (i === 0 && list.length === 1) {
|
|
1536
|
+
list.length = 0;
|
|
1537
|
+
} else {
|
|
1538
|
+
list.splice(i, 1);
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
emit(ev, code, signal) {
|
|
1542
|
+
if (this.emitted[ev]) {
|
|
1543
|
+
return false;
|
|
1544
|
+
}
|
|
1545
|
+
this.emitted[ev] = true;
|
|
1546
|
+
let ret = false;
|
|
1547
|
+
for (const fn of this.listeners[ev]) {
|
|
1548
|
+
ret = fn(code, signal) === true || ret;
|
|
1549
|
+
}
|
|
1550
|
+
if (ev === "exit") {
|
|
1551
|
+
ret = this.emit("afterExit", code, signal) || ret;
|
|
1552
|
+
}
|
|
1553
|
+
return ret;
|
|
1554
|
+
}
|
|
1555
|
+
};
|
|
1556
|
+
var SignalExitBase = class {
|
|
1557
|
+
};
|
|
1558
|
+
var signalExitWrap = (handler) => {
|
|
1559
|
+
return {
|
|
1560
|
+
onExit(cb, opts) {
|
|
1561
|
+
return handler.onExit(cb, opts);
|
|
1562
|
+
},
|
|
1563
|
+
load() {
|
|
1564
|
+
return handler.load();
|
|
1565
|
+
},
|
|
1566
|
+
unload() {
|
|
1567
|
+
return handler.unload();
|
|
1568
|
+
}
|
|
1569
|
+
};
|
|
1570
|
+
};
|
|
1571
|
+
var SignalExitFallback = class extends SignalExitBase {
|
|
1572
|
+
onExit() {
|
|
1573
|
+
return () => {
|
|
1574
|
+
};
|
|
1575
|
+
}
|
|
1576
|
+
load() {
|
|
1577
|
+
}
|
|
1578
|
+
unload() {
|
|
1579
|
+
}
|
|
1580
|
+
};
|
|
1581
|
+
var SignalExit = class extends SignalExitBase {
|
|
1582
|
+
// "SIGHUP" throws an `ENOSYS` error on Windows,
|
|
1583
|
+
// so use a supported signal instead
|
|
1584
|
+
/* c8 ignore start */
|
|
1585
|
+
#hupSig = process3.platform === "win32" ? "SIGINT" : "SIGHUP";
|
|
1586
|
+
/* c8 ignore stop */
|
|
1587
|
+
#emitter = new Emitter();
|
|
1588
|
+
#process;
|
|
1589
|
+
#originalProcessEmit;
|
|
1590
|
+
#originalProcessReallyExit;
|
|
1591
|
+
#sigListeners = {};
|
|
1592
|
+
#loaded = false;
|
|
1593
|
+
constructor(process4) {
|
|
1594
|
+
super();
|
|
1595
|
+
this.#process = process4;
|
|
1596
|
+
this.#sigListeners = {};
|
|
1597
|
+
for (const sig of signals) {
|
|
1598
|
+
this.#sigListeners[sig] = () => {
|
|
1599
|
+
const listeners = this.#process.listeners(sig);
|
|
1600
|
+
let { count } = this.#emitter;
|
|
1601
|
+
const p = process4;
|
|
1602
|
+
if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") {
|
|
1603
|
+
count += p.__signal_exit_emitter__.count;
|
|
1604
|
+
}
|
|
1605
|
+
if (listeners.length === count) {
|
|
1606
|
+
this.unload();
|
|
1607
|
+
const ret = this.#emitter.emit("exit", null, sig);
|
|
1608
|
+
const s = sig === "SIGHUP" ? this.#hupSig : sig;
|
|
1609
|
+
if (!ret)
|
|
1610
|
+
process4.kill(process4.pid, s);
|
|
1611
|
+
}
|
|
1612
|
+
};
|
|
1613
|
+
}
|
|
1614
|
+
this.#originalProcessReallyExit = process4.reallyExit;
|
|
1615
|
+
this.#originalProcessEmit = process4.emit;
|
|
1616
|
+
}
|
|
1617
|
+
onExit(cb, opts) {
|
|
1618
|
+
if (!processOk(this.#process)) {
|
|
1619
|
+
return () => {
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1622
|
+
if (this.#loaded === false) {
|
|
1623
|
+
this.load();
|
|
1624
|
+
}
|
|
1625
|
+
const ev = opts?.alwaysLast ? "afterExit" : "exit";
|
|
1626
|
+
this.#emitter.on(ev, cb);
|
|
1627
|
+
return () => {
|
|
1628
|
+
this.#emitter.removeListener(ev, cb);
|
|
1629
|
+
if (this.#emitter.listeners["exit"].length === 0 && this.#emitter.listeners["afterExit"].length === 0) {
|
|
1630
|
+
this.unload();
|
|
1631
|
+
}
|
|
1632
|
+
};
|
|
1633
|
+
}
|
|
1634
|
+
load() {
|
|
1635
|
+
if (this.#loaded) {
|
|
1636
|
+
return;
|
|
1637
|
+
}
|
|
1638
|
+
this.#loaded = true;
|
|
1639
|
+
this.#emitter.count += 1;
|
|
1640
|
+
for (const sig of signals) {
|
|
1641
|
+
try {
|
|
1642
|
+
const fn = this.#sigListeners[sig];
|
|
1643
|
+
if (fn)
|
|
1644
|
+
this.#process.on(sig, fn);
|
|
1645
|
+
} catch (_) {
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
this.#process.emit = (ev, ...a) => {
|
|
1649
|
+
return this.#processEmit(ev, ...a);
|
|
1650
|
+
};
|
|
1651
|
+
this.#process.reallyExit = (code) => {
|
|
1652
|
+
return this.#processReallyExit(code);
|
|
1653
|
+
};
|
|
1654
|
+
}
|
|
1655
|
+
unload() {
|
|
1656
|
+
if (!this.#loaded) {
|
|
1657
|
+
return;
|
|
1658
|
+
}
|
|
1659
|
+
this.#loaded = false;
|
|
1660
|
+
signals.forEach((sig) => {
|
|
1661
|
+
const listener = this.#sigListeners[sig];
|
|
1662
|
+
if (!listener) {
|
|
1663
|
+
throw new Error("Listener not defined for signal: " + sig);
|
|
1664
|
+
}
|
|
1665
|
+
try {
|
|
1666
|
+
this.#process.removeListener(sig, listener);
|
|
1667
|
+
} catch (_) {
|
|
1668
|
+
}
|
|
1669
|
+
});
|
|
1670
|
+
this.#process.emit = this.#originalProcessEmit;
|
|
1671
|
+
this.#process.reallyExit = this.#originalProcessReallyExit;
|
|
1672
|
+
this.#emitter.count -= 1;
|
|
1673
|
+
}
|
|
1674
|
+
#processReallyExit(code) {
|
|
1675
|
+
if (!processOk(this.#process)) {
|
|
1676
|
+
return 0;
|
|
1677
|
+
}
|
|
1678
|
+
this.#process.exitCode = code || 0;
|
|
1679
|
+
this.#emitter.emit("exit", this.#process.exitCode, null);
|
|
1680
|
+
return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode);
|
|
1681
|
+
}
|
|
1682
|
+
#processEmit(ev, ...args2) {
|
|
1683
|
+
const og = this.#originalProcessEmit;
|
|
1684
|
+
if (ev === "exit" && processOk(this.#process)) {
|
|
1685
|
+
if (typeof args2[0] === "number") {
|
|
1686
|
+
this.#process.exitCode = args2[0];
|
|
1687
|
+
}
|
|
1688
|
+
const ret = og.call(this.#process, ev, ...args2);
|
|
1689
|
+
this.#emitter.emit("exit", this.#process.exitCode, null);
|
|
1690
|
+
return ret;
|
|
1691
|
+
} else {
|
|
1692
|
+
return og.call(this.#process, ev, ...args2);
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
};
|
|
1696
|
+
var process3 = globalThis.process;
|
|
1697
|
+
var {
|
|
1698
|
+
/**
|
|
1699
|
+
* Called when the process is exiting, whether via signal, explicit
|
|
1700
|
+
* exit, or running out of stuff to do.
|
|
1701
|
+
*
|
|
1702
|
+
* If the global process object is not suitable for instrumentation,
|
|
1703
|
+
* then this will be a no-op.
|
|
1704
|
+
*
|
|
1705
|
+
* Returns a function that may be used to unload signal-exit.
|
|
1706
|
+
*/
|
|
1707
|
+
onExit,
|
|
1708
|
+
/**
|
|
1709
|
+
* Load the listeners. Likely you never need to call this, unless
|
|
1710
|
+
* doing a rather deep integration with signal-exit functionality.
|
|
1711
|
+
* Mostly exposed for the benefit of testing.
|
|
1712
|
+
*
|
|
1713
|
+
* @internal
|
|
1714
|
+
*/
|
|
1715
|
+
load,
|
|
1716
|
+
/**
|
|
1717
|
+
* Unload the listeners. Likely you never need to call this, unless
|
|
1718
|
+
* doing a rather deep integration with signal-exit functionality.
|
|
1719
|
+
* Mostly exposed for the benefit of testing.
|
|
1720
|
+
*
|
|
1721
|
+
* @internal
|
|
1722
|
+
*/
|
|
1723
|
+
unload
|
|
1724
|
+
} = signalExitWrap(processOk(process3) ? new SignalExit(process3) : new SignalExitFallback());
|
|
1725
|
+
|
|
1726
|
+
// node_modules/@inquirer/core/dist/lib/screen-manager.js
|
|
1727
|
+
import { stripVTControlCharacters } from "node:util";
|
|
1728
|
+
|
|
1729
|
+
// node_modules/@inquirer/ansi/dist/index.js
|
|
1730
|
+
var ESC = "\x1B[";
|
|
1731
|
+
var cursorLeft = ESC + "G";
|
|
1732
|
+
var cursorHide = ESC + "?25l";
|
|
1733
|
+
var cursorShow = ESC + "?25h";
|
|
1734
|
+
var cursorUp = (rows = 1) => rows > 0 ? `${ESC}${rows}A` : "";
|
|
1735
|
+
var cursorDown = (rows = 1) => rows > 0 ? `${ESC}${rows}B` : "";
|
|
1736
|
+
var cursorTo = (x, y) => {
|
|
1737
|
+
if (typeof y === "number" && !Number.isNaN(y)) {
|
|
1738
|
+
return `${ESC}${y + 1};${x + 1}H`;
|
|
1739
|
+
}
|
|
1740
|
+
return `${ESC}${x + 1}G`;
|
|
1741
|
+
};
|
|
1742
|
+
var eraseLine = ESC + "2K";
|
|
1743
|
+
var eraseLines = (lines) => lines > 0 ? (eraseLine + cursorUp(1)).repeat(lines - 1) + eraseLine + cursorLeft : "";
|
|
1744
|
+
|
|
1745
|
+
// node_modules/@inquirer/core/dist/lib/screen-manager.js
|
|
1746
|
+
var height = (content) => content.split("\n").length;
|
|
1747
|
+
var lastLine = (content) => content.split("\n").pop() ?? "";
|
|
1748
|
+
var ScreenManager = class {
|
|
1749
|
+
// These variables are keeping information to allow correct prompt re-rendering
|
|
1750
|
+
height = 0;
|
|
1751
|
+
extraLinesUnderPrompt = 0;
|
|
1752
|
+
cursorPos;
|
|
1753
|
+
rl;
|
|
1754
|
+
constructor(rl) {
|
|
1755
|
+
this.rl = rl;
|
|
1756
|
+
this.cursorPos = rl.getCursorPos();
|
|
1757
|
+
}
|
|
1758
|
+
write(content) {
|
|
1759
|
+
this.rl.output.unmute();
|
|
1760
|
+
this.rl.output.write(content);
|
|
1761
|
+
this.rl.output.mute();
|
|
1762
|
+
}
|
|
1763
|
+
render(content, bottomContent = "") {
|
|
1764
|
+
const promptLine = lastLine(content);
|
|
1765
|
+
const rawPromptLine = stripVTControlCharacters(promptLine);
|
|
1766
|
+
let prompt = rawPromptLine;
|
|
1767
|
+
if (this.rl.line.length > 0) {
|
|
1768
|
+
prompt = prompt.slice(0, -this.rl.line.length);
|
|
1769
|
+
}
|
|
1770
|
+
this.rl.setPrompt(prompt);
|
|
1771
|
+
this.cursorPos = this.rl.getCursorPos();
|
|
1772
|
+
const width = readlineWidth();
|
|
1773
|
+
content = breakLines(content, width);
|
|
1774
|
+
bottomContent = breakLines(bottomContent, width);
|
|
1775
|
+
if (rawPromptLine.length % width === 0) {
|
|
1776
|
+
content += "\n";
|
|
1777
|
+
}
|
|
1778
|
+
let output = content + (bottomContent ? "\n" + bottomContent : "");
|
|
1779
|
+
const promptLineUpDiff = Math.floor(rawPromptLine.length / width) - this.cursorPos.rows;
|
|
1780
|
+
const bottomContentHeight = promptLineUpDiff + (bottomContent ? height(bottomContent) : 0);
|
|
1781
|
+
if (bottomContentHeight > 0)
|
|
1782
|
+
output += cursorUp(bottomContentHeight);
|
|
1783
|
+
output += cursorTo(this.cursorPos.cols);
|
|
1784
|
+
this.write(cursorDown(this.extraLinesUnderPrompt) + eraseLines(this.height) + output);
|
|
1785
|
+
this.extraLinesUnderPrompt = bottomContentHeight;
|
|
1786
|
+
this.height = height(output);
|
|
1787
|
+
}
|
|
1788
|
+
checkCursorPos() {
|
|
1789
|
+
const cursorPos = this.rl.getCursorPos();
|
|
1790
|
+
if (cursorPos.cols !== this.cursorPos.cols) {
|
|
1791
|
+
this.write(cursorTo(cursorPos.cols));
|
|
1792
|
+
this.cursorPos = cursorPos;
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
done({ clearContent }) {
|
|
1796
|
+
this.rl.setPrompt("");
|
|
1797
|
+
let output = cursorDown(this.extraLinesUnderPrompt);
|
|
1798
|
+
output += clearContent ? eraseLines(this.height) : "\n";
|
|
1799
|
+
output += cursorShow;
|
|
1800
|
+
this.write(output);
|
|
1801
|
+
this.rl.close();
|
|
1802
|
+
}
|
|
1803
|
+
};
|
|
1804
|
+
|
|
1805
|
+
// node_modules/@inquirer/core/dist/lib/promise-polyfill.js
|
|
1806
|
+
var PromisePolyfill = class extends Promise {
|
|
1807
|
+
// Available starting from Node 22
|
|
1808
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
|
|
1809
|
+
static withResolver() {
|
|
1810
|
+
let resolve;
|
|
1811
|
+
let reject;
|
|
1812
|
+
const promise = new Promise((res, rej) => {
|
|
1813
|
+
resolve = res;
|
|
1814
|
+
reject = rej;
|
|
1815
|
+
});
|
|
1816
|
+
return { promise, resolve, reject };
|
|
1817
|
+
}
|
|
1818
|
+
};
|
|
1819
|
+
|
|
1820
|
+
// node_modules/@inquirer/core/dist/lib/create-prompt.js
|
|
1821
|
+
function getCallSites() {
|
|
1822
|
+
const _prepareStackTrace = Error.prepareStackTrace;
|
|
1823
|
+
let result = [];
|
|
1824
|
+
try {
|
|
1825
|
+
Error.prepareStackTrace = (_, callSites) => {
|
|
1826
|
+
const callSitesWithoutCurrent = callSites.slice(1);
|
|
1827
|
+
result = callSitesWithoutCurrent;
|
|
1828
|
+
return callSitesWithoutCurrent;
|
|
1829
|
+
};
|
|
1830
|
+
new Error().stack;
|
|
1831
|
+
} catch {
|
|
1832
|
+
return result;
|
|
1833
|
+
}
|
|
1834
|
+
Error.prepareStackTrace = _prepareStackTrace;
|
|
1835
|
+
return result;
|
|
1836
|
+
}
|
|
1837
|
+
function createPrompt(view) {
|
|
1838
|
+
const callSites = getCallSites();
|
|
1839
|
+
const prompt = (config, context = {}) => {
|
|
1840
|
+
const { input = process.stdin, signal } = context;
|
|
1841
|
+
const cleanups = /* @__PURE__ */ new Set();
|
|
1842
|
+
const output = new import_mute_stream.default();
|
|
1843
|
+
output.pipe(context.output ?? process.stdout);
|
|
1844
|
+
const rl = readline2.createInterface({
|
|
1845
|
+
terminal: true,
|
|
1846
|
+
input,
|
|
1847
|
+
output
|
|
1848
|
+
});
|
|
1849
|
+
const screen = new ScreenManager(rl);
|
|
1850
|
+
const { promise, resolve, reject } = PromisePolyfill.withResolver();
|
|
1851
|
+
const cancel = () => reject(new CancelPromptError());
|
|
1852
|
+
if (signal) {
|
|
1853
|
+
const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
|
|
1854
|
+
if (signal.aborted) {
|
|
1855
|
+
abort();
|
|
1856
|
+
return Object.assign(promise, { cancel });
|
|
1857
|
+
}
|
|
1858
|
+
signal.addEventListener("abort", abort);
|
|
1859
|
+
cleanups.add(() => signal.removeEventListener("abort", abort));
|
|
1860
|
+
}
|
|
1861
|
+
cleanups.add(onExit((code, signal2) => {
|
|
1862
|
+
reject(new ExitPromptError(`User force closed the prompt with ${code} ${signal2}`));
|
|
1863
|
+
}));
|
|
1864
|
+
const sigint = () => reject(new ExitPromptError(`User force closed the prompt with SIGINT`));
|
|
1865
|
+
rl.on("SIGINT", sigint);
|
|
1866
|
+
cleanups.add(() => rl.removeListener("SIGINT", sigint));
|
|
1867
|
+
const checkCursorPos = () => screen.checkCursorPos();
|
|
1868
|
+
rl.input.on("keypress", checkCursorPos);
|
|
1869
|
+
cleanups.add(() => rl.input.removeListener("keypress", checkCursorPos));
|
|
1870
|
+
return withHooks(rl, (cycle) => {
|
|
1871
|
+
const hooksCleanup = AsyncResource3.bind(() => effectScheduler.clearAll());
|
|
1872
|
+
rl.on("close", hooksCleanup);
|
|
1873
|
+
cleanups.add(() => rl.removeListener("close", hooksCleanup));
|
|
1874
|
+
cycle(() => {
|
|
1875
|
+
try {
|
|
1876
|
+
const nextView = view(config, (value) => {
|
|
1877
|
+
setImmediate(() => resolve(value));
|
|
1878
|
+
});
|
|
1879
|
+
if (nextView === void 0) {
|
|
1880
|
+
const callerFilename = callSites[1]?.getFileName();
|
|
1881
|
+
throw new Error(`Prompt functions must return a string.
|
|
1882
|
+
at ${callerFilename}`);
|
|
1883
|
+
}
|
|
1884
|
+
const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
|
|
1885
|
+
screen.render(content, bottomContent);
|
|
1886
|
+
effectScheduler.run();
|
|
1887
|
+
} catch (error) {
|
|
1888
|
+
reject(error);
|
|
1889
|
+
}
|
|
1890
|
+
});
|
|
1891
|
+
return Object.assign(promise.then((answer) => {
|
|
1892
|
+
effectScheduler.clearAll();
|
|
1893
|
+
return answer;
|
|
1894
|
+
}, (error) => {
|
|
1895
|
+
effectScheduler.clearAll();
|
|
1896
|
+
throw error;
|
|
1897
|
+
}).finally(() => {
|
|
1898
|
+
cleanups.forEach((cleanup) => cleanup());
|
|
1899
|
+
screen.done({ clearContent: Boolean(context.clearPromptOnDone) });
|
|
1900
|
+
output.end();
|
|
1901
|
+
}).then(() => promise), { cancel });
|
|
1902
|
+
});
|
|
1903
|
+
};
|
|
1904
|
+
return prompt;
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
// node_modules/@inquirer/core/dist/lib/Separator.js
|
|
1908
|
+
import { styleText as styleText2 } from "node:util";
|
|
1909
|
+
var Separator = class {
|
|
1910
|
+
separator = styleText2("dim", Array.from({ length: 15 }).join(dist_default.line));
|
|
1911
|
+
type = "separator";
|
|
1912
|
+
constructor(separator) {
|
|
1913
|
+
if (separator) {
|
|
1914
|
+
this.separator = separator;
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
static isSeparator(choice) {
|
|
1918
|
+
return Boolean(choice && typeof choice === "object" && "type" in choice && choice.type === "separator");
|
|
1919
|
+
}
|
|
1920
|
+
};
|
|
1921
|
+
|
|
1922
|
+
// node_modules/@inquirer/checkbox/dist/index.js
|
|
1923
|
+
import { styleText as styleText3 } from "node:util";
|
|
1924
|
+
var checkboxTheme = {
|
|
1925
|
+
icon: {
|
|
1926
|
+
checked: styleText3("green", dist_default.circleFilled),
|
|
1927
|
+
unchecked: dist_default.circle,
|
|
1928
|
+
cursor: dist_default.pointer
|
|
1929
|
+
},
|
|
1930
|
+
style: {
|
|
1931
|
+
disabledChoice: (text) => styleText3("dim", `- ${text}`),
|
|
1932
|
+
renderSelectedChoices: (selectedChoices) => selectedChoices.map((choice) => choice.short).join(", "),
|
|
1933
|
+
description: (text) => styleText3("cyan", text),
|
|
1934
|
+
keysHelpTip: (keys) => keys.map(([key, action]) => `${styleText3("bold", key)} ${styleText3("dim", action)}`).join(styleText3("dim", " \u2022 "))
|
|
1935
|
+
},
|
|
1936
|
+
keybindings: []
|
|
1937
|
+
};
|
|
1938
|
+
function isSelectable(item) {
|
|
1939
|
+
return !Separator.isSeparator(item) && !item.disabled;
|
|
1940
|
+
}
|
|
1941
|
+
function isChecked(item) {
|
|
1942
|
+
return isSelectable(item) && item.checked;
|
|
1943
|
+
}
|
|
1944
|
+
function toggle(item) {
|
|
1945
|
+
return isSelectable(item) ? { ...item, checked: !item.checked } : item;
|
|
1946
|
+
}
|
|
1947
|
+
function check(checked) {
|
|
1948
|
+
return function(item) {
|
|
1949
|
+
return isSelectable(item) ? { ...item, checked } : item;
|
|
1950
|
+
};
|
|
1951
|
+
}
|
|
1952
|
+
function normalizeChoices(choices) {
|
|
1953
|
+
return choices.map((choice) => {
|
|
1954
|
+
if (Separator.isSeparator(choice))
|
|
1955
|
+
return choice;
|
|
1956
|
+
if (typeof choice === "string") {
|
|
1957
|
+
return {
|
|
1958
|
+
value: choice,
|
|
1959
|
+
name: choice,
|
|
1960
|
+
short: choice,
|
|
1961
|
+
checkedName: choice,
|
|
1962
|
+
disabled: false,
|
|
1963
|
+
checked: false
|
|
1964
|
+
};
|
|
1965
|
+
}
|
|
1966
|
+
const name = choice.name ?? String(choice.value);
|
|
1967
|
+
const normalizedChoice = {
|
|
1968
|
+
value: choice.value,
|
|
1969
|
+
name,
|
|
1970
|
+
short: choice.short ?? name,
|
|
1971
|
+
checkedName: choice.checkedName ?? name,
|
|
1972
|
+
disabled: choice.disabled ?? false,
|
|
1973
|
+
checked: choice.checked ?? false
|
|
1974
|
+
};
|
|
1975
|
+
if (choice.description) {
|
|
1976
|
+
normalizedChoice.description = choice.description;
|
|
1977
|
+
}
|
|
1978
|
+
return normalizedChoice;
|
|
1979
|
+
});
|
|
1980
|
+
}
|
|
1981
|
+
var dist_default2 = createPrompt((config, done) => {
|
|
1982
|
+
const { pageSize = 7, loop = true, required, validate: validate2 = () => true } = config;
|
|
1983
|
+
const shortcuts = { all: "a", invert: "i", ...config.shortcuts };
|
|
1984
|
+
const theme = makeTheme(checkboxTheme, config.theme);
|
|
1985
|
+
const { keybindings } = theme;
|
|
1986
|
+
const [status, setStatus] = useState("idle");
|
|
1987
|
+
const prefix = usePrefix({ status, theme });
|
|
1988
|
+
const [items, setItems] = useState(normalizeChoices(config.choices));
|
|
1989
|
+
const bounds = useMemo(() => {
|
|
1990
|
+
const first = items.findIndex(isSelectable);
|
|
1991
|
+
const last = items.findLastIndex(isSelectable);
|
|
1992
|
+
if (first === -1) {
|
|
1993
|
+
throw new ValidationError("[checkbox prompt] No selectable choices. All choices are disabled.");
|
|
1994
|
+
}
|
|
1995
|
+
return { first, last };
|
|
1996
|
+
}, [items]);
|
|
1997
|
+
const [active, setActive] = useState(bounds.first);
|
|
1998
|
+
const [errorMsg, setError] = useState();
|
|
1999
|
+
useKeypress(async (key) => {
|
|
2000
|
+
if (isEnterKey(key)) {
|
|
2001
|
+
const selection = items.filter(isChecked);
|
|
2002
|
+
const isValid = await validate2([...selection]);
|
|
2003
|
+
if (required && !items.some(isChecked)) {
|
|
2004
|
+
setError("At least one choice must be selected");
|
|
2005
|
+
} else if (isValid === true) {
|
|
2006
|
+
setStatus("done");
|
|
2007
|
+
done(selection.map((choice) => choice.value));
|
|
2008
|
+
} else {
|
|
2009
|
+
setError(isValid || "You must select a valid value");
|
|
2010
|
+
}
|
|
2011
|
+
} else if (isUpKey(key, keybindings) || isDownKey(key, keybindings)) {
|
|
2012
|
+
if (loop || isUpKey(key, keybindings) && active !== bounds.first || isDownKey(key, keybindings) && active !== bounds.last) {
|
|
2013
|
+
const offset = isUpKey(key, keybindings) ? -1 : 1;
|
|
2014
|
+
let next = active;
|
|
2015
|
+
do {
|
|
2016
|
+
next = (next + offset + items.length) % items.length;
|
|
2017
|
+
} while (!isSelectable(items[next]));
|
|
2018
|
+
setActive(next);
|
|
2019
|
+
}
|
|
2020
|
+
} else if (isSpaceKey(key)) {
|
|
2021
|
+
setError(void 0);
|
|
2022
|
+
setItems(items.map((choice, i) => i === active ? toggle(choice) : choice));
|
|
2023
|
+
} else if (key.name === shortcuts.all) {
|
|
2024
|
+
const selectAll = items.some((choice) => isSelectable(choice) && !choice.checked);
|
|
2025
|
+
setItems(items.map(check(selectAll)));
|
|
2026
|
+
} else if (key.name === shortcuts.invert) {
|
|
2027
|
+
setItems(items.map(toggle));
|
|
2028
|
+
} else if (isNumberKey(key)) {
|
|
2029
|
+
const selectedIndex = Number(key.name) - 1;
|
|
2030
|
+
let selectableIndex = -1;
|
|
2031
|
+
const position = items.findIndex((item) => {
|
|
2032
|
+
if (Separator.isSeparator(item))
|
|
2033
|
+
return false;
|
|
2034
|
+
selectableIndex++;
|
|
2035
|
+
return selectableIndex === selectedIndex;
|
|
2036
|
+
});
|
|
2037
|
+
const selectedItem = items[position];
|
|
2038
|
+
if (selectedItem && isSelectable(selectedItem)) {
|
|
2039
|
+
setActive(position);
|
|
2040
|
+
setItems(items.map((choice, i) => i === position ? toggle(choice) : choice));
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
});
|
|
2044
|
+
const message = theme.style.message(config.message, status);
|
|
2045
|
+
let description;
|
|
2046
|
+
const page = usePagination({
|
|
2047
|
+
items,
|
|
2048
|
+
active,
|
|
2049
|
+
renderItem({ item, isActive }) {
|
|
2050
|
+
if (Separator.isSeparator(item)) {
|
|
2051
|
+
return ` ${item.separator}`;
|
|
2052
|
+
}
|
|
2053
|
+
if (item.disabled) {
|
|
2054
|
+
const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
|
|
2055
|
+
return theme.style.disabledChoice(`${item.name} ${disabledLabel}`);
|
|
2056
|
+
}
|
|
2057
|
+
if (isActive) {
|
|
2058
|
+
description = item.description;
|
|
2059
|
+
}
|
|
2060
|
+
const checkbox = item.checked ? theme.icon.checked : theme.icon.unchecked;
|
|
2061
|
+
const name = item.checked ? item.checkedName : item.name;
|
|
2062
|
+
const color = isActive ? theme.style.highlight : (x) => x;
|
|
2063
|
+
const cursor = isActive ? theme.icon.cursor : " ";
|
|
2064
|
+
return color(`${cursor}${checkbox} ${name}`);
|
|
2065
|
+
},
|
|
2066
|
+
pageSize,
|
|
2067
|
+
loop
|
|
2068
|
+
});
|
|
2069
|
+
if (status === "done") {
|
|
2070
|
+
const selection = items.filter(isChecked);
|
|
2071
|
+
const answer = theme.style.answer(theme.style.renderSelectedChoices(selection, items));
|
|
2072
|
+
return [prefix, message, answer].filter(Boolean).join(" ");
|
|
2073
|
+
}
|
|
2074
|
+
const keys = [
|
|
2075
|
+
["\u2191\u2193", "navigate"],
|
|
2076
|
+
["space", "select"]
|
|
2077
|
+
];
|
|
2078
|
+
if (shortcuts.all)
|
|
2079
|
+
keys.push([shortcuts.all, "all"]);
|
|
2080
|
+
if (shortcuts.invert)
|
|
2081
|
+
keys.push([shortcuts.invert, "invert"]);
|
|
2082
|
+
keys.push(["\u23CE", "submit"]);
|
|
2083
|
+
const helpLine = theme.style.keysHelpTip(keys);
|
|
2084
|
+
const lines = [
|
|
2085
|
+
[prefix, message].filter(Boolean).join(" "),
|
|
2086
|
+
page,
|
|
2087
|
+
" ",
|
|
2088
|
+
description ? theme.style.description(description) : "",
|
|
2089
|
+
errorMsg ? theme.style.error(errorMsg) : "",
|
|
2090
|
+
helpLine
|
|
2091
|
+
].filter(Boolean).join("\n").trimEnd();
|
|
2092
|
+
return `${lines}${cursorHide}`;
|
|
2093
|
+
});
|
|
2094
|
+
|
|
2095
|
+
// node_modules/@inquirer/confirm/dist/index.js
|
|
2096
|
+
function getBooleanValue(value, defaultValue) {
|
|
2097
|
+
let answer = defaultValue !== false;
|
|
2098
|
+
if (/^(y|yes)/i.test(value))
|
|
2099
|
+
answer = true;
|
|
2100
|
+
else if (/^(n|no)/i.test(value))
|
|
2101
|
+
answer = false;
|
|
2102
|
+
return answer;
|
|
2103
|
+
}
|
|
2104
|
+
function boolToString(value) {
|
|
2105
|
+
return value ? "Yes" : "No";
|
|
2106
|
+
}
|
|
2107
|
+
var dist_default3 = createPrompt((config, done) => {
|
|
2108
|
+
const { transformer = boolToString } = config;
|
|
2109
|
+
const [status, setStatus] = useState("idle");
|
|
2110
|
+
const [value, setValue] = useState("");
|
|
2111
|
+
const theme = makeTheme(config.theme);
|
|
2112
|
+
const prefix = usePrefix({ status, theme });
|
|
2113
|
+
useKeypress((key, rl) => {
|
|
2114
|
+
if (status !== "idle")
|
|
2115
|
+
return;
|
|
2116
|
+
if (isEnterKey(key)) {
|
|
2117
|
+
const answer = getBooleanValue(value, config.default);
|
|
2118
|
+
setValue(transformer(answer));
|
|
2119
|
+
setStatus("done");
|
|
2120
|
+
done(answer);
|
|
2121
|
+
} else if (isTabKey(key)) {
|
|
2122
|
+
const answer = boolToString(!getBooleanValue(value, config.default));
|
|
2123
|
+
rl.clearLine(0);
|
|
2124
|
+
rl.write(answer);
|
|
2125
|
+
setValue(answer);
|
|
2126
|
+
} else {
|
|
2127
|
+
setValue(rl.line);
|
|
2128
|
+
}
|
|
2129
|
+
});
|
|
2130
|
+
let formattedValue = value;
|
|
2131
|
+
let defaultValue = "";
|
|
2132
|
+
if (status === "done") {
|
|
2133
|
+
formattedValue = theme.style.answer(value);
|
|
2134
|
+
} else {
|
|
2135
|
+
defaultValue = ` ${theme.style.defaultAnswer(config.default === false ? "y/N" : "Y/n")}`;
|
|
2136
|
+
}
|
|
2137
|
+
const message = theme.style.message(config.message, status);
|
|
2138
|
+
return `${prefix} ${message}${defaultValue} ${formattedValue}`;
|
|
2139
|
+
});
|
|
2140
|
+
|
|
2141
|
+
// node_modules/@inquirer/input/dist/index.js
|
|
2142
|
+
var inputTheme = {
|
|
2143
|
+
validationFailureMode: "keep"
|
|
2144
|
+
};
|
|
2145
|
+
var dist_default4 = createPrompt((config, done) => {
|
|
2146
|
+
const { prefill = "tab" } = config;
|
|
2147
|
+
const theme = makeTheme(inputTheme, config.theme);
|
|
2148
|
+
const [status, setStatus] = useState("idle");
|
|
2149
|
+
const [defaultValue = "", setDefaultValue] = useState(config.default);
|
|
2150
|
+
const [errorMsg, setError] = useState();
|
|
2151
|
+
const [value, setValue] = useState("");
|
|
2152
|
+
const prefix = usePrefix({ status, theme });
|
|
2153
|
+
async function validate2(value2) {
|
|
2154
|
+
const { required, pattern, patternError = "Invalid input" } = config;
|
|
2155
|
+
if (required && !value2) {
|
|
2156
|
+
return "You must provide a value";
|
|
2157
|
+
}
|
|
2158
|
+
if (pattern && !pattern.test(value2)) {
|
|
2159
|
+
return patternError;
|
|
2160
|
+
}
|
|
2161
|
+
if (typeof config.validate === "function") {
|
|
2162
|
+
return await config.validate(value2) || "You must provide a valid value";
|
|
2163
|
+
}
|
|
2164
|
+
return true;
|
|
2165
|
+
}
|
|
2166
|
+
useKeypress(async (key, rl) => {
|
|
2167
|
+
if (status !== "idle") {
|
|
2168
|
+
return;
|
|
2169
|
+
}
|
|
2170
|
+
if (isEnterKey(key)) {
|
|
2171
|
+
const answer = value || defaultValue;
|
|
2172
|
+
setStatus("loading");
|
|
2173
|
+
const isValid = await validate2(answer);
|
|
2174
|
+
if (isValid === true) {
|
|
2175
|
+
setValue(answer);
|
|
2176
|
+
setStatus("done");
|
|
2177
|
+
done(answer);
|
|
2178
|
+
} else {
|
|
2179
|
+
if (theme.validationFailureMode === "clear") {
|
|
2180
|
+
setValue("");
|
|
2181
|
+
} else {
|
|
2182
|
+
rl.write(value);
|
|
2183
|
+
}
|
|
2184
|
+
setError(isValid);
|
|
2185
|
+
setStatus("idle");
|
|
2186
|
+
}
|
|
2187
|
+
} else if (isBackspaceKey(key) && !value) {
|
|
2188
|
+
setDefaultValue(void 0);
|
|
2189
|
+
} else if (isTabKey(key) && !value) {
|
|
2190
|
+
setDefaultValue(void 0);
|
|
2191
|
+
rl.clearLine(0);
|
|
2192
|
+
rl.write(defaultValue);
|
|
2193
|
+
setValue(defaultValue);
|
|
2194
|
+
} else {
|
|
2195
|
+
setValue(rl.line);
|
|
2196
|
+
setError(void 0);
|
|
2197
|
+
}
|
|
2198
|
+
});
|
|
2199
|
+
useEffect((rl) => {
|
|
2200
|
+
if (prefill === "editable" && defaultValue) {
|
|
2201
|
+
rl.write(defaultValue);
|
|
2202
|
+
setValue(defaultValue);
|
|
2203
|
+
}
|
|
2204
|
+
}, []);
|
|
2205
|
+
const message = theme.style.message(config.message, status);
|
|
2206
|
+
let formattedValue = value;
|
|
2207
|
+
if (typeof config.transformer === "function") {
|
|
2208
|
+
formattedValue = config.transformer(value, { isFinal: status === "done" });
|
|
2209
|
+
} else if (status === "done") {
|
|
2210
|
+
formattedValue = theme.style.answer(value);
|
|
2211
|
+
}
|
|
2212
|
+
let defaultStr;
|
|
2213
|
+
if (defaultValue && status !== "done" && !value) {
|
|
2214
|
+
defaultStr = theme.style.defaultAnswer(defaultValue);
|
|
2215
|
+
}
|
|
2216
|
+
let error = "";
|
|
2217
|
+
if (errorMsg) {
|
|
2218
|
+
error = theme.style.error(errorMsg);
|
|
2219
|
+
}
|
|
2220
|
+
return [
|
|
2221
|
+
[prefix, message, defaultStr, formattedValue].filter((v) => v !== void 0).join(" "),
|
|
2222
|
+
error
|
|
2223
|
+
];
|
|
2224
|
+
});
|
|
2225
|
+
|
|
2226
|
+
// node_modules/@inquirer/password/dist/index.js
|
|
2227
|
+
var dist_default5 = createPrompt((config, done) => {
|
|
2228
|
+
const { validate: validate2 = () => true } = config;
|
|
2229
|
+
const theme = makeTheme(config.theme);
|
|
2230
|
+
const [status, setStatus] = useState("idle");
|
|
2231
|
+
const [errorMsg, setError] = useState();
|
|
2232
|
+
const [value, setValue] = useState("");
|
|
2233
|
+
const prefix = usePrefix({ status, theme });
|
|
2234
|
+
useKeypress(async (key, rl) => {
|
|
2235
|
+
if (status !== "idle") {
|
|
2236
|
+
return;
|
|
2237
|
+
}
|
|
2238
|
+
if (isEnterKey(key)) {
|
|
2239
|
+
const answer = value;
|
|
2240
|
+
setStatus("loading");
|
|
2241
|
+
const isValid = await validate2(answer);
|
|
2242
|
+
if (isValid === true) {
|
|
2243
|
+
setValue(answer);
|
|
2244
|
+
setStatus("done");
|
|
2245
|
+
done(answer);
|
|
2246
|
+
} else {
|
|
2247
|
+
rl.write(value);
|
|
2248
|
+
setError(isValid || "You must provide a valid value");
|
|
2249
|
+
setStatus("idle");
|
|
2250
|
+
}
|
|
2251
|
+
} else {
|
|
2252
|
+
setValue(rl.line);
|
|
2253
|
+
setError(void 0);
|
|
2254
|
+
}
|
|
2255
|
+
});
|
|
2256
|
+
const message = theme.style.message(config.message, status);
|
|
2257
|
+
let formattedValue = "";
|
|
2258
|
+
let helpTip;
|
|
2259
|
+
if (config.mask) {
|
|
2260
|
+
const maskChar = typeof config.mask === "string" ? config.mask : "*";
|
|
2261
|
+
formattedValue = maskChar.repeat(value.length);
|
|
2262
|
+
} else if (status !== "done") {
|
|
2263
|
+
helpTip = `${theme.style.help("[input is masked]")}${cursorHide}`;
|
|
2264
|
+
}
|
|
2265
|
+
if (status === "done") {
|
|
2266
|
+
formattedValue = theme.style.answer(formattedValue);
|
|
2267
|
+
}
|
|
2268
|
+
let error = "";
|
|
2269
|
+
if (errorMsg) {
|
|
2270
|
+
error = theme.style.error(errorMsg);
|
|
2271
|
+
}
|
|
2272
|
+
return [[prefix, message, config.mask ? formattedValue : helpTip].join(" "), error];
|
|
2273
|
+
});
|
|
2274
|
+
|
|
2275
|
+
// node_modules/@inquirer/select/dist/index.js
|
|
2276
|
+
import { styleText as styleText4 } from "node:util";
|
|
2277
|
+
var selectTheme = {
|
|
2278
|
+
icon: { cursor: dist_default.pointer },
|
|
2279
|
+
style: {
|
|
2280
|
+
disabled: (text) => styleText4("dim", `- ${text}`),
|
|
2281
|
+
description: (text) => styleText4("cyan", text),
|
|
2282
|
+
keysHelpTip: (keys) => keys.map(([key, action]) => `${styleText4("bold", key)} ${styleText4("dim", action)}`).join(styleText4("dim", " \u2022 "))
|
|
2283
|
+
},
|
|
2284
|
+
indexMode: "hidden",
|
|
2285
|
+
keybindings: []
|
|
2286
|
+
};
|
|
2287
|
+
function isSelectable2(item) {
|
|
2288
|
+
return !Separator.isSeparator(item) && !item.disabled;
|
|
2289
|
+
}
|
|
2290
|
+
function normalizeChoices2(choices) {
|
|
2291
|
+
return choices.map((choice) => {
|
|
2292
|
+
if (Separator.isSeparator(choice))
|
|
2293
|
+
return choice;
|
|
2294
|
+
if (typeof choice !== "object" || choice === null || !("value" in choice)) {
|
|
2295
|
+
const name2 = String(choice);
|
|
2296
|
+
return {
|
|
2297
|
+
value: choice,
|
|
2298
|
+
name: name2,
|
|
2299
|
+
short: name2,
|
|
2300
|
+
disabled: false
|
|
2301
|
+
};
|
|
2302
|
+
}
|
|
2303
|
+
const name = choice.name ?? String(choice.value);
|
|
2304
|
+
const normalizedChoice = {
|
|
2305
|
+
value: choice.value,
|
|
2306
|
+
name,
|
|
2307
|
+
short: choice.short ?? name,
|
|
2308
|
+
disabled: choice.disabled ?? false
|
|
2309
|
+
};
|
|
2310
|
+
if (choice.description) {
|
|
2311
|
+
normalizedChoice.description = choice.description;
|
|
2312
|
+
}
|
|
2313
|
+
return normalizedChoice;
|
|
2314
|
+
});
|
|
2315
|
+
}
|
|
2316
|
+
var dist_default6 = createPrompt((config, done) => {
|
|
2317
|
+
const { loop = true, pageSize = 7 } = config;
|
|
2318
|
+
const theme = makeTheme(selectTheme, config.theme);
|
|
2319
|
+
const { keybindings } = theme;
|
|
2320
|
+
const [status, setStatus] = useState("idle");
|
|
2321
|
+
const prefix = usePrefix({ status, theme });
|
|
2322
|
+
const searchTimeoutRef = useRef();
|
|
2323
|
+
const searchEnabled = !keybindings.includes("vim");
|
|
2324
|
+
const items = useMemo(() => normalizeChoices2(config.choices), [config.choices]);
|
|
2325
|
+
const bounds = useMemo(() => {
|
|
2326
|
+
const first = items.findIndex(isSelectable2);
|
|
2327
|
+
const last = items.findLastIndex(isSelectable2);
|
|
2328
|
+
if (first === -1) {
|
|
2329
|
+
throw new ValidationError("[select prompt] No selectable choices. All choices are disabled.");
|
|
2330
|
+
}
|
|
2331
|
+
return { first, last };
|
|
2332
|
+
}, [items]);
|
|
2333
|
+
const defaultItemIndex = useMemo(() => {
|
|
2334
|
+
if (!("default" in config))
|
|
2335
|
+
return -1;
|
|
2336
|
+
return items.findIndex((item) => isSelectable2(item) && item.value === config.default);
|
|
2337
|
+
}, [config.default, items]);
|
|
2338
|
+
const [active, setActive] = useState(defaultItemIndex === -1 ? bounds.first : defaultItemIndex);
|
|
2339
|
+
const selectedChoice = items[active];
|
|
2340
|
+
useKeypress((key, rl) => {
|
|
2341
|
+
clearTimeout(searchTimeoutRef.current);
|
|
2342
|
+
if (isEnterKey(key)) {
|
|
2343
|
+
setStatus("done");
|
|
2344
|
+
done(selectedChoice.value);
|
|
2345
|
+
} else if (isUpKey(key, keybindings) || isDownKey(key, keybindings)) {
|
|
2346
|
+
rl.clearLine(0);
|
|
2347
|
+
if (loop || isUpKey(key, keybindings) && active !== bounds.first || isDownKey(key, keybindings) && active !== bounds.last) {
|
|
2348
|
+
const offset = isUpKey(key, keybindings) ? -1 : 1;
|
|
2349
|
+
let next = active;
|
|
2350
|
+
do {
|
|
2351
|
+
next = (next + offset + items.length) % items.length;
|
|
2352
|
+
} while (!isSelectable2(items[next]));
|
|
2353
|
+
setActive(next);
|
|
2354
|
+
}
|
|
2355
|
+
} else if (isNumberKey(key) && !Number.isNaN(Number(rl.line))) {
|
|
2356
|
+
const selectedIndex = Number(rl.line) - 1;
|
|
2357
|
+
let selectableIndex = -1;
|
|
2358
|
+
const position = items.findIndex((item2) => {
|
|
2359
|
+
if (Separator.isSeparator(item2))
|
|
2360
|
+
return false;
|
|
2361
|
+
selectableIndex++;
|
|
2362
|
+
return selectableIndex === selectedIndex;
|
|
2363
|
+
});
|
|
2364
|
+
const item = items[position];
|
|
2365
|
+
if (item != null && isSelectable2(item)) {
|
|
2366
|
+
setActive(position);
|
|
2367
|
+
}
|
|
2368
|
+
searchTimeoutRef.current = setTimeout(() => {
|
|
2369
|
+
rl.clearLine(0);
|
|
2370
|
+
}, 700);
|
|
2371
|
+
} else if (isBackspaceKey(key)) {
|
|
2372
|
+
rl.clearLine(0);
|
|
2373
|
+
} else if (searchEnabled) {
|
|
2374
|
+
const searchTerm = rl.line.toLowerCase();
|
|
2375
|
+
const matchIndex = items.findIndex((item) => {
|
|
2376
|
+
if (Separator.isSeparator(item) || !isSelectable2(item))
|
|
2377
|
+
return false;
|
|
2378
|
+
return item.name.toLowerCase().startsWith(searchTerm);
|
|
2379
|
+
});
|
|
2380
|
+
if (matchIndex !== -1) {
|
|
2381
|
+
setActive(matchIndex);
|
|
2382
|
+
}
|
|
2383
|
+
searchTimeoutRef.current = setTimeout(() => {
|
|
2384
|
+
rl.clearLine(0);
|
|
2385
|
+
}, 700);
|
|
2386
|
+
}
|
|
2387
|
+
});
|
|
2388
|
+
useEffect(() => () => {
|
|
2389
|
+
clearTimeout(searchTimeoutRef.current);
|
|
2390
|
+
}, []);
|
|
2391
|
+
const message = theme.style.message(config.message, status);
|
|
2392
|
+
const helpLine = theme.style.keysHelpTip([
|
|
2393
|
+
["\u2191\u2193", "navigate"],
|
|
2394
|
+
["\u23CE", "select"]
|
|
2395
|
+
]);
|
|
2396
|
+
let separatorCount = 0;
|
|
2397
|
+
const page = usePagination({
|
|
2398
|
+
items,
|
|
2399
|
+
active,
|
|
2400
|
+
renderItem({ item, isActive, index }) {
|
|
2401
|
+
if (Separator.isSeparator(item)) {
|
|
2402
|
+
separatorCount++;
|
|
2403
|
+
return ` ${item.separator}`;
|
|
2404
|
+
}
|
|
2405
|
+
const indexLabel = theme.indexMode === "number" ? `${index + 1 - separatorCount}. ` : "";
|
|
2406
|
+
if (item.disabled) {
|
|
2407
|
+
const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
|
|
2408
|
+
return theme.style.disabled(`${indexLabel}${item.name} ${disabledLabel}`);
|
|
2409
|
+
}
|
|
2410
|
+
const color = isActive ? theme.style.highlight : (x) => x;
|
|
2411
|
+
const cursor = isActive ? theme.icon.cursor : ` `;
|
|
2412
|
+
return color(`${cursor} ${indexLabel}${item.name}`);
|
|
2413
|
+
},
|
|
2414
|
+
pageSize,
|
|
2415
|
+
loop
|
|
2416
|
+
});
|
|
2417
|
+
if (status === "done") {
|
|
2418
|
+
return [prefix, message, theme.style.answer(selectedChoice.short)].filter(Boolean).join(" ");
|
|
2419
|
+
}
|
|
2420
|
+
const { description } = selectedChoice;
|
|
2421
|
+
const lines = [
|
|
2422
|
+
[prefix, message].filter(Boolean).join(" "),
|
|
2423
|
+
page,
|
|
2424
|
+
" ",
|
|
2425
|
+
description ? theme.style.description(description) : "",
|
|
2426
|
+
helpLine
|
|
2427
|
+
].filter(Boolean).join("\n").trimEnd();
|
|
2428
|
+
return `${lines}${cursorHide}`;
|
|
2429
|
+
});
|
|
2430
|
+
|
|
2431
|
+
// src/commands/init.ts
|
|
2432
|
+
init_auth();
|
|
2433
|
+
|
|
2434
|
+
// src/config.ts
|
|
2435
|
+
import { existsSync, renameSync } from "fs";
|
|
2436
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
2437
|
+
import { join as join2 } from "path";
|
|
2438
|
+
import { homedir as homedir2 } from "os";
|
|
2439
|
+
|
|
2440
|
+
// src/shared/constants.ts
|
|
2441
|
+
var DEFAULT_NAMESPACE = "jssm";
|
|
2442
|
+
var CONFIG_DIR = ".jssm";
|
|
2443
|
+
var CONFIG_FILE = "config";
|
|
2444
|
+
var LOCAL_CONFIG_FILE = ".jssm";
|
|
2445
|
+
var LEGACY_LOCAL_CONFIG_FILE = ".jssm.json";
|
|
2446
|
+
|
|
2447
|
+
// src/config.ts
|
|
2448
|
+
async function getConfigPath(local = false) {
|
|
2449
|
+
if (local) {
|
|
2450
|
+
return join2(process.cwd(), LOCAL_CONFIG_FILE);
|
|
2451
|
+
}
|
|
2452
|
+
const configDir = join2(homedir2(), CONFIG_DIR);
|
|
2453
|
+
return join2(configDir, CONFIG_FILE);
|
|
2454
|
+
}
|
|
2455
|
+
function getLegacyConfigPath() {
|
|
2456
|
+
return join2(process.cwd(), LEGACY_LOCAL_CONFIG_FILE);
|
|
2457
|
+
}
|
|
2458
|
+
async function migrateLegacyConfig() {
|
|
2459
|
+
const legacyPath = getLegacyConfigPath();
|
|
2460
|
+
const newPath = await getConfigPath(true);
|
|
2461
|
+
if (existsSync(legacyPath) && !existsSync(newPath)) {
|
|
2462
|
+
try {
|
|
2463
|
+
renameSync(legacyPath, newPath);
|
|
2464
|
+
console.log(
|
|
2465
|
+
`\u{1F4E6} Migrated config from ${LEGACY_LOCAL_CONFIG_FILE} to ${LOCAL_CONFIG_FILE}`
|
|
2466
|
+
);
|
|
2467
|
+
return true;
|
|
2468
|
+
} catch (error) {
|
|
2469
|
+
console.error(`Failed to migrate legacy config: ${error}`);
|
|
2470
|
+
return false;
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
return false;
|
|
2474
|
+
}
|
|
2475
|
+
async function hasLocalConfig() {
|
|
2476
|
+
await migrateLegacyConfig();
|
|
2477
|
+
const configPath = await getConfigPath(true);
|
|
2478
|
+
return existsSync(configPath);
|
|
2479
|
+
}
|
|
2480
|
+
async function getConfigLocation() {
|
|
2481
|
+
await migrateLegacyConfig();
|
|
2482
|
+
const localPath = await getConfigPath(true);
|
|
2483
|
+
if (existsSync(localPath)) {
|
|
2484
|
+
return localPath;
|
|
2485
|
+
}
|
|
2486
|
+
return null;
|
|
2487
|
+
}
|
|
2488
|
+
function getGlobalConfigDir() {
|
|
2489
|
+
return join2(homedir2(), CONFIG_DIR);
|
|
2490
|
+
}
|
|
2491
|
+
function getGlobalConfigPath() {
|
|
2492
|
+
return join2(getGlobalConfigDir(), CONFIG_FILE);
|
|
2493
|
+
}
|
|
2494
|
+
async function ensureGlobalConfigDir() {
|
|
2495
|
+
const configDir = getGlobalConfigDir();
|
|
2496
|
+
if (!existsSync(configDir)) {
|
|
2497
|
+
await mkdir2(configDir, { recursive: true });
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
async function loadGlobalConfig() {
|
|
2501
|
+
const configPath = getGlobalConfigPath();
|
|
2502
|
+
if (!existsSync(configPath)) {
|
|
2503
|
+
return {};
|
|
2504
|
+
}
|
|
2505
|
+
try {
|
|
2506
|
+
const content = await readFile2(configPath, "utf-8");
|
|
2507
|
+
return JSON.parse(content);
|
|
2508
|
+
} catch (error) {
|
|
2509
|
+
console.error("Failed to load global config:", error);
|
|
2510
|
+
return {};
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
async function saveGlobalConfig(config) {
|
|
2514
|
+
await ensureGlobalConfigDir();
|
|
2515
|
+
const configPath = getGlobalConfigPath();
|
|
2516
|
+
await writeFile2(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
2517
|
+
}
|
|
2518
|
+
async function setGlobalConfigValue(key, value) {
|
|
2519
|
+
const config = await loadGlobalConfig();
|
|
2520
|
+
config[key] = value;
|
|
2521
|
+
await saveGlobalConfig(config);
|
|
2522
|
+
}
|
|
2523
|
+
async function deleteGlobalConfigValue(key) {
|
|
2524
|
+
const config = await loadGlobalConfig();
|
|
2525
|
+
delete config[key];
|
|
2526
|
+
await saveGlobalConfig(config);
|
|
2527
|
+
}
|
|
2528
|
+
async function loadProjectConfig() {
|
|
2529
|
+
await migrateLegacyConfig();
|
|
2530
|
+
const configPath = await getConfigPath(true);
|
|
2531
|
+
if (!existsSync(configPath)) {
|
|
2532
|
+
return null;
|
|
2533
|
+
}
|
|
2534
|
+
try {
|
|
2535
|
+
const content = await readFile2(configPath, "utf-8");
|
|
2536
|
+
return JSON.parse(content);
|
|
2537
|
+
} catch (error) {
|
|
2538
|
+
console.error("Failed to load project config:", error);
|
|
2539
|
+
return null;
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
async function saveProjectConfig(config) {
|
|
2543
|
+
const configPath = await getConfigPath(true);
|
|
2544
|
+
await writeFile2(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
2545
|
+
}
|
|
2546
|
+
async function resolveConfig() {
|
|
2547
|
+
const globalConfig = await loadGlobalConfig();
|
|
2548
|
+
const projectConfig = await loadProjectConfig();
|
|
2549
|
+
if (!projectConfig) {
|
|
2550
|
+
return null;
|
|
2551
|
+
}
|
|
2552
|
+
let authToken;
|
|
2553
|
+
try {
|
|
2554
|
+
const { getAuthToken: getAuthToken4 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
2555
|
+
authToken = await getAuthToken4() || void 0;
|
|
2556
|
+
} catch (error) {
|
|
2557
|
+
}
|
|
2558
|
+
const resolved = {
|
|
2559
|
+
project: projectConfig.project,
|
|
2560
|
+
environment: projectConfig.environment,
|
|
2561
|
+
host: projectConfig.host || globalConfig.host || "",
|
|
2562
|
+
namespace: projectConfig.namespace || globalConfig.namespace || DEFAULT_NAMESPACE,
|
|
2563
|
+
authToken
|
|
2564
|
+
};
|
|
2565
|
+
return resolved;
|
|
2566
|
+
}
|
|
2567
|
+
function validateResolvedConfig(config) {
|
|
2568
|
+
const errors = [];
|
|
2569
|
+
if (!config.project) {
|
|
2570
|
+
errors.push("Project name is required");
|
|
2571
|
+
}
|
|
2572
|
+
if (!config.environment) {
|
|
2573
|
+
errors.push("Environment name is required");
|
|
2574
|
+
}
|
|
2575
|
+
if (!config.host) {
|
|
2576
|
+
errors.push(
|
|
2577
|
+
"Host URL is required (set globally with: jssm config set host <url>)"
|
|
2578
|
+
);
|
|
2579
|
+
}
|
|
2580
|
+
if (!config.authToken) {
|
|
2581
|
+
errors.push("Not logged in. Run: jssm login");
|
|
2582
|
+
}
|
|
2583
|
+
return { valid: errors.length === 0, errors };
|
|
2584
|
+
}
|
|
2585
|
+
|
|
2586
|
+
// src/api.ts
|
|
2587
|
+
async function apiRequest(url, authToken, options = {}) {
|
|
2588
|
+
const headers = {
|
|
2589
|
+
"Content-Type": "application/json",
|
|
2590
|
+
Authorization: `Bearer ${authToken}`,
|
|
2591
|
+
...options.headers
|
|
2592
|
+
};
|
|
2593
|
+
const response = await fetch(url, {
|
|
2594
|
+
...options,
|
|
2595
|
+
headers
|
|
2596
|
+
});
|
|
2597
|
+
if (!response.ok) {
|
|
2598
|
+
const error = await response.json().catch(() => ({
|
|
2599
|
+
error: `HTTP ${response.status} ${response.statusText}`
|
|
2600
|
+
}));
|
|
2601
|
+
const message = typeof error === "object" && error !== null && "error" in error && error.error ? String(error.error) : void 0;
|
|
2602
|
+
throw new Error(
|
|
2603
|
+
message || `HTTP ${response.status} ${response.statusText}`
|
|
2604
|
+
);
|
|
2605
|
+
}
|
|
2606
|
+
return response.json();
|
|
2607
|
+
}
|
|
2608
|
+
async function createProject(host, apiKey, name, repositoryType) {
|
|
2609
|
+
const url = `${host}/projects`;
|
|
2610
|
+
return apiRequest(url, apiKey, {
|
|
2611
|
+
method: "POST",
|
|
2612
|
+
body: JSON.stringify({ name, repositoryType })
|
|
2613
|
+
});
|
|
2614
|
+
}
|
|
2615
|
+
async function getProjects(host, apiKey) {
|
|
2616
|
+
const url = `${host}/projects`;
|
|
2617
|
+
return apiRequest(url, apiKey);
|
|
2618
|
+
}
|
|
2619
|
+
async function createEnvironment(host, apiKey, project, name) {
|
|
2620
|
+
const url = `${host}/projects/${project}/envs`;
|
|
2621
|
+
return apiRequest(url, apiKey, {
|
|
2622
|
+
method: "POST",
|
|
2623
|
+
body: JSON.stringify({ name })
|
|
2624
|
+
});
|
|
2625
|
+
}
|
|
2626
|
+
async function getEnvironments(host, apiKey, project) {
|
|
2627
|
+
const url = `${host}/projects/${project}/envs`;
|
|
2628
|
+
return apiRequest(url, apiKey);
|
|
2629
|
+
}
|
|
2630
|
+
async function pushVariables(host, apiKey, project, environment, variables) {
|
|
2631
|
+
const url = `${host}/projects/${project}/envs/${environment}/push`;
|
|
2632
|
+
return apiRequest(url, apiKey, {
|
|
2633
|
+
method: "POST",
|
|
2634
|
+
body: JSON.stringify({ variables })
|
|
2635
|
+
});
|
|
2636
|
+
}
|
|
2637
|
+
async function pushEnvFile(host, apiKey, project, environment, content, filename = ".env") {
|
|
2638
|
+
const url = `${host}/projects/${project}/envs/${environment}/push-file`;
|
|
2639
|
+
return apiRequest(url, apiKey, {
|
|
2640
|
+
method: "POST",
|
|
2641
|
+
body: JSON.stringify({ content, filename })
|
|
2642
|
+
});
|
|
2643
|
+
}
|
|
2644
|
+
async function pullEnvFile(host, apiKey, project, environment, filename = ".env") {
|
|
2645
|
+
const url = `${host}/projects/${project}/envs/${environment}/pull-file?filename=${encodeURIComponent(
|
|
2646
|
+
filename
|
|
2647
|
+
)}`;
|
|
2648
|
+
const data = await apiRequest(url, apiKey);
|
|
2649
|
+
return data.content;
|
|
2650
|
+
}
|
|
2651
|
+
async function listEnvFiles(host, apiKey, project, environment) {
|
|
2652
|
+
const url = `${host}/projects/${project}/envs/${environment}/list-files`;
|
|
2653
|
+
const data = await apiRequest(url, apiKey);
|
|
2654
|
+
return data.files;
|
|
2655
|
+
}
|
|
2656
|
+
|
|
2657
|
+
// src/utils/repoDetector.ts
|
|
2658
|
+
import { readdir, readFile as readFile3, stat } from "fs/promises";
|
|
2659
|
+
import { join as join3, relative } from "path";
|
|
2660
|
+
function isEnvFile(filename) {
|
|
2661
|
+
return filename === ".env" || filename.startsWith(".env.");
|
|
2662
|
+
}
|
|
2663
|
+
async function isMonorepo(rootPath) {
|
|
2664
|
+
try {
|
|
2665
|
+
const indicators = [
|
|
2666
|
+
"lerna.json",
|
|
2667
|
+
"nx.json",
|
|
2668
|
+
"pnpm-workspace.yaml",
|
|
2669
|
+
"rush.json"
|
|
2670
|
+
];
|
|
2671
|
+
for (const indicator of indicators) {
|
|
2672
|
+
try {
|
|
2673
|
+
await stat(join3(rootPath, indicator));
|
|
2674
|
+
return true;
|
|
2675
|
+
} catch {
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
const commonDirs = ["packages", "apps", "services"];
|
|
2679
|
+
for (const dir of commonDirs) {
|
|
2680
|
+
try {
|
|
2681
|
+
const dirPath = join3(rootPath, dir);
|
|
2682
|
+
const dirStat = await stat(dirPath);
|
|
2683
|
+
if (dirStat.isDirectory()) {
|
|
2684
|
+
const entries = await readdir(dirPath, { withFileTypes: true });
|
|
2685
|
+
const subdirs = entries.filter((e) => e.isDirectory());
|
|
2686
|
+
if (subdirs.length >= 2) {
|
|
2687
|
+
return true;
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
} catch {
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
try {
|
|
2694
|
+
const packageJsonPath = join3(rootPath, "package.json");
|
|
2695
|
+
const packageJson = JSON.parse(await readFile3(packageJsonPath, "utf-8"));
|
|
2696
|
+
if (packageJson.workspaces) {
|
|
2697
|
+
return true;
|
|
2698
|
+
}
|
|
2699
|
+
} catch {
|
|
2700
|
+
}
|
|
2701
|
+
return false;
|
|
2702
|
+
} catch {
|
|
2703
|
+
return false;
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
async function findEnvFiles(rootPath, maxDepth = 10) {
|
|
2707
|
+
const envFiles = [];
|
|
2708
|
+
async function search(currentPath, depth) {
|
|
2709
|
+
if (maxDepth !== -1 && depth > maxDepth)
|
|
2710
|
+
return;
|
|
2711
|
+
try {
|
|
2712
|
+
const entries = await readdir(currentPath, { withFileTypes: true });
|
|
2713
|
+
for (const entry of entries) {
|
|
2714
|
+
const fullPath = join3(currentPath, entry.name);
|
|
2715
|
+
if (entry.isDirectory() && ![
|
|
2716
|
+
"node_modules",
|
|
2717
|
+
".git",
|
|
2718
|
+
"dist",
|
|
2719
|
+
"build",
|
|
2720
|
+
".next",
|
|
2721
|
+
"coverage",
|
|
2722
|
+
".turbo",
|
|
2723
|
+
".cache",
|
|
2724
|
+
"out",
|
|
2725
|
+
"target"
|
|
2726
|
+
].includes(entry.name)) {
|
|
2727
|
+
await search(fullPath, depth + 1);
|
|
2728
|
+
} else if (entry.isFile() && isEnvFile(entry.name)) {
|
|
2729
|
+
try {
|
|
2730
|
+
const content = await readFile3(fullPath, "utf-8");
|
|
2731
|
+
const lines = content.split("\n");
|
|
2732
|
+
const variableCount = lines.filter((line) => {
|
|
2733
|
+
const trimmed = line.trim();
|
|
2734
|
+
return trimmed && !trimmed.startsWith("#") && trimmed.includes("=");
|
|
2735
|
+
}).length;
|
|
2736
|
+
envFiles.push({
|
|
2737
|
+
path: fullPath,
|
|
2738
|
+
relativePath: relative(rootPath, fullPath),
|
|
2739
|
+
variableCount
|
|
2740
|
+
});
|
|
2741
|
+
} catch {
|
|
2742
|
+
}
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
} catch {
|
|
2746
|
+
}
|
|
2747
|
+
}
|
|
2748
|
+
await search(rootPath, 0);
|
|
2749
|
+
return envFiles;
|
|
2750
|
+
}
|
|
2751
|
+
async function getRepositoryType(rootPath) {
|
|
2752
|
+
const isMonorepoResult = await isMonorepo(rootPath);
|
|
2753
|
+
return isMonorepoResult ? "monorepo" : "normal";
|
|
2754
|
+
}
|
|
2755
|
+
|
|
2756
|
+
// src/utils/envParser.ts
|
|
2757
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
2758
|
+
function parseEnvFile(content) {
|
|
2759
|
+
const variables = [];
|
|
2760
|
+
const lines = content.split("\n");
|
|
2761
|
+
for (const line of lines) {
|
|
2762
|
+
const trimmed = line.trim();
|
|
2763
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
2764
|
+
continue;
|
|
2765
|
+
}
|
|
2766
|
+
const match = trimmed.match(/^([A-Z0-9_]+)=(.*)$/);
|
|
2767
|
+
if (match) {
|
|
2768
|
+
const [, key, value] = match;
|
|
2769
|
+
let cleanValue = value.trim();
|
|
2770
|
+
if (cleanValue.startsWith('"') && cleanValue.endsWith('"') || cleanValue.startsWith("'") && cleanValue.endsWith("'")) {
|
|
2771
|
+
cleanValue = cleanValue.slice(1, -1);
|
|
2772
|
+
}
|
|
2773
|
+
variables.push({ key, value: cleanValue });
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
return variables;
|
|
2777
|
+
}
|
|
2778
|
+
async function readEnvFile(filePath) {
|
|
2779
|
+
try {
|
|
2780
|
+
const content = await readFile4(filePath, "utf-8");
|
|
2781
|
+
return parseEnvFile(content);
|
|
2782
|
+
} catch (error) {
|
|
2783
|
+
if (error.code === "ENOENT") {
|
|
2784
|
+
return [];
|
|
2785
|
+
}
|
|
2786
|
+
throw error;
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2789
|
+
function formatVariablesPreview(variables, maxDisplay = 5) {
|
|
2790
|
+
if (variables.length === 0) {
|
|
2791
|
+
return " (no variables)";
|
|
2792
|
+
}
|
|
2793
|
+
const preview = variables.slice(0, maxDisplay).map((v) => {
|
|
2794
|
+
const valuePreview = v.value.length > 30 ? v.value.substring(0, 30) + "..." : v.value;
|
|
2795
|
+
return ` ${v.key}=${valuePreview}`;
|
|
2796
|
+
}).join("\n");
|
|
2797
|
+
if (variables.length > maxDisplay) {
|
|
2798
|
+
return `${preview}
|
|
2799
|
+
... and ${variables.length - maxDisplay} more`;
|
|
2800
|
+
}
|
|
2801
|
+
return preview;
|
|
2802
|
+
}
|
|
2803
|
+
function validateVariableName(name) {
|
|
2804
|
+
return /^[A-Z0-9_]+$/.test(name);
|
|
2805
|
+
}
|
|
2806
|
+
function getInvalidVariableNames(variables) {
|
|
2807
|
+
return variables.filter((v) => !validateVariableName(v.key)).map((v) => v.key);
|
|
2808
|
+
}
|
|
2809
|
+
|
|
2810
|
+
// src/commands/pull.ts
|
|
2811
|
+
import { writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
2812
|
+
import { join as join4, dirname } from "path";
|
|
2813
|
+
async function pullCommand(args2) {
|
|
2814
|
+
const flags = {};
|
|
2815
|
+
let pullAll = false;
|
|
2816
|
+
for (let i = 0; i < args2.length; i++) {
|
|
2817
|
+
if (args2[i] === "--all" || args2[i] === "-a") {
|
|
2818
|
+
pullAll = true;
|
|
2819
|
+
} else if (args2[i].startsWith("-")) {
|
|
2820
|
+
const key = args2[i].replace(/^-+/, "");
|
|
2821
|
+
const value = args2[i + 1];
|
|
2822
|
+
if (value && !value.startsWith("-")) {
|
|
2823
|
+
flags[key] = value;
|
|
2824
|
+
i++;
|
|
2825
|
+
}
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
const config = await resolveConfig();
|
|
2829
|
+
if (!config) {
|
|
2830
|
+
console.error("\u274C No .jssm configuration found in current directory.");
|
|
2831
|
+
console.error('\u{1F4A1} Run "jssm init -p <project> -e <env>" to initialize.');
|
|
2832
|
+
process.exit(1);
|
|
2833
|
+
}
|
|
2834
|
+
const { valid, errors } = validateResolvedConfig(config);
|
|
2835
|
+
if (!valid) {
|
|
2836
|
+
console.error("\u274C Configuration is incomplete:");
|
|
2837
|
+
errors.forEach((e) => console.error(` \u2022 ${e}`));
|
|
2838
|
+
process.exit(1);
|
|
2839
|
+
}
|
|
2840
|
+
const project = flags.p || flags.project || config.project;
|
|
2841
|
+
const environment = flags.e || flags.env || config.environment;
|
|
2842
|
+
const output = flags.out;
|
|
2843
|
+
if (project !== config.project || environment !== config.environment) {
|
|
2844
|
+
console.log(`\u26A0\uFE0F Warning: Pulling from ${project}/${environment}`);
|
|
2845
|
+
console.log(
|
|
2846
|
+
` This directory is initialized for ${config.project}/${config.environment}`
|
|
2847
|
+
);
|
|
2848
|
+
}
|
|
2849
|
+
try {
|
|
2850
|
+
if (output) {
|
|
2851
|
+
console.log(`\u{1F4E5} Pulling ${output} from ${project}/${environment}...`);
|
|
2852
|
+
const content = await pullEnvFile(
|
|
2853
|
+
config.host,
|
|
2854
|
+
config.authToken,
|
|
2855
|
+
project,
|
|
2856
|
+
environment,
|
|
2857
|
+
output
|
|
2858
|
+
);
|
|
2859
|
+
const outputPath = join4(process.cwd(), output);
|
|
2860
|
+
const dir = dirname(outputPath);
|
|
2861
|
+
if (dir !== process.cwd()) {
|
|
2862
|
+
await mkdir3(dir, { recursive: true });
|
|
2863
|
+
}
|
|
2864
|
+
await writeFile3(outputPath, content, "utf-8");
|
|
2865
|
+
const varCount = countVariables(content);
|
|
2866
|
+
console.log(`\u2705 Wrote ${output} (${varCount} variables)`);
|
|
2867
|
+
return;
|
|
2868
|
+
}
|
|
2869
|
+
console.log(`\u{1F4E5} Checking available files in ${project}/${environment}...`);
|
|
2870
|
+
const availableFiles = await listEnvFiles(
|
|
2871
|
+
config.host,
|
|
2872
|
+
config.authToken,
|
|
2873
|
+
project,
|
|
2874
|
+
environment
|
|
2875
|
+
);
|
|
2876
|
+
if (availableFiles.length === 0) {
|
|
2877
|
+
console.error("\u274C No .env files found on server");
|
|
2878
|
+
console.error("\u{1F4A1} Push files first with: jssm push");
|
|
2879
|
+
process.exit(1);
|
|
2880
|
+
}
|
|
2881
|
+
let selectedFiles = [];
|
|
2882
|
+
if (availableFiles.length === 1) {
|
|
2883
|
+
selectedFiles = [availableFiles[0]];
|
|
2884
|
+
console.log(`\u{1F4C4} Found ${availableFiles[0]} on server`);
|
|
2885
|
+
} else if (pullAll) {
|
|
2886
|
+
selectedFiles = availableFiles;
|
|
2887
|
+
console.log(`\u{1F4C4} Found ${availableFiles.length} files on server`);
|
|
2888
|
+
} else {
|
|
2889
|
+
console.log(`\u{1F4C4} Found ${availableFiles.length} .env files on server:
|
|
2890
|
+
`);
|
|
2891
|
+
availableFiles.forEach((file) => {
|
|
2892
|
+
console.log(` \u2022 ${file}`);
|
|
2893
|
+
});
|
|
2894
|
+
console.log();
|
|
2895
|
+
const pullOption = await dist_default6({
|
|
2896
|
+
message: "What would you like to pull?",
|
|
2897
|
+
choices: [
|
|
2898
|
+
{
|
|
2899
|
+
name: "\u2728 All files",
|
|
2900
|
+
value: "all"
|
|
2901
|
+
},
|
|
2902
|
+
{
|
|
2903
|
+
name: "\u{1F4C1} Select specific files",
|
|
2904
|
+
value: "specific"
|
|
2905
|
+
}
|
|
2906
|
+
]
|
|
2907
|
+
});
|
|
2908
|
+
if (pullOption === "all") {
|
|
2909
|
+
selectedFiles = availableFiles;
|
|
2910
|
+
} else {
|
|
2911
|
+
const fileChoices = availableFiles.map((file) => ({
|
|
2912
|
+
name: file,
|
|
2913
|
+
value: file,
|
|
2914
|
+
checked: false
|
|
2915
|
+
}));
|
|
2916
|
+
selectedFiles = await dist_default2({
|
|
2917
|
+
message: "Select .env file(s) to pull:",
|
|
2918
|
+
choices: fileChoices,
|
|
2919
|
+
validate: (answer) => {
|
|
2920
|
+
if (answer.length === 0) {
|
|
2921
|
+
return "Please select at least one file";
|
|
2922
|
+
}
|
|
2923
|
+
return true;
|
|
2924
|
+
}
|
|
2925
|
+
});
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
if (selectedFiles.length === 1) {
|
|
2929
|
+
console.log(`
|
|
2930
|
+
\u{1F4E5} Pulling ${selectedFiles[0]}...`);
|
|
2931
|
+
} else {
|
|
2932
|
+
console.log(`
|
|
2933
|
+
\u{1F4E5} Pulling ${selectedFiles.length} files...
|
|
2934
|
+
`);
|
|
2935
|
+
}
|
|
2936
|
+
let successCount = 0;
|
|
2937
|
+
let failCount = 0;
|
|
2938
|
+
for (const filename of selectedFiles) {
|
|
2939
|
+
try {
|
|
2940
|
+
const content = await pullEnvFile(
|
|
2941
|
+
config.host,
|
|
2942
|
+
config.authToken,
|
|
2943
|
+
project,
|
|
2944
|
+
environment,
|
|
2945
|
+
filename
|
|
2946
|
+
);
|
|
2947
|
+
const outputPath = join4(process.cwd(), filename);
|
|
2948
|
+
const dir = dirname(outputPath);
|
|
2949
|
+
if (dir !== process.cwd()) {
|
|
2950
|
+
await mkdir3(dir, { recursive: true });
|
|
2951
|
+
}
|
|
2952
|
+
await writeFile3(outputPath, content, "utf-8");
|
|
2953
|
+
const varCount = countVariables(content);
|
|
2954
|
+
if (selectedFiles.length === 1) {
|
|
2955
|
+
console.log(`\u2705 Wrote ${filename} (${varCount} variables)`);
|
|
2956
|
+
} else {
|
|
2957
|
+
console.log(`\u2705 ${filename}: Pulled (${varCount} variables)`);
|
|
2958
|
+
}
|
|
2959
|
+
successCount++;
|
|
2960
|
+
} catch (error) {
|
|
2961
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2962
|
+
console.error(`\u274C ${filename}: Failed to pull - ${message}`);
|
|
2963
|
+
failCount++;
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
if (selectedFiles.length > 1) {
|
|
2967
|
+
console.log(`
|
|
2968
|
+
\u{1F4CA} Summary:`);
|
|
2969
|
+
if (successCount > 0) {
|
|
2970
|
+
console.log(` \u2705 Success: ${successCount} file(s)`);
|
|
2971
|
+
}
|
|
2972
|
+
if (failCount > 0) {
|
|
2973
|
+
console.log(` \u274C Failed: ${failCount} file(s)`);
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2976
|
+
if (failCount > 0 && successCount === 0) {
|
|
2977
|
+
process.exit(1);
|
|
2978
|
+
}
|
|
2979
|
+
} catch (error) {
|
|
2980
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2981
|
+
console.error("\u274C Failed to pull .env files:", message);
|
|
2982
|
+
process.exit(1);
|
|
2983
|
+
}
|
|
2984
|
+
}
|
|
2985
|
+
function countVariables(content) {
|
|
2986
|
+
return content.split("\n").filter((line) => {
|
|
2987
|
+
const trimmed = line.trim();
|
|
2988
|
+
return trimmed && !trimmed.startsWith("#") && trimmed.includes("=");
|
|
2989
|
+
}).length;
|
|
2990
|
+
}
|
|
2991
|
+
|
|
2992
|
+
// src/commands/push.ts
|
|
2993
|
+
import { readFile as readFile5 } from "fs/promises";
|
|
2994
|
+
import { join as join5 } from "path";
|
|
2995
|
+
async function pushCommand(args2) {
|
|
2996
|
+
const flags = {};
|
|
2997
|
+
for (let i = 0; i < args2.length; i++) {
|
|
2998
|
+
if (args2[i].startsWith("-")) {
|
|
2999
|
+
const key = args2[i].replace(/^-+/, "");
|
|
3000
|
+
const value = args2[i + 1];
|
|
3001
|
+
if (value && !value.startsWith("-")) {
|
|
3002
|
+
flags[key] = value;
|
|
3003
|
+
i++;
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
3007
|
+
const config = await resolveConfig();
|
|
3008
|
+
if (!config) {
|
|
3009
|
+
console.error("\u274C No .jssm configuration found in current directory.");
|
|
3010
|
+
console.error('\u{1F4A1} Run "jssm init -p <project> -e <env>" to initialize.');
|
|
3011
|
+
process.exit(1);
|
|
3012
|
+
}
|
|
3013
|
+
const { valid, errors } = validateResolvedConfig(config);
|
|
3014
|
+
if (!valid) {
|
|
3015
|
+
console.error("\u274C Configuration is incomplete:");
|
|
3016
|
+
errors.forEach((e) => console.error(` \u2022 ${e}`));
|
|
3017
|
+
process.exit(1);
|
|
3018
|
+
}
|
|
3019
|
+
const project = flags.p || flags.project || config.project;
|
|
3020
|
+
const environment = flags.e || flags.env || config.environment;
|
|
3021
|
+
let input = flags.in || flags.input;
|
|
3022
|
+
let searchDepth = 10;
|
|
3023
|
+
if (flags.depth) {
|
|
3024
|
+
const parsedDepth = parseInt(flags.depth, 10);
|
|
3025
|
+
if (!isNaN(parsedDepth)) {
|
|
3026
|
+
searchDepth = parsedDepth;
|
|
3027
|
+
}
|
|
3028
|
+
}
|
|
3029
|
+
if (project !== config.project || environment !== config.environment) {
|
|
3030
|
+
console.log(`\u26A0\uFE0F Warning: Pushing to ${project}/${environment}`);
|
|
3031
|
+
console.log(
|
|
3032
|
+
` This directory is initialized for ${config.project}/${config.environment}`
|
|
3033
|
+
);
|
|
3034
|
+
}
|
|
3035
|
+
let selectedFiles = [];
|
|
3036
|
+
if (!input) {
|
|
3037
|
+
const cwd = process.cwd();
|
|
3038
|
+
const envFiles = await findEnvFiles(cwd, searchDepth);
|
|
3039
|
+
if (envFiles.length === 0) {
|
|
3040
|
+
console.error("\u274C No .env files found");
|
|
3041
|
+
console.error("\u{1F4A1} Create a .env file or specify one with --input <file>");
|
|
3042
|
+
process.exit(1);
|
|
3043
|
+
} else if (envFiles.length === 1) {
|
|
3044
|
+
selectedFiles = [envFiles[0].relativePath];
|
|
3045
|
+
console.log(
|
|
3046
|
+
`\u{1F4C4} Found ${envFiles[0].relativePath} (${envFiles[0].variableCount} variables)`
|
|
3047
|
+
);
|
|
3048
|
+
} else {
|
|
3049
|
+
console.log(`\u{1F4C4} Found ${envFiles.length} .env files:
|
|
3050
|
+
`);
|
|
3051
|
+
envFiles.forEach((file) => {
|
|
3052
|
+
console.log(
|
|
3053
|
+
` \u2022 ${file.relativePath} (${file.variableCount} variables)`
|
|
3054
|
+
);
|
|
3055
|
+
});
|
|
3056
|
+
console.log();
|
|
3057
|
+
const pushOption = await dist_default6({
|
|
3058
|
+
message: "What would you like to push?",
|
|
3059
|
+
choices: [
|
|
3060
|
+
{
|
|
3061
|
+
name: "\u2728 All files",
|
|
3062
|
+
value: "all"
|
|
3063
|
+
},
|
|
3064
|
+
{
|
|
3065
|
+
name: "\u{1F4C1} Select specific files",
|
|
3066
|
+
value: "specific"
|
|
3067
|
+
}
|
|
3068
|
+
]
|
|
3069
|
+
});
|
|
3070
|
+
if (pushOption === "all") {
|
|
3071
|
+
selectedFiles = envFiles.map((f) => f.relativePath);
|
|
3072
|
+
} else {
|
|
3073
|
+
const fileChoices = envFiles.map((file) => ({
|
|
3074
|
+
name: `${file.relativePath} (${file.variableCount} variables)`,
|
|
3075
|
+
value: file.relativePath,
|
|
3076
|
+
checked: false
|
|
3077
|
+
}));
|
|
3078
|
+
const selected = await dist_default2({
|
|
3079
|
+
message: "Select .env file(s) to push:",
|
|
3080
|
+
choices: fileChoices,
|
|
3081
|
+
validate: (answer) => {
|
|
3082
|
+
if (answer.length === 0) {
|
|
3083
|
+
return "Please select at least one file";
|
|
3084
|
+
}
|
|
3085
|
+
return true;
|
|
3086
|
+
}
|
|
3087
|
+
});
|
|
3088
|
+
selectedFiles = selected;
|
|
3089
|
+
}
|
|
3090
|
+
}
|
|
3091
|
+
} else {
|
|
3092
|
+
selectedFiles = [input];
|
|
3093
|
+
}
|
|
3094
|
+
if (selectedFiles.length === 1) {
|
|
3095
|
+
console.log(
|
|
3096
|
+
`
|
|
3097
|
+
\u{1F4E4} Pushing ${selectedFiles[0]} to ${project}/${environment}...`
|
|
3098
|
+
);
|
|
3099
|
+
} else {
|
|
3100
|
+
console.log(
|
|
3101
|
+
`
|
|
3102
|
+
\u{1F4E4} Pushing ${selectedFiles.length} files to ${project}/${environment}...
|
|
3103
|
+
`
|
|
3104
|
+
);
|
|
3105
|
+
}
|
|
3106
|
+
let successCount = 0;
|
|
3107
|
+
let failCount = 0;
|
|
3108
|
+
for (const file of selectedFiles) {
|
|
3109
|
+
let fileContent = "";
|
|
3110
|
+
let fileSize = 0;
|
|
3111
|
+
try {
|
|
3112
|
+
const inputPath = join5(process.cwd(), file);
|
|
3113
|
+
fileContent = await readFile5(inputPath, "utf-8");
|
|
3114
|
+
fileSize = Buffer.byteLength(fileContent, "utf-8");
|
|
3115
|
+
const variables = parseVariables(fileContent, file);
|
|
3116
|
+
if (variables.length === 0) {
|
|
3117
|
+
console.log(`\u26A0\uFE0F ${file}: No variables found, skipping`);
|
|
3118
|
+
continue;
|
|
3119
|
+
}
|
|
3120
|
+
const invalidVars = variables.filter((v) => !/^[A-Z0-9_]+$/.test(v.key));
|
|
3121
|
+
if (invalidVars.length > 0) {
|
|
3122
|
+
console.error(`\u274C ${file}: Invalid variable names found:`);
|
|
3123
|
+
invalidVars.forEach(
|
|
3124
|
+
(v) => console.error(
|
|
3125
|
+
` \u2022 ${v.key} (must contain only uppercase letters, numbers, and underscores)`
|
|
3126
|
+
)
|
|
3127
|
+
);
|
|
3128
|
+
failCount++;
|
|
3129
|
+
continue;
|
|
3130
|
+
}
|
|
3131
|
+
if (fileSize > 8192) {
|
|
3132
|
+
console.error(
|
|
3133
|
+
`\u274C ${file}: File size (${fileSize} bytes) exceeds maximum (8192 bytes)`
|
|
3134
|
+
);
|
|
3135
|
+
console.error(" Consider reducing comments or splitting variables");
|
|
3136
|
+
failCount++;
|
|
3137
|
+
continue;
|
|
3138
|
+
}
|
|
3139
|
+
await pushEnvFile(
|
|
3140
|
+
config.host,
|
|
3141
|
+
config.authToken,
|
|
3142
|
+
project,
|
|
3143
|
+
environment,
|
|
3144
|
+
fileContent,
|
|
3145
|
+
file
|
|
3146
|
+
// Use full relative path, not just filename
|
|
3147
|
+
);
|
|
3148
|
+
if (selectedFiles.length === 1) {
|
|
3149
|
+
console.log(
|
|
3150
|
+
`\u2705 Pushed ${file} (${variables.length} variables) to ${project}/${environment}`
|
|
3151
|
+
);
|
|
3152
|
+
} else {
|
|
3153
|
+
console.log(`\u2705 ${file}: Pushed (${variables.length} variables)`);
|
|
3154
|
+
}
|
|
3155
|
+
successCount++;
|
|
3156
|
+
} catch (error) {
|
|
3157
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3158
|
+
console.error(`\u274C ${file}: Failed to push - ${message}`);
|
|
3159
|
+
failCount++;
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
if (selectedFiles.length > 1) {
|
|
3163
|
+
console.log(`
|
|
3164
|
+
\u{1F4CA} Summary:`);
|
|
3165
|
+
console.log(` \u2705 Success: ${successCount} file(s)`);
|
|
3166
|
+
if (failCount > 0) {
|
|
3167
|
+
console.log(` \u274C Failed: ${failCount} file(s)`);
|
|
3168
|
+
}
|
|
3169
|
+
}
|
|
3170
|
+
if (failCount > 0) {
|
|
3171
|
+
process.exit(1);
|
|
3172
|
+
}
|
|
3173
|
+
}
|
|
3174
|
+
function parseVariables(content, filename) {
|
|
3175
|
+
const variables = [];
|
|
3176
|
+
if (filename.endsWith(".json")) {
|
|
3177
|
+
try {
|
|
3178
|
+
const obj = JSON.parse(content);
|
|
3179
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
3180
|
+
variables.push({ key, value: String(value) });
|
|
3181
|
+
}
|
|
3182
|
+
return variables;
|
|
3183
|
+
} catch (error) {
|
|
3184
|
+
throw new Error("Invalid JSON file");
|
|
3185
|
+
}
|
|
3186
|
+
}
|
|
3187
|
+
const lines = content.split("\n");
|
|
3188
|
+
let pendingComment;
|
|
3189
|
+
for (let i = 0; i < lines.length; i++) {
|
|
3190
|
+
const line = lines[i];
|
|
3191
|
+
const trimmed = line.trim();
|
|
3192
|
+
if (trimmed.startsWith("#")) {
|
|
3193
|
+
const commentText = trimmed.substring(1).trim();
|
|
3194
|
+
if (commentText && !commentText.match(/^[=\-]+$/)) {
|
|
3195
|
+
pendingComment = commentText;
|
|
3196
|
+
}
|
|
3197
|
+
continue;
|
|
3198
|
+
}
|
|
3199
|
+
if (!trimmed) {
|
|
3200
|
+
pendingComment = void 0;
|
|
3201
|
+
continue;
|
|
3202
|
+
}
|
|
3203
|
+
const match = trimmed.match(/^([A-Z0-9_]+)=(.*)$/);
|
|
3204
|
+
if (match) {
|
|
3205
|
+
const [, key, valueWithComment] = match;
|
|
3206
|
+
const inlineCommentMatch = valueWithComment.match(
|
|
3207
|
+
/^([^#]*?)\s*#\s*(.+)$/
|
|
3208
|
+
);
|
|
3209
|
+
let value;
|
|
3210
|
+
let comment = pendingComment;
|
|
3211
|
+
if (inlineCommentMatch) {
|
|
3212
|
+
value = inlineCommentMatch[1].trim();
|
|
3213
|
+
comment = inlineCommentMatch[2].trim();
|
|
3214
|
+
} else {
|
|
3215
|
+
value = valueWithComment.trim();
|
|
3216
|
+
}
|
|
3217
|
+
const cleanValue = value.replace(/^["']|["']$/g, "");
|
|
3218
|
+
const variable = { key, value: cleanValue };
|
|
3219
|
+
if (comment) {
|
|
3220
|
+
variable.comment = comment;
|
|
3221
|
+
}
|
|
3222
|
+
variables.push(variable);
|
|
3223
|
+
pendingComment = void 0;
|
|
3224
|
+
}
|
|
3225
|
+
}
|
|
3226
|
+
return variables;
|
|
3227
|
+
}
|
|
3228
|
+
|
|
3229
|
+
// src/commands/init.ts
|
|
3230
|
+
async function initCommand(args2) {
|
|
3231
|
+
const flags = {};
|
|
3232
|
+
for (let i = 0; i < args2.length; i++) {
|
|
3233
|
+
if (args2[i].startsWith("-")) {
|
|
3234
|
+
const key = args2[i].replace(/^-+/, "");
|
|
3235
|
+
const value = args2[i + 1];
|
|
3236
|
+
if (value && !value.startsWith("-")) {
|
|
3237
|
+
flags[key] = value;
|
|
3238
|
+
i++;
|
|
3239
|
+
} else {
|
|
3240
|
+
flags[key] = "true";
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3244
|
+
const configExists = await hasLocalConfig();
|
|
3245
|
+
if (configExists && !flags.force && !flags.f) {
|
|
3246
|
+
const projectConfig = await loadProjectConfig();
|
|
3247
|
+
if (projectConfig) {
|
|
3248
|
+
console.log("\u{1F4C1} JSSM project already initialized\n");
|
|
3249
|
+
console.log(` Project: ${projectConfig.project}`);
|
|
3250
|
+
console.log(` Environment: ${projectConfig.environment}`);
|
|
3251
|
+
console.log();
|
|
3252
|
+
try {
|
|
3253
|
+
const action = await dist_default6({
|
|
3254
|
+
message: "What would you like to do?",
|
|
3255
|
+
choices: [
|
|
3256
|
+
{
|
|
3257
|
+
name: "\u{1F4E5} Pull - Download .env files from server",
|
|
3258
|
+
value: "pull"
|
|
3259
|
+
},
|
|
3260
|
+
{
|
|
3261
|
+
name: "\u{1F4E4} Push - Upload local .env files to server",
|
|
3262
|
+
value: "push"
|
|
3263
|
+
},
|
|
3264
|
+
{
|
|
3265
|
+
name: "\u{1F504} Reinitialize - Set up a different project/environment",
|
|
3266
|
+
value: "reinit"
|
|
3267
|
+
},
|
|
3268
|
+
{ name: "\u274C Cancel", value: "cancel" }
|
|
3269
|
+
]
|
|
3270
|
+
});
|
|
3271
|
+
if (action === "pull") {
|
|
3272
|
+
await pullCommand([]);
|
|
3273
|
+
return;
|
|
3274
|
+
} else if (action === "push") {
|
|
3275
|
+
await pushCommand([]);
|
|
3276
|
+
return;
|
|
3277
|
+
} else if (action === "cancel") {
|
|
3278
|
+
console.log("\n\u{1F44B} Cancelled");
|
|
3279
|
+
return;
|
|
3280
|
+
}
|
|
3281
|
+
console.log();
|
|
3282
|
+
} catch (error) {
|
|
3283
|
+
if (error.name === "ExitPromptError") {
|
|
3284
|
+
console.log("\n\u{1F44B} Cancelled");
|
|
3285
|
+
return;
|
|
3286
|
+
}
|
|
3287
|
+
throw error;
|
|
3288
|
+
}
|
|
3289
|
+
}
|
|
3290
|
+
}
|
|
3291
|
+
console.log("\u{1F680} JSSM Project Initialization\n");
|
|
3292
|
+
console.log("\u{1F510} Checking authentication...");
|
|
3293
|
+
const authData = await loadAuthData();
|
|
3294
|
+
if (!authData) {
|
|
3295
|
+
console.log("\n\u274C You are not logged in");
|
|
3296
|
+
console.log("\u{1F4A1} Please login or register first:");
|
|
3297
|
+
console.log(" jssm login");
|
|
3298
|
+
console.log(" jssm register");
|
|
3299
|
+
process.exit(1);
|
|
3300
|
+
}
|
|
3301
|
+
console.log(`\u2705 Logged in as ${authData.user.email}
|
|
3302
|
+
`);
|
|
3303
|
+
const globalConfig = await loadGlobalConfig();
|
|
3304
|
+
const host = flags.host || flags.h || globalConfig.host;
|
|
3305
|
+
if (!host) {
|
|
3306
|
+
console.error("\u274C Host URL is required");
|
|
3307
|
+
console.error("\u{1F4A1} Set it globally: jssm config set host <url>");
|
|
3308
|
+
process.exit(1);
|
|
3309
|
+
}
|
|
3310
|
+
const authToken = authData.token;
|
|
3311
|
+
console.log("\u{1F50D} Analyzing repository...");
|
|
3312
|
+
const cwd = process.cwd();
|
|
3313
|
+
const repoType = await getRepositoryType(cwd);
|
|
3314
|
+
console.log(` Repository type: ${repoType}`);
|
|
3315
|
+
const envFiles = await findEnvFiles(cwd);
|
|
3316
|
+
if (envFiles.length > 0) {
|
|
3317
|
+
console.log(` Found ${envFiles.length} .env file(s)`);
|
|
3318
|
+
} else {
|
|
3319
|
+
console.log(` No .env files found`);
|
|
3320
|
+
}
|
|
3321
|
+
console.log();
|
|
3322
|
+
let projectName;
|
|
3323
|
+
let environmentName;
|
|
3324
|
+
try {
|
|
3325
|
+
console.log("\u{1F4E6} Loading your projects...");
|
|
3326
|
+
const projects = await getProjects(host, authToken);
|
|
3327
|
+
if (projects.length === 0) {
|
|
3328
|
+
console.log(" No existing projects found\n");
|
|
3329
|
+
projectName = await dist_default4({
|
|
3330
|
+
message: "Project name:",
|
|
3331
|
+
validate: (value) => {
|
|
3332
|
+
if (!value)
|
|
3333
|
+
return "Project name is required";
|
|
3334
|
+
if (!/^[a-z0-9-_.]+$/.test(value)) {
|
|
3335
|
+
return "Project name must contain only lowercase letters, numbers, hyphens, underscores, and dots";
|
|
3336
|
+
}
|
|
3337
|
+
return true;
|
|
3338
|
+
}
|
|
3339
|
+
});
|
|
3340
|
+
console.log(`
|
|
3341
|
+
\u{1F4E6} Creating project "${projectName}"...`);
|
|
3342
|
+
await createProject(host, authToken, projectName, repoType);
|
|
3343
|
+
console.log(`\u2705 Project created
|
|
3344
|
+
`);
|
|
3345
|
+
} else {
|
|
3346
|
+
const projectChoices = [
|
|
3347
|
+
...projects.map((p) => ({ name: p.name, value: p.name })),
|
|
3348
|
+
{ name: "+ Create new project", value: "__new__" }
|
|
3349
|
+
];
|
|
3350
|
+
const selectedProject = await dist_default6({
|
|
3351
|
+
message: "Select a project:",
|
|
3352
|
+
choices: projectChoices
|
|
3353
|
+
});
|
|
3354
|
+
if (selectedProject === "__new__") {
|
|
3355
|
+
projectName = await dist_default4({
|
|
3356
|
+
message: "New project name:",
|
|
3357
|
+
validate: (value) => {
|
|
3358
|
+
if (!value)
|
|
3359
|
+
return "Project name is required";
|
|
3360
|
+
if (!/^[a-z0-9-_.]+$/.test(value)) {
|
|
3361
|
+
return "Project name must contain only lowercase letters, numbers, hyphens, underscores, and dots";
|
|
3362
|
+
}
|
|
3363
|
+
if (projects.some((p) => p.name === value)) {
|
|
3364
|
+
return "Project already exists";
|
|
3365
|
+
}
|
|
3366
|
+
return true;
|
|
3367
|
+
}
|
|
3368
|
+
});
|
|
3369
|
+
console.log(`
|
|
3370
|
+
\u{1F4E6} Creating project "${projectName}"...`);
|
|
3371
|
+
await createProject(host, authToken, projectName, repoType);
|
|
3372
|
+
console.log(`\u2705 Project created
|
|
3373
|
+
`);
|
|
3374
|
+
} else {
|
|
3375
|
+
projectName = selectedProject;
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
console.log("\u{1F30D} Loading environments...");
|
|
3379
|
+
const environments = await getEnvironments(host, authToken, projectName);
|
|
3380
|
+
if (environments.length === 0) {
|
|
3381
|
+
console.log(" No existing environments found\n");
|
|
3382
|
+
environmentName = await dist_default4({
|
|
3383
|
+
message: "Environment name:",
|
|
3384
|
+
default: "development",
|
|
3385
|
+
validate: (value) => {
|
|
3386
|
+
if (!value)
|
|
3387
|
+
return "Environment name is required";
|
|
3388
|
+
if (!/^[a-z0-9-_]+$/.test(value)) {
|
|
3389
|
+
return "Environment name must contain only lowercase letters, numbers, hyphens, and underscores";
|
|
3390
|
+
}
|
|
3391
|
+
return true;
|
|
3392
|
+
}
|
|
3393
|
+
});
|
|
3394
|
+
console.log(`
|
|
3395
|
+
\u{1F30D} Creating environment "${environmentName}"...`);
|
|
3396
|
+
await createEnvironment(host, authToken, projectName, environmentName);
|
|
3397
|
+
console.log(`\u2705 Environment created
|
|
3398
|
+
`);
|
|
3399
|
+
} else {
|
|
3400
|
+
const envChoices = [
|
|
3401
|
+
...environments.map((e) => ({ name: e.name, value: e.name })),
|
|
3402
|
+
{ name: "+ Create new environment", value: "__new__" }
|
|
3403
|
+
];
|
|
3404
|
+
const selectedEnv = await dist_default6({
|
|
3405
|
+
message: "Select an environment:",
|
|
3406
|
+
choices: envChoices
|
|
3407
|
+
});
|
|
3408
|
+
if (selectedEnv === "__new__") {
|
|
3409
|
+
environmentName = await dist_default4({
|
|
3410
|
+
message: "New environment name:",
|
|
3411
|
+
default: "development",
|
|
3412
|
+
validate: (value) => {
|
|
3413
|
+
if (!value)
|
|
3414
|
+
return "Environment name is required";
|
|
3415
|
+
if (!/^[a-z0-9-_]+$/.test(value)) {
|
|
3416
|
+
return "Environment name must contain only lowercase letters, numbers, hyphens, and underscores";
|
|
3417
|
+
}
|
|
3418
|
+
if (environments.some((e) => e.name === value)) {
|
|
3419
|
+
return "Environment already exists";
|
|
3420
|
+
}
|
|
3421
|
+
return true;
|
|
3422
|
+
}
|
|
3423
|
+
});
|
|
3424
|
+
console.log(`
|
|
3425
|
+
\u{1F30D} Creating environment "${environmentName}"...`);
|
|
3426
|
+
await createEnvironment(host, authToken, projectName, environmentName);
|
|
3427
|
+
console.log(`\u2705 Environment created
|
|
3428
|
+
`);
|
|
3429
|
+
} else {
|
|
3430
|
+
environmentName = selectedEnv;
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3433
|
+
if (envFiles.length > 0) {
|
|
3434
|
+
console.log("\u{1F4C4} .env files detected:");
|
|
3435
|
+
envFiles.forEach((file) => {
|
|
3436
|
+
console.log(
|
|
3437
|
+
` ${file.relativePath} (${file.variableCount} variables)`
|
|
3438
|
+
);
|
|
3439
|
+
});
|
|
3440
|
+
console.log();
|
|
3441
|
+
const shouldUpload = await dist_default3({
|
|
3442
|
+
message: "Would you like to upload variables from .env files?",
|
|
3443
|
+
default: true
|
|
3444
|
+
});
|
|
3445
|
+
if (shouldUpload) {
|
|
3446
|
+
let selectedFiles;
|
|
3447
|
+
if (repoType === "monorepo" && envFiles.length > 1) {
|
|
3448
|
+
const fileChoices = envFiles.map((file) => ({
|
|
3449
|
+
name: `${file.relativePath} (${file.variableCount} variables)`,
|
|
3450
|
+
value: file.path
|
|
3451
|
+
}));
|
|
3452
|
+
selectedFiles = await dist_default2({
|
|
3453
|
+
message: "Select .env files to upload:",
|
|
3454
|
+
choices: fileChoices,
|
|
3455
|
+
validate: (answer) => {
|
|
3456
|
+
if (answer.length === 0) {
|
|
3457
|
+
return "Please select at least one file";
|
|
3458
|
+
}
|
|
3459
|
+
return true;
|
|
3460
|
+
}
|
|
3461
|
+
});
|
|
3462
|
+
} else {
|
|
3463
|
+
selectedFiles = [envFiles[0].path];
|
|
3464
|
+
}
|
|
3465
|
+
const allVariables = [];
|
|
3466
|
+
const variablesByFile = /* @__PURE__ */ new Map();
|
|
3467
|
+
for (const filePath of selectedFiles) {
|
|
3468
|
+
const variables = await readEnvFile(filePath);
|
|
3469
|
+
variablesByFile.set(filePath, variables);
|
|
3470
|
+
for (const variable of variables) {
|
|
3471
|
+
const existingIndex = allVariables.findIndex(
|
|
3472
|
+
(v) => v.key === variable.key
|
|
3473
|
+
);
|
|
3474
|
+
if (existingIndex >= 0) {
|
|
3475
|
+
allVariables[existingIndex] = variable;
|
|
3476
|
+
} else {
|
|
3477
|
+
allVariables.push(variable);
|
|
3478
|
+
}
|
|
3479
|
+
}
|
|
3480
|
+
}
|
|
3481
|
+
const invalidNames = getInvalidVariableNames(allVariables);
|
|
3482
|
+
if (invalidNames.length > 0) {
|
|
3483
|
+
console.log("\n\u26A0\uFE0F Warning: Some variable names are invalid:");
|
|
3484
|
+
invalidNames.forEach((name) => console.log(` ${name}`));
|
|
3485
|
+
console.log(
|
|
3486
|
+
" Variable names must contain only uppercase letters, numbers, and underscores"
|
|
3487
|
+
);
|
|
3488
|
+
const continueAnyway = await dist_default3({
|
|
3489
|
+
message: "Continue with valid variables only?",
|
|
3490
|
+
default: true
|
|
3491
|
+
});
|
|
3492
|
+
if (!continueAnyway) {
|
|
3493
|
+
console.log("\n\u274C Upload cancelled");
|
|
3494
|
+
process.exit(0);
|
|
3495
|
+
}
|
|
3496
|
+
const validVariables = allVariables.filter(
|
|
3497
|
+
(v) => !invalidNames.includes(v.key)
|
|
3498
|
+
);
|
|
3499
|
+
allVariables.length = 0;
|
|
3500
|
+
allVariables.push(...validVariables);
|
|
3501
|
+
}
|
|
3502
|
+
console.log(`
|
|
3503
|
+
\u{1F4CB} Variables to upload (${allVariables.length} total):`);
|
|
3504
|
+
console.log(formatVariablesPreview(allVariables, 10));
|
|
3505
|
+
const confirmUpload = await dist_default3({
|
|
3506
|
+
message: "\nProceed with upload?",
|
|
3507
|
+
default: true
|
|
3508
|
+
});
|
|
3509
|
+
if (confirmUpload) {
|
|
3510
|
+
console.log(`
|
|
3511
|
+
\u2B06\uFE0F Uploading ${allVariables.length} variables...`);
|
|
3512
|
+
await pushVariables(
|
|
3513
|
+
host,
|
|
3514
|
+
authToken,
|
|
3515
|
+
projectName,
|
|
3516
|
+
environmentName,
|
|
3517
|
+
allVariables
|
|
3518
|
+
);
|
|
3519
|
+
console.log(`\u2705 Variables uploaded successfully`);
|
|
3520
|
+
} else {
|
|
3521
|
+
console.log("\n\u23ED\uFE0F Skipping variable upload");
|
|
3522
|
+
}
|
|
3523
|
+
}
|
|
3524
|
+
}
|
|
3525
|
+
const namespace = flags.namespace || globalConfig.namespace || DEFAULT_NAMESPACE;
|
|
3526
|
+
const projectConfig = {
|
|
3527
|
+
project: projectName,
|
|
3528
|
+
environment: environmentName
|
|
3529
|
+
};
|
|
3530
|
+
if (flags.host && flags.host !== globalConfig.host) {
|
|
3531
|
+
projectConfig.host = flags.host;
|
|
3532
|
+
}
|
|
3533
|
+
if (flags.namespace && flags.namespace !== globalConfig.namespace) {
|
|
3534
|
+
projectConfig.namespace = flags.namespace;
|
|
3535
|
+
}
|
|
3536
|
+
await saveProjectConfig(projectConfig);
|
|
3537
|
+
console.log(`
|
|
3538
|
+
\u2705 Project initialized successfully!`);
|
|
3539
|
+
console.log(` Config file: .jssm`);
|
|
3540
|
+
console.log(` Project: ${projectName}`);
|
|
3541
|
+
console.log(` Environment: ${environmentName}`);
|
|
3542
|
+
console.log(` Repository type: ${repoType}`);
|
|
3543
|
+
console.log(`
|
|
3544
|
+
\u{1F4A1} Next steps:`);
|
|
3545
|
+
console.log(` - Run "jssm pull" to fetch variables`);
|
|
3546
|
+
console.log(` - Run "jssm sync" to sync variables to .env`);
|
|
3547
|
+
console.log(` - Run "jssm push" to upload local .env changes`);
|
|
3548
|
+
} catch (error) {
|
|
3549
|
+
if (error.name === "ExitPromptError") {
|
|
3550
|
+
console.log("\n\u274C Initialization cancelled");
|
|
3551
|
+
process.exit(0);
|
|
3552
|
+
}
|
|
3553
|
+
console.error(`
|
|
3554
|
+
\u274C Error: ${error.message}`);
|
|
3555
|
+
process.exit(1);
|
|
3556
|
+
}
|
|
3557
|
+
}
|
|
3558
|
+
|
|
3559
|
+
// src/commands/sync.ts
|
|
3560
|
+
import { writeFile as writeFile4 } from "fs/promises";
|
|
3561
|
+
import { join as join6 } from "path";
|
|
3562
|
+
async function syncCommand() {
|
|
3563
|
+
const config = await resolveConfig();
|
|
3564
|
+
if (!config) {
|
|
3565
|
+
console.error("\u274C No .jssm configuration found in current directory.");
|
|
3566
|
+
console.error('\u{1F4A1} Run "jssm init -p <project> -e <env>" to initialize.');
|
|
3567
|
+
process.exit(1);
|
|
3568
|
+
}
|
|
3569
|
+
const { valid, errors } = validateResolvedConfig(config);
|
|
3570
|
+
if (!valid) {
|
|
3571
|
+
console.error("\u274C Configuration is incomplete:");
|
|
3572
|
+
errors.forEach((e) => console.error(` \u2022 ${e}`));
|
|
3573
|
+
process.exit(1);
|
|
3574
|
+
}
|
|
3575
|
+
console.log(
|
|
3576
|
+
`\u{1F504} Syncing .env file for ${config.project}/${config.environment}...`
|
|
3577
|
+
);
|
|
3578
|
+
try {
|
|
3579
|
+
const content = await pullEnvFile(
|
|
3580
|
+
config.host,
|
|
3581
|
+
config.authToken,
|
|
3582
|
+
config.project,
|
|
3583
|
+
config.environment
|
|
3584
|
+
);
|
|
3585
|
+
const outputPath = join6(process.cwd(), ".env");
|
|
3586
|
+
await writeFile4(outputPath, content, "utf-8");
|
|
3587
|
+
const varCount = content.split("\n").filter((line) => {
|
|
3588
|
+
const trimmed = line.trim();
|
|
3589
|
+
return trimmed && !trimmed.startsWith("#") && trimmed.includes("=");
|
|
3590
|
+
}).length;
|
|
3591
|
+
console.log(`\u2705 Synced .env file (${varCount} variables)`);
|
|
3592
|
+
console.log(` Project: ${config.project}`);
|
|
3593
|
+
console.log(` Environment: ${config.environment}`);
|
|
3594
|
+
} catch (error) {
|
|
3595
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3596
|
+
console.error("\u274C Failed to sync .env file:", message);
|
|
3597
|
+
process.exit(1);
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3600
|
+
|
|
3601
|
+
// src/commands/project.ts
|
|
3602
|
+
init_auth();
|
|
3603
|
+
async function projectCommand(args2) {
|
|
3604
|
+
const subcommand = args2[0];
|
|
3605
|
+
if (subcommand === "create") {
|
|
3606
|
+
await createProjectCommand(args2.slice(1));
|
|
3607
|
+
} else if (subcommand === "list" || subcommand === "ls") {
|
|
3608
|
+
await listProjectsCommand();
|
|
3609
|
+
} else {
|
|
3610
|
+
printProjectHelp();
|
|
3611
|
+
}
|
|
3612
|
+
}
|
|
3613
|
+
async function createProjectCommand(args2) {
|
|
3614
|
+
const flags = {};
|
|
3615
|
+
for (let i = 0; i < args2.length; i++) {
|
|
3616
|
+
if (args2[i].startsWith("-")) {
|
|
3617
|
+
const key = args2[i].replace(/^-+/, "");
|
|
3618
|
+
const value = args2[i + 1];
|
|
3619
|
+
if (value && !value.startsWith("-")) {
|
|
3620
|
+
flags[key] = value;
|
|
3621
|
+
i++;
|
|
3622
|
+
}
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
const name = flags.n || flags.name || args2[0];
|
|
3626
|
+
const host = flags.host;
|
|
3627
|
+
if (!name) {
|
|
3628
|
+
console.error("Usage: jssm project create <name> [--host <api_url>]");
|
|
3629
|
+
console.error("\nOptions:");
|
|
3630
|
+
console.error(" -n, --name Project name");
|
|
3631
|
+
console.error(" --host API host URL (optional if config exists)");
|
|
3632
|
+
process.exit(1);
|
|
3633
|
+
}
|
|
3634
|
+
const authToken = await getAuthToken();
|
|
3635
|
+
if (!authToken) {
|
|
3636
|
+
console.error("\u274C Not logged in");
|
|
3637
|
+
console.error("\u{1F4A1} Run: jssm login");
|
|
3638
|
+
process.exit(1);
|
|
3639
|
+
}
|
|
3640
|
+
const globalConfig = await loadGlobalConfig();
|
|
3641
|
+
const projectConfig = await loadProjectConfig();
|
|
3642
|
+
const finalHost = host || projectConfig?.host || globalConfig.host;
|
|
3643
|
+
if (!finalHost) {
|
|
3644
|
+
console.error("\u274C Host is required");
|
|
3645
|
+
console.error("\u{1F4A1} Set globally: jssm config set host <url>");
|
|
3646
|
+
process.exit(1);
|
|
3647
|
+
}
|
|
3648
|
+
try {
|
|
3649
|
+
console.log(`\u{1F4E6} Creating project "${name}"...`);
|
|
3650
|
+
const project = await createProject(finalHost, authToken, name);
|
|
3651
|
+
console.log(`\u2705 Project "${name}" created successfully`);
|
|
3652
|
+
console.log(` ID: ${project._id}`);
|
|
3653
|
+
console.log(` Created: ${new Date(project.createdAt).toLocaleString()}`);
|
|
3654
|
+
console.log("\n\u{1F4A1} Next steps:");
|
|
3655
|
+
console.log(
|
|
3656
|
+
` - Run "jssm env create <env-name> -p ${name}" to create an environment`
|
|
3657
|
+
);
|
|
3658
|
+
console.log(
|
|
3659
|
+
` - Run "jssm init -p ${name} -e <env-name>" to configure CLI`
|
|
3660
|
+
);
|
|
3661
|
+
} catch (error) {
|
|
3662
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3663
|
+
console.error(`\u274C Failed to create project: ${message}`);
|
|
3664
|
+
process.exit(1);
|
|
3665
|
+
}
|
|
3666
|
+
}
|
|
3667
|
+
async function listProjectsCommand() {
|
|
3668
|
+
const authToken = await getAuthToken();
|
|
3669
|
+
if (!authToken) {
|
|
3670
|
+
console.error("\u274C Not logged in");
|
|
3671
|
+
console.error("\u{1F4A1} Run: jssm login");
|
|
3672
|
+
process.exit(1);
|
|
3673
|
+
}
|
|
3674
|
+
const globalConfig = await loadGlobalConfig();
|
|
3675
|
+
const projectConfig = await loadProjectConfig();
|
|
3676
|
+
const host = projectConfig?.host || globalConfig.host;
|
|
3677
|
+
if (!host) {
|
|
3678
|
+
console.error("\u274C Host is required");
|
|
3679
|
+
console.error("\u{1F4A1} Set globally: jssm config set host <url>");
|
|
3680
|
+
process.exit(1);
|
|
3681
|
+
}
|
|
3682
|
+
try {
|
|
3683
|
+
console.log("\u{1F4E6} Fetching projects...\n");
|
|
3684
|
+
const projects = await getProjects(host, authToken);
|
|
3685
|
+
if (projects.length === 0) {
|
|
3686
|
+
console.log("No projects found.");
|
|
3687
|
+
console.log("\u{1F4A1} Create one with: jssm project create <name>");
|
|
3688
|
+
return;
|
|
3689
|
+
}
|
|
3690
|
+
console.log(`Found ${projects.length} project(s):
|
|
3691
|
+
`);
|
|
3692
|
+
projects.forEach((project) => {
|
|
3693
|
+
console.log(` \u2022 ${project.name}`);
|
|
3694
|
+
console.log(` ID: ${project._id}`);
|
|
3695
|
+
console.log(
|
|
3696
|
+
` Created: ${new Date(project.createdAt).toLocaleString()}`
|
|
3697
|
+
);
|
|
3698
|
+
console.log("");
|
|
3699
|
+
});
|
|
3700
|
+
} catch (error) {
|
|
3701
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3702
|
+
console.error(`\u274C Failed to list projects: ${message}`);
|
|
3703
|
+
process.exit(1);
|
|
3704
|
+
}
|
|
3705
|
+
}
|
|
3706
|
+
function printProjectHelp() {
|
|
3707
|
+
console.log(`
|
|
3708
|
+
JSSM Project Management
|
|
3709
|
+
|
|
3710
|
+
Usage:
|
|
3711
|
+
jssm project <command> [options]
|
|
3712
|
+
|
|
3713
|
+
Commands:
|
|
3714
|
+
create Create a new project
|
|
3715
|
+
list List all projects (alias: ls)
|
|
3716
|
+
|
|
3717
|
+
Examples:
|
|
3718
|
+
jssm project create my-app
|
|
3719
|
+
jssm project list
|
|
3720
|
+
`);
|
|
3721
|
+
}
|
|
3722
|
+
|
|
3723
|
+
// src/commands/env.ts
|
|
3724
|
+
init_auth();
|
|
3725
|
+
async function envCommand(args2) {
|
|
3726
|
+
const subcommand = args2[0];
|
|
3727
|
+
if (subcommand === "create") {
|
|
3728
|
+
await createEnvCommand(args2.slice(1));
|
|
3729
|
+
} else if (subcommand === "list" || subcommand === "ls") {
|
|
3730
|
+
await listEnvsCommand(args2.slice(1));
|
|
3731
|
+
} else {
|
|
3732
|
+
printEnvHelp();
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3735
|
+
async function createEnvCommand(args2) {
|
|
3736
|
+
const flags = {};
|
|
3737
|
+
for (let i = 0; i < args2.length; i++) {
|
|
3738
|
+
if (args2[i].startsWith("-")) {
|
|
3739
|
+
const key = args2[i].replace(/^-+/, "");
|
|
3740
|
+
const value = args2[i + 1];
|
|
3741
|
+
if (value && !value.startsWith("-")) {
|
|
3742
|
+
flags[key] = value;
|
|
3743
|
+
i++;
|
|
3744
|
+
}
|
|
3745
|
+
}
|
|
3746
|
+
}
|
|
3747
|
+
const name = flags.n || flags.name || args2[0];
|
|
3748
|
+
const project = flags.p || flags.project;
|
|
3749
|
+
const host = flags.host;
|
|
3750
|
+
if (!name) {
|
|
3751
|
+
console.error(
|
|
3752
|
+
"Usage: jssm env create <name> -p <project> [--host <api_url>]"
|
|
3753
|
+
);
|
|
3754
|
+
console.error("\nOptions:");
|
|
3755
|
+
console.error(" -n, --name Environment name");
|
|
3756
|
+
console.error(" -p, --project Project name (required)");
|
|
3757
|
+
console.error(
|
|
3758
|
+
" --host API host URL (optional if global config exists)"
|
|
3759
|
+
);
|
|
3760
|
+
process.exit(1);
|
|
3761
|
+
}
|
|
3762
|
+
const authToken = await getAuthToken();
|
|
3763
|
+
if (!authToken) {
|
|
3764
|
+
console.error("\u274C Not logged in");
|
|
3765
|
+
console.error("\u{1F4A1} Run: jssm login");
|
|
3766
|
+
process.exit(1);
|
|
3767
|
+
}
|
|
3768
|
+
const globalConfig = await loadGlobalConfig();
|
|
3769
|
+
const projectConfig = await loadProjectConfig();
|
|
3770
|
+
const finalProject = project || projectConfig?.project;
|
|
3771
|
+
const finalHost = host || projectConfig?.host || globalConfig.host;
|
|
3772
|
+
if (!finalProject) {
|
|
3773
|
+
console.error("\u274C Project name is required");
|
|
3774
|
+
console.error('\u{1F4A1} Either provide -p <project>, or run "jssm init" first');
|
|
3775
|
+
process.exit(1);
|
|
3776
|
+
}
|
|
3777
|
+
if (!finalHost) {
|
|
3778
|
+
console.error("\u274C Host is required");
|
|
3779
|
+
console.error("\u{1F4A1} Set globally: jssm config set host <url>");
|
|
3780
|
+
process.exit(1);
|
|
3781
|
+
}
|
|
3782
|
+
try {
|
|
3783
|
+
console.log(
|
|
3784
|
+
`\u{1F30D} Creating environment "${name}" in project "${finalProject}"...`
|
|
3785
|
+
);
|
|
3786
|
+
const env = await createEnvironment(
|
|
3787
|
+
finalHost,
|
|
3788
|
+
authToken,
|
|
3789
|
+
finalProject,
|
|
3790
|
+
name
|
|
3791
|
+
);
|
|
3792
|
+
console.log(`\u2705 Environment "${name}" created successfully`);
|
|
3793
|
+
console.log(` ID: ${env._id}`);
|
|
3794
|
+
console.log(` Project: ${finalProject}`);
|
|
3795
|
+
console.log(` Created: ${new Date(env.createdAt).toLocaleString()}`);
|
|
3796
|
+
console.log("\n\u{1F4A1} Next steps:");
|
|
3797
|
+
console.log(
|
|
3798
|
+
` - Run "jssm init -p ${finalProject} -e ${name}" to configure CLI`
|
|
3799
|
+
);
|
|
3800
|
+
console.log(" - Add variables via the web UI or API");
|
|
3801
|
+
} catch (error) {
|
|
3802
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3803
|
+
console.error(`\u274C Failed to create environment: ${message}`);
|
|
3804
|
+
process.exit(1);
|
|
3805
|
+
}
|
|
3806
|
+
}
|
|
3807
|
+
async function listEnvsCommand(args2) {
|
|
3808
|
+
const flags = {};
|
|
3809
|
+
for (let i = 0; i < args2.length; i++) {
|
|
3810
|
+
if (args2[i].startsWith("-")) {
|
|
3811
|
+
const key = args2[i].replace(/^-+/, "");
|
|
3812
|
+
const value = args2[i + 1];
|
|
3813
|
+
if (value && !value.startsWith("-")) {
|
|
3814
|
+
flags[key] = value;
|
|
3815
|
+
i++;
|
|
3816
|
+
}
|
|
3817
|
+
}
|
|
3818
|
+
}
|
|
3819
|
+
const project = flags.p || flags.project;
|
|
3820
|
+
const authToken = await getAuthToken();
|
|
3821
|
+
if (!authToken) {
|
|
3822
|
+
console.error("\u274C Not logged in");
|
|
3823
|
+
console.error("\u{1F4A1} Run: jssm login");
|
|
3824
|
+
process.exit(1);
|
|
3825
|
+
}
|
|
3826
|
+
const globalConfig = await loadGlobalConfig();
|
|
3827
|
+
const projectConfig = await loadProjectConfig();
|
|
3828
|
+
const finalProject = project || projectConfig?.project;
|
|
3829
|
+
const host = projectConfig?.host || globalConfig.host;
|
|
3830
|
+
if (!finalProject || !host) {
|
|
3831
|
+
console.error("\u274C Project and host are required");
|
|
3832
|
+
console.error("\u{1F4A1} Set globally: jssm config set host <url>");
|
|
3833
|
+
process.exit(1);
|
|
3834
|
+
}
|
|
3835
|
+
try {
|
|
3836
|
+
console.log(`\u{1F30D} Fetching environments for project "${finalProject}"...
|
|
3837
|
+
`);
|
|
3838
|
+
const environments = await getEnvironments(host, authToken, finalProject);
|
|
3839
|
+
if (environments.length === 0) {
|
|
3840
|
+
console.log("No environments found.");
|
|
3841
|
+
console.log(
|
|
3842
|
+
`\u{1F4A1} Create one with: jssm env create <name> -p ${finalProject}`
|
|
3843
|
+
);
|
|
3844
|
+
return;
|
|
3845
|
+
}
|
|
3846
|
+
console.log(`Found ${environments.length} environment(s):
|
|
3847
|
+
`);
|
|
3848
|
+
environments.forEach((env) => {
|
|
3849
|
+
console.log(` \u2022 ${env.name}`);
|
|
3850
|
+
console.log(` ID: ${env._id}`);
|
|
3851
|
+
console.log(` Created: ${new Date(env.createdAt).toLocaleString()}`);
|
|
3852
|
+
console.log("");
|
|
3853
|
+
});
|
|
3854
|
+
} catch (error) {
|
|
3855
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3856
|
+
console.error(`\u274C Failed to list environments: ${message}`);
|
|
3857
|
+
process.exit(1);
|
|
3858
|
+
}
|
|
3859
|
+
}
|
|
3860
|
+
function printEnvHelp() {
|
|
3861
|
+
console.log(`
|
|
3862
|
+
JSSM Environment Management
|
|
3863
|
+
|
|
3864
|
+
Usage:
|
|
3865
|
+
jssm env <command> [options]
|
|
3866
|
+
|
|
3867
|
+
Commands:
|
|
3868
|
+
create Create a new environment
|
|
3869
|
+
list List all environments (alias: ls)
|
|
3870
|
+
|
|
3871
|
+
Examples:
|
|
3872
|
+
jssm env create staging -p my-app
|
|
3873
|
+
jssm env list -p my-app
|
|
3874
|
+
`);
|
|
3875
|
+
}
|
|
3876
|
+
|
|
3877
|
+
// src/commands/status.ts
|
|
3878
|
+
init_auth();
|
|
3879
|
+
async function statusCommand() {
|
|
3880
|
+
const globalConfig = await loadGlobalConfig();
|
|
3881
|
+
const hasProject = await hasLocalConfig();
|
|
3882
|
+
const projectConfig = await loadProjectConfig();
|
|
3883
|
+
const projectConfigPath = await getConfigLocation();
|
|
3884
|
+
const globalConfigPath = getGlobalConfigPath();
|
|
3885
|
+
const authData = await getAuthData();
|
|
3886
|
+
console.log("\u{1F527} JSSM Status\n");
|
|
3887
|
+
console.log("\u{1F510} Authentication");
|
|
3888
|
+
if (authData) {
|
|
3889
|
+
console.log(` Logged in as: ${authData.user.email}`);
|
|
3890
|
+
console.log(` User: ${authData.user.name}`);
|
|
3891
|
+
const expiresAt = new Date(authData.expiresAt);
|
|
3892
|
+
const isExpired = expiresAt < /* @__PURE__ */ new Date();
|
|
3893
|
+
if (isExpired) {
|
|
3894
|
+
console.log(` Token: \u274C Expired`);
|
|
3895
|
+
console.log(" \u{1F4A1} Run: jssm login");
|
|
3896
|
+
} else {
|
|
3897
|
+
console.log(` Token: \u2705 Valid until ${expiresAt.toLocaleString()}`);
|
|
3898
|
+
}
|
|
3899
|
+
} else {
|
|
3900
|
+
console.log(" \u274C Not logged in");
|
|
3901
|
+
console.log(" \u{1F4A1} Run: jssm login");
|
|
3902
|
+
}
|
|
3903
|
+
console.log("");
|
|
3904
|
+
console.log("\u{1F4C1} Global Configuration");
|
|
3905
|
+
console.log(` Location: ${globalConfigPath}`);
|
|
3906
|
+
if (Object.keys(globalConfig).length === 0) {
|
|
3907
|
+
console.log(" (no global config set)");
|
|
3908
|
+
} else {
|
|
3909
|
+
if (globalConfig.host) {
|
|
3910
|
+
console.log(` Host: ${globalConfig.host}`);
|
|
3911
|
+
}
|
|
3912
|
+
if (globalConfig.namespace) {
|
|
3913
|
+
console.log(` Namespace: ${globalConfig.namespace}`);
|
|
3914
|
+
}
|
|
3915
|
+
}
|
|
3916
|
+
console.log("");
|
|
3917
|
+
if (!hasProject) {
|
|
3918
|
+
console.log("\u{1F4C2} Project Configuration");
|
|
3919
|
+
console.log(" \u274C Not a JSSM directory");
|
|
3920
|
+
console.log(' \u{1F4A1} Run "jssm init -p <project> -e <env>" to initialize');
|
|
3921
|
+
return;
|
|
3922
|
+
}
|
|
3923
|
+
if (!projectConfig) {
|
|
3924
|
+
console.log("\u{1F4C2} Project Configuration");
|
|
3925
|
+
console.log(" \u274C Failed to load project configuration");
|
|
3926
|
+
return;
|
|
3927
|
+
}
|
|
3928
|
+
console.log("\u{1F4C2} Project Configuration");
|
|
3929
|
+
console.log(` Location: ${projectConfigPath}`);
|
|
3930
|
+
console.log(` Project: ${projectConfig.project}`);
|
|
3931
|
+
console.log(` Environment: ${projectConfig.environment}`);
|
|
3932
|
+
if (projectConfig.host) {
|
|
3933
|
+
console.log(` Host: ${projectConfig.host} (override)`);
|
|
3934
|
+
}
|
|
3935
|
+
if (projectConfig.namespace) {
|
|
3936
|
+
console.log(` Namespace: ${projectConfig.namespace} (override)`);
|
|
3937
|
+
}
|
|
3938
|
+
console.log("");
|
|
3939
|
+
const resolved = await resolveConfig();
|
|
3940
|
+
if (resolved) {
|
|
3941
|
+
console.log("\u{1F517} Resolved Configuration (merged)");
|
|
3942
|
+
console.log(` Project: ${resolved.project}`);
|
|
3943
|
+
console.log(` Environment: ${resolved.environment}`);
|
|
3944
|
+
console.log(` Host: ${resolved.host || "(not set)"}`);
|
|
3945
|
+
console.log(` Namespace: ${resolved.namespace}`);
|
|
3946
|
+
console.log(
|
|
3947
|
+
` Auth: ${resolved.authToken ? "\u2705 Authenticated" : "\u274C Not authenticated"}`
|
|
3948
|
+
);
|
|
3949
|
+
if (!resolved.host) {
|
|
3950
|
+
console.log("\n\u26A0\uFE0F Host is not configured");
|
|
3951
|
+
console.log(" Set globally: jssm config set host <url>");
|
|
3952
|
+
}
|
|
3953
|
+
if (!resolved.authToken) {
|
|
3954
|
+
console.log("\n\u26A0\uFE0F Not logged in");
|
|
3955
|
+
console.log(" Run: jssm login");
|
|
3956
|
+
}
|
|
3957
|
+
}
|
|
3958
|
+
console.log("\n\u{1F4A1} This directory is locked to this project/environment");
|
|
3959
|
+
console.log(" Use -p and -e flags with pull to override");
|
|
3960
|
+
}
|
|
3961
|
+
|
|
3962
|
+
// src/commands/config.ts
|
|
3963
|
+
var VALID_KEYS = ["host", "namespace"];
|
|
3964
|
+
async function configCommand(args2) {
|
|
3965
|
+
const subcommand = args2[0];
|
|
3966
|
+
switch (subcommand) {
|
|
3967
|
+
case "get":
|
|
3968
|
+
await configGetCommand(args2.slice(1));
|
|
3969
|
+
break;
|
|
3970
|
+
case "set":
|
|
3971
|
+
await configSetCommand(args2.slice(1));
|
|
3972
|
+
break;
|
|
3973
|
+
case "unset":
|
|
3974
|
+
case "delete":
|
|
3975
|
+
await configUnsetCommand(args2.slice(1));
|
|
3976
|
+
break;
|
|
3977
|
+
case "list":
|
|
3978
|
+
case "ls":
|
|
3979
|
+
await configListCommand();
|
|
3980
|
+
break;
|
|
3981
|
+
case "path":
|
|
3982
|
+
await configPathCommand();
|
|
3983
|
+
break;
|
|
3984
|
+
default:
|
|
3985
|
+
printConfigHelp();
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
async function configGetCommand(args2) {
|
|
3989
|
+
const key = args2[0];
|
|
3990
|
+
if (!key) {
|
|
3991
|
+
console.error("Usage: jssm config get <key>");
|
|
3992
|
+
console.error(`
|
|
3993
|
+
Valid keys: ${VALID_KEYS.join(", ")}`);
|
|
3994
|
+
process.exit(1);
|
|
3995
|
+
}
|
|
3996
|
+
if (!VALID_KEYS.includes(key)) {
|
|
3997
|
+
console.error(`Unknown config key: ${key}`);
|
|
3998
|
+
console.error(`Valid keys: ${VALID_KEYS.join(", ")}`);
|
|
3999
|
+
process.exit(1);
|
|
4000
|
+
}
|
|
4001
|
+
const config = await loadGlobalConfig();
|
|
4002
|
+
const value = config[key];
|
|
4003
|
+
if (value === void 0) {
|
|
4004
|
+
console.log(`${key} is not set`);
|
|
4005
|
+
} else {
|
|
4006
|
+
console.log(`${key}=${value}`);
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
async function configSetCommand(args2) {
|
|
4010
|
+
const key = args2[0];
|
|
4011
|
+
const value = args2[1];
|
|
4012
|
+
if (!key || value === void 0) {
|
|
4013
|
+
console.error("Usage: jssm config set <key> <value>");
|
|
4014
|
+
console.error(`
|
|
4015
|
+
Valid keys: ${VALID_KEYS.join(", ")}`);
|
|
4016
|
+
process.exit(1);
|
|
4017
|
+
}
|
|
4018
|
+
if (!VALID_KEYS.includes(key)) {
|
|
4019
|
+
console.error(`Unknown config key: ${key}`);
|
|
4020
|
+
console.error(`Valid keys: ${VALID_KEYS.join(", ")}`);
|
|
4021
|
+
process.exit(1);
|
|
4022
|
+
}
|
|
4023
|
+
try {
|
|
4024
|
+
await setGlobalConfigValue(key, value);
|
|
4025
|
+
console.log(`\u2705 Set ${key}=${value}`);
|
|
4026
|
+
} catch (error) {
|
|
4027
|
+
console.error(`\u274C Failed to set config: ${error}`);
|
|
4028
|
+
process.exit(1);
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
async function configUnsetCommand(args2) {
|
|
4032
|
+
const key = args2[0];
|
|
4033
|
+
if (!key) {
|
|
4034
|
+
console.error("Usage: jssm config unset <key>");
|
|
4035
|
+
console.error(`
|
|
4036
|
+
Valid keys: ${VALID_KEYS.join(", ")}`);
|
|
4037
|
+
process.exit(1);
|
|
4038
|
+
}
|
|
4039
|
+
if (!VALID_KEYS.includes(key)) {
|
|
4040
|
+
console.error(`Unknown config key: ${key}`);
|
|
4041
|
+
console.error(`Valid keys: ${VALID_KEYS.join(", ")}`);
|
|
4042
|
+
process.exit(1);
|
|
4043
|
+
}
|
|
4044
|
+
await deleteGlobalConfigValue(key);
|
|
4045
|
+
console.log(`\u2705 Unset ${key}`);
|
|
4046
|
+
}
|
|
4047
|
+
async function configListCommand() {
|
|
4048
|
+
const config = await loadGlobalConfig();
|
|
4049
|
+
const configPath = getGlobalConfigPath();
|
|
4050
|
+
console.log("\u{1F527} Global Configuration");
|
|
4051
|
+
console.log(` Location: ${configPath}
|
|
4052
|
+
`);
|
|
4053
|
+
if (Object.keys(config).length === 0) {
|
|
4054
|
+
console.log(" (no configuration set)");
|
|
4055
|
+
console.log("\n\u{1F4A1} Set values with: jssm config set <key> <value>");
|
|
4056
|
+
return;
|
|
4057
|
+
}
|
|
4058
|
+
for (const key of VALID_KEYS) {
|
|
4059
|
+
const value = config[key];
|
|
4060
|
+
if (value !== void 0) {
|
|
4061
|
+
console.log(` ${key}: ${value}`);
|
|
4062
|
+
}
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
async function configPathCommand() {
|
|
4066
|
+
const configDir = getGlobalConfigDir();
|
|
4067
|
+
const configPath = getGlobalConfigPath();
|
|
4068
|
+
console.log("\u{1F4C1} Global Configuration Paths");
|
|
4069
|
+
console.log(` Directory: ${configDir}`);
|
|
4070
|
+
console.log(` Config file: ${configPath}`);
|
|
4071
|
+
}
|
|
4072
|
+
function printConfigHelp() {
|
|
4073
|
+
console.log(`
|
|
4074
|
+
JSSM Global Configuration Management
|
|
4075
|
+
|
|
4076
|
+
Usage:
|
|
4077
|
+
jssm config <command> [options]
|
|
4078
|
+
|
|
4079
|
+
Commands:
|
|
4080
|
+
get <key> Get a configuration value
|
|
4081
|
+
set <key> <value> Set a configuration value
|
|
4082
|
+
unset <key> Remove a configuration value
|
|
4083
|
+
list List all configuration values (alias: ls)
|
|
4084
|
+
path Show configuration file path
|
|
4085
|
+
|
|
4086
|
+
Valid Keys:
|
|
4087
|
+
host Default API server URL
|
|
4088
|
+
namespace Default SSM namespace (default: jssm)
|
|
4089
|
+
|
|
4090
|
+
Examples:
|
|
4091
|
+
jssm config set host http://localhost:3000
|
|
4092
|
+
jssm config get host
|
|
4093
|
+
jssm config list
|
|
4094
|
+
|
|
4095
|
+
Note:
|
|
4096
|
+
Global config is stored in ~/.jssm/config
|
|
4097
|
+
Project-specific settings in .jssm override global settings
|
|
4098
|
+
For authentication, use: jssm login
|
|
4099
|
+
`);
|
|
4100
|
+
}
|
|
4101
|
+
|
|
4102
|
+
// src/commands/login.ts
|
|
4103
|
+
init_auth();
|
|
4104
|
+
async function loginCommand() {
|
|
4105
|
+
const authData = await loadAuthData();
|
|
4106
|
+
if (authData) {
|
|
4107
|
+
console.log(`\u2705 Already logged in as ${authData.user.email}`);
|
|
4108
|
+
console.log(`\u{1F4A1} Use 'jssm logout' to logout`);
|
|
4109
|
+
return;
|
|
4110
|
+
}
|
|
4111
|
+
const globalConfig = await loadGlobalConfig();
|
|
4112
|
+
const host = globalConfig.host;
|
|
4113
|
+
if (!host) {
|
|
4114
|
+
console.error("\u274C Host URL is required");
|
|
4115
|
+
console.error("\u{1F4A1} Set it globally: jssm config set host <url>");
|
|
4116
|
+
process.exit(1);
|
|
4117
|
+
}
|
|
4118
|
+
console.log("\u{1F510} Login to JSSM\n");
|
|
4119
|
+
try {
|
|
4120
|
+
const email = await dist_default4({
|
|
4121
|
+
message: "Email:",
|
|
4122
|
+
validate: (value) => {
|
|
4123
|
+
if (!value)
|
|
4124
|
+
return "Email is required";
|
|
4125
|
+
if (!value.includes("@"))
|
|
4126
|
+
return "Invalid email address";
|
|
4127
|
+
return true;
|
|
4128
|
+
}
|
|
4129
|
+
});
|
|
4130
|
+
const pass = await dist_default5({
|
|
4131
|
+
message: "Password:",
|
|
4132
|
+
mask: "*",
|
|
4133
|
+
validate: (value) => {
|
|
4134
|
+
if (!value)
|
|
4135
|
+
return "Password is required";
|
|
4136
|
+
return true;
|
|
4137
|
+
}
|
|
4138
|
+
});
|
|
4139
|
+
console.log("\n\u{1F504} Logging in...");
|
|
4140
|
+
const result = await login(host, email, pass);
|
|
4141
|
+
if (result.success) {
|
|
4142
|
+
const authData2 = await loadAuthData();
|
|
4143
|
+
console.log(`
|
|
4144
|
+
\u2705 Successfully logged in as ${authData2?.user.email}`);
|
|
4145
|
+
console.log(`\u{1F464} Name: ${authData2?.user.name}`);
|
|
4146
|
+
console.log(`
|
|
4147
|
+
\u{1F4A1} You can now use 'jssm init' to set up your projects`);
|
|
4148
|
+
} else {
|
|
4149
|
+
console.error(`
|
|
4150
|
+
\u274C Login failed: ${result.error}`);
|
|
4151
|
+
process.exit(1);
|
|
4152
|
+
}
|
|
4153
|
+
} catch (error) {
|
|
4154
|
+
if (error.name === "ExitPromptError") {
|
|
4155
|
+
console.log("\n\u274C Login cancelled");
|
|
4156
|
+
process.exit(0);
|
|
4157
|
+
}
|
|
4158
|
+
console.error(`
|
|
4159
|
+
\u274C Error: ${error.message}`);
|
|
4160
|
+
process.exit(1);
|
|
4161
|
+
}
|
|
4162
|
+
}
|
|
4163
|
+
|
|
4164
|
+
// src/commands/register.ts
|
|
4165
|
+
init_auth();
|
|
4166
|
+
async function registerCommand() {
|
|
4167
|
+
const authData = await loadAuthData();
|
|
4168
|
+
if (authData) {
|
|
4169
|
+
console.log(`\u2705 Already logged in as ${authData.user.email}`);
|
|
4170
|
+
console.log(`\u{1F4A1} Use 'jssm logout' to logout first if you want to register a new account`);
|
|
4171
|
+
return;
|
|
4172
|
+
}
|
|
4173
|
+
const globalConfig = await loadGlobalConfig();
|
|
4174
|
+
const host = globalConfig.host;
|
|
4175
|
+
if (!host) {
|
|
4176
|
+
console.error("\u274C Host URL is required");
|
|
4177
|
+
console.error("\u{1F4A1} Set it globally: jssm config set host <url>");
|
|
4178
|
+
process.exit(1);
|
|
4179
|
+
}
|
|
4180
|
+
console.log("\u{1F4DD} Register for JSSM\n");
|
|
4181
|
+
try {
|
|
4182
|
+
const name = await dist_default4({
|
|
4183
|
+
message: "Full Name:",
|
|
4184
|
+
validate: (value) => {
|
|
4185
|
+
if (!value)
|
|
4186
|
+
return "Name is required";
|
|
4187
|
+
return true;
|
|
4188
|
+
}
|
|
4189
|
+
});
|
|
4190
|
+
const email = await dist_default4({
|
|
4191
|
+
message: "Email:",
|
|
4192
|
+
validate: (value) => {
|
|
4193
|
+
if (!value)
|
|
4194
|
+
return "Email is required";
|
|
4195
|
+
if (!value.includes("@"))
|
|
4196
|
+
return "Invalid email address";
|
|
4197
|
+
return true;
|
|
4198
|
+
}
|
|
4199
|
+
});
|
|
4200
|
+
const pass = await dist_default5({
|
|
4201
|
+
message: "Password (min 8 characters):",
|
|
4202
|
+
mask: "*",
|
|
4203
|
+
validate: (value) => {
|
|
4204
|
+
if (!value)
|
|
4205
|
+
return "Password is required";
|
|
4206
|
+
if (value.length < 8)
|
|
4207
|
+
return "Password must be at least 8 characters";
|
|
4208
|
+
return true;
|
|
4209
|
+
}
|
|
4210
|
+
});
|
|
4211
|
+
const confirmPass = await dist_default5({
|
|
4212
|
+
message: "Confirm Password:",
|
|
4213
|
+
mask: "*",
|
|
4214
|
+
validate: (value) => {
|
|
4215
|
+
if (value !== pass)
|
|
4216
|
+
return "Passwords do not match";
|
|
4217
|
+
return true;
|
|
4218
|
+
}
|
|
4219
|
+
});
|
|
4220
|
+
console.log("\n\u{1F504} Creating account...");
|
|
4221
|
+
const result = await register(host, email, pass, name);
|
|
4222
|
+
if (result.success) {
|
|
4223
|
+
const authData2 = await loadAuthData();
|
|
4224
|
+
console.log(`
|
|
4225
|
+
\u2705 Successfully registered and logged in!`);
|
|
4226
|
+
console.log(`\u{1F464} Name: ${authData2?.user.name}`);
|
|
4227
|
+
console.log(`\u{1F4E7} Email: ${authData2?.user.email}`);
|
|
4228
|
+
console.log(`
|
|
4229
|
+
\u{1F4A1} You can now use 'jssm init' to set up your projects`);
|
|
4230
|
+
} else {
|
|
4231
|
+
console.error(`
|
|
4232
|
+
\u274C Registration failed: ${result.error}`);
|
|
4233
|
+
process.exit(1);
|
|
4234
|
+
}
|
|
4235
|
+
} catch (error) {
|
|
4236
|
+
if (error.name === "ExitPromptError") {
|
|
4237
|
+
console.log("\n\u274C Registration cancelled");
|
|
4238
|
+
process.exit(0);
|
|
4239
|
+
}
|
|
4240
|
+
console.error(`
|
|
4241
|
+
\u274C Error: ${error.message}`);
|
|
4242
|
+
process.exit(1);
|
|
4243
|
+
}
|
|
4244
|
+
}
|
|
4245
|
+
|
|
4246
|
+
// src/commands/logout.ts
|
|
4247
|
+
init_auth();
|
|
4248
|
+
async function logoutCommand() {
|
|
4249
|
+
const authData = await loadAuthData();
|
|
4250
|
+
if (!authData) {
|
|
4251
|
+
console.log("\u2139\uFE0F Not currently logged in");
|
|
4252
|
+
return;
|
|
4253
|
+
}
|
|
4254
|
+
await clearAuthData();
|
|
4255
|
+
console.log(`\u2705 Successfully logged out (was logged in as ${authData.user.email})`);
|
|
4256
|
+
}
|
|
4257
|
+
|
|
4258
|
+
// src/index.ts
|
|
4259
|
+
var args = process.argv.slice(2);
|
|
4260
|
+
var command = args[0];
|
|
4261
|
+
async function main() {
|
|
4262
|
+
switch (command) {
|
|
4263
|
+
case "login":
|
|
4264
|
+
await loginCommand();
|
|
4265
|
+
break;
|
|
4266
|
+
case "register":
|
|
4267
|
+
await registerCommand();
|
|
4268
|
+
break;
|
|
4269
|
+
case "logout":
|
|
4270
|
+
await logoutCommand();
|
|
4271
|
+
break;
|
|
4272
|
+
case "init":
|
|
4273
|
+
await initCommand(args.slice(1));
|
|
4274
|
+
break;
|
|
4275
|
+
case "pull":
|
|
4276
|
+
await pullCommand(args.slice(1));
|
|
4277
|
+
break;
|
|
4278
|
+
case "push":
|
|
4279
|
+
await pushCommand(args.slice(1));
|
|
4280
|
+
break;
|
|
4281
|
+
case "sync":
|
|
4282
|
+
await syncCommand();
|
|
4283
|
+
break;
|
|
4284
|
+
case "status":
|
|
4285
|
+
await statusCommand();
|
|
4286
|
+
break;
|
|
4287
|
+
case "project":
|
|
4288
|
+
await projectCommand(args.slice(1));
|
|
4289
|
+
break;
|
|
4290
|
+
case "env":
|
|
4291
|
+
await envCommand(args.slice(1));
|
|
4292
|
+
break;
|
|
4293
|
+
case "config":
|
|
4294
|
+
await configCommand(args.slice(1));
|
|
4295
|
+
break;
|
|
4296
|
+
case "help":
|
|
4297
|
+
case "--help":
|
|
4298
|
+
case "-h":
|
|
4299
|
+
case void 0:
|
|
4300
|
+
printHelp();
|
|
4301
|
+
break;
|
|
4302
|
+
default:
|
|
4303
|
+
console.error(`Unknown command: ${command}`);
|
|
4304
|
+
printHelp();
|
|
4305
|
+
process.exit(1);
|
|
4306
|
+
}
|
|
4307
|
+
}
|
|
4308
|
+
function printHelp() {
|
|
4309
|
+
console.log(`
|
|
4310
|
+
JSSM - Simple environment variable manager backed by AWS SSM
|
|
4311
|
+
|
|
4312
|
+
Usage:
|
|
4313
|
+
jssm <command> [options]
|
|
4314
|
+
|
|
4315
|
+
Commands:
|
|
4316
|
+
login Login to your JSSM account
|
|
4317
|
+
register Register a new JSSM account
|
|
4318
|
+
logout Logout from your account
|
|
4319
|
+
init Initialize current directory (creates .jssm config file)
|
|
4320
|
+
status Show current configuration
|
|
4321
|
+
pull Pull variables from configured project/environment
|
|
4322
|
+
push Push variables from local file to configured project/environment
|
|
4323
|
+
sync Sync variables to .env file
|
|
4324
|
+
project Manage projects (create, list)
|
|
4325
|
+
env Manage environments (create, list)
|
|
4326
|
+
config Manage global configuration (set, get, list)
|
|
4327
|
+
help Show this help message
|
|
4328
|
+
|
|
4329
|
+
Setup (recommended):
|
|
4330
|
+
# 1. Set global host and login
|
|
4331
|
+
jssm config set host http://localhost:3000
|
|
4332
|
+
jssm register # or: jssm login
|
|
4333
|
+
|
|
4334
|
+
# 2. Initialize a project directory (creates .jssm file)
|
|
4335
|
+
jssm init # Interactive mode - will prompt for project/env
|
|
4336
|
+
|
|
4337
|
+
# 3. Pull and push variables
|
|
4338
|
+
jssm pull # Download variables from backend
|
|
4339
|
+
jssm push # Upload variables from .env to backend
|
|
4340
|
+
jssm sync # Sync variables to .env file
|
|
4341
|
+
|
|
4342
|
+
Quick Start (all-in-one):
|
|
4343
|
+
# Initialize with all options (for one-off use)
|
|
4344
|
+
jssm init -p my-app -e production
|
|
4345
|
+
|
|
4346
|
+
Advanced:
|
|
4347
|
+
# Manage global configuration
|
|
4348
|
+
jssm config list
|
|
4349
|
+
jssm config set host http://api.example.com
|
|
4350
|
+
|
|
4351
|
+
# Create project and environment separately
|
|
4352
|
+
jssm project create my-app
|
|
4353
|
+
jssm env create staging -p my-app
|
|
4354
|
+
jssm env create production -p my-app
|
|
4355
|
+
|
|
4356
|
+
# List resources
|
|
4357
|
+
jssm project list
|
|
4358
|
+
jssm env list -p my-app
|
|
4359
|
+
|
|
4360
|
+
Note:
|
|
4361
|
+
- Global config (~/.jssm/config) stores host and preferences
|
|
4362
|
+
- Auth data (~/.jssm/auth) stores your login session
|
|
4363
|
+
- Project config (.jssm) stores project name and environment
|
|
4364
|
+
- Add .jssm to .gitignore (may contain sensitive overrides)
|
|
4365
|
+
|
|
4366
|
+
For more information, visit: https://github.com/yourusername/jssm
|
|
4367
|
+
`);
|
|
4368
|
+
}
|
|
4369
|
+
main().catch((error) => {
|
|
4370
|
+
console.error("Error:", error);
|
|
4371
|
+
process.exit(1);
|
|
4372
|
+
});
|