@saidulbadhon/jssm-cli 1.5.5 → 1.6.2
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 +2848 -1106
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -304,7 +304,9 @@ async function login(host, email, password) {
|
|
|
304
304
|
});
|
|
305
305
|
return { success: true };
|
|
306
306
|
} catch (error) {
|
|
307
|
-
|
|
307
|
+
const isConnectionError = error.code === "ECONNREFUSED" || error.code === "ENOTFOUND" || error.code === "ETIMEDOUT" || error.code === "ECONNRESET" || error.cause?.code === "ECONNREFUSED" || error.cause?.code === "ENOTFOUND" || error.cause?.code === "ETIMEDOUT" || error.cause?.code === "ECONNRESET" || error.message?.includes("fetch failed") || error.message?.includes("ECONNREFUSED") || error.message?.includes("ENOTFOUND");
|
|
308
|
+
const errorMessage = isConnectionError ? "Unable to connect. Is the computer able to access the url?" : error.message || "Network error";
|
|
309
|
+
return { success: false, error: errorMessage, isConnectionError };
|
|
308
310
|
}
|
|
309
311
|
}
|
|
310
312
|
async function register(host, email, password, name) {
|
|
@@ -329,7 +331,9 @@ async function register(host, email, password, name) {
|
|
|
329
331
|
});
|
|
330
332
|
return { success: true };
|
|
331
333
|
} catch (error) {
|
|
332
|
-
|
|
334
|
+
const isConnectionError = error.code === "ECONNREFUSED" || error.code === "ENOTFOUND" || error.code === "ETIMEDOUT" || error.code === "ECONNRESET" || error.cause?.code === "ECONNREFUSED" || error.cause?.code === "ENOTFOUND" || error.cause?.code === "ETIMEDOUT" || error.cause?.code === "ECONNRESET" || error.message?.includes("fetch failed") || error.message?.includes("ECONNREFUSED") || error.message?.includes("ENOTFOUND");
|
|
335
|
+
const errorMessage = isConnectionError ? "Unable to connect. Is the computer able to access the url?" : error.message || "Network error";
|
|
336
|
+
return { success: false, error: errorMessage, isConnectionError };
|
|
333
337
|
}
|
|
334
338
|
}
|
|
335
339
|
var AUTH_DIR, AUTH_FILE;
|
|
@@ -341,176 +345,1723 @@ var init_auth = __esm({
|
|
|
341
345
|
}
|
|
342
346
|
});
|
|
343
347
|
|
|
344
|
-
// node_modules
|
|
345
|
-
var
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
348
|
+
// ../node_modules/color-name/index.js
|
|
349
|
+
var require_color_name = __commonJS({
|
|
350
|
+
"../node_modules/color-name/index.js"(exports, module) {
|
|
351
|
+
"use strict";
|
|
352
|
+
module.exports = {
|
|
353
|
+
"aliceblue": [240, 248, 255],
|
|
354
|
+
"antiquewhite": [250, 235, 215],
|
|
355
|
+
"aqua": [0, 255, 255],
|
|
356
|
+
"aquamarine": [127, 255, 212],
|
|
357
|
+
"azure": [240, 255, 255],
|
|
358
|
+
"beige": [245, 245, 220],
|
|
359
|
+
"bisque": [255, 228, 196],
|
|
360
|
+
"black": [0, 0, 0],
|
|
361
|
+
"blanchedalmond": [255, 235, 205],
|
|
362
|
+
"blue": [0, 0, 255],
|
|
363
|
+
"blueviolet": [138, 43, 226],
|
|
364
|
+
"brown": [165, 42, 42],
|
|
365
|
+
"burlywood": [222, 184, 135],
|
|
366
|
+
"cadetblue": [95, 158, 160],
|
|
367
|
+
"chartreuse": [127, 255, 0],
|
|
368
|
+
"chocolate": [210, 105, 30],
|
|
369
|
+
"coral": [255, 127, 80],
|
|
370
|
+
"cornflowerblue": [100, 149, 237],
|
|
371
|
+
"cornsilk": [255, 248, 220],
|
|
372
|
+
"crimson": [220, 20, 60],
|
|
373
|
+
"cyan": [0, 255, 255],
|
|
374
|
+
"darkblue": [0, 0, 139],
|
|
375
|
+
"darkcyan": [0, 139, 139],
|
|
376
|
+
"darkgoldenrod": [184, 134, 11],
|
|
377
|
+
"darkgray": [169, 169, 169],
|
|
378
|
+
"darkgreen": [0, 100, 0],
|
|
379
|
+
"darkgrey": [169, 169, 169],
|
|
380
|
+
"darkkhaki": [189, 183, 107],
|
|
381
|
+
"darkmagenta": [139, 0, 139],
|
|
382
|
+
"darkolivegreen": [85, 107, 47],
|
|
383
|
+
"darkorange": [255, 140, 0],
|
|
384
|
+
"darkorchid": [153, 50, 204],
|
|
385
|
+
"darkred": [139, 0, 0],
|
|
386
|
+
"darksalmon": [233, 150, 122],
|
|
387
|
+
"darkseagreen": [143, 188, 143],
|
|
388
|
+
"darkslateblue": [72, 61, 139],
|
|
389
|
+
"darkslategray": [47, 79, 79],
|
|
390
|
+
"darkslategrey": [47, 79, 79],
|
|
391
|
+
"darkturquoise": [0, 206, 209],
|
|
392
|
+
"darkviolet": [148, 0, 211],
|
|
393
|
+
"deeppink": [255, 20, 147],
|
|
394
|
+
"deepskyblue": [0, 191, 255],
|
|
395
|
+
"dimgray": [105, 105, 105],
|
|
396
|
+
"dimgrey": [105, 105, 105],
|
|
397
|
+
"dodgerblue": [30, 144, 255],
|
|
398
|
+
"firebrick": [178, 34, 34],
|
|
399
|
+
"floralwhite": [255, 250, 240],
|
|
400
|
+
"forestgreen": [34, 139, 34],
|
|
401
|
+
"fuchsia": [255, 0, 255],
|
|
402
|
+
"gainsboro": [220, 220, 220],
|
|
403
|
+
"ghostwhite": [248, 248, 255],
|
|
404
|
+
"gold": [255, 215, 0],
|
|
405
|
+
"goldenrod": [218, 165, 32],
|
|
406
|
+
"gray": [128, 128, 128],
|
|
407
|
+
"green": [0, 128, 0],
|
|
408
|
+
"greenyellow": [173, 255, 47],
|
|
409
|
+
"grey": [128, 128, 128],
|
|
410
|
+
"honeydew": [240, 255, 240],
|
|
411
|
+
"hotpink": [255, 105, 180],
|
|
412
|
+
"indianred": [205, 92, 92],
|
|
413
|
+
"indigo": [75, 0, 130],
|
|
414
|
+
"ivory": [255, 255, 240],
|
|
415
|
+
"khaki": [240, 230, 140],
|
|
416
|
+
"lavender": [230, 230, 250],
|
|
417
|
+
"lavenderblush": [255, 240, 245],
|
|
418
|
+
"lawngreen": [124, 252, 0],
|
|
419
|
+
"lemonchiffon": [255, 250, 205],
|
|
420
|
+
"lightblue": [173, 216, 230],
|
|
421
|
+
"lightcoral": [240, 128, 128],
|
|
422
|
+
"lightcyan": [224, 255, 255],
|
|
423
|
+
"lightgoldenrodyellow": [250, 250, 210],
|
|
424
|
+
"lightgray": [211, 211, 211],
|
|
425
|
+
"lightgreen": [144, 238, 144],
|
|
426
|
+
"lightgrey": [211, 211, 211],
|
|
427
|
+
"lightpink": [255, 182, 193],
|
|
428
|
+
"lightsalmon": [255, 160, 122],
|
|
429
|
+
"lightseagreen": [32, 178, 170],
|
|
430
|
+
"lightskyblue": [135, 206, 250],
|
|
431
|
+
"lightslategray": [119, 136, 153],
|
|
432
|
+
"lightslategrey": [119, 136, 153],
|
|
433
|
+
"lightsteelblue": [176, 196, 222],
|
|
434
|
+
"lightyellow": [255, 255, 224],
|
|
435
|
+
"lime": [0, 255, 0],
|
|
436
|
+
"limegreen": [50, 205, 50],
|
|
437
|
+
"linen": [250, 240, 230],
|
|
438
|
+
"magenta": [255, 0, 255],
|
|
439
|
+
"maroon": [128, 0, 0],
|
|
440
|
+
"mediumaquamarine": [102, 205, 170],
|
|
441
|
+
"mediumblue": [0, 0, 205],
|
|
442
|
+
"mediumorchid": [186, 85, 211],
|
|
443
|
+
"mediumpurple": [147, 112, 219],
|
|
444
|
+
"mediumseagreen": [60, 179, 113],
|
|
445
|
+
"mediumslateblue": [123, 104, 238],
|
|
446
|
+
"mediumspringgreen": [0, 250, 154],
|
|
447
|
+
"mediumturquoise": [72, 209, 204],
|
|
448
|
+
"mediumvioletred": [199, 21, 133],
|
|
449
|
+
"midnightblue": [25, 25, 112],
|
|
450
|
+
"mintcream": [245, 255, 250],
|
|
451
|
+
"mistyrose": [255, 228, 225],
|
|
452
|
+
"moccasin": [255, 228, 181],
|
|
453
|
+
"navajowhite": [255, 222, 173],
|
|
454
|
+
"navy": [0, 0, 128],
|
|
455
|
+
"oldlace": [253, 245, 230],
|
|
456
|
+
"olive": [128, 128, 0],
|
|
457
|
+
"olivedrab": [107, 142, 35],
|
|
458
|
+
"orange": [255, 165, 0],
|
|
459
|
+
"orangered": [255, 69, 0],
|
|
460
|
+
"orchid": [218, 112, 214],
|
|
461
|
+
"palegoldenrod": [238, 232, 170],
|
|
462
|
+
"palegreen": [152, 251, 152],
|
|
463
|
+
"paleturquoise": [175, 238, 238],
|
|
464
|
+
"palevioletred": [219, 112, 147],
|
|
465
|
+
"papayawhip": [255, 239, 213],
|
|
466
|
+
"peachpuff": [255, 218, 185],
|
|
467
|
+
"peru": [205, 133, 63],
|
|
468
|
+
"pink": [255, 192, 203],
|
|
469
|
+
"plum": [221, 160, 221],
|
|
470
|
+
"powderblue": [176, 224, 230],
|
|
471
|
+
"purple": [128, 0, 128],
|
|
472
|
+
"rebeccapurple": [102, 51, 153],
|
|
473
|
+
"red": [255, 0, 0],
|
|
474
|
+
"rosybrown": [188, 143, 143],
|
|
475
|
+
"royalblue": [65, 105, 225],
|
|
476
|
+
"saddlebrown": [139, 69, 19],
|
|
477
|
+
"salmon": [250, 128, 114],
|
|
478
|
+
"sandybrown": [244, 164, 96],
|
|
479
|
+
"seagreen": [46, 139, 87],
|
|
480
|
+
"seashell": [255, 245, 238],
|
|
481
|
+
"sienna": [160, 82, 45],
|
|
482
|
+
"silver": [192, 192, 192],
|
|
483
|
+
"skyblue": [135, 206, 235],
|
|
484
|
+
"slateblue": [106, 90, 205],
|
|
485
|
+
"slategray": [112, 128, 144],
|
|
486
|
+
"slategrey": [112, 128, 144],
|
|
487
|
+
"snow": [255, 250, 250],
|
|
488
|
+
"springgreen": [0, 255, 127],
|
|
489
|
+
"steelblue": [70, 130, 180],
|
|
490
|
+
"tan": [210, 180, 140],
|
|
491
|
+
"teal": [0, 128, 128],
|
|
492
|
+
"thistle": [216, 191, 216],
|
|
493
|
+
"tomato": [255, 99, 71],
|
|
494
|
+
"turquoise": [64, 224, 208],
|
|
495
|
+
"violet": [238, 130, 238],
|
|
496
|
+
"wheat": [245, 222, 179],
|
|
497
|
+
"white": [255, 255, 255],
|
|
498
|
+
"whitesmoke": [245, 245, 245],
|
|
499
|
+
"yellow": [255, 255, 0],
|
|
500
|
+
"yellowgreen": [154, 205, 50]
|
|
501
|
+
};
|
|
370
502
|
}
|
|
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";
|
|
503
|
+
});
|
|
388
504
|
|
|
389
|
-
// node_modules
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
hooksCleanup: [],
|
|
397
|
-
hooksEffect: [],
|
|
398
|
-
index: 0,
|
|
399
|
-
handleChange() {
|
|
505
|
+
// ../node_modules/color-convert/conversions.js
|
|
506
|
+
var require_conversions = __commonJS({
|
|
507
|
+
"../node_modules/color-convert/conversions.js"(exports, module) {
|
|
508
|
+
var cssKeywords = require_color_name();
|
|
509
|
+
var reverseKeywords = {};
|
|
510
|
+
for (const key of Object.keys(cssKeywords)) {
|
|
511
|
+
reverseKeywords[cssKeywords[key]] = key;
|
|
400
512
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
}
|
|
412
|
-
|
|
513
|
+
var convert = {
|
|
514
|
+
rgb: { channels: 3, labels: "rgb" },
|
|
515
|
+
hsl: { channels: 3, labels: "hsl" },
|
|
516
|
+
hsv: { channels: 3, labels: "hsv" },
|
|
517
|
+
hwb: { channels: 3, labels: "hwb" },
|
|
518
|
+
cmyk: { channels: 4, labels: "cmyk" },
|
|
519
|
+
xyz: { channels: 3, labels: "xyz" },
|
|
520
|
+
lab: { channels: 3, labels: "lab" },
|
|
521
|
+
lch: { channels: 3, labels: "lch" },
|
|
522
|
+
hex: { channels: 1, labels: ["hex"] },
|
|
523
|
+
keyword: { channels: 1, labels: ["keyword"] },
|
|
524
|
+
ansi16: { channels: 1, labels: ["ansi16"] },
|
|
525
|
+
ansi256: { channels: 1, labels: ["ansi256"] },
|
|
526
|
+
hcg: { channels: 3, labels: ["h", "c", "g"] },
|
|
527
|
+
apple: { channels: 3, labels: ["r16", "g16", "b16"] },
|
|
528
|
+
gray: { channels: 1, labels: ["gray"] }
|
|
529
|
+
};
|
|
530
|
+
module.exports = convert;
|
|
531
|
+
for (const model of Object.keys(convert)) {
|
|
532
|
+
if (!("channels" in convert[model])) {
|
|
533
|
+
throw new Error("missing channels property: " + model);
|
|
534
|
+
}
|
|
535
|
+
if (!("labels" in convert[model])) {
|
|
536
|
+
throw new Error("missing channel labels property: " + model);
|
|
537
|
+
}
|
|
538
|
+
if (convert[model].labels.length !== convert[model].channels) {
|
|
539
|
+
throw new Error("channel and label counts mismatch: " + model);
|
|
540
|
+
}
|
|
541
|
+
const { channels, labels } = convert[model];
|
|
542
|
+
delete convert[model].channels;
|
|
543
|
+
delete convert[model].labels;
|
|
544
|
+
Object.defineProperty(convert[model], "channels", { value: channels });
|
|
545
|
+
Object.defineProperty(convert[model], "labels", { value: labels });
|
|
413
546
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
547
|
+
convert.rgb.hsl = function(rgb) {
|
|
548
|
+
const r = rgb[0] / 255;
|
|
549
|
+
const g = rgb[1] / 255;
|
|
550
|
+
const b = rgb[2] / 255;
|
|
551
|
+
const min = Math.min(r, g, b);
|
|
552
|
+
const max = Math.max(r, g, b);
|
|
553
|
+
const delta = max - min;
|
|
554
|
+
let h;
|
|
555
|
+
let s;
|
|
556
|
+
if (max === min) {
|
|
557
|
+
h = 0;
|
|
558
|
+
} else if (r === max) {
|
|
559
|
+
h = (g - b) / delta;
|
|
560
|
+
} else if (g === max) {
|
|
561
|
+
h = 2 + (b - r) / delta;
|
|
562
|
+
} else if (b === max) {
|
|
563
|
+
h = 4 + (r - g) / delta;
|
|
564
|
+
}
|
|
565
|
+
h = Math.min(h * 60, 360);
|
|
566
|
+
if (h < 0) {
|
|
567
|
+
h += 360;
|
|
568
|
+
}
|
|
569
|
+
const l = (min + max) / 2;
|
|
570
|
+
if (max === min) {
|
|
571
|
+
s = 0;
|
|
572
|
+
} else if (l <= 0.5) {
|
|
573
|
+
s = delta / (max + min);
|
|
574
|
+
} else {
|
|
575
|
+
s = delta / (2 - max - min);
|
|
576
|
+
}
|
|
577
|
+
return [h, s * 100, l * 100];
|
|
434
578
|
};
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
579
|
+
convert.rgb.hsv = function(rgb) {
|
|
580
|
+
let rdif;
|
|
581
|
+
let gdif;
|
|
582
|
+
let bdif;
|
|
583
|
+
let h;
|
|
584
|
+
let s;
|
|
585
|
+
const r = rgb[0] / 255;
|
|
586
|
+
const g = rgb[1] / 255;
|
|
587
|
+
const b = rgb[2] / 255;
|
|
588
|
+
const v = Math.max(r, g, b);
|
|
589
|
+
const diff = v - Math.min(r, g, b);
|
|
590
|
+
const diffc = function(c) {
|
|
591
|
+
return (v - c) / 6 / diff + 1 / 2;
|
|
592
|
+
};
|
|
593
|
+
if (diff === 0) {
|
|
594
|
+
h = 0;
|
|
595
|
+
s = 0;
|
|
596
|
+
} else {
|
|
597
|
+
s = diff / v;
|
|
598
|
+
rdif = diffc(r);
|
|
599
|
+
gdif = diffc(g);
|
|
600
|
+
bdif = diffc(b);
|
|
601
|
+
if (r === v) {
|
|
602
|
+
h = bdif - gdif;
|
|
603
|
+
} else if (g === v) {
|
|
604
|
+
h = 1 / 3 + rdif - bdif;
|
|
605
|
+
} else if (b === v) {
|
|
606
|
+
h = 2 / 3 + gdif - rdif;
|
|
607
|
+
}
|
|
608
|
+
if (h < 0) {
|
|
609
|
+
h += 1;
|
|
610
|
+
} else if (h > 1) {
|
|
611
|
+
h -= 1;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
return [
|
|
615
|
+
h * 360,
|
|
616
|
+
s * 100,
|
|
617
|
+
v * 100
|
|
618
|
+
];
|
|
619
|
+
};
|
|
620
|
+
convert.rgb.hwb = function(rgb) {
|
|
621
|
+
const r = rgb[0];
|
|
622
|
+
const g = rgb[1];
|
|
623
|
+
let b = rgb[2];
|
|
624
|
+
const h = convert.rgb.hsl(rgb)[0];
|
|
625
|
+
const w = 1 / 255 * Math.min(r, Math.min(g, b));
|
|
626
|
+
b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
|
|
627
|
+
return [h, w * 100, b * 100];
|
|
628
|
+
};
|
|
629
|
+
convert.rgb.cmyk = function(rgb) {
|
|
630
|
+
const r = rgb[0] / 255;
|
|
631
|
+
const g = rgb[1] / 255;
|
|
632
|
+
const b = rgb[2] / 255;
|
|
633
|
+
const k = Math.min(1 - r, 1 - g, 1 - b);
|
|
634
|
+
const c = (1 - r - k) / (1 - k) || 0;
|
|
635
|
+
const m = (1 - g - k) / (1 - k) || 0;
|
|
636
|
+
const y = (1 - b - k) / (1 - k) || 0;
|
|
637
|
+
return [c * 100, m * 100, y * 100, k * 100];
|
|
638
|
+
};
|
|
639
|
+
function comparativeDistance(x, y) {
|
|
640
|
+
return (x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2 + (x[2] - y[2]) ** 2;
|
|
438
641
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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.");
|
|
642
|
+
convert.rgb.keyword = function(rgb) {
|
|
643
|
+
const reversed = reverseKeywords[rgb];
|
|
644
|
+
if (reversed) {
|
|
645
|
+
return reversed;
|
|
472
646
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
647
|
+
let currentClosestDistance = Infinity;
|
|
648
|
+
let currentClosestKeyword;
|
|
649
|
+
for (const keyword of Object.keys(cssKeywords)) {
|
|
650
|
+
const value = cssKeywords[keyword];
|
|
651
|
+
const distance = comparativeDistance(rgb, value);
|
|
652
|
+
if (distance < currentClosestDistance) {
|
|
653
|
+
currentClosestDistance = distance;
|
|
654
|
+
currentClosestKeyword = keyword;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
return currentClosestKeyword;
|
|
658
|
+
};
|
|
659
|
+
convert.keyword.rgb = function(keyword) {
|
|
660
|
+
return cssKeywords[keyword];
|
|
661
|
+
};
|
|
662
|
+
convert.rgb.xyz = function(rgb) {
|
|
663
|
+
let r = rgb[0] / 255;
|
|
664
|
+
let g = rgb[1] / 255;
|
|
665
|
+
let b = rgb[2] / 255;
|
|
666
|
+
r = r > 0.04045 ? ((r + 0.055) / 1.055) ** 2.4 : r / 12.92;
|
|
667
|
+
g = g > 0.04045 ? ((g + 0.055) / 1.055) ** 2.4 : g / 12.92;
|
|
668
|
+
b = b > 0.04045 ? ((b + 0.055) / 1.055) ** 2.4 : b / 12.92;
|
|
669
|
+
const x = r * 0.4124 + g * 0.3576 + b * 0.1805;
|
|
670
|
+
const y = r * 0.2126 + g * 0.7152 + b * 0.0722;
|
|
671
|
+
const z = r * 0.0193 + g * 0.1192 + b * 0.9505;
|
|
672
|
+
return [x * 100, y * 100, z * 100];
|
|
673
|
+
};
|
|
674
|
+
convert.rgb.lab = function(rgb) {
|
|
675
|
+
const xyz = convert.rgb.xyz(rgb);
|
|
676
|
+
let x = xyz[0];
|
|
677
|
+
let y = xyz[1];
|
|
678
|
+
let z = xyz[2];
|
|
679
|
+
x /= 95.047;
|
|
680
|
+
y /= 100;
|
|
681
|
+
z /= 108.883;
|
|
682
|
+
x = x > 8856e-6 ? x ** (1 / 3) : 7.787 * x + 16 / 116;
|
|
683
|
+
y = y > 8856e-6 ? y ** (1 / 3) : 7.787 * y + 16 / 116;
|
|
684
|
+
z = z > 8856e-6 ? z ** (1 / 3) : 7.787 * z + 16 / 116;
|
|
685
|
+
const l = 116 * y - 16;
|
|
686
|
+
const a = 500 * (x - y);
|
|
687
|
+
const b = 200 * (y - z);
|
|
688
|
+
return [l, a, b];
|
|
689
|
+
};
|
|
690
|
+
convert.hsl.rgb = function(hsl) {
|
|
691
|
+
const h = hsl[0] / 360;
|
|
692
|
+
const s = hsl[1] / 100;
|
|
693
|
+
const l = hsl[2] / 100;
|
|
694
|
+
let t2;
|
|
695
|
+
let t3;
|
|
696
|
+
let val;
|
|
697
|
+
if (s === 0) {
|
|
698
|
+
val = l * 255;
|
|
699
|
+
return [val, val, val];
|
|
700
|
+
}
|
|
701
|
+
if (l < 0.5) {
|
|
702
|
+
t2 = l * (1 + s);
|
|
703
|
+
} else {
|
|
704
|
+
t2 = l + s - l * s;
|
|
705
|
+
}
|
|
706
|
+
const t1 = 2 * l - t2;
|
|
707
|
+
const rgb = [0, 0, 0];
|
|
708
|
+
for (let i = 0; i < 3; i++) {
|
|
709
|
+
t3 = h + 1 / 3 * -(i - 1);
|
|
710
|
+
if (t3 < 0) {
|
|
711
|
+
t3++;
|
|
712
|
+
}
|
|
713
|
+
if (t3 > 1) {
|
|
714
|
+
t3--;
|
|
715
|
+
}
|
|
716
|
+
if (6 * t3 < 1) {
|
|
717
|
+
val = t1 + (t2 - t1) * 6 * t3;
|
|
718
|
+
} else if (2 * t3 < 1) {
|
|
719
|
+
val = t2;
|
|
720
|
+
} else if (3 * t3 < 2) {
|
|
721
|
+
val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
|
|
722
|
+
} else {
|
|
723
|
+
val = t1;
|
|
724
|
+
}
|
|
725
|
+
rgb[i] = val * 255;
|
|
726
|
+
}
|
|
727
|
+
return rgb;
|
|
728
|
+
};
|
|
729
|
+
convert.hsl.hsv = function(hsl) {
|
|
730
|
+
const h = hsl[0];
|
|
731
|
+
let s = hsl[1] / 100;
|
|
732
|
+
let l = hsl[2] / 100;
|
|
733
|
+
let smin = s;
|
|
734
|
+
const lmin = Math.max(l, 0.01);
|
|
735
|
+
l *= 2;
|
|
736
|
+
s *= l <= 1 ? l : 2 - l;
|
|
737
|
+
smin *= lmin <= 1 ? lmin : 2 - lmin;
|
|
738
|
+
const v = (l + s) / 2;
|
|
739
|
+
const sv = l === 0 ? 2 * smin / (lmin + smin) : 2 * s / (l + s);
|
|
740
|
+
return [h, sv * 100, v * 100];
|
|
741
|
+
};
|
|
742
|
+
convert.hsv.rgb = function(hsv) {
|
|
743
|
+
const h = hsv[0] / 60;
|
|
744
|
+
const s = hsv[1] / 100;
|
|
745
|
+
let v = hsv[2] / 100;
|
|
746
|
+
const hi = Math.floor(h) % 6;
|
|
747
|
+
const f = h - Math.floor(h);
|
|
748
|
+
const p = 255 * v * (1 - s);
|
|
749
|
+
const q = 255 * v * (1 - s * f);
|
|
750
|
+
const t = 255 * v * (1 - s * (1 - f));
|
|
751
|
+
v *= 255;
|
|
752
|
+
switch (hi) {
|
|
753
|
+
case 0:
|
|
754
|
+
return [v, t, p];
|
|
755
|
+
case 1:
|
|
756
|
+
return [q, v, p];
|
|
757
|
+
case 2:
|
|
758
|
+
return [p, v, t];
|
|
759
|
+
case 3:
|
|
760
|
+
return [p, q, v];
|
|
761
|
+
case 4:
|
|
762
|
+
return [t, p, v];
|
|
763
|
+
case 5:
|
|
764
|
+
return [v, p, q];
|
|
765
|
+
}
|
|
766
|
+
};
|
|
767
|
+
convert.hsv.hsl = function(hsv) {
|
|
768
|
+
const h = hsv[0];
|
|
769
|
+
const s = hsv[1] / 100;
|
|
770
|
+
const v = hsv[2] / 100;
|
|
771
|
+
const vmin = Math.max(v, 0.01);
|
|
772
|
+
let sl;
|
|
773
|
+
let l;
|
|
774
|
+
l = (2 - s) * v;
|
|
775
|
+
const lmin = (2 - s) * vmin;
|
|
776
|
+
sl = s * vmin;
|
|
777
|
+
sl /= lmin <= 1 ? lmin : 2 - lmin;
|
|
778
|
+
sl = sl || 0;
|
|
779
|
+
l /= 2;
|
|
780
|
+
return [h, sl * 100, l * 100];
|
|
781
|
+
};
|
|
782
|
+
convert.hwb.rgb = function(hwb) {
|
|
783
|
+
const h = hwb[0] / 360;
|
|
784
|
+
let wh = hwb[1] / 100;
|
|
785
|
+
let bl = hwb[2] / 100;
|
|
786
|
+
const ratio = wh + bl;
|
|
787
|
+
let f;
|
|
788
|
+
if (ratio > 1) {
|
|
789
|
+
wh /= ratio;
|
|
790
|
+
bl /= ratio;
|
|
791
|
+
}
|
|
792
|
+
const i = Math.floor(6 * h);
|
|
793
|
+
const v = 1 - bl;
|
|
794
|
+
f = 6 * h - i;
|
|
795
|
+
if ((i & 1) !== 0) {
|
|
796
|
+
f = 1 - f;
|
|
797
|
+
}
|
|
798
|
+
const n = wh + f * (v - wh);
|
|
799
|
+
let r;
|
|
800
|
+
let g;
|
|
801
|
+
let b;
|
|
802
|
+
switch (i) {
|
|
803
|
+
default:
|
|
804
|
+
case 6:
|
|
805
|
+
case 0:
|
|
806
|
+
r = v;
|
|
807
|
+
g = n;
|
|
808
|
+
b = wh;
|
|
809
|
+
break;
|
|
810
|
+
case 1:
|
|
811
|
+
r = n;
|
|
812
|
+
g = v;
|
|
813
|
+
b = wh;
|
|
814
|
+
break;
|
|
815
|
+
case 2:
|
|
816
|
+
r = wh;
|
|
817
|
+
g = v;
|
|
818
|
+
b = n;
|
|
819
|
+
break;
|
|
820
|
+
case 3:
|
|
821
|
+
r = wh;
|
|
822
|
+
g = n;
|
|
823
|
+
b = v;
|
|
824
|
+
break;
|
|
825
|
+
case 4:
|
|
826
|
+
r = n;
|
|
827
|
+
g = wh;
|
|
828
|
+
b = v;
|
|
829
|
+
break;
|
|
830
|
+
case 5:
|
|
831
|
+
r = v;
|
|
832
|
+
g = wh;
|
|
833
|
+
b = n;
|
|
834
|
+
break;
|
|
835
|
+
}
|
|
836
|
+
return [r * 255, g * 255, b * 255];
|
|
837
|
+
};
|
|
838
|
+
convert.cmyk.rgb = function(cmyk) {
|
|
839
|
+
const c = cmyk[0] / 100;
|
|
840
|
+
const m = cmyk[1] / 100;
|
|
841
|
+
const y = cmyk[2] / 100;
|
|
842
|
+
const k = cmyk[3] / 100;
|
|
843
|
+
const r = 1 - Math.min(1, c * (1 - k) + k);
|
|
844
|
+
const g = 1 - Math.min(1, m * (1 - k) + k);
|
|
845
|
+
const b = 1 - Math.min(1, y * (1 - k) + k);
|
|
846
|
+
return [r * 255, g * 255, b * 255];
|
|
847
|
+
};
|
|
848
|
+
convert.xyz.rgb = function(xyz) {
|
|
849
|
+
const x = xyz[0] / 100;
|
|
850
|
+
const y = xyz[1] / 100;
|
|
851
|
+
const z = xyz[2] / 100;
|
|
852
|
+
let r;
|
|
853
|
+
let g;
|
|
854
|
+
let b;
|
|
855
|
+
r = x * 3.2406 + y * -1.5372 + z * -0.4986;
|
|
856
|
+
g = x * -0.9689 + y * 1.8758 + z * 0.0415;
|
|
857
|
+
b = x * 0.0557 + y * -0.204 + z * 1.057;
|
|
858
|
+
r = r > 31308e-7 ? 1.055 * r ** (1 / 2.4) - 0.055 : r * 12.92;
|
|
859
|
+
g = g > 31308e-7 ? 1.055 * g ** (1 / 2.4) - 0.055 : g * 12.92;
|
|
860
|
+
b = b > 31308e-7 ? 1.055 * b ** (1 / 2.4) - 0.055 : b * 12.92;
|
|
861
|
+
r = Math.min(Math.max(0, r), 1);
|
|
862
|
+
g = Math.min(Math.max(0, g), 1);
|
|
863
|
+
b = Math.min(Math.max(0, b), 1);
|
|
864
|
+
return [r * 255, g * 255, b * 255];
|
|
865
|
+
};
|
|
866
|
+
convert.xyz.lab = function(xyz) {
|
|
867
|
+
let x = xyz[0];
|
|
868
|
+
let y = xyz[1];
|
|
869
|
+
let z = xyz[2];
|
|
870
|
+
x /= 95.047;
|
|
871
|
+
y /= 100;
|
|
872
|
+
z /= 108.883;
|
|
873
|
+
x = x > 8856e-6 ? x ** (1 / 3) : 7.787 * x + 16 / 116;
|
|
874
|
+
y = y > 8856e-6 ? y ** (1 / 3) : 7.787 * y + 16 / 116;
|
|
875
|
+
z = z > 8856e-6 ? z ** (1 / 3) : 7.787 * z + 16 / 116;
|
|
876
|
+
const l = 116 * y - 16;
|
|
877
|
+
const a = 500 * (x - y);
|
|
878
|
+
const b = 200 * (y - z);
|
|
879
|
+
return [l, a, b];
|
|
880
|
+
};
|
|
881
|
+
convert.lab.xyz = function(lab) {
|
|
882
|
+
const l = lab[0];
|
|
883
|
+
const a = lab[1];
|
|
884
|
+
const b = lab[2];
|
|
885
|
+
let x;
|
|
886
|
+
let y;
|
|
887
|
+
let z;
|
|
888
|
+
y = (l + 16) / 116;
|
|
889
|
+
x = a / 500 + y;
|
|
890
|
+
z = y - b / 200;
|
|
891
|
+
const y2 = y ** 3;
|
|
892
|
+
const x2 = x ** 3;
|
|
893
|
+
const z2 = z ** 3;
|
|
894
|
+
y = y2 > 8856e-6 ? y2 : (y - 16 / 116) / 7.787;
|
|
895
|
+
x = x2 > 8856e-6 ? x2 : (x - 16 / 116) / 7.787;
|
|
896
|
+
z = z2 > 8856e-6 ? z2 : (z - 16 / 116) / 7.787;
|
|
897
|
+
x *= 95.047;
|
|
898
|
+
y *= 100;
|
|
899
|
+
z *= 108.883;
|
|
900
|
+
return [x, y, z];
|
|
901
|
+
};
|
|
902
|
+
convert.lab.lch = function(lab) {
|
|
903
|
+
const l = lab[0];
|
|
904
|
+
const a = lab[1];
|
|
905
|
+
const b = lab[2];
|
|
906
|
+
let h;
|
|
907
|
+
const hr = Math.atan2(b, a);
|
|
908
|
+
h = hr * 360 / 2 / Math.PI;
|
|
909
|
+
if (h < 0) {
|
|
910
|
+
h += 360;
|
|
911
|
+
}
|
|
912
|
+
const c = Math.sqrt(a * a + b * b);
|
|
913
|
+
return [l, c, h];
|
|
914
|
+
};
|
|
915
|
+
convert.lch.lab = function(lch) {
|
|
916
|
+
const l = lch[0];
|
|
917
|
+
const c = lch[1];
|
|
918
|
+
const h = lch[2];
|
|
919
|
+
const hr = h / 360 * 2 * Math.PI;
|
|
920
|
+
const a = c * Math.cos(hr);
|
|
921
|
+
const b = c * Math.sin(hr);
|
|
922
|
+
return [l, a, b];
|
|
923
|
+
};
|
|
924
|
+
convert.rgb.ansi16 = function(args2, saturation = null) {
|
|
925
|
+
const [r, g, b] = args2;
|
|
926
|
+
let value = saturation === null ? convert.rgb.hsv(args2)[2] : saturation;
|
|
927
|
+
value = Math.round(value / 50);
|
|
928
|
+
if (value === 0) {
|
|
929
|
+
return 30;
|
|
930
|
+
}
|
|
931
|
+
let ansi = 30 + (Math.round(b / 255) << 2 | Math.round(g / 255) << 1 | Math.round(r / 255));
|
|
932
|
+
if (value === 2) {
|
|
933
|
+
ansi += 60;
|
|
934
|
+
}
|
|
935
|
+
return ansi;
|
|
936
|
+
};
|
|
937
|
+
convert.hsv.ansi16 = function(args2) {
|
|
938
|
+
return convert.rgb.ansi16(convert.hsv.rgb(args2), args2[2]);
|
|
939
|
+
};
|
|
940
|
+
convert.rgb.ansi256 = function(args2) {
|
|
941
|
+
const r = args2[0];
|
|
942
|
+
const g = args2[1];
|
|
943
|
+
const b = args2[2];
|
|
944
|
+
if (r === g && g === b) {
|
|
945
|
+
if (r < 8) {
|
|
946
|
+
return 16;
|
|
947
|
+
}
|
|
948
|
+
if (r > 248) {
|
|
949
|
+
return 231;
|
|
950
|
+
}
|
|
951
|
+
return Math.round((r - 8) / 247 * 24) + 232;
|
|
952
|
+
}
|
|
953
|
+
const ansi = 16 + 36 * Math.round(r / 255 * 5) + 6 * Math.round(g / 255 * 5) + Math.round(b / 255 * 5);
|
|
954
|
+
return ansi;
|
|
955
|
+
};
|
|
956
|
+
convert.ansi16.rgb = function(args2) {
|
|
957
|
+
let color = args2 % 10;
|
|
958
|
+
if (color === 0 || color === 7) {
|
|
959
|
+
if (args2 > 50) {
|
|
960
|
+
color += 3.5;
|
|
961
|
+
}
|
|
962
|
+
color = color / 10.5 * 255;
|
|
963
|
+
return [color, color, color];
|
|
964
|
+
}
|
|
965
|
+
const mult = (~~(args2 > 50) + 1) * 0.5;
|
|
966
|
+
const r = (color & 1) * mult * 255;
|
|
967
|
+
const g = (color >> 1 & 1) * mult * 255;
|
|
968
|
+
const b = (color >> 2 & 1) * mult * 255;
|
|
969
|
+
return [r, g, b];
|
|
970
|
+
};
|
|
971
|
+
convert.ansi256.rgb = function(args2) {
|
|
972
|
+
if (args2 >= 232) {
|
|
973
|
+
const c = (args2 - 232) * 10 + 8;
|
|
974
|
+
return [c, c, c];
|
|
975
|
+
}
|
|
976
|
+
args2 -= 16;
|
|
977
|
+
let rem;
|
|
978
|
+
const r = Math.floor(args2 / 36) / 5 * 255;
|
|
979
|
+
const g = Math.floor((rem = args2 % 36) / 6) / 5 * 255;
|
|
980
|
+
const b = rem % 6 / 5 * 255;
|
|
981
|
+
return [r, g, b];
|
|
982
|
+
};
|
|
983
|
+
convert.rgb.hex = function(args2) {
|
|
984
|
+
const integer = ((Math.round(args2[0]) & 255) << 16) + ((Math.round(args2[1]) & 255) << 8) + (Math.round(args2[2]) & 255);
|
|
985
|
+
const string = integer.toString(16).toUpperCase();
|
|
986
|
+
return "000000".substring(string.length) + string;
|
|
987
|
+
};
|
|
988
|
+
convert.hex.rgb = function(args2) {
|
|
989
|
+
const match = args2.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
|
|
990
|
+
if (!match) {
|
|
991
|
+
return [0, 0, 0];
|
|
992
|
+
}
|
|
993
|
+
let colorString = match[0];
|
|
994
|
+
if (match[0].length === 3) {
|
|
995
|
+
colorString = colorString.split("").map((char) => {
|
|
996
|
+
return char + char;
|
|
997
|
+
}).join("");
|
|
998
|
+
}
|
|
999
|
+
const integer = parseInt(colorString, 16);
|
|
1000
|
+
const r = integer >> 16 & 255;
|
|
1001
|
+
const g = integer >> 8 & 255;
|
|
1002
|
+
const b = integer & 255;
|
|
1003
|
+
return [r, g, b];
|
|
1004
|
+
};
|
|
1005
|
+
convert.rgb.hcg = function(rgb) {
|
|
1006
|
+
const r = rgb[0] / 255;
|
|
1007
|
+
const g = rgb[1] / 255;
|
|
1008
|
+
const b = rgb[2] / 255;
|
|
1009
|
+
const max = Math.max(Math.max(r, g), b);
|
|
1010
|
+
const min = Math.min(Math.min(r, g), b);
|
|
1011
|
+
const chroma = max - min;
|
|
1012
|
+
let grayscale;
|
|
1013
|
+
let hue;
|
|
1014
|
+
if (chroma < 1) {
|
|
1015
|
+
grayscale = min / (1 - chroma);
|
|
1016
|
+
} else {
|
|
1017
|
+
grayscale = 0;
|
|
1018
|
+
}
|
|
1019
|
+
if (chroma <= 0) {
|
|
1020
|
+
hue = 0;
|
|
1021
|
+
} else if (max === r) {
|
|
1022
|
+
hue = (g - b) / chroma % 6;
|
|
1023
|
+
} else if (max === g) {
|
|
1024
|
+
hue = 2 + (b - r) / chroma;
|
|
1025
|
+
} else {
|
|
1026
|
+
hue = 4 + (r - g) / chroma;
|
|
1027
|
+
}
|
|
1028
|
+
hue /= 6;
|
|
1029
|
+
hue %= 1;
|
|
1030
|
+
return [hue * 360, chroma * 100, grayscale * 100];
|
|
1031
|
+
};
|
|
1032
|
+
convert.hsl.hcg = function(hsl) {
|
|
1033
|
+
const s = hsl[1] / 100;
|
|
1034
|
+
const l = hsl[2] / 100;
|
|
1035
|
+
const c = l < 0.5 ? 2 * s * l : 2 * s * (1 - l);
|
|
1036
|
+
let f = 0;
|
|
1037
|
+
if (c < 1) {
|
|
1038
|
+
f = (l - 0.5 * c) / (1 - c);
|
|
1039
|
+
}
|
|
1040
|
+
return [hsl[0], c * 100, f * 100];
|
|
1041
|
+
};
|
|
1042
|
+
convert.hsv.hcg = function(hsv) {
|
|
1043
|
+
const s = hsv[1] / 100;
|
|
1044
|
+
const v = hsv[2] / 100;
|
|
1045
|
+
const c = s * v;
|
|
1046
|
+
let f = 0;
|
|
1047
|
+
if (c < 1) {
|
|
1048
|
+
f = (v - c) / (1 - c);
|
|
1049
|
+
}
|
|
1050
|
+
return [hsv[0], c * 100, f * 100];
|
|
1051
|
+
};
|
|
1052
|
+
convert.hcg.rgb = function(hcg) {
|
|
1053
|
+
const h = hcg[0] / 360;
|
|
1054
|
+
const c = hcg[1] / 100;
|
|
1055
|
+
const g = hcg[2] / 100;
|
|
1056
|
+
if (c === 0) {
|
|
1057
|
+
return [g * 255, g * 255, g * 255];
|
|
1058
|
+
}
|
|
1059
|
+
const pure = [0, 0, 0];
|
|
1060
|
+
const hi = h % 1 * 6;
|
|
1061
|
+
const v = hi % 1;
|
|
1062
|
+
const w = 1 - v;
|
|
1063
|
+
let mg = 0;
|
|
1064
|
+
switch (Math.floor(hi)) {
|
|
1065
|
+
case 0:
|
|
1066
|
+
pure[0] = 1;
|
|
1067
|
+
pure[1] = v;
|
|
1068
|
+
pure[2] = 0;
|
|
1069
|
+
break;
|
|
1070
|
+
case 1:
|
|
1071
|
+
pure[0] = w;
|
|
1072
|
+
pure[1] = 1;
|
|
1073
|
+
pure[2] = 0;
|
|
1074
|
+
break;
|
|
1075
|
+
case 2:
|
|
1076
|
+
pure[0] = 0;
|
|
1077
|
+
pure[1] = 1;
|
|
1078
|
+
pure[2] = v;
|
|
1079
|
+
break;
|
|
1080
|
+
case 3:
|
|
1081
|
+
pure[0] = 0;
|
|
1082
|
+
pure[1] = w;
|
|
1083
|
+
pure[2] = 1;
|
|
1084
|
+
break;
|
|
1085
|
+
case 4:
|
|
1086
|
+
pure[0] = v;
|
|
1087
|
+
pure[1] = 0;
|
|
1088
|
+
pure[2] = 1;
|
|
1089
|
+
break;
|
|
1090
|
+
default:
|
|
1091
|
+
pure[0] = 1;
|
|
1092
|
+
pure[1] = 0;
|
|
1093
|
+
pure[2] = w;
|
|
1094
|
+
}
|
|
1095
|
+
mg = (1 - c) * g;
|
|
1096
|
+
return [
|
|
1097
|
+
(c * pure[0] + mg) * 255,
|
|
1098
|
+
(c * pure[1] + mg) * 255,
|
|
1099
|
+
(c * pure[2] + mg) * 255
|
|
1100
|
+
];
|
|
1101
|
+
};
|
|
1102
|
+
convert.hcg.hsv = function(hcg) {
|
|
1103
|
+
const c = hcg[1] / 100;
|
|
1104
|
+
const g = hcg[2] / 100;
|
|
1105
|
+
const v = c + g * (1 - c);
|
|
1106
|
+
let f = 0;
|
|
1107
|
+
if (v > 0) {
|
|
1108
|
+
f = c / v;
|
|
1109
|
+
}
|
|
1110
|
+
return [hcg[0], f * 100, v * 100];
|
|
1111
|
+
};
|
|
1112
|
+
convert.hcg.hsl = function(hcg) {
|
|
1113
|
+
const c = hcg[1] / 100;
|
|
1114
|
+
const g = hcg[2] / 100;
|
|
1115
|
+
const l = g * (1 - c) + 0.5 * c;
|
|
1116
|
+
let s = 0;
|
|
1117
|
+
if (l > 0 && l < 0.5) {
|
|
1118
|
+
s = c / (2 * l);
|
|
1119
|
+
} else if (l >= 0.5 && l < 1) {
|
|
1120
|
+
s = c / (2 * (1 - l));
|
|
1121
|
+
}
|
|
1122
|
+
return [hcg[0], s * 100, l * 100];
|
|
1123
|
+
};
|
|
1124
|
+
convert.hcg.hwb = function(hcg) {
|
|
1125
|
+
const c = hcg[1] / 100;
|
|
1126
|
+
const g = hcg[2] / 100;
|
|
1127
|
+
const v = c + g * (1 - c);
|
|
1128
|
+
return [hcg[0], (v - c) * 100, (1 - v) * 100];
|
|
1129
|
+
};
|
|
1130
|
+
convert.hwb.hcg = function(hwb) {
|
|
1131
|
+
const w = hwb[1] / 100;
|
|
1132
|
+
const b = hwb[2] / 100;
|
|
1133
|
+
const v = 1 - b;
|
|
1134
|
+
const c = v - w;
|
|
1135
|
+
let g = 0;
|
|
1136
|
+
if (c < 1) {
|
|
1137
|
+
g = (v - c) / (1 - c);
|
|
1138
|
+
}
|
|
1139
|
+
return [hwb[0], c * 100, g * 100];
|
|
1140
|
+
};
|
|
1141
|
+
convert.apple.rgb = function(apple) {
|
|
1142
|
+
return [apple[0] / 65535 * 255, apple[1] / 65535 * 255, apple[2] / 65535 * 255];
|
|
1143
|
+
};
|
|
1144
|
+
convert.rgb.apple = function(rgb) {
|
|
1145
|
+
return [rgb[0] / 255 * 65535, rgb[1] / 255 * 65535, rgb[2] / 255 * 65535];
|
|
1146
|
+
};
|
|
1147
|
+
convert.gray.rgb = function(args2) {
|
|
1148
|
+
return [args2[0] / 100 * 255, args2[0] / 100 * 255, args2[0] / 100 * 255];
|
|
1149
|
+
};
|
|
1150
|
+
convert.gray.hsl = function(args2) {
|
|
1151
|
+
return [0, 0, args2[0]];
|
|
1152
|
+
};
|
|
1153
|
+
convert.gray.hsv = convert.gray.hsl;
|
|
1154
|
+
convert.gray.hwb = function(gray) {
|
|
1155
|
+
return [0, 100, gray[0]];
|
|
1156
|
+
};
|
|
1157
|
+
convert.gray.cmyk = function(gray) {
|
|
1158
|
+
return [0, 0, 0, gray[0]];
|
|
1159
|
+
};
|
|
1160
|
+
convert.gray.lab = function(gray) {
|
|
1161
|
+
return [gray[0], 0, 0];
|
|
1162
|
+
};
|
|
1163
|
+
convert.gray.hex = function(gray) {
|
|
1164
|
+
const val = Math.round(gray[0] / 100 * 255) & 255;
|
|
1165
|
+
const integer = (val << 16) + (val << 8) + val;
|
|
1166
|
+
const string = integer.toString(16).toUpperCase();
|
|
1167
|
+
return "000000".substring(string.length) + string;
|
|
1168
|
+
};
|
|
1169
|
+
convert.rgb.gray = function(rgb) {
|
|
1170
|
+
const val = (rgb[0] + rgb[1] + rgb[2]) / 3;
|
|
1171
|
+
return [val / 255 * 100];
|
|
1172
|
+
};
|
|
492
1173
|
}
|
|
493
|
-
};
|
|
1174
|
+
});
|
|
494
1175
|
|
|
495
|
-
// node_modules
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
1176
|
+
// ../node_modules/color-convert/route.js
|
|
1177
|
+
var require_route = __commonJS({
|
|
1178
|
+
"../node_modules/color-convert/route.js"(exports, module) {
|
|
1179
|
+
var conversions = require_conversions();
|
|
1180
|
+
function buildGraph() {
|
|
1181
|
+
const graph = {};
|
|
1182
|
+
const models = Object.keys(conversions);
|
|
1183
|
+
for (let len = models.length, i = 0; i < len; i++) {
|
|
1184
|
+
graph[models[i]] = {
|
|
1185
|
+
// http://jsperf.com/1-vs-infinity
|
|
1186
|
+
// micro-opt, but this is simple.
|
|
1187
|
+
distance: -1,
|
|
1188
|
+
parent: null
|
|
1189
|
+
};
|
|
502
1190
|
}
|
|
503
|
-
|
|
504
|
-
if (pointer.initialized) {
|
|
505
|
-
return [pointer.get(), setState];
|
|
1191
|
+
return graph;
|
|
506
1192
|
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
1193
|
+
function deriveBFS(fromModel) {
|
|
1194
|
+
const graph = buildGraph();
|
|
1195
|
+
const queue = [fromModel];
|
|
1196
|
+
graph[fromModel].distance = 0;
|
|
1197
|
+
while (queue.length) {
|
|
1198
|
+
const current = queue.pop();
|
|
1199
|
+
const adjacents = Object.keys(conversions[current]);
|
|
1200
|
+
for (let len = adjacents.length, i = 0; i < len; i++) {
|
|
1201
|
+
const adjacent = adjacents[i];
|
|
1202
|
+
const node = graph[adjacent];
|
|
1203
|
+
if (node.distance === -1) {
|
|
1204
|
+
node.distance = graph[current].distance + 1;
|
|
1205
|
+
node.parent = current;
|
|
1206
|
+
queue.unshift(adjacent);
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
return graph;
|
|
1211
|
+
}
|
|
1212
|
+
function link(from, to) {
|
|
1213
|
+
return function(args2) {
|
|
1214
|
+
return to(from(args2));
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
function wrapConversion(toModel, graph) {
|
|
1218
|
+
const path = [graph[toModel].parent, toModel];
|
|
1219
|
+
let fn = conversions[graph[toModel].parent][toModel];
|
|
1220
|
+
let cur = graph[toModel].parent;
|
|
1221
|
+
while (graph[cur].parent) {
|
|
1222
|
+
path.unshift(graph[cur].parent);
|
|
1223
|
+
fn = link(conversions[graph[cur].parent][cur], fn);
|
|
1224
|
+
cur = graph[cur].parent;
|
|
1225
|
+
}
|
|
1226
|
+
fn.conversion = path;
|
|
1227
|
+
return fn;
|
|
1228
|
+
}
|
|
1229
|
+
module.exports = function(fromModel) {
|
|
1230
|
+
const graph = deriveBFS(fromModel);
|
|
1231
|
+
const conversion = {};
|
|
1232
|
+
const models = Object.keys(graph);
|
|
1233
|
+
for (let len = models.length, i = 0; i < len; i++) {
|
|
1234
|
+
const toModel = models[i];
|
|
1235
|
+
const node = graph[toModel];
|
|
1236
|
+
if (node.parent === null) {
|
|
1237
|
+
continue;
|
|
1238
|
+
}
|
|
1239
|
+
conversion[toModel] = wrapConversion(toModel, graph);
|
|
1240
|
+
}
|
|
1241
|
+
return conversion;
|
|
1242
|
+
};
|
|
1243
|
+
}
|
|
1244
|
+
});
|
|
1245
|
+
|
|
1246
|
+
// ../node_modules/color-convert/index.js
|
|
1247
|
+
var require_color_convert = __commonJS({
|
|
1248
|
+
"../node_modules/color-convert/index.js"(exports, module) {
|
|
1249
|
+
var conversions = require_conversions();
|
|
1250
|
+
var route = require_route();
|
|
1251
|
+
var convert = {};
|
|
1252
|
+
var models = Object.keys(conversions);
|
|
1253
|
+
function wrapRaw(fn) {
|
|
1254
|
+
const wrappedFn = function(...args2) {
|
|
1255
|
+
const arg0 = args2[0];
|
|
1256
|
+
if (arg0 === void 0 || arg0 === null) {
|
|
1257
|
+
return arg0;
|
|
1258
|
+
}
|
|
1259
|
+
if (arg0.length > 1) {
|
|
1260
|
+
args2 = arg0;
|
|
1261
|
+
}
|
|
1262
|
+
return fn(args2);
|
|
1263
|
+
};
|
|
1264
|
+
if ("conversion" in fn) {
|
|
1265
|
+
wrappedFn.conversion = fn.conversion;
|
|
1266
|
+
}
|
|
1267
|
+
return wrappedFn;
|
|
1268
|
+
}
|
|
1269
|
+
function wrapRounded(fn) {
|
|
1270
|
+
const wrappedFn = function(...args2) {
|
|
1271
|
+
const arg0 = args2[0];
|
|
1272
|
+
if (arg0 === void 0 || arg0 === null) {
|
|
1273
|
+
return arg0;
|
|
1274
|
+
}
|
|
1275
|
+
if (arg0.length > 1) {
|
|
1276
|
+
args2 = arg0;
|
|
1277
|
+
}
|
|
1278
|
+
const result = fn(args2);
|
|
1279
|
+
if (typeof result === "object") {
|
|
1280
|
+
for (let len = result.length, i = 0; i < len; i++) {
|
|
1281
|
+
result[i] = Math.round(result[i]);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
return result;
|
|
1285
|
+
};
|
|
1286
|
+
if ("conversion" in fn) {
|
|
1287
|
+
wrappedFn.conversion = fn.conversion;
|
|
1288
|
+
}
|
|
1289
|
+
return wrappedFn;
|
|
1290
|
+
}
|
|
1291
|
+
models.forEach((fromModel) => {
|
|
1292
|
+
convert[fromModel] = {};
|
|
1293
|
+
Object.defineProperty(convert[fromModel], "channels", { value: conversions[fromModel].channels });
|
|
1294
|
+
Object.defineProperty(convert[fromModel], "labels", { value: conversions[fromModel].labels });
|
|
1295
|
+
const routes = route(fromModel);
|
|
1296
|
+
const routeModels = Object.keys(routes);
|
|
1297
|
+
routeModels.forEach((toModel) => {
|
|
1298
|
+
const fn = routes[toModel];
|
|
1299
|
+
convert[fromModel][toModel] = wrapRounded(fn);
|
|
1300
|
+
convert[fromModel][toModel].raw = wrapRaw(fn);
|
|
1301
|
+
});
|
|
1302
|
+
});
|
|
1303
|
+
module.exports = convert;
|
|
1304
|
+
}
|
|
1305
|
+
});
|
|
1306
|
+
|
|
1307
|
+
// ../node_modules/ansi-styles/index.js
|
|
1308
|
+
var require_ansi_styles = __commonJS({
|
|
1309
|
+
"../node_modules/ansi-styles/index.js"(exports, module) {
|
|
1310
|
+
"use strict";
|
|
1311
|
+
var wrapAnsi162 = (fn, offset) => (...args2) => {
|
|
1312
|
+
const code = fn(...args2);
|
|
1313
|
+
return `\x1B[${code + offset}m`;
|
|
1314
|
+
};
|
|
1315
|
+
var wrapAnsi2562 = (fn, offset) => (...args2) => {
|
|
1316
|
+
const code = fn(...args2);
|
|
1317
|
+
return `\x1B[${38 + offset};5;${code}m`;
|
|
1318
|
+
};
|
|
1319
|
+
var wrapAnsi16m2 = (fn, offset) => (...args2) => {
|
|
1320
|
+
const rgb = fn(...args2);
|
|
1321
|
+
return `\x1B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
|
|
1322
|
+
};
|
|
1323
|
+
var ansi2ansi = (n) => n;
|
|
1324
|
+
var rgb2rgb = (r, g, b) => [r, g, b];
|
|
1325
|
+
var setLazyProperty = (object, property, get) => {
|
|
1326
|
+
Object.defineProperty(object, property, {
|
|
1327
|
+
get: () => {
|
|
1328
|
+
const value = get();
|
|
1329
|
+
Object.defineProperty(object, property, {
|
|
1330
|
+
value,
|
|
1331
|
+
enumerable: true,
|
|
1332
|
+
configurable: true
|
|
1333
|
+
});
|
|
1334
|
+
return value;
|
|
1335
|
+
},
|
|
1336
|
+
enumerable: true,
|
|
1337
|
+
configurable: true
|
|
1338
|
+
});
|
|
1339
|
+
};
|
|
1340
|
+
var colorConvert;
|
|
1341
|
+
var makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => {
|
|
1342
|
+
if (colorConvert === void 0) {
|
|
1343
|
+
colorConvert = require_color_convert();
|
|
1344
|
+
}
|
|
1345
|
+
const offset = isBackground ? 10 : 0;
|
|
1346
|
+
const styles2 = {};
|
|
1347
|
+
for (const [sourceSpace, suite] of Object.entries(colorConvert)) {
|
|
1348
|
+
const name = sourceSpace === "ansi16" ? "ansi" : sourceSpace;
|
|
1349
|
+
if (sourceSpace === targetSpace) {
|
|
1350
|
+
styles2[name] = wrap(identity, offset);
|
|
1351
|
+
} else if (typeof suite === "object") {
|
|
1352
|
+
styles2[name] = wrap(suite[targetSpace], offset);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
return styles2;
|
|
1356
|
+
};
|
|
1357
|
+
function assembleStyles2() {
|
|
1358
|
+
const codes = /* @__PURE__ */ new Map();
|
|
1359
|
+
const styles2 = {
|
|
1360
|
+
modifier: {
|
|
1361
|
+
reset: [0, 0],
|
|
1362
|
+
// 21 isn't widely supported and 22 does the same thing
|
|
1363
|
+
bold: [1, 22],
|
|
1364
|
+
dim: [2, 22],
|
|
1365
|
+
italic: [3, 23],
|
|
1366
|
+
underline: [4, 24],
|
|
1367
|
+
inverse: [7, 27],
|
|
1368
|
+
hidden: [8, 28],
|
|
1369
|
+
strikethrough: [9, 29]
|
|
1370
|
+
},
|
|
1371
|
+
color: {
|
|
1372
|
+
black: [30, 39],
|
|
1373
|
+
red: [31, 39],
|
|
1374
|
+
green: [32, 39],
|
|
1375
|
+
yellow: [33, 39],
|
|
1376
|
+
blue: [34, 39],
|
|
1377
|
+
magenta: [35, 39],
|
|
1378
|
+
cyan: [36, 39],
|
|
1379
|
+
white: [37, 39],
|
|
1380
|
+
// Bright color
|
|
1381
|
+
blackBright: [90, 39],
|
|
1382
|
+
redBright: [91, 39],
|
|
1383
|
+
greenBright: [92, 39],
|
|
1384
|
+
yellowBright: [93, 39],
|
|
1385
|
+
blueBright: [94, 39],
|
|
1386
|
+
magentaBright: [95, 39],
|
|
1387
|
+
cyanBright: [96, 39],
|
|
1388
|
+
whiteBright: [97, 39]
|
|
1389
|
+
},
|
|
1390
|
+
bgColor: {
|
|
1391
|
+
bgBlack: [40, 49],
|
|
1392
|
+
bgRed: [41, 49],
|
|
1393
|
+
bgGreen: [42, 49],
|
|
1394
|
+
bgYellow: [43, 49],
|
|
1395
|
+
bgBlue: [44, 49],
|
|
1396
|
+
bgMagenta: [45, 49],
|
|
1397
|
+
bgCyan: [46, 49],
|
|
1398
|
+
bgWhite: [47, 49],
|
|
1399
|
+
// Bright color
|
|
1400
|
+
bgBlackBright: [100, 49],
|
|
1401
|
+
bgRedBright: [101, 49],
|
|
1402
|
+
bgGreenBright: [102, 49],
|
|
1403
|
+
bgYellowBright: [103, 49],
|
|
1404
|
+
bgBlueBright: [104, 49],
|
|
1405
|
+
bgMagentaBright: [105, 49],
|
|
1406
|
+
bgCyanBright: [106, 49],
|
|
1407
|
+
bgWhiteBright: [107, 49]
|
|
1408
|
+
}
|
|
1409
|
+
};
|
|
1410
|
+
styles2.color.gray = styles2.color.blackBright;
|
|
1411
|
+
styles2.bgColor.bgGray = styles2.bgColor.bgBlackBright;
|
|
1412
|
+
styles2.color.grey = styles2.color.blackBright;
|
|
1413
|
+
styles2.bgColor.bgGrey = styles2.bgColor.bgBlackBright;
|
|
1414
|
+
for (const [groupName, group] of Object.entries(styles2)) {
|
|
1415
|
+
for (const [styleName, style] of Object.entries(group)) {
|
|
1416
|
+
styles2[styleName] = {
|
|
1417
|
+
open: `\x1B[${style[0]}m`,
|
|
1418
|
+
close: `\x1B[${style[1]}m`
|
|
1419
|
+
};
|
|
1420
|
+
group[styleName] = styles2[styleName];
|
|
1421
|
+
codes.set(style[0], style[1]);
|
|
1422
|
+
}
|
|
1423
|
+
Object.defineProperty(styles2, groupName, {
|
|
1424
|
+
value: group,
|
|
1425
|
+
enumerable: false
|
|
1426
|
+
});
|
|
1427
|
+
}
|
|
1428
|
+
Object.defineProperty(styles2, "codes", {
|
|
1429
|
+
value: codes,
|
|
1430
|
+
enumerable: false
|
|
1431
|
+
});
|
|
1432
|
+
styles2.color.close = "\x1B[39m";
|
|
1433
|
+
styles2.bgColor.close = "\x1B[49m";
|
|
1434
|
+
setLazyProperty(styles2.color, "ansi", () => makeDynamicStyles(wrapAnsi162, "ansi16", ansi2ansi, false));
|
|
1435
|
+
setLazyProperty(styles2.color, "ansi256", () => makeDynamicStyles(wrapAnsi2562, "ansi256", ansi2ansi, false));
|
|
1436
|
+
setLazyProperty(styles2.color, "ansi16m", () => makeDynamicStyles(wrapAnsi16m2, "rgb", rgb2rgb, false));
|
|
1437
|
+
setLazyProperty(styles2.bgColor, "ansi", () => makeDynamicStyles(wrapAnsi162, "ansi16", ansi2ansi, true));
|
|
1438
|
+
setLazyProperty(styles2.bgColor, "ansi256", () => makeDynamicStyles(wrapAnsi2562, "ansi256", ansi2ansi, true));
|
|
1439
|
+
setLazyProperty(styles2.bgColor, "ansi16m", () => makeDynamicStyles(wrapAnsi16m2, "rgb", rgb2rgb, true));
|
|
1440
|
+
return styles2;
|
|
1441
|
+
}
|
|
1442
|
+
Object.defineProperty(module, "exports", {
|
|
1443
|
+
enumerable: true,
|
|
1444
|
+
get: assembleStyles2
|
|
1445
|
+
});
|
|
1446
|
+
}
|
|
1447
|
+
});
|
|
1448
|
+
|
|
1449
|
+
// ../node_modules/has-flag/index.js
|
|
1450
|
+
var require_has_flag = __commonJS({
|
|
1451
|
+
"../node_modules/has-flag/index.js"(exports, module) {
|
|
1452
|
+
"use strict";
|
|
1453
|
+
module.exports = (flag, argv = process.argv) => {
|
|
1454
|
+
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
1455
|
+
const position = argv.indexOf(prefix + flag);
|
|
1456
|
+
const terminatorPosition = argv.indexOf("--");
|
|
1457
|
+
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
});
|
|
1461
|
+
|
|
1462
|
+
// ../node_modules/chalk/node_modules/supports-color/index.js
|
|
1463
|
+
var require_supports_color = __commonJS({
|
|
1464
|
+
"../node_modules/chalk/node_modules/supports-color/index.js"(exports, module) {
|
|
1465
|
+
"use strict";
|
|
1466
|
+
var os = __require("os");
|
|
1467
|
+
var tty = __require("tty");
|
|
1468
|
+
var hasFlag = require_has_flag();
|
|
1469
|
+
var { env } = process;
|
|
1470
|
+
var forceColor;
|
|
1471
|
+
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
|
|
1472
|
+
forceColor = 0;
|
|
1473
|
+
} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
|
|
1474
|
+
forceColor = 1;
|
|
1475
|
+
}
|
|
1476
|
+
if ("FORCE_COLOR" in env) {
|
|
1477
|
+
if (env.FORCE_COLOR === "true") {
|
|
1478
|
+
forceColor = 1;
|
|
1479
|
+
} else if (env.FORCE_COLOR === "false") {
|
|
1480
|
+
forceColor = 0;
|
|
1481
|
+
} else {
|
|
1482
|
+
forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
function translateLevel(level) {
|
|
1486
|
+
if (level === 0) {
|
|
1487
|
+
return false;
|
|
1488
|
+
}
|
|
1489
|
+
return {
|
|
1490
|
+
level,
|
|
1491
|
+
hasBasic: true,
|
|
1492
|
+
has256: level >= 2,
|
|
1493
|
+
has16m: level >= 3
|
|
1494
|
+
};
|
|
1495
|
+
}
|
|
1496
|
+
function supportsColor(haveStream, streamIsTTY) {
|
|
1497
|
+
if (forceColor === 0) {
|
|
1498
|
+
return 0;
|
|
1499
|
+
}
|
|
1500
|
+
if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
|
|
1501
|
+
return 3;
|
|
1502
|
+
}
|
|
1503
|
+
if (hasFlag("color=256")) {
|
|
1504
|
+
return 2;
|
|
1505
|
+
}
|
|
1506
|
+
if (haveStream && !streamIsTTY && forceColor === void 0) {
|
|
1507
|
+
return 0;
|
|
1508
|
+
}
|
|
1509
|
+
const min = forceColor || 0;
|
|
1510
|
+
if (env.TERM === "dumb") {
|
|
1511
|
+
return min;
|
|
1512
|
+
}
|
|
1513
|
+
if (process.platform === "win32") {
|
|
1514
|
+
const osRelease = os.release().split(".");
|
|
1515
|
+
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
1516
|
+
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
1517
|
+
}
|
|
1518
|
+
return 1;
|
|
1519
|
+
}
|
|
1520
|
+
if ("CI" in env) {
|
|
1521
|
+
if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
|
|
1522
|
+
return 1;
|
|
1523
|
+
}
|
|
1524
|
+
return min;
|
|
1525
|
+
}
|
|
1526
|
+
if ("TEAMCITY_VERSION" in env) {
|
|
1527
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
1528
|
+
}
|
|
1529
|
+
if (env.COLORTERM === "truecolor") {
|
|
1530
|
+
return 3;
|
|
1531
|
+
}
|
|
1532
|
+
if ("TERM_PROGRAM" in env) {
|
|
1533
|
+
const version = parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
|
|
1534
|
+
switch (env.TERM_PROGRAM) {
|
|
1535
|
+
case "iTerm.app":
|
|
1536
|
+
return version >= 3 ? 3 : 2;
|
|
1537
|
+
case "Apple_Terminal":
|
|
1538
|
+
return 2;
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
if (/-256(color)?$/i.test(env.TERM)) {
|
|
1542
|
+
return 2;
|
|
1543
|
+
}
|
|
1544
|
+
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
1545
|
+
return 1;
|
|
1546
|
+
}
|
|
1547
|
+
if ("COLORTERM" in env) {
|
|
1548
|
+
return 1;
|
|
1549
|
+
}
|
|
1550
|
+
return min;
|
|
1551
|
+
}
|
|
1552
|
+
function getSupportLevel(stream) {
|
|
1553
|
+
const level = supportsColor(stream, stream && stream.isTTY);
|
|
1554
|
+
return translateLevel(level);
|
|
1555
|
+
}
|
|
1556
|
+
module.exports = {
|
|
1557
|
+
supportsColor: getSupportLevel,
|
|
1558
|
+
stdout: translateLevel(supportsColor(true, tty.isatty(1))),
|
|
1559
|
+
stderr: translateLevel(supportsColor(true, tty.isatty(2)))
|
|
1560
|
+
};
|
|
1561
|
+
}
|
|
1562
|
+
});
|
|
1563
|
+
|
|
1564
|
+
// ../node_modules/chalk/source/util.js
|
|
1565
|
+
var require_util = __commonJS({
|
|
1566
|
+
"../node_modules/chalk/source/util.js"(exports, module) {
|
|
1567
|
+
"use strict";
|
|
1568
|
+
var stringReplaceAll = (string, substring, replacer) => {
|
|
1569
|
+
let index = string.indexOf(substring);
|
|
1570
|
+
if (index === -1) {
|
|
1571
|
+
return string;
|
|
1572
|
+
}
|
|
1573
|
+
const substringLength = substring.length;
|
|
1574
|
+
let endIndex = 0;
|
|
1575
|
+
let returnValue = "";
|
|
1576
|
+
do {
|
|
1577
|
+
returnValue += string.substr(endIndex, index - endIndex) + substring + replacer;
|
|
1578
|
+
endIndex = index + substringLength;
|
|
1579
|
+
index = string.indexOf(substring, endIndex);
|
|
1580
|
+
} while (index !== -1);
|
|
1581
|
+
returnValue += string.substr(endIndex);
|
|
1582
|
+
return returnValue;
|
|
1583
|
+
};
|
|
1584
|
+
var stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => {
|
|
1585
|
+
let endIndex = 0;
|
|
1586
|
+
let returnValue = "";
|
|
1587
|
+
do {
|
|
1588
|
+
const gotCR = string[index - 1] === "\r";
|
|
1589
|
+
returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
|
|
1590
|
+
endIndex = index + 1;
|
|
1591
|
+
index = string.indexOf("\n", endIndex);
|
|
1592
|
+
} while (index !== -1);
|
|
1593
|
+
returnValue += string.substr(endIndex);
|
|
1594
|
+
return returnValue;
|
|
1595
|
+
};
|
|
1596
|
+
module.exports = {
|
|
1597
|
+
stringReplaceAll,
|
|
1598
|
+
stringEncaseCRLFWithFirstIndex
|
|
1599
|
+
};
|
|
1600
|
+
}
|
|
1601
|
+
});
|
|
1602
|
+
|
|
1603
|
+
// ../node_modules/chalk/source/templates.js
|
|
1604
|
+
var require_templates = __commonJS({
|
|
1605
|
+
"../node_modules/chalk/source/templates.js"(exports, module) {
|
|
1606
|
+
"use strict";
|
|
1607
|
+
var TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
|
|
1608
|
+
var STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
|
|
1609
|
+
var STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
|
|
1610
|
+
var ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi;
|
|
1611
|
+
var ESCAPES2 = /* @__PURE__ */ new Map([
|
|
1612
|
+
["n", "\n"],
|
|
1613
|
+
["r", "\r"],
|
|
1614
|
+
["t", " "],
|
|
1615
|
+
["b", "\b"],
|
|
1616
|
+
["f", "\f"],
|
|
1617
|
+
["v", "\v"],
|
|
1618
|
+
["0", "\0"],
|
|
1619
|
+
["\\", "\\"],
|
|
1620
|
+
["e", "\x1B"],
|
|
1621
|
+
["a", "\x07"]
|
|
1622
|
+
]);
|
|
1623
|
+
function unescape(c) {
|
|
1624
|
+
const u = c[0] === "u";
|
|
1625
|
+
const bracket = c[1] === "{";
|
|
1626
|
+
if (u && !bracket && c.length === 5 || c[0] === "x" && c.length === 3) {
|
|
1627
|
+
return String.fromCharCode(parseInt(c.slice(1), 16));
|
|
1628
|
+
}
|
|
1629
|
+
if (u && bracket) {
|
|
1630
|
+
return String.fromCodePoint(parseInt(c.slice(2, -1), 16));
|
|
1631
|
+
}
|
|
1632
|
+
return ESCAPES2.get(c) || c;
|
|
1633
|
+
}
|
|
1634
|
+
function parseArguments(name, arguments_) {
|
|
1635
|
+
const results = [];
|
|
1636
|
+
const chunks = arguments_.trim().split(/\s*,\s*/g);
|
|
1637
|
+
let matches;
|
|
1638
|
+
for (const chunk of chunks) {
|
|
1639
|
+
const number = Number(chunk);
|
|
1640
|
+
if (!Number.isNaN(number)) {
|
|
1641
|
+
results.push(number);
|
|
1642
|
+
} else if (matches = chunk.match(STRING_REGEX)) {
|
|
1643
|
+
results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character));
|
|
1644
|
+
} else {
|
|
1645
|
+
throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
return results;
|
|
1649
|
+
}
|
|
1650
|
+
function parseStyle(style) {
|
|
1651
|
+
STYLE_REGEX.lastIndex = 0;
|
|
1652
|
+
const results = [];
|
|
1653
|
+
let matches;
|
|
1654
|
+
while ((matches = STYLE_REGEX.exec(style)) !== null) {
|
|
1655
|
+
const name = matches[1];
|
|
1656
|
+
if (matches[2]) {
|
|
1657
|
+
const args2 = parseArguments(name, matches[2]);
|
|
1658
|
+
results.push([name].concat(args2));
|
|
1659
|
+
} else {
|
|
1660
|
+
results.push([name]);
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
return results;
|
|
1664
|
+
}
|
|
1665
|
+
function buildStyle(chalk2, styles2) {
|
|
1666
|
+
const enabled = {};
|
|
1667
|
+
for (const layer of styles2) {
|
|
1668
|
+
for (const style of layer.styles) {
|
|
1669
|
+
enabled[style[0]] = layer.inverse ? null : style.slice(1);
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1672
|
+
let current = chalk2;
|
|
1673
|
+
for (const [styleName, styles3] of Object.entries(enabled)) {
|
|
1674
|
+
if (!Array.isArray(styles3)) {
|
|
1675
|
+
continue;
|
|
1676
|
+
}
|
|
1677
|
+
if (!(styleName in current)) {
|
|
1678
|
+
throw new Error(`Unknown Chalk style: ${styleName}`);
|
|
1679
|
+
}
|
|
1680
|
+
current = styles3.length > 0 ? current[styleName](...styles3) : current[styleName];
|
|
1681
|
+
}
|
|
1682
|
+
return current;
|
|
1683
|
+
}
|
|
1684
|
+
module.exports = (chalk2, temporary) => {
|
|
1685
|
+
const styles2 = [];
|
|
1686
|
+
const chunks = [];
|
|
1687
|
+
let chunk = [];
|
|
1688
|
+
temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => {
|
|
1689
|
+
if (escapeCharacter) {
|
|
1690
|
+
chunk.push(unescape(escapeCharacter));
|
|
1691
|
+
} else if (style) {
|
|
1692
|
+
const string = chunk.join("");
|
|
1693
|
+
chunk = [];
|
|
1694
|
+
chunks.push(styles2.length === 0 ? string : buildStyle(chalk2, styles2)(string));
|
|
1695
|
+
styles2.push({ inverse, styles: parseStyle(style) });
|
|
1696
|
+
} else if (close) {
|
|
1697
|
+
if (styles2.length === 0) {
|
|
1698
|
+
throw new Error("Found extraneous } in Chalk template literal");
|
|
1699
|
+
}
|
|
1700
|
+
chunks.push(buildStyle(chalk2, styles2)(chunk.join("")));
|
|
1701
|
+
chunk = [];
|
|
1702
|
+
styles2.pop();
|
|
1703
|
+
} else {
|
|
1704
|
+
chunk.push(character);
|
|
1705
|
+
}
|
|
1706
|
+
});
|
|
1707
|
+
chunks.push(chunk.join(""));
|
|
1708
|
+
if (styles2.length > 0) {
|
|
1709
|
+
const errMessage = `Chalk template literal is missing ${styles2.length} closing bracket${styles2.length === 1 ? "" : "s"} (\`}\`)`;
|
|
1710
|
+
throw new Error(errMessage);
|
|
1711
|
+
}
|
|
1712
|
+
return chunks.join("");
|
|
1713
|
+
};
|
|
1714
|
+
}
|
|
1715
|
+
});
|
|
1716
|
+
|
|
1717
|
+
// ../node_modules/chalk/source/index.js
|
|
1718
|
+
var require_source = __commonJS({
|
|
1719
|
+
"../node_modules/chalk/source/index.js"(exports, module) {
|
|
1720
|
+
"use strict";
|
|
1721
|
+
var ansiStyles2 = require_ansi_styles();
|
|
1722
|
+
var { stdout: stdoutColor, stderr: stderrColor } = require_supports_color();
|
|
1723
|
+
var {
|
|
1724
|
+
stringReplaceAll,
|
|
1725
|
+
stringEncaseCRLFWithFirstIndex
|
|
1726
|
+
} = require_util();
|
|
1727
|
+
var { isArray } = Array;
|
|
1728
|
+
var levelMapping = [
|
|
1729
|
+
"ansi",
|
|
1730
|
+
"ansi",
|
|
1731
|
+
"ansi256",
|
|
1732
|
+
"ansi16m"
|
|
1733
|
+
];
|
|
1734
|
+
var styles2 = /* @__PURE__ */ Object.create(null);
|
|
1735
|
+
var applyOptions = (object, options = {}) => {
|
|
1736
|
+
if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
|
|
1737
|
+
throw new Error("The `level` option should be an integer from 0 to 3");
|
|
1738
|
+
}
|
|
1739
|
+
const colorLevel = stdoutColor ? stdoutColor.level : 0;
|
|
1740
|
+
object.level = options.level === void 0 ? colorLevel : options.level;
|
|
1741
|
+
};
|
|
1742
|
+
var ChalkClass = class {
|
|
1743
|
+
constructor(options) {
|
|
1744
|
+
return chalkFactory(options);
|
|
1745
|
+
}
|
|
1746
|
+
};
|
|
1747
|
+
var chalkFactory = (options) => {
|
|
1748
|
+
const chalk3 = {};
|
|
1749
|
+
applyOptions(chalk3, options);
|
|
1750
|
+
chalk3.template = (...arguments_) => chalkTag(chalk3.template, ...arguments_);
|
|
1751
|
+
Object.setPrototypeOf(chalk3, Chalk.prototype);
|
|
1752
|
+
Object.setPrototypeOf(chalk3.template, chalk3);
|
|
1753
|
+
chalk3.template.constructor = () => {
|
|
1754
|
+
throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
|
|
1755
|
+
};
|
|
1756
|
+
chalk3.template.Instance = ChalkClass;
|
|
1757
|
+
return chalk3.template;
|
|
1758
|
+
};
|
|
1759
|
+
function Chalk(options) {
|
|
1760
|
+
return chalkFactory(options);
|
|
1761
|
+
}
|
|
1762
|
+
for (const [styleName, style] of Object.entries(ansiStyles2)) {
|
|
1763
|
+
styles2[styleName] = {
|
|
1764
|
+
get() {
|
|
1765
|
+
const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty);
|
|
1766
|
+
Object.defineProperty(this, styleName, { value: builder });
|
|
1767
|
+
return builder;
|
|
1768
|
+
}
|
|
1769
|
+
};
|
|
1770
|
+
}
|
|
1771
|
+
styles2.visible = {
|
|
1772
|
+
get() {
|
|
1773
|
+
const builder = createBuilder(this, this._styler, true);
|
|
1774
|
+
Object.defineProperty(this, "visible", { value: builder });
|
|
1775
|
+
return builder;
|
|
1776
|
+
}
|
|
1777
|
+
};
|
|
1778
|
+
var usedModels = ["rgb", "hex", "keyword", "hsl", "hsv", "hwb", "ansi", "ansi256"];
|
|
1779
|
+
for (const model of usedModels) {
|
|
1780
|
+
styles2[model] = {
|
|
1781
|
+
get() {
|
|
1782
|
+
const { level } = this;
|
|
1783
|
+
return function(...arguments_) {
|
|
1784
|
+
const styler = createStyler(ansiStyles2.color[levelMapping[level]][model](...arguments_), ansiStyles2.color.close, this._styler);
|
|
1785
|
+
return createBuilder(this, styler, this._isEmpty);
|
|
1786
|
+
};
|
|
1787
|
+
}
|
|
1788
|
+
};
|
|
1789
|
+
}
|
|
1790
|
+
for (const model of usedModels) {
|
|
1791
|
+
const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
|
|
1792
|
+
styles2[bgModel] = {
|
|
1793
|
+
get() {
|
|
1794
|
+
const { level } = this;
|
|
1795
|
+
return function(...arguments_) {
|
|
1796
|
+
const styler = createStyler(ansiStyles2.bgColor[levelMapping[level]][model](...arguments_), ansiStyles2.bgColor.close, this._styler);
|
|
1797
|
+
return createBuilder(this, styler, this._isEmpty);
|
|
1798
|
+
};
|
|
1799
|
+
}
|
|
1800
|
+
};
|
|
1801
|
+
}
|
|
1802
|
+
var proto = Object.defineProperties(() => {
|
|
1803
|
+
}, {
|
|
1804
|
+
...styles2,
|
|
1805
|
+
level: {
|
|
1806
|
+
enumerable: true,
|
|
1807
|
+
get() {
|
|
1808
|
+
return this._generator.level;
|
|
1809
|
+
},
|
|
1810
|
+
set(level) {
|
|
1811
|
+
this._generator.level = level;
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
});
|
|
1815
|
+
var createStyler = (open, close, parent) => {
|
|
1816
|
+
let openAll;
|
|
1817
|
+
let closeAll;
|
|
1818
|
+
if (parent === void 0) {
|
|
1819
|
+
openAll = open;
|
|
1820
|
+
closeAll = close;
|
|
1821
|
+
} else {
|
|
1822
|
+
openAll = parent.openAll + open;
|
|
1823
|
+
closeAll = close + parent.closeAll;
|
|
1824
|
+
}
|
|
1825
|
+
return {
|
|
1826
|
+
open,
|
|
1827
|
+
close,
|
|
1828
|
+
openAll,
|
|
1829
|
+
closeAll,
|
|
1830
|
+
parent
|
|
1831
|
+
};
|
|
1832
|
+
};
|
|
1833
|
+
var createBuilder = (self, _styler, _isEmpty) => {
|
|
1834
|
+
const builder = (...arguments_) => {
|
|
1835
|
+
if (isArray(arguments_[0]) && isArray(arguments_[0].raw)) {
|
|
1836
|
+
return applyStyle(builder, chalkTag(builder, ...arguments_));
|
|
1837
|
+
}
|
|
1838
|
+
return applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
|
|
1839
|
+
};
|
|
1840
|
+
Object.setPrototypeOf(builder, proto);
|
|
1841
|
+
builder._generator = self;
|
|
1842
|
+
builder._styler = _styler;
|
|
1843
|
+
builder._isEmpty = _isEmpty;
|
|
1844
|
+
return builder;
|
|
1845
|
+
};
|
|
1846
|
+
var applyStyle = (self, string) => {
|
|
1847
|
+
if (self.level <= 0 || !string) {
|
|
1848
|
+
return self._isEmpty ? "" : string;
|
|
1849
|
+
}
|
|
1850
|
+
let styler = self._styler;
|
|
1851
|
+
if (styler === void 0) {
|
|
1852
|
+
return string;
|
|
1853
|
+
}
|
|
1854
|
+
const { openAll, closeAll } = styler;
|
|
1855
|
+
if (string.indexOf("\x1B") !== -1) {
|
|
1856
|
+
while (styler !== void 0) {
|
|
1857
|
+
string = stringReplaceAll(string, styler.close, styler.open);
|
|
1858
|
+
styler = styler.parent;
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
const lfIndex = string.indexOf("\n");
|
|
1862
|
+
if (lfIndex !== -1) {
|
|
1863
|
+
string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
|
|
1864
|
+
}
|
|
1865
|
+
return openAll + string + closeAll;
|
|
1866
|
+
};
|
|
1867
|
+
var template;
|
|
1868
|
+
var chalkTag = (chalk3, ...strings) => {
|
|
1869
|
+
const [firstString] = strings;
|
|
1870
|
+
if (!isArray(firstString) || !isArray(firstString.raw)) {
|
|
1871
|
+
return strings.join(" ");
|
|
1872
|
+
}
|
|
1873
|
+
const arguments_ = strings.slice(1);
|
|
1874
|
+
const parts = [firstString.raw[0]];
|
|
1875
|
+
for (let i = 1; i < firstString.length; i++) {
|
|
1876
|
+
parts.push(
|
|
1877
|
+
String(arguments_[i - 1]).replace(/[{}\\]/g, "\\$&"),
|
|
1878
|
+
String(firstString.raw[i])
|
|
1879
|
+
);
|
|
1880
|
+
}
|
|
1881
|
+
if (template === void 0) {
|
|
1882
|
+
template = require_templates();
|
|
1883
|
+
}
|
|
1884
|
+
return template(chalk3, parts.join(""));
|
|
1885
|
+
};
|
|
1886
|
+
Object.defineProperties(Chalk.prototype, styles2);
|
|
1887
|
+
var chalk2 = Chalk();
|
|
1888
|
+
chalk2.supportsColor = stdoutColor;
|
|
1889
|
+
chalk2.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
1890
|
+
chalk2.stderr.supportsColor = stderrColor;
|
|
1891
|
+
module.exports = chalk2;
|
|
1892
|
+
}
|
|
1893
|
+
});
|
|
1894
|
+
|
|
1895
|
+
// node_modules/@inquirer/core/dist/lib/key.js
|
|
1896
|
+
var isUpKey = (key, keybindings = []) => (
|
|
1897
|
+
// The up key
|
|
1898
|
+
key.name === "up" || // Vim keybinding: hjkl keys map to left/down/up/right
|
|
1899
|
+
keybindings.includes("vim") && key.name === "k" || // Emacs keybinding: Ctrl+P means "previous" in Emacs navigation conventions
|
|
1900
|
+
keybindings.includes("emacs") && key.ctrl && key.name === "p"
|
|
1901
|
+
);
|
|
1902
|
+
var isDownKey = (key, keybindings = []) => (
|
|
1903
|
+
// The down key
|
|
1904
|
+
key.name === "down" || // Vim keybinding: hjkl keys map to left/down/up/right
|
|
1905
|
+
keybindings.includes("vim") && key.name === "j" || // Emacs keybinding: Ctrl+N means "next" in Emacs navigation conventions
|
|
1906
|
+
keybindings.includes("emacs") && key.ctrl && key.name === "n"
|
|
1907
|
+
);
|
|
1908
|
+
var isSpaceKey = (key) => key.name === "space";
|
|
1909
|
+
var isBackspaceKey = (key) => key.name === "backspace";
|
|
1910
|
+
var isTabKey = (key) => key.name === "tab";
|
|
1911
|
+
var isNumberKey = (key) => "1234567890".includes(key.name);
|
|
1912
|
+
var isEnterKey = (key) => key.name === "enter" || key.name === "return";
|
|
1913
|
+
|
|
1914
|
+
// node_modules/@inquirer/core/dist/lib/errors.js
|
|
1915
|
+
var AbortPromptError = class extends Error {
|
|
1916
|
+
name = "AbortPromptError";
|
|
1917
|
+
message = "Prompt was aborted";
|
|
1918
|
+
constructor(options) {
|
|
1919
|
+
super();
|
|
1920
|
+
this.cause = options?.cause;
|
|
1921
|
+
}
|
|
1922
|
+
};
|
|
1923
|
+
var CancelPromptError = class extends Error {
|
|
1924
|
+
name = "CancelPromptError";
|
|
1925
|
+
message = "Prompt was canceled";
|
|
1926
|
+
};
|
|
1927
|
+
var ExitPromptError = class extends Error {
|
|
1928
|
+
name = "ExitPromptError";
|
|
1929
|
+
};
|
|
1930
|
+
var HookError = class extends Error {
|
|
1931
|
+
name = "HookError";
|
|
1932
|
+
};
|
|
1933
|
+
var ValidationError = class extends Error {
|
|
1934
|
+
name = "ValidationError";
|
|
1935
|
+
};
|
|
1936
|
+
|
|
1937
|
+
// node_modules/@inquirer/core/dist/lib/use-state.js
|
|
1938
|
+
import { AsyncResource as AsyncResource2 } from "node:async_hooks";
|
|
1939
|
+
|
|
1940
|
+
// node_modules/@inquirer/core/dist/lib/hook-engine.js
|
|
1941
|
+
import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
|
|
1942
|
+
var hookStorage = new AsyncLocalStorage();
|
|
1943
|
+
function createStore(rl) {
|
|
1944
|
+
const store = {
|
|
1945
|
+
rl,
|
|
1946
|
+
hooks: [],
|
|
1947
|
+
hooksCleanup: [],
|
|
1948
|
+
hooksEffect: [],
|
|
1949
|
+
index: 0,
|
|
1950
|
+
handleChange() {
|
|
1951
|
+
}
|
|
1952
|
+
};
|
|
1953
|
+
return store;
|
|
1954
|
+
}
|
|
1955
|
+
function withHooks(rl, cb) {
|
|
1956
|
+
const store = createStore(rl);
|
|
1957
|
+
return hookStorage.run(store, () => {
|
|
1958
|
+
function cycle(render) {
|
|
1959
|
+
store.handleChange = () => {
|
|
1960
|
+
store.index = 0;
|
|
1961
|
+
render();
|
|
1962
|
+
};
|
|
1963
|
+
store.handleChange();
|
|
1964
|
+
}
|
|
1965
|
+
return cb(cycle);
|
|
1966
|
+
});
|
|
1967
|
+
}
|
|
1968
|
+
function getStore() {
|
|
1969
|
+
const store = hookStorage.getStore();
|
|
1970
|
+
if (!store) {
|
|
1971
|
+
throw new HookError("[Inquirer] Hook functions can only be called from within a prompt");
|
|
1972
|
+
}
|
|
1973
|
+
return store;
|
|
1974
|
+
}
|
|
1975
|
+
function readline() {
|
|
1976
|
+
return getStore().rl;
|
|
1977
|
+
}
|
|
1978
|
+
function withUpdates(fn) {
|
|
1979
|
+
const wrapped = (...args2) => {
|
|
1980
|
+
const store = getStore();
|
|
1981
|
+
let shouldUpdate = false;
|
|
1982
|
+
const oldHandleChange = store.handleChange;
|
|
1983
|
+
store.handleChange = () => {
|
|
1984
|
+
shouldUpdate = true;
|
|
1985
|
+
};
|
|
1986
|
+
const returnValue = fn(...args2);
|
|
1987
|
+
if (shouldUpdate) {
|
|
1988
|
+
oldHandleChange();
|
|
1989
|
+
}
|
|
1990
|
+
store.handleChange = oldHandleChange;
|
|
1991
|
+
return returnValue;
|
|
1992
|
+
};
|
|
1993
|
+
return AsyncResource.bind(wrapped);
|
|
1994
|
+
}
|
|
1995
|
+
function withPointer(cb) {
|
|
1996
|
+
const store = getStore();
|
|
1997
|
+
const { index } = store;
|
|
1998
|
+
const pointer = {
|
|
1999
|
+
get() {
|
|
2000
|
+
return store.hooks[index];
|
|
2001
|
+
},
|
|
2002
|
+
set(value) {
|
|
2003
|
+
store.hooks[index] = value;
|
|
2004
|
+
},
|
|
2005
|
+
initialized: index in store.hooks
|
|
2006
|
+
};
|
|
2007
|
+
const returnValue = cb(pointer);
|
|
2008
|
+
store.index++;
|
|
2009
|
+
return returnValue;
|
|
2010
|
+
}
|
|
2011
|
+
function handleChange() {
|
|
2012
|
+
getStore().handleChange();
|
|
2013
|
+
}
|
|
2014
|
+
var effectScheduler = {
|
|
2015
|
+
queue(cb) {
|
|
2016
|
+
const store = getStore();
|
|
2017
|
+
const { index } = store;
|
|
2018
|
+
store.hooksEffect.push(() => {
|
|
2019
|
+
store.hooksCleanup[index]?.();
|
|
2020
|
+
const cleanFn = cb(readline());
|
|
2021
|
+
if (cleanFn != null && typeof cleanFn !== "function") {
|
|
2022
|
+
throw new ValidationError("useEffect return value must be a cleanup function or nothing.");
|
|
2023
|
+
}
|
|
2024
|
+
store.hooksCleanup[index] = cleanFn;
|
|
2025
|
+
});
|
|
2026
|
+
},
|
|
2027
|
+
run() {
|
|
2028
|
+
const store = getStore();
|
|
2029
|
+
withUpdates(() => {
|
|
2030
|
+
store.hooksEffect.forEach((effect) => {
|
|
2031
|
+
effect();
|
|
2032
|
+
});
|
|
2033
|
+
store.hooksEffect.length = 0;
|
|
2034
|
+
})();
|
|
2035
|
+
},
|
|
2036
|
+
clearAll() {
|
|
2037
|
+
const store = getStore();
|
|
2038
|
+
store.hooksCleanup.forEach((cleanFn) => {
|
|
2039
|
+
cleanFn?.();
|
|
2040
|
+
});
|
|
2041
|
+
store.hooksEffect.length = 0;
|
|
2042
|
+
store.hooksCleanup.length = 0;
|
|
2043
|
+
}
|
|
2044
|
+
};
|
|
2045
|
+
|
|
2046
|
+
// node_modules/@inquirer/core/dist/lib/use-state.js
|
|
2047
|
+
function useState(defaultValue) {
|
|
2048
|
+
return withPointer((pointer) => {
|
|
2049
|
+
const setState = AsyncResource2.bind(function setState2(newValue) {
|
|
2050
|
+
if (pointer.get() !== newValue) {
|
|
2051
|
+
pointer.set(newValue);
|
|
2052
|
+
handleChange();
|
|
2053
|
+
}
|
|
2054
|
+
});
|
|
2055
|
+
if (pointer.initialized) {
|
|
2056
|
+
return [pointer.get(), setState];
|
|
2057
|
+
}
|
|
2058
|
+
const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
|
|
2059
|
+
pointer.set(value);
|
|
2060
|
+
return [value, setState];
|
|
2061
|
+
});
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
// node_modules/@inquirer/core/dist/lib/use-effect.js
|
|
514
2065
|
function useEffect(cb, depArray) {
|
|
515
2066
|
withPointer((pointer) => {
|
|
516
2067
|
const oldDeps = pointer.get();
|
|
@@ -2558,7 +4109,6 @@ async function resolveConfig() {
|
|
|
2558
4109
|
}
|
|
2559
4110
|
const resolved = {
|
|
2560
4111
|
project: projectConfig.project,
|
|
2561
|
-
environment: projectConfig.environment,
|
|
2562
4112
|
host: projectConfig.host || globalConfig.host || DEFAULT_HOST,
|
|
2563
4113
|
namespace: projectConfig.namespace || globalConfig.namespace || DEFAULT_NAMESPACE,
|
|
2564
4114
|
authToken
|
|
@@ -2570,9 +4120,6 @@ function validateResolvedConfig(config) {
|
|
|
2570
4120
|
if (!config.project) {
|
|
2571
4121
|
errors.push("Project name is required");
|
|
2572
4122
|
}
|
|
2573
|
-
if (!config.environment) {
|
|
2574
|
-
errors.push("Environment name is required");
|
|
2575
|
-
}
|
|
2576
4123
|
if (!config.host) {
|
|
2577
4124
|
errors.push(
|
|
2578
4125
|
"Host URL is required (set globally with: jssm config set host <url>)"
|
|
@@ -2617,140 +4164,395 @@ async function getProjects(host, apiKey) {
|
|
|
2617
4164
|
const url = `${host}/projects`;
|
|
2618
4165
|
return apiRequest(url, apiKey);
|
|
2619
4166
|
}
|
|
2620
|
-
async function
|
|
2621
|
-
const url = `${host}/projects/${project}/
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
body
|
|
2625
|
-
}
|
|
2626
|
-
}
|
|
2627
|
-
async function getEnvironments(host, apiKey, project) {
|
|
2628
|
-
const url = `${host}/projects/${project}/envs`;
|
|
2629
|
-
return apiRequest(url, apiKey);
|
|
2630
|
-
}
|
|
2631
|
-
async function pushEnvFile(host, apiKey, project, environment, content, filename = ".env") {
|
|
2632
|
-
const url = `${host}/projects/${project}/envs/${environment}/push-file`;
|
|
4167
|
+
async function pushEnvFile(host, apiKey, project, content, filename = ".env", environment) {
|
|
4168
|
+
const url = `${host}/projects/${project}/files/push`;
|
|
4169
|
+
const body = { content, filename };
|
|
4170
|
+
if (environment) {
|
|
4171
|
+
body.environment = environment;
|
|
4172
|
+
}
|
|
2633
4173
|
return apiRequest(url, apiKey, {
|
|
2634
4174
|
method: "POST",
|
|
2635
|
-
body: JSON.stringify(
|
|
4175
|
+
body: JSON.stringify(body)
|
|
2636
4176
|
});
|
|
2637
4177
|
}
|
|
2638
|
-
async function pullEnvFile(host, apiKey, project,
|
|
2639
|
-
const url = `${host}/projects/${project}/
|
|
4178
|
+
async function pullEnvFile(host, apiKey, project, filename = ".env") {
|
|
4179
|
+
const url = `${host}/projects/${project}/files/pull?filename=${encodeURIComponent(
|
|
2640
4180
|
filename
|
|
2641
4181
|
)}`;
|
|
2642
4182
|
const data = await apiRequest(url, apiKey);
|
|
2643
4183
|
return data.content;
|
|
2644
4184
|
}
|
|
2645
|
-
async function listEnvFiles(host, apiKey, project
|
|
2646
|
-
const url = `${host}/projects/${project}/
|
|
2647
|
-
const data = await apiRequest(url, apiKey);
|
|
2648
|
-
return data.files;
|
|
4185
|
+
async function listEnvFiles(host, apiKey, project) {
|
|
4186
|
+
const url = `${host}/projects/${project}/files/list`;
|
|
4187
|
+
const data = await apiRequest(url, apiKey);
|
|
4188
|
+
return data.files;
|
|
4189
|
+
}
|
|
4190
|
+
|
|
4191
|
+
// src/utils/repoDetector.ts
|
|
4192
|
+
import { readdir, readFile as readFile3, stat } from "fs/promises";
|
|
4193
|
+
import { join as join3, relative } from "path";
|
|
4194
|
+
function isEnvFile(filename) {
|
|
4195
|
+
return filename === ".env" || filename.startsWith(".env.");
|
|
4196
|
+
}
|
|
4197
|
+
async function isMonorepo(rootPath) {
|
|
4198
|
+
try {
|
|
4199
|
+
const indicators = [
|
|
4200
|
+
"lerna.json",
|
|
4201
|
+
"nx.json",
|
|
4202
|
+
"pnpm-workspace.yaml",
|
|
4203
|
+
"rush.json"
|
|
4204
|
+
];
|
|
4205
|
+
for (const indicator of indicators) {
|
|
4206
|
+
try {
|
|
4207
|
+
await stat(join3(rootPath, indicator));
|
|
4208
|
+
return true;
|
|
4209
|
+
} catch {
|
|
4210
|
+
}
|
|
4211
|
+
}
|
|
4212
|
+
const commonDirs = ["packages", "apps", "services"];
|
|
4213
|
+
for (const dir of commonDirs) {
|
|
4214
|
+
try {
|
|
4215
|
+
const dirPath = join3(rootPath, dir);
|
|
4216
|
+
const dirStat = await stat(dirPath);
|
|
4217
|
+
if (dirStat.isDirectory()) {
|
|
4218
|
+
const entries = await readdir(dirPath, { withFileTypes: true });
|
|
4219
|
+
const subdirs = entries.filter((e) => e.isDirectory());
|
|
4220
|
+
if (subdirs.length >= 2) {
|
|
4221
|
+
return true;
|
|
4222
|
+
}
|
|
4223
|
+
}
|
|
4224
|
+
} catch {
|
|
4225
|
+
}
|
|
4226
|
+
}
|
|
4227
|
+
try {
|
|
4228
|
+
const packageJsonPath = join3(rootPath, "package.json");
|
|
4229
|
+
const packageJson = JSON.parse(await readFile3(packageJsonPath, "utf-8"));
|
|
4230
|
+
if (packageJson.workspaces) {
|
|
4231
|
+
return true;
|
|
4232
|
+
}
|
|
4233
|
+
} catch {
|
|
4234
|
+
}
|
|
4235
|
+
return false;
|
|
4236
|
+
} catch {
|
|
4237
|
+
return false;
|
|
4238
|
+
}
|
|
4239
|
+
}
|
|
4240
|
+
async function findEnvFiles(rootPath, maxDepth = 10) {
|
|
4241
|
+
const envFiles = [];
|
|
4242
|
+
async function search(currentPath, depth) {
|
|
4243
|
+
if (maxDepth !== -1 && depth > maxDepth)
|
|
4244
|
+
return;
|
|
4245
|
+
try {
|
|
4246
|
+
const entries = await readdir(currentPath, { withFileTypes: true });
|
|
4247
|
+
for (const entry of entries) {
|
|
4248
|
+
const fullPath = join3(currentPath, entry.name);
|
|
4249
|
+
if (entry.isDirectory() && ![
|
|
4250
|
+
"node_modules",
|
|
4251
|
+
".git",
|
|
4252
|
+
"dist",
|
|
4253
|
+
"build",
|
|
4254
|
+
".next",
|
|
4255
|
+
"coverage",
|
|
4256
|
+
".turbo",
|
|
4257
|
+
".cache",
|
|
4258
|
+
"out",
|
|
4259
|
+
"target"
|
|
4260
|
+
].includes(entry.name)) {
|
|
4261
|
+
await search(fullPath, depth + 1);
|
|
4262
|
+
} else if (entry.isFile() && isEnvFile(entry.name)) {
|
|
4263
|
+
try {
|
|
4264
|
+
const content = await readFile3(fullPath, "utf-8");
|
|
4265
|
+
const lines = content.split("\n");
|
|
4266
|
+
const variableCount = lines.filter((line) => {
|
|
4267
|
+
const trimmed = line.trim();
|
|
4268
|
+
return trimmed && !trimmed.startsWith("#") && trimmed.includes("=");
|
|
4269
|
+
}).length;
|
|
4270
|
+
envFiles.push({
|
|
4271
|
+
path: fullPath,
|
|
4272
|
+
relativePath: relative(rootPath, fullPath),
|
|
4273
|
+
variableCount
|
|
4274
|
+
});
|
|
4275
|
+
} catch {
|
|
4276
|
+
}
|
|
4277
|
+
}
|
|
4278
|
+
}
|
|
4279
|
+
} catch {
|
|
4280
|
+
}
|
|
4281
|
+
}
|
|
4282
|
+
await search(rootPath, 0);
|
|
4283
|
+
return envFiles;
|
|
4284
|
+
}
|
|
4285
|
+
async function getRepositoryType(rootPath) {
|
|
4286
|
+
const isMonorepoResult = await isMonorepo(rootPath);
|
|
4287
|
+
return isMonorepoResult ? "monorepo" : "normal";
|
|
2649
4288
|
}
|
|
2650
4289
|
|
|
2651
|
-
// src/
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
"rush.json"
|
|
2664
|
-
];
|
|
2665
|
-
for (const indicator of indicators) {
|
|
2666
|
-
try {
|
|
2667
|
-
await stat(join3(rootPath, indicator));
|
|
2668
|
-
return true;
|
|
2669
|
-
} catch {
|
|
4290
|
+
// src/commands/init.ts
|
|
4291
|
+
async function initCommand(args2) {
|
|
4292
|
+
const flags = {};
|
|
4293
|
+
for (let i = 0; i < args2.length; i++) {
|
|
4294
|
+
if (args2[i].startsWith("-")) {
|
|
4295
|
+
const key = args2[i].replace(/^-+/, "");
|
|
4296
|
+
const value = args2[i + 1];
|
|
4297
|
+
if (value && !value.startsWith("-")) {
|
|
4298
|
+
flags[key] = value;
|
|
4299
|
+
i++;
|
|
4300
|
+
} else {
|
|
4301
|
+
flags[key] = "true";
|
|
2670
4302
|
}
|
|
2671
4303
|
}
|
|
2672
|
-
|
|
2673
|
-
|
|
4304
|
+
}
|
|
4305
|
+
const configExists = await hasLocalConfig();
|
|
4306
|
+
if (configExists && !flags.force && !flags.f) {
|
|
4307
|
+
const projectConfig = await loadProjectConfig();
|
|
4308
|
+
if (projectConfig) {
|
|
4309
|
+
console.log("\u{1F4C1} JSSM project already initialized\n");
|
|
4310
|
+
console.log(` Project: ${projectConfig.project}`);
|
|
4311
|
+
console.log();
|
|
2674
4312
|
try {
|
|
2675
|
-
const
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
4313
|
+
const action = await dist_default6({
|
|
4314
|
+
message: "What would you like to do?",
|
|
4315
|
+
choices: [
|
|
4316
|
+
{
|
|
4317
|
+
name: "\u{1F4E5} Pull - Download .env files from server",
|
|
4318
|
+
value: "pull"
|
|
4319
|
+
},
|
|
4320
|
+
{
|
|
4321
|
+
name: "\u{1F4E4} Push - Upload local .env files to server",
|
|
4322
|
+
value: "push"
|
|
4323
|
+
},
|
|
4324
|
+
{
|
|
4325
|
+
name: "\u{1F504} Reinitialize - Set up a different project",
|
|
4326
|
+
value: "reinit"
|
|
4327
|
+
},
|
|
4328
|
+
{ name: "\u274C Cancel", value: "cancel" }
|
|
4329
|
+
]
|
|
4330
|
+
});
|
|
4331
|
+
if (action === "pull") {
|
|
4332
|
+
await pullCommand([]);
|
|
4333
|
+
return;
|
|
4334
|
+
} else if (action === "push") {
|
|
4335
|
+
await pushCommand([]);
|
|
4336
|
+
return;
|
|
4337
|
+
} else if (action === "cancel") {
|
|
4338
|
+
console.log("\n\u{1F44B} Cancelled");
|
|
4339
|
+
return;
|
|
4340
|
+
}
|
|
4341
|
+
console.log();
|
|
4342
|
+
} catch (error) {
|
|
4343
|
+
if (error.name === "ExitPromptError") {
|
|
4344
|
+
console.log("\n\u{1F44B} Cancelled");
|
|
4345
|
+
return;
|
|
4346
|
+
}
|
|
4347
|
+
throw error;
|
|
4348
|
+
}
|
|
4349
|
+
}
|
|
4350
|
+
}
|
|
4351
|
+
console.log("\u{1F680} JSSM Project Initialization\n");
|
|
4352
|
+
console.log("\u{1F510} Checking authentication...");
|
|
4353
|
+
const authData = await loadAuthData();
|
|
4354
|
+
if (!authData) {
|
|
4355
|
+
console.log("\n\u274C You are not logged in");
|
|
4356
|
+
console.log("\u{1F4A1} Please login or register first:");
|
|
4357
|
+
console.log(" jssm login");
|
|
4358
|
+
console.log(" jssm register");
|
|
4359
|
+
process.exit(1);
|
|
4360
|
+
}
|
|
4361
|
+
console.log(`\u2705 Logged in as ${authData.user.email}
|
|
4362
|
+
`);
|
|
4363
|
+
const globalConfig = await loadGlobalConfig();
|
|
4364
|
+
const host = flags.host || flags.h || globalConfig.host;
|
|
4365
|
+
if (!host) {
|
|
4366
|
+
console.error("\u274C Host URL is required");
|
|
4367
|
+
console.error("\u{1F4A1} Set it globally: jssm config set host <url>");
|
|
4368
|
+
process.exit(1);
|
|
4369
|
+
}
|
|
4370
|
+
const authToken = authData.token;
|
|
4371
|
+
console.log("\u{1F50D} Analyzing repository...");
|
|
4372
|
+
const cwd = process.cwd();
|
|
4373
|
+
const repoType = await getRepositoryType(cwd);
|
|
4374
|
+
console.log(` Repository type: ${repoType}`);
|
|
4375
|
+
const envFiles = await findEnvFiles(cwd);
|
|
4376
|
+
if (envFiles.length > 0) {
|
|
4377
|
+
console.log(` Found ${envFiles.length} .env file(s)`);
|
|
4378
|
+
} else {
|
|
4379
|
+
console.log(` No .env files found`);
|
|
4380
|
+
}
|
|
4381
|
+
console.log();
|
|
4382
|
+
let projectName;
|
|
4383
|
+
try {
|
|
4384
|
+
console.log("\u{1F4E6} Loading your projects...");
|
|
4385
|
+
const projects = await getProjects(host, authToken);
|
|
4386
|
+
if (projects.length === 0) {
|
|
4387
|
+
console.log(" No existing projects found\n");
|
|
4388
|
+
projectName = await dist_default4({
|
|
4389
|
+
message: "Project name:",
|
|
4390
|
+
validate: (value) => {
|
|
4391
|
+
if (!value)
|
|
4392
|
+
return "Project name is required";
|
|
4393
|
+
if (!/^[a-z0-9-_.]+$/.test(value)) {
|
|
4394
|
+
return "Project name must contain only lowercase letters, numbers, hyphens, underscores, and dots";
|
|
4395
|
+
}
|
|
4396
|
+
return true;
|
|
4397
|
+
}
|
|
4398
|
+
});
|
|
4399
|
+
console.log(`
|
|
4400
|
+
\u{1F4E6} Creating project "${projectName}"...`);
|
|
4401
|
+
await createProject(host, authToken, projectName, repoType);
|
|
4402
|
+
console.log(`\u2705 Project created
|
|
4403
|
+
`);
|
|
4404
|
+
} else {
|
|
4405
|
+
const projectChoices = [
|
|
4406
|
+
...projects.map((p) => ({ name: p.name, value: p.name })),
|
|
4407
|
+
{ name: "+ Create new project", value: "__new__" }
|
|
4408
|
+
];
|
|
4409
|
+
const selectedProject = await dist_default6({
|
|
4410
|
+
message: "Select a project:",
|
|
4411
|
+
choices: projectChoices
|
|
4412
|
+
});
|
|
4413
|
+
if (selectedProject === "__new__") {
|
|
4414
|
+
projectName = await dist_default4({
|
|
4415
|
+
message: "New project name:",
|
|
4416
|
+
validate: (value) => {
|
|
4417
|
+
if (!value)
|
|
4418
|
+
return "Project name is required";
|
|
4419
|
+
if (!/^[a-z0-9-_.]+$/.test(value)) {
|
|
4420
|
+
return "Project name must contain only lowercase letters, numbers, hyphens, underscores, and dots";
|
|
4421
|
+
}
|
|
4422
|
+
if (projects.some((p) => p.name === value)) {
|
|
4423
|
+
return "Project already exists";
|
|
4424
|
+
}
|
|
2681
4425
|
return true;
|
|
2682
4426
|
}
|
|
4427
|
+
});
|
|
4428
|
+
console.log(`
|
|
4429
|
+
\u{1F4E6} Creating project "${projectName}"...`);
|
|
4430
|
+
await createProject(host, authToken, projectName, repoType);
|
|
4431
|
+
console.log(`\u2705 Project created
|
|
4432
|
+
`);
|
|
4433
|
+
} else {
|
|
4434
|
+
projectName = selectedProject;
|
|
4435
|
+
}
|
|
4436
|
+
}
|
|
4437
|
+
if (envFiles.length > 0) {
|
|
4438
|
+
console.log("\u{1F4C4} .env files detected:");
|
|
4439
|
+
envFiles.forEach((file) => {
|
|
4440
|
+
console.log(
|
|
4441
|
+
` ${file.relativePath} (${file.variableCount} variables)`
|
|
4442
|
+
);
|
|
4443
|
+
});
|
|
4444
|
+
console.log();
|
|
4445
|
+
const shouldUpload = await dist_default3({
|
|
4446
|
+
message: "Would you like to upload variables from .env files?",
|
|
4447
|
+
default: true
|
|
4448
|
+
});
|
|
4449
|
+
if (shouldUpload) {
|
|
4450
|
+
let selectedFileInfos;
|
|
4451
|
+
if (repoType === "monorepo" && envFiles.length > 1) {
|
|
4452
|
+
const fileChoices = envFiles.map((file) => ({
|
|
4453
|
+
name: `${file.relativePath} (${file.variableCount} variables)`,
|
|
4454
|
+
value: file.relativePath
|
|
4455
|
+
}));
|
|
4456
|
+
const selectedPaths = await dist_default2({
|
|
4457
|
+
message: "Select .env files to upload:",
|
|
4458
|
+
choices: fileChoices,
|
|
4459
|
+
validate: (answer) => {
|
|
4460
|
+
if (answer.length === 0) {
|
|
4461
|
+
return "Please select at least one file";
|
|
4462
|
+
}
|
|
4463
|
+
return true;
|
|
4464
|
+
}
|
|
4465
|
+
});
|
|
4466
|
+
selectedFileInfos = envFiles.filter(
|
|
4467
|
+
(f) => selectedPaths.includes(f.relativePath)
|
|
4468
|
+
);
|
|
4469
|
+
} else {
|
|
4470
|
+
selectedFileInfos = [envFiles[0]];
|
|
4471
|
+
}
|
|
4472
|
+
const totalVars = selectedFileInfos.reduce(
|
|
4473
|
+
(sum, f) => sum + f.variableCount,
|
|
4474
|
+
0
|
|
4475
|
+
);
|
|
4476
|
+
console.log(
|
|
4477
|
+
`
|
|
4478
|
+
\u{1F4CB} Files to upload (${selectedFileInfos.length} files, ${totalVars} total variables):`
|
|
4479
|
+
);
|
|
4480
|
+
selectedFileInfos.forEach((f) => {
|
|
4481
|
+
console.log(` ${f.relativePath} (${f.variableCount} variables)`);
|
|
4482
|
+
});
|
|
4483
|
+
const confirmUpload = await dist_default3({
|
|
4484
|
+
message: "\nProceed with upload?",
|
|
4485
|
+
default: true
|
|
4486
|
+
});
|
|
4487
|
+
if (confirmUpload) {
|
|
4488
|
+
console.log(`
|
|
4489
|
+
\u2B06\uFE0F Uploading ${selectedFileInfos.length} file(s)...`);
|
|
4490
|
+
let successCount = 0;
|
|
4491
|
+
let failCount = 0;
|
|
4492
|
+
for (const fileInfo of selectedFileInfos) {
|
|
4493
|
+
try {
|
|
4494
|
+
const { readFile: readFileAsync } = await import("fs/promises");
|
|
4495
|
+
const content = await readFileAsync(fileInfo.path, "utf-8");
|
|
4496
|
+
await pushEnvFile(
|
|
4497
|
+
host,
|
|
4498
|
+
authToken,
|
|
4499
|
+
projectName,
|
|
4500
|
+
content,
|
|
4501
|
+
fileInfo.relativePath
|
|
4502
|
+
);
|
|
4503
|
+
console.log(` \u2705 ${fileInfo.relativePath}`);
|
|
4504
|
+
successCount++;
|
|
4505
|
+
} catch (error) {
|
|
4506
|
+
console.log(` \u274C ${fileInfo.relativePath}: ${error.message}`);
|
|
4507
|
+
failCount++;
|
|
4508
|
+
}
|
|
4509
|
+
}
|
|
4510
|
+
if (failCount === 0) {
|
|
4511
|
+
console.log(`\u2705 All files uploaded successfully`);
|
|
4512
|
+
} else {
|
|
4513
|
+
console.log(`
|
|
4514
|
+
\u26A0\uFE0F ${successCount} succeeded, ${failCount} failed`);
|
|
4515
|
+
}
|
|
4516
|
+
} else {
|
|
4517
|
+
console.log("\n\u23ED\uFE0F Skipping file upload");
|
|
2683
4518
|
}
|
|
2684
|
-
} catch {
|
|
2685
4519
|
}
|
|
2686
4520
|
}
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
}
|
|
2693
|
-
} catch {
|
|
4521
|
+
const projectConfig = {
|
|
4522
|
+
project: projectName
|
|
4523
|
+
};
|
|
4524
|
+
if (flags.host && flags.host !== globalConfig.host) {
|
|
4525
|
+
projectConfig.host = flags.host;
|
|
2694
4526
|
}
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
"build",
|
|
2714
|
-
".next",
|
|
2715
|
-
"coverage",
|
|
2716
|
-
".turbo",
|
|
2717
|
-
".cache",
|
|
2718
|
-
"out",
|
|
2719
|
-
"target"
|
|
2720
|
-
].includes(entry.name)) {
|
|
2721
|
-
await search(fullPath, depth + 1);
|
|
2722
|
-
} else if (entry.isFile() && isEnvFile(entry.name)) {
|
|
2723
|
-
try {
|
|
2724
|
-
const content = await readFile3(fullPath, "utf-8");
|
|
2725
|
-
const lines = content.split("\n");
|
|
2726
|
-
const variableCount = lines.filter((line) => {
|
|
2727
|
-
const trimmed = line.trim();
|
|
2728
|
-
return trimmed && !trimmed.startsWith("#") && trimmed.includes("=");
|
|
2729
|
-
}).length;
|
|
2730
|
-
envFiles.push({
|
|
2731
|
-
path: fullPath,
|
|
2732
|
-
relativePath: relative(rootPath, fullPath),
|
|
2733
|
-
variableCount
|
|
2734
|
-
});
|
|
2735
|
-
} catch {
|
|
2736
|
-
}
|
|
2737
|
-
}
|
|
2738
|
-
}
|
|
2739
|
-
} catch {
|
|
4527
|
+
if (flags.namespace && flags.namespace !== globalConfig.namespace) {
|
|
4528
|
+
projectConfig.namespace = flags.namespace;
|
|
4529
|
+
}
|
|
4530
|
+
await saveProjectConfig(projectConfig);
|
|
4531
|
+
console.log(`
|
|
4532
|
+
\u2705 Project initialized successfully!`);
|
|
4533
|
+
console.log(` Config file: .jssm`);
|
|
4534
|
+
console.log(` Project: ${projectName}`);
|
|
4535
|
+
console.log(` Repository type: ${repoType}`);
|
|
4536
|
+
console.log(`
|
|
4537
|
+
\u{1F4A1} Next steps:`);
|
|
4538
|
+
console.log(` - Run "jssm pull" to fetch variables`);
|
|
4539
|
+
console.log(` - Run "jssm sync" to sync variables to .env`);
|
|
4540
|
+
console.log(` - Run "jssm push" to upload local .env changes`);
|
|
4541
|
+
} catch (error) {
|
|
4542
|
+
if (error.name === "ExitPromptError") {
|
|
4543
|
+
console.log("\n\u274C Initialization cancelled");
|
|
4544
|
+
process.exit(0);
|
|
2740
4545
|
}
|
|
4546
|
+
console.error(`
|
|
4547
|
+
\u274C Error: ${error.message}`);
|
|
4548
|
+
process.exit(1);
|
|
2741
4549
|
}
|
|
2742
|
-
await search(rootPath, 0);
|
|
2743
|
-
return envFiles;
|
|
2744
|
-
}
|
|
2745
|
-
async function getRepositoryType(rootPath) {
|
|
2746
|
-
const isMonorepoResult = await isMonorepo(rootPath);
|
|
2747
|
-
return isMonorepoResult ? "monorepo" : "normal";
|
|
2748
4550
|
}
|
|
2749
4551
|
|
|
2750
4552
|
// src/commands/pull.ts
|
|
2751
4553
|
import { writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
2752
4554
|
import { join as join4, dirname } from "path";
|
|
2753
|
-
async function
|
|
4555
|
+
async function pullCommand2(args2) {
|
|
2754
4556
|
const flags = {};
|
|
2755
4557
|
let pullAll = false;
|
|
2756
4558
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -2768,7 +4570,7 @@ async function pullCommand(args2) {
|
|
|
2768
4570
|
const config = await resolveConfig();
|
|
2769
4571
|
if (!config) {
|
|
2770
4572
|
console.error("\u274C No .jssm configuration found in current directory.");
|
|
2771
|
-
console.error('\u{1F4A1} Run "jssm init -p <project>
|
|
4573
|
+
console.error('\u{1F4A1} Run "jssm init -p <project>" to initialize.');
|
|
2772
4574
|
process.exit(1);
|
|
2773
4575
|
}
|
|
2774
4576
|
const { valid, errors } = validateResolvedConfig(config);
|
|
@@ -2778,22 +4580,18 @@ async function pullCommand(args2) {
|
|
|
2778
4580
|
process.exit(1);
|
|
2779
4581
|
}
|
|
2780
4582
|
const project = flags.p || flags.project || config.project;
|
|
2781
|
-
const environment = flags.e || flags.env || config.environment;
|
|
2782
4583
|
const output = flags.out;
|
|
2783
|
-
if (project !== config.project
|
|
2784
|
-
console.log(`\u26A0\uFE0F Warning: Pulling from ${project}
|
|
2785
|
-
console.log(
|
|
2786
|
-
` This directory is initialized for ${config.project}/${config.environment}`
|
|
2787
|
-
);
|
|
4584
|
+
if (project !== config.project) {
|
|
4585
|
+
console.log(`\u26A0\uFE0F Warning: Pulling from ${project}`);
|
|
4586
|
+
console.log(` This directory is initialized for ${config.project}`);
|
|
2788
4587
|
}
|
|
2789
4588
|
try {
|
|
2790
4589
|
if (output) {
|
|
2791
|
-
console.log(`\u{1F4E5} Pulling ${output} from ${project}
|
|
4590
|
+
console.log(`\u{1F4E5} Pulling ${output} from ${project}...`);
|
|
2792
4591
|
const content = await pullEnvFile(
|
|
2793
4592
|
config.host,
|
|
2794
4593
|
config.authToken,
|
|
2795
4594
|
project,
|
|
2796
|
-
environment,
|
|
2797
4595
|
output
|
|
2798
4596
|
);
|
|
2799
4597
|
const outputPath = join4(process.cwd(), output);
|
|
@@ -2806,196 +4604,33 @@ async function pullCommand(args2) {
|
|
|
2806
4604
|
console.log(`\u2705 Wrote ${output} (${varCount} variables)`);
|
|
2807
4605
|
return;
|
|
2808
4606
|
}
|
|
2809
|
-
console.log(`\u{1F4E5} Checking available files in ${project}
|
|
4607
|
+
console.log(`\u{1F4E5} Checking available files in ${project}...`);
|
|
2810
4608
|
const availableFiles = await listEnvFiles(
|
|
2811
4609
|
config.host,
|
|
2812
4610
|
config.authToken,
|
|
2813
|
-
project
|
|
2814
|
-
environment
|
|
4611
|
+
project
|
|
2815
4612
|
);
|
|
2816
4613
|
if (availableFiles.length === 0) {
|
|
2817
4614
|
console.error("\u274C No .env files found on server");
|
|
2818
4615
|
console.error("\u{1F4A1} Push files first with: jssm push");
|
|
2819
4616
|
process.exit(1);
|
|
2820
4617
|
}
|
|
2821
|
-
let selectedFiles = [];
|
|
2822
|
-
if (availableFiles.length === 1) {
|
|
2823
|
-
selectedFiles = [availableFiles[0]];
|
|
2824
|
-
console.log(`\u{1F4C4} Found ${availableFiles[0]} on server`);
|
|
2825
|
-
} else if (pullAll) {
|
|
2826
|
-
selectedFiles = availableFiles;
|
|
2827
|
-
console.log(`\u{1F4C4} Found ${availableFiles.length} files on server`);
|
|
2828
|
-
} else {
|
|
2829
|
-
console.log(`\u{1F4C4} Found ${availableFiles.length} .env files on server:
|
|
2830
|
-
`);
|
|
2831
|
-
availableFiles.forEach((file) => {
|
|
2832
|
-
console.log(` \u2022 ${file}`);
|
|
2833
|
-
});
|
|
2834
|
-
console.log();
|
|
2835
|
-
const pullOption = await dist_default6({
|
|
2836
|
-
message: "What would you like to pull?",
|
|
2837
|
-
choices: [
|
|
2838
|
-
{
|
|
2839
|
-
name: "\u2728 All files",
|
|
2840
|
-
value: "all"
|
|
2841
|
-
},
|
|
2842
|
-
{
|
|
2843
|
-
name: "\u{1F4C1} Select specific files",
|
|
2844
|
-
value: "specific"
|
|
2845
|
-
}
|
|
2846
|
-
]
|
|
2847
|
-
});
|
|
2848
|
-
if (pullOption === "all") {
|
|
2849
|
-
selectedFiles = availableFiles;
|
|
2850
|
-
} else {
|
|
2851
|
-
const fileChoices = availableFiles.map((file) => ({
|
|
2852
|
-
name: file,
|
|
2853
|
-
value: file,
|
|
2854
|
-
checked: false
|
|
2855
|
-
}));
|
|
2856
|
-
selectedFiles = await dist_default2({
|
|
2857
|
-
message: "Select .env file(s) to pull:",
|
|
2858
|
-
choices: fileChoices,
|
|
2859
|
-
validate: (answer) => {
|
|
2860
|
-
if (answer.length === 0) {
|
|
2861
|
-
return "Please select at least one file";
|
|
2862
|
-
}
|
|
2863
|
-
return true;
|
|
2864
|
-
}
|
|
2865
|
-
});
|
|
2866
|
-
}
|
|
2867
|
-
}
|
|
2868
|
-
if (selectedFiles.length === 1) {
|
|
2869
|
-
console.log(`
|
|
2870
|
-
\u{1F4E5} Pulling ${selectedFiles[0]}...`);
|
|
2871
|
-
} else {
|
|
2872
|
-
console.log(`
|
|
2873
|
-
\u{1F4E5} Pulling ${selectedFiles.length} files...
|
|
2874
|
-
`);
|
|
2875
|
-
}
|
|
2876
|
-
let successCount = 0;
|
|
2877
|
-
let failCount = 0;
|
|
2878
|
-
for (const filename of selectedFiles) {
|
|
2879
|
-
try {
|
|
2880
|
-
const content = await pullEnvFile(
|
|
2881
|
-
config.host,
|
|
2882
|
-
config.authToken,
|
|
2883
|
-
project,
|
|
2884
|
-
environment,
|
|
2885
|
-
filename
|
|
2886
|
-
);
|
|
2887
|
-
const outputPath = join4(process.cwd(), filename);
|
|
2888
|
-
const dir = dirname(outputPath);
|
|
2889
|
-
if (dir !== process.cwd()) {
|
|
2890
|
-
await mkdir3(dir, { recursive: true });
|
|
2891
|
-
}
|
|
2892
|
-
await writeFile3(outputPath, content, "utf-8");
|
|
2893
|
-
const varCount = countVariables(content);
|
|
2894
|
-
if (selectedFiles.length === 1) {
|
|
2895
|
-
console.log(`\u2705 Wrote ${filename} (${varCount} variables)`);
|
|
2896
|
-
} else {
|
|
2897
|
-
console.log(`\u2705 ${filename}: Pulled (${varCount} variables)`);
|
|
2898
|
-
}
|
|
2899
|
-
successCount++;
|
|
2900
|
-
} catch (error) {
|
|
2901
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2902
|
-
console.error(`\u274C ${filename}: Failed to pull - ${message}`);
|
|
2903
|
-
failCount++;
|
|
2904
|
-
}
|
|
2905
|
-
}
|
|
2906
|
-
if (selectedFiles.length > 1) {
|
|
2907
|
-
console.log(`
|
|
2908
|
-
\u{1F4CA} Summary:`);
|
|
2909
|
-
if (successCount > 0) {
|
|
2910
|
-
console.log(` \u2705 Success: ${successCount} file(s)`);
|
|
2911
|
-
}
|
|
2912
|
-
if (failCount > 0) {
|
|
2913
|
-
console.log(` \u274C Failed: ${failCount} file(s)`);
|
|
2914
|
-
}
|
|
2915
|
-
}
|
|
2916
|
-
if (failCount > 0 && successCount === 0) {
|
|
2917
|
-
process.exit(1);
|
|
2918
|
-
}
|
|
2919
|
-
} catch (error) {
|
|
2920
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2921
|
-
console.error("\u274C Failed to pull .env files:", message);
|
|
2922
|
-
process.exit(1);
|
|
2923
|
-
}
|
|
2924
|
-
}
|
|
2925
|
-
function countVariables(content) {
|
|
2926
|
-
return content.split("\n").filter((line) => {
|
|
2927
|
-
const trimmed = line.trim();
|
|
2928
|
-
return trimmed && !trimmed.startsWith("#") && trimmed.includes("=");
|
|
2929
|
-
}).length;
|
|
2930
|
-
}
|
|
2931
|
-
|
|
2932
|
-
// src/commands/push.ts
|
|
2933
|
-
import { readFile as readFile4 } from "fs/promises";
|
|
2934
|
-
import { join as join5 } from "path";
|
|
2935
|
-
async function pushCommand(args2) {
|
|
2936
|
-
const flags = {};
|
|
2937
|
-
for (let i = 0; i < args2.length; i++) {
|
|
2938
|
-
if (args2[i].startsWith("-")) {
|
|
2939
|
-
const key = args2[i].replace(/^-+/, "");
|
|
2940
|
-
const value = args2[i + 1];
|
|
2941
|
-
if (value && !value.startsWith("-")) {
|
|
2942
|
-
flags[key] = value;
|
|
2943
|
-
i++;
|
|
2944
|
-
}
|
|
2945
|
-
}
|
|
2946
|
-
}
|
|
2947
|
-
const config = await resolveConfig();
|
|
2948
|
-
if (!config) {
|
|
2949
|
-
console.error("\u274C No .jssm configuration found in current directory.");
|
|
2950
|
-
console.error('\u{1F4A1} Run "jssm init -p <project> -e <env>" to initialize.');
|
|
2951
|
-
process.exit(1);
|
|
2952
|
-
}
|
|
2953
|
-
const { valid, errors } = validateResolvedConfig(config);
|
|
2954
|
-
if (!valid) {
|
|
2955
|
-
console.error("\u274C Configuration is incomplete:");
|
|
2956
|
-
errors.forEach((e) => console.error(` \u2022 ${e}`));
|
|
2957
|
-
process.exit(1);
|
|
2958
|
-
}
|
|
2959
|
-
const project = flags.p || flags.project || config.project;
|
|
2960
|
-
const environment = flags.e || flags.env || config.environment;
|
|
2961
|
-
let input = flags.in || flags.input;
|
|
2962
|
-
let searchDepth = 10;
|
|
2963
|
-
if (flags.depth) {
|
|
2964
|
-
const parsedDepth = parseInt(flags.depth, 10);
|
|
2965
|
-
if (!isNaN(parsedDepth)) {
|
|
2966
|
-
searchDepth = parsedDepth;
|
|
2967
|
-
}
|
|
2968
|
-
}
|
|
2969
|
-
if (project !== config.project || environment !== config.environment) {
|
|
2970
|
-
console.log(`\u26A0\uFE0F Warning: Pushing to ${project}/${environment}`);
|
|
2971
|
-
console.log(
|
|
2972
|
-
` This directory is initialized for ${config.project}/${config.environment}`
|
|
2973
|
-
);
|
|
2974
|
-
}
|
|
2975
|
-
let selectedFiles = [];
|
|
2976
|
-
if (!input) {
|
|
2977
|
-
const cwd = process.cwd();
|
|
2978
|
-
const envFiles = await findEnvFiles(cwd, searchDepth);
|
|
2979
|
-
if (envFiles.length === 0) {
|
|
2980
|
-
console.error("\u274C No .env files found");
|
|
2981
|
-
console.error("\u{1F4A1} Create a .env file or specify one with --input <file>");
|
|
2982
|
-
process.exit(1);
|
|
2983
|
-
} else if (envFiles.length === 1) {
|
|
2984
|
-
selectedFiles = [envFiles[0].relativePath];
|
|
2985
|
-
console.log(
|
|
2986
|
-
`\u{1F4C4} Found ${envFiles[0].relativePath} (${envFiles[0].variableCount} variables)`
|
|
2987
|
-
);
|
|
4618
|
+
let selectedFiles = [];
|
|
4619
|
+
if (availableFiles.length === 1) {
|
|
4620
|
+
selectedFiles = [availableFiles[0]];
|
|
4621
|
+
console.log(`\u{1F4C4} Found ${availableFiles[0]} on server`);
|
|
4622
|
+
} else if (pullAll) {
|
|
4623
|
+
selectedFiles = availableFiles;
|
|
4624
|
+
console.log(`\u{1F4C4} Found ${availableFiles.length} files on server`);
|
|
2988
4625
|
} else {
|
|
2989
|
-
console.log(`\u{1F4C4} Found ${
|
|
4626
|
+
console.log(`\u{1F4C4} Found ${availableFiles.length} .env files on server:
|
|
2990
4627
|
`);
|
|
2991
|
-
|
|
2992
|
-
console.log(
|
|
2993
|
-
` \u2022 ${file.relativePath} (${file.variableCount} variables)`
|
|
2994
|
-
);
|
|
4628
|
+
availableFiles.forEach((file) => {
|
|
4629
|
+
console.log(` \u2022 ${file}`);
|
|
2995
4630
|
});
|
|
2996
4631
|
console.log();
|
|
2997
|
-
const
|
|
2998
|
-
message: "What would you like to
|
|
4632
|
+
const pullOption = await dist_default6({
|
|
4633
|
+
message: "What would you like to pull?",
|
|
2999
4634
|
choices: [
|
|
3000
4635
|
{
|
|
3001
4636
|
name: "\u2728 All files",
|
|
@@ -3007,16 +4642,16 @@ async function pushCommand(args2) {
|
|
|
3007
4642
|
}
|
|
3008
4643
|
]
|
|
3009
4644
|
});
|
|
3010
|
-
if (
|
|
3011
|
-
selectedFiles =
|
|
4645
|
+
if (pullOption === "all") {
|
|
4646
|
+
selectedFiles = availableFiles;
|
|
3012
4647
|
} else {
|
|
3013
|
-
const fileChoices =
|
|
3014
|
-
name:
|
|
3015
|
-
value: file
|
|
4648
|
+
const fileChoices = availableFiles.map((file) => ({
|
|
4649
|
+
name: file,
|
|
4650
|
+
value: file,
|
|
3016
4651
|
checked: false
|
|
3017
4652
|
}));
|
|
3018
|
-
|
|
3019
|
-
message: "Select .env file(s) to
|
|
4653
|
+
selectedFiles = await dist_default2({
|
|
4654
|
+
message: "Select .env file(s) to pull:",
|
|
3020
4655
|
choices: fileChoices,
|
|
3021
4656
|
validate: (answer) => {
|
|
3022
4657
|
if (answer.length === 0) {
|
|
@@ -3025,469 +4660,307 @@ async function pushCommand(args2) {
|
|
|
3025
4660
|
return true;
|
|
3026
4661
|
}
|
|
3027
4662
|
});
|
|
3028
|
-
selectedFiles = selected;
|
|
3029
4663
|
}
|
|
3030
4664
|
}
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
for (const file of selectedFiles) {
|
|
3049
|
-
let fileContent = "";
|
|
3050
|
-
let fileSize = 0;
|
|
3051
|
-
try {
|
|
3052
|
-
const inputPath = join5(process.cwd(), file);
|
|
3053
|
-
fileContent = await readFile4(inputPath, "utf-8");
|
|
3054
|
-
fileSize = Buffer.byteLength(fileContent, "utf-8");
|
|
3055
|
-
const variables = parseVariables(fileContent, file);
|
|
3056
|
-
if (variables.length === 0) {
|
|
3057
|
-
console.log(`\u26A0\uFE0F ${file}: No variables found, skipping`);
|
|
3058
|
-
continue;
|
|
3059
|
-
}
|
|
3060
|
-
const invalidVars = variables.filter((v) => !/^[A-Z0-9_]+$/.test(v.key));
|
|
3061
|
-
if (invalidVars.length > 0) {
|
|
3062
|
-
console.error(`\u274C ${file}: Invalid variable names found:`);
|
|
3063
|
-
invalidVars.forEach(
|
|
3064
|
-
(v) => console.error(
|
|
3065
|
-
` \u2022 ${v.key} (must contain only uppercase letters, numbers, and underscores)`
|
|
3066
|
-
)
|
|
3067
|
-
);
|
|
3068
|
-
failCount++;
|
|
3069
|
-
continue;
|
|
3070
|
-
}
|
|
3071
|
-
if (fileSize > 8192) {
|
|
3072
|
-
console.error(
|
|
3073
|
-
`\u274C ${file}: File size (${fileSize} bytes) exceeds maximum (8192 bytes)`
|
|
4665
|
+
if (selectedFiles.length === 1) {
|
|
4666
|
+
console.log(`
|
|
4667
|
+
\u{1F4E5} Pulling ${selectedFiles[0]}...`);
|
|
4668
|
+
} else {
|
|
4669
|
+
console.log(`
|
|
4670
|
+
\u{1F4E5} Pulling ${selectedFiles.length} files...
|
|
4671
|
+
`);
|
|
4672
|
+
}
|
|
4673
|
+
let successCount = 0;
|
|
4674
|
+
let failCount = 0;
|
|
4675
|
+
for (const filename of selectedFiles) {
|
|
4676
|
+
try {
|
|
4677
|
+
const content = await pullEnvFile(
|
|
4678
|
+
config.host,
|
|
4679
|
+
config.authToken,
|
|
4680
|
+
project,
|
|
4681
|
+
filename
|
|
3074
4682
|
);
|
|
3075
|
-
|
|
4683
|
+
const outputPath = join4(process.cwd(), filename);
|
|
4684
|
+
const dir = dirname(outputPath);
|
|
4685
|
+
if (dir !== process.cwd()) {
|
|
4686
|
+
await mkdir3(dir, { recursive: true });
|
|
4687
|
+
}
|
|
4688
|
+
await writeFile3(outputPath, content, "utf-8");
|
|
4689
|
+
const varCount = countVariables(content);
|
|
4690
|
+
if (selectedFiles.length === 1) {
|
|
4691
|
+
console.log(`\u2705 Wrote ${filename} (${varCount} variables)`);
|
|
4692
|
+
} else {
|
|
4693
|
+
console.log(`\u2705 ${filename}: Pulled (${varCount} variables)`);
|
|
4694
|
+
}
|
|
4695
|
+
successCount++;
|
|
4696
|
+
} catch (error) {
|
|
4697
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4698
|
+
console.error(`\u274C ${filename}: Failed to pull - ${message}`);
|
|
3076
4699
|
failCount++;
|
|
3077
|
-
continue;
|
|
3078
|
-
}
|
|
3079
|
-
await pushEnvFile(
|
|
3080
|
-
config.host,
|
|
3081
|
-
config.authToken,
|
|
3082
|
-
project,
|
|
3083
|
-
environment,
|
|
3084
|
-
fileContent,
|
|
3085
|
-
file
|
|
3086
|
-
// Use full relative path, not just filename
|
|
3087
|
-
);
|
|
3088
|
-
if (selectedFiles.length === 1) {
|
|
3089
|
-
console.log(
|
|
3090
|
-
`\u2705 Pushed ${file} (${variables.length} variables) to ${project}/${environment}`
|
|
3091
|
-
);
|
|
3092
|
-
} else {
|
|
3093
|
-
console.log(`\u2705 ${file}: Pushed (${variables.length} variables)`);
|
|
3094
4700
|
}
|
|
3095
|
-
successCount++;
|
|
3096
|
-
} catch (error) {
|
|
3097
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3098
|
-
console.error(`\u274C ${file}: Failed to push - ${message}`);
|
|
3099
|
-
failCount++;
|
|
3100
4701
|
}
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
console.log(`
|
|
4702
|
+
if (selectedFiles.length > 1) {
|
|
4703
|
+
console.log(`
|
|
3104
4704
|
\u{1F4CA} Summary:`);
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
console.log(` \u274C Failed: ${failCount} file(s)`);
|
|
3108
|
-
}
|
|
3109
|
-
}
|
|
3110
|
-
if (failCount > 0) {
|
|
3111
|
-
process.exit(1);
|
|
3112
|
-
}
|
|
3113
|
-
}
|
|
3114
|
-
function parseVariables(content, filename) {
|
|
3115
|
-
const variables = [];
|
|
3116
|
-
if (filename.endsWith(".json")) {
|
|
3117
|
-
try {
|
|
3118
|
-
const obj = JSON.parse(content);
|
|
3119
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
3120
|
-
variables.push({ key, value: String(value) });
|
|
3121
|
-
}
|
|
3122
|
-
return variables;
|
|
3123
|
-
} catch (error) {
|
|
3124
|
-
throw new Error("Invalid JSON file");
|
|
3125
|
-
}
|
|
3126
|
-
}
|
|
3127
|
-
const lines = content.split("\n");
|
|
3128
|
-
let pendingComment;
|
|
3129
|
-
for (let i = 0; i < lines.length; i++) {
|
|
3130
|
-
const line = lines[i];
|
|
3131
|
-
const trimmed = line.trim();
|
|
3132
|
-
if (trimmed.startsWith("#")) {
|
|
3133
|
-
const commentText = trimmed.substring(1).trim();
|
|
3134
|
-
if (commentText && !commentText.match(/^[=\-]+$/)) {
|
|
3135
|
-
pendingComment = commentText;
|
|
3136
|
-
}
|
|
3137
|
-
continue;
|
|
3138
|
-
}
|
|
3139
|
-
if (!trimmed) {
|
|
3140
|
-
pendingComment = void 0;
|
|
3141
|
-
continue;
|
|
3142
|
-
}
|
|
3143
|
-
const match = trimmed.match(/^([A-Z0-9_]+)=(.*)$/);
|
|
3144
|
-
if (match) {
|
|
3145
|
-
const [, key, valueWithComment] = match;
|
|
3146
|
-
const inlineCommentMatch = valueWithComment.match(
|
|
3147
|
-
/^([^#]*?)\s*#\s*(.+)$/
|
|
3148
|
-
);
|
|
3149
|
-
let value;
|
|
3150
|
-
let comment = pendingComment;
|
|
3151
|
-
if (inlineCommentMatch) {
|
|
3152
|
-
value = inlineCommentMatch[1].trim();
|
|
3153
|
-
comment = inlineCommentMatch[2].trim();
|
|
3154
|
-
} else {
|
|
3155
|
-
value = valueWithComment.trim();
|
|
4705
|
+
if (successCount > 0) {
|
|
4706
|
+
console.log(` \u2705 Success: ${successCount} file(s)`);
|
|
3156
4707
|
}
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
if (comment) {
|
|
3160
|
-
variable.comment = comment;
|
|
4708
|
+
if (failCount > 0) {
|
|
4709
|
+
console.log(` \u274C Failed: ${failCount} file(s)`);
|
|
3161
4710
|
}
|
|
3162
|
-
variables.push(variable);
|
|
3163
|
-
pendingComment = void 0;
|
|
3164
4711
|
}
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
}
|
|
3168
|
-
|
|
3169
|
-
// src/commands/init.ts
|
|
3170
|
-
async function initCommand(args2) {
|
|
3171
|
-
const flags = {};
|
|
3172
|
-
for (let i = 0; i < args2.length; i++) {
|
|
3173
|
-
if (args2[i].startsWith("-")) {
|
|
3174
|
-
const key = args2[i].replace(/^-+/, "");
|
|
3175
|
-
const value = args2[i + 1];
|
|
3176
|
-
if (value && !value.startsWith("-")) {
|
|
3177
|
-
flags[key] = value;
|
|
3178
|
-
i++;
|
|
3179
|
-
} else {
|
|
3180
|
-
flags[key] = "true";
|
|
3181
|
-
}
|
|
4712
|
+
if (failCount > 0 && successCount === 0) {
|
|
4713
|
+
process.exit(1);
|
|
3182
4714
|
}
|
|
3183
|
-
}
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
{ name: "\u274C Cancel", value: "cancel" }
|
|
3209
|
-
]
|
|
3210
|
-
});
|
|
3211
|
-
if (action === "pull") {
|
|
3212
|
-
await pullCommand([]);
|
|
3213
|
-
return;
|
|
3214
|
-
} else if (action === "push") {
|
|
3215
|
-
await pushCommand([]);
|
|
3216
|
-
return;
|
|
3217
|
-
} else if (action === "cancel") {
|
|
3218
|
-
console.log("\n\u{1F44B} Cancelled");
|
|
3219
|
-
return;
|
|
3220
|
-
}
|
|
3221
|
-
console.log();
|
|
3222
|
-
} catch (error) {
|
|
3223
|
-
if (error.name === "ExitPromptError") {
|
|
3224
|
-
console.log("\n\u{1F44B} Cancelled");
|
|
3225
|
-
return;
|
|
3226
|
-
}
|
|
3227
|
-
throw error;
|
|
4715
|
+
} catch (error) {
|
|
4716
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4717
|
+
console.error("\u274C Failed to pull .env files:", message);
|
|
4718
|
+
process.exit(1);
|
|
4719
|
+
}
|
|
4720
|
+
}
|
|
4721
|
+
function countVariables(content) {
|
|
4722
|
+
return content.split("\n").filter((line) => {
|
|
4723
|
+
const trimmed = line.trim();
|
|
4724
|
+
return trimmed && !trimmed.startsWith("#") && trimmed.includes("=");
|
|
4725
|
+
}).length;
|
|
4726
|
+
}
|
|
4727
|
+
|
|
4728
|
+
// src/commands/push.ts
|
|
4729
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
4730
|
+
import { join as join5 } from "path";
|
|
4731
|
+
async function pushCommand2(args2) {
|
|
4732
|
+
const flags = {};
|
|
4733
|
+
for (let i = 0; i < args2.length; i++) {
|
|
4734
|
+
if (args2[i].startsWith("-")) {
|
|
4735
|
+
const key = args2[i].replace(/^-+/, "");
|
|
4736
|
+
const value = args2[i + 1];
|
|
4737
|
+
if (value && !value.startsWith("-")) {
|
|
4738
|
+
flags[key] = value;
|
|
4739
|
+
i++;
|
|
3228
4740
|
}
|
|
3229
4741
|
}
|
|
3230
4742
|
}
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
console.log("\n\u274C You are not logged in");
|
|
3236
|
-
console.log("\u{1F4A1} Please login or register first:");
|
|
3237
|
-
console.log(" jssm login");
|
|
3238
|
-
console.log(" jssm register");
|
|
4743
|
+
const config = await resolveConfig();
|
|
4744
|
+
if (!config) {
|
|
4745
|
+
console.error("\u274C No .jssm configuration found in current directory.");
|
|
4746
|
+
console.error('\u{1F4A1} Run "jssm init -p <project>" to initialize.');
|
|
3239
4747
|
process.exit(1);
|
|
3240
4748
|
}
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
if (!host) {
|
|
3246
|
-
console.error("\u274C Host URL is required");
|
|
3247
|
-
console.error("\u{1F4A1} Set it globally: jssm config set host <url>");
|
|
4749
|
+
const { valid, errors } = validateResolvedConfig(config);
|
|
4750
|
+
if (!valid) {
|
|
4751
|
+
console.error("\u274C Configuration is incomplete:");
|
|
4752
|
+
errors.forEach((e) => console.error(` \u2022 ${e}`));
|
|
3248
4753
|
process.exit(1);
|
|
3249
4754
|
}
|
|
3250
|
-
const
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
console.log(` No .env files found`);
|
|
4755
|
+
const project = flags.p || flags.project || config.project;
|
|
4756
|
+
const environment = flags.e || flags.env;
|
|
4757
|
+
let input = flags.in || flags.input;
|
|
4758
|
+
let searchDepth = 10;
|
|
4759
|
+
if (flags.depth) {
|
|
4760
|
+
const parsedDepth = parseInt(flags.depth, 10);
|
|
4761
|
+
if (!isNaN(parsedDepth)) {
|
|
4762
|
+
searchDepth = parsedDepth;
|
|
4763
|
+
}
|
|
3260
4764
|
}
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
}
|
|
3279
|
-
});
|
|
3280
|
-
console.log(`
|
|
3281
|
-
\u{1F4E6} Creating project "${projectName}"...`);
|
|
3282
|
-
await createProject(host, authToken, projectName, repoType);
|
|
3283
|
-
console.log(`\u2705 Project created
|
|
3284
|
-
`);
|
|
4765
|
+
if (project !== config.project) {
|
|
4766
|
+
console.log(`\u26A0\uFE0F Warning: Pushing to ${project}`);
|
|
4767
|
+
console.log(` This directory is initialized for ${config.project}`);
|
|
4768
|
+
}
|
|
4769
|
+
let selectedFiles = [];
|
|
4770
|
+
if (!input) {
|
|
4771
|
+
const cwd = process.cwd();
|
|
4772
|
+
const envFiles = await findEnvFiles(cwd, searchDepth);
|
|
4773
|
+
if (envFiles.length === 0) {
|
|
4774
|
+
console.error("\u274C No .env files found");
|
|
4775
|
+
console.error("\u{1F4A1} Create a .env file or specify one with --input <file>");
|
|
4776
|
+
process.exit(1);
|
|
4777
|
+
} else if (envFiles.length === 1) {
|
|
4778
|
+
selectedFiles = [envFiles[0].relativePath];
|
|
4779
|
+
console.log(
|
|
4780
|
+
`\u{1F4C4} Found ${envFiles[0].relativePath} (${envFiles[0].variableCount} variables)`
|
|
4781
|
+
);
|
|
3285
4782
|
} else {
|
|
3286
|
-
|
|
3287
|
-
...projects.map((p) => ({ name: p.name, value: p.name })),
|
|
3288
|
-
{ name: "+ Create new project", value: "__new__" }
|
|
3289
|
-
];
|
|
3290
|
-
const selectedProject = await dist_default6({
|
|
3291
|
-
message: "Select a project:",
|
|
3292
|
-
choices: projectChoices
|
|
3293
|
-
});
|
|
3294
|
-
if (selectedProject === "__new__") {
|
|
3295
|
-
projectName = await dist_default4({
|
|
3296
|
-
message: "New project name:",
|
|
3297
|
-
validate: (value) => {
|
|
3298
|
-
if (!value)
|
|
3299
|
-
return "Project name is required";
|
|
3300
|
-
if (!/^[a-z0-9-_.]+$/.test(value)) {
|
|
3301
|
-
return "Project name must contain only lowercase letters, numbers, hyphens, underscores, and dots";
|
|
3302
|
-
}
|
|
3303
|
-
if (projects.some((p) => p.name === value)) {
|
|
3304
|
-
return "Project already exists";
|
|
3305
|
-
}
|
|
3306
|
-
return true;
|
|
3307
|
-
}
|
|
3308
|
-
});
|
|
3309
|
-
console.log(`
|
|
3310
|
-
\u{1F4E6} Creating project "${projectName}"...`);
|
|
3311
|
-
await createProject(host, authToken, projectName, repoType);
|
|
3312
|
-
console.log(`\u2705 Project created
|
|
4783
|
+
console.log(`\u{1F4C4} Found ${envFiles.length} .env files:
|
|
3313
4784
|
`);
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
console.log("\u{1F30D} Loading environments...");
|
|
3319
|
-
const environments = await getEnvironments(host, authToken, projectName);
|
|
3320
|
-
if (environments.length === 0) {
|
|
3321
|
-
console.log(" No existing environments found\n");
|
|
3322
|
-
environmentName = await dist_default4({
|
|
3323
|
-
message: "Environment name:",
|
|
3324
|
-
default: "development",
|
|
3325
|
-
validate: (value) => {
|
|
3326
|
-
if (!value)
|
|
3327
|
-
return "Environment name is required";
|
|
3328
|
-
if (!/^[a-z0-9-_]+$/.test(value)) {
|
|
3329
|
-
return "Environment name must contain only lowercase letters, numbers, hyphens, and underscores";
|
|
3330
|
-
}
|
|
3331
|
-
return true;
|
|
3332
|
-
}
|
|
4785
|
+
envFiles.forEach((file) => {
|
|
4786
|
+
console.log(
|
|
4787
|
+
` \u2022 ${file.relativePath} (${file.variableCount} variables)`
|
|
4788
|
+
);
|
|
3333
4789
|
});
|
|
3334
|
-
console.log(
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
4790
|
+
console.log();
|
|
4791
|
+
const pushOption = await dist_default6({
|
|
4792
|
+
message: "What would you like to push?",
|
|
4793
|
+
choices: [
|
|
4794
|
+
{
|
|
4795
|
+
name: "\u2728 All files",
|
|
4796
|
+
value: "all"
|
|
4797
|
+
},
|
|
4798
|
+
{
|
|
4799
|
+
name: "\u{1F4C1} Select specific files",
|
|
4800
|
+
value: "specific"
|
|
4801
|
+
}
|
|
4802
|
+
]
|
|
3347
4803
|
});
|
|
3348
|
-
if (
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
4804
|
+
if (pushOption === "all") {
|
|
4805
|
+
selectedFiles = envFiles.map((f) => f.relativePath);
|
|
4806
|
+
} else {
|
|
4807
|
+
const fileChoices = envFiles.map((file) => ({
|
|
4808
|
+
name: `${file.relativePath} (${file.variableCount} variables)`,
|
|
4809
|
+
value: file.relativePath,
|
|
4810
|
+
checked: false
|
|
4811
|
+
}));
|
|
4812
|
+
const selected = await dist_default2({
|
|
4813
|
+
message: "Select .env file(s) to push:",
|
|
4814
|
+
choices: fileChoices,
|
|
4815
|
+
validate: (answer) => {
|
|
4816
|
+
if (answer.length === 0) {
|
|
4817
|
+
return "Please select at least one file";
|
|
3360
4818
|
}
|
|
3361
4819
|
return true;
|
|
3362
4820
|
}
|
|
3363
4821
|
});
|
|
3364
|
-
|
|
3365
|
-
\u{1F30D} Creating environment "${environmentName}"...`);
|
|
3366
|
-
await createEnvironment(host, authToken, projectName, environmentName);
|
|
3367
|
-
console.log(`\u2705 Environment created
|
|
3368
|
-
`);
|
|
3369
|
-
} else {
|
|
3370
|
-
environmentName = selectedEnv;
|
|
4822
|
+
selectedFiles = selected;
|
|
3371
4823
|
}
|
|
3372
4824
|
}
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
4825
|
+
} else {
|
|
4826
|
+
selectedFiles = [input];
|
|
4827
|
+
}
|
|
4828
|
+
const envSuffix = environment ? ` (env: ${environment})` : "";
|
|
4829
|
+
if (selectedFiles.length === 1) {
|
|
4830
|
+
console.log(
|
|
4831
|
+
`
|
|
4832
|
+
\u{1F4E4} Pushing ${selectedFiles[0]} to ${project}${envSuffix}...`
|
|
4833
|
+
);
|
|
4834
|
+
} else {
|
|
4835
|
+
console.log(
|
|
4836
|
+
`
|
|
4837
|
+
\u{1F4E4} Pushing ${selectedFiles.length} files to ${project}${envSuffix}...
|
|
4838
|
+
`
|
|
4839
|
+
);
|
|
4840
|
+
}
|
|
4841
|
+
let successCount = 0;
|
|
4842
|
+
let failCount = 0;
|
|
4843
|
+
for (const file of selectedFiles) {
|
|
4844
|
+
let fileContent = "";
|
|
4845
|
+
let fileSize = 0;
|
|
4846
|
+
try {
|
|
4847
|
+
const inputPath = join5(process.cwd(), file);
|
|
4848
|
+
fileContent = await readFile4(inputPath, "utf-8");
|
|
4849
|
+
fileSize = Buffer.byteLength(fileContent, "utf-8");
|
|
4850
|
+
const variables = parseVariables(fileContent, file);
|
|
4851
|
+
if (variables.length === 0) {
|
|
4852
|
+
console.log(`\u26A0\uFE0F ${file}: No variables found, skipping`);
|
|
4853
|
+
continue;
|
|
4854
|
+
}
|
|
4855
|
+
const invalidVars = variables.filter((v) => !/^[A-Z0-9_]+$/.test(v.key));
|
|
4856
|
+
if (invalidVars.length > 0) {
|
|
4857
|
+
console.error(`\u274C ${file}: Invalid variable names found:`);
|
|
4858
|
+
invalidVars.forEach(
|
|
4859
|
+
(v) => console.error(
|
|
4860
|
+
` \u2022 ${v.key} (must contain only uppercase letters, numbers, and underscores)`
|
|
4861
|
+
)
|
|
3378
4862
|
);
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
if (shouldUpload) {
|
|
3386
|
-
let selectedFileInfos;
|
|
3387
|
-
if (repoType === "monorepo" && envFiles.length > 1) {
|
|
3388
|
-
const fileChoices = envFiles.map((file) => ({
|
|
3389
|
-
name: `${file.relativePath} (${file.variableCount} variables)`,
|
|
3390
|
-
value: file.relativePath
|
|
3391
|
-
}));
|
|
3392
|
-
const selectedPaths = await dist_default2({
|
|
3393
|
-
message: "Select .env files to upload:",
|
|
3394
|
-
choices: fileChoices,
|
|
3395
|
-
validate: (answer) => {
|
|
3396
|
-
if (answer.length === 0) {
|
|
3397
|
-
return "Please select at least one file";
|
|
3398
|
-
}
|
|
3399
|
-
return true;
|
|
3400
|
-
}
|
|
3401
|
-
});
|
|
3402
|
-
selectedFileInfos = envFiles.filter(
|
|
3403
|
-
(f) => selectedPaths.includes(f.relativePath)
|
|
3404
|
-
);
|
|
3405
|
-
} else {
|
|
3406
|
-
selectedFileInfos = [envFiles[0]];
|
|
3407
|
-
}
|
|
3408
|
-
const totalVars = selectedFileInfos.reduce(
|
|
3409
|
-
(sum, f) => sum + f.variableCount,
|
|
3410
|
-
0
|
|
4863
|
+
failCount++;
|
|
4864
|
+
continue;
|
|
4865
|
+
}
|
|
4866
|
+
if (fileSize > 8192) {
|
|
4867
|
+
console.error(
|
|
4868
|
+
`\u274C ${file}: File size (${fileSize} bytes) exceeds maximum (8192 bytes)`
|
|
3411
4869
|
);
|
|
4870
|
+
console.error(" Consider reducing comments or splitting variables");
|
|
4871
|
+
failCount++;
|
|
4872
|
+
continue;
|
|
4873
|
+
}
|
|
4874
|
+
await pushEnvFile(
|
|
4875
|
+
config.host,
|
|
4876
|
+
config.authToken,
|
|
4877
|
+
project,
|
|
4878
|
+
fileContent,
|
|
4879
|
+
file,
|
|
4880
|
+
// Use full relative path, not just filename
|
|
4881
|
+
environment
|
|
4882
|
+
// Optional environment tag
|
|
4883
|
+
);
|
|
4884
|
+
if (selectedFiles.length === 1) {
|
|
3412
4885
|
console.log(
|
|
3413
|
-
`
|
|
3414
|
-
\u{1F4CB} Files to upload (${selectedFileInfos.length} files, ${totalVars} total variables):`
|
|
4886
|
+
`\u2705 Pushed ${file} (${variables.length} variables) to ${project}${envSuffix}`
|
|
3415
4887
|
);
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
});
|
|
3419
|
-
const confirmUpload = await dist_default3({
|
|
3420
|
-
message: "\nProceed with upload?",
|
|
3421
|
-
default: true
|
|
3422
|
-
});
|
|
3423
|
-
if (confirmUpload) {
|
|
3424
|
-
console.log(`
|
|
3425
|
-
\u2B06\uFE0F Uploading ${selectedFileInfos.length} file(s)...`);
|
|
3426
|
-
let successCount = 0;
|
|
3427
|
-
let failCount = 0;
|
|
3428
|
-
for (const fileInfo of selectedFileInfos) {
|
|
3429
|
-
try {
|
|
3430
|
-
const { readFile: readFileAsync } = await import("fs/promises");
|
|
3431
|
-
const content = await readFileAsync(fileInfo.path, "utf-8");
|
|
3432
|
-
await pushEnvFile(
|
|
3433
|
-
host,
|
|
3434
|
-
authToken,
|
|
3435
|
-
projectName,
|
|
3436
|
-
environmentName,
|
|
3437
|
-
content,
|
|
3438
|
-
fileInfo.relativePath
|
|
3439
|
-
);
|
|
3440
|
-
console.log(` \u2705 ${fileInfo.relativePath}`);
|
|
3441
|
-
successCount++;
|
|
3442
|
-
} catch (error) {
|
|
3443
|
-
console.log(` \u274C ${fileInfo.relativePath}: ${error.message}`);
|
|
3444
|
-
failCount++;
|
|
3445
|
-
}
|
|
3446
|
-
}
|
|
3447
|
-
if (failCount === 0) {
|
|
3448
|
-
console.log(`\u2705 All files uploaded successfully`);
|
|
3449
|
-
} else {
|
|
3450
|
-
console.log(`
|
|
3451
|
-
\u26A0\uFE0F ${successCount} succeeded, ${failCount} failed`);
|
|
3452
|
-
}
|
|
3453
|
-
} else {
|
|
3454
|
-
console.log("\n\u23ED\uFE0F Skipping file upload");
|
|
3455
|
-
}
|
|
4888
|
+
} else {
|
|
4889
|
+
console.log(`\u2705 ${file}: Pushed (${variables.length} variables)`);
|
|
3456
4890
|
}
|
|
4891
|
+
successCount++;
|
|
4892
|
+
} catch (error) {
|
|
4893
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4894
|
+
console.error(`\u274C ${file}: Failed to push - ${message}`);
|
|
4895
|
+
failCount++;
|
|
3457
4896
|
}
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
project: projectName,
|
|
3461
|
-
environment: environmentName
|
|
3462
|
-
};
|
|
3463
|
-
if (flags.host && flags.host !== globalConfig.host) {
|
|
3464
|
-
projectConfig.host = flags.host;
|
|
3465
|
-
}
|
|
3466
|
-
if (flags.namespace && flags.namespace !== globalConfig.namespace) {
|
|
3467
|
-
projectConfig.namespace = flags.namespace;
|
|
3468
|
-
}
|
|
3469
|
-
await saveProjectConfig(projectConfig);
|
|
3470
|
-
console.log(`
|
|
3471
|
-
\u2705 Project initialized successfully!`);
|
|
3472
|
-
console.log(` Config file: .jssm`);
|
|
3473
|
-
console.log(` Project: ${projectName}`);
|
|
3474
|
-
console.log(` Environment: ${environmentName}`);
|
|
3475
|
-
console.log(` Repository type: ${repoType}`);
|
|
4897
|
+
}
|
|
4898
|
+
if (selectedFiles.length > 1) {
|
|
3476
4899
|
console.log(`
|
|
3477
|
-
\u{
|
|
3478
|
-
console.log(`
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
} catch (error) {
|
|
3482
|
-
if (error.name === "ExitPromptError") {
|
|
3483
|
-
console.log("\n\u274C Initialization cancelled");
|
|
3484
|
-
process.exit(0);
|
|
4900
|
+
\u{1F4CA} Summary:`);
|
|
4901
|
+
console.log(` \u2705 Success: ${successCount} file(s)`);
|
|
4902
|
+
if (failCount > 0) {
|
|
4903
|
+
console.log(` \u274C Failed: ${failCount} file(s)`);
|
|
3485
4904
|
}
|
|
3486
|
-
|
|
3487
|
-
|
|
4905
|
+
}
|
|
4906
|
+
if (failCount > 0) {
|
|
3488
4907
|
process.exit(1);
|
|
3489
4908
|
}
|
|
3490
4909
|
}
|
|
4910
|
+
function parseVariables(content, filename) {
|
|
4911
|
+
const variables = [];
|
|
4912
|
+
if (filename.endsWith(".json")) {
|
|
4913
|
+
try {
|
|
4914
|
+
const obj = JSON.parse(content);
|
|
4915
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
4916
|
+
variables.push({ key, value: String(value) });
|
|
4917
|
+
}
|
|
4918
|
+
return variables;
|
|
4919
|
+
} catch (error) {
|
|
4920
|
+
throw new Error("Invalid JSON file");
|
|
4921
|
+
}
|
|
4922
|
+
}
|
|
4923
|
+
const lines = content.split("\n");
|
|
4924
|
+
let pendingComment;
|
|
4925
|
+
for (let i = 0; i < lines.length; i++) {
|
|
4926
|
+
const line = lines[i];
|
|
4927
|
+
const trimmed = line.trim();
|
|
4928
|
+
if (trimmed.startsWith("#")) {
|
|
4929
|
+
const commentText = trimmed.substring(1).trim();
|
|
4930
|
+
if (commentText && !commentText.match(/^[=\-]+$/)) {
|
|
4931
|
+
pendingComment = commentText;
|
|
4932
|
+
}
|
|
4933
|
+
continue;
|
|
4934
|
+
}
|
|
4935
|
+
if (!trimmed) {
|
|
4936
|
+
pendingComment = void 0;
|
|
4937
|
+
continue;
|
|
4938
|
+
}
|
|
4939
|
+
const match = trimmed.match(/^([A-Z0-9_]+)=(.*)$/);
|
|
4940
|
+
if (match) {
|
|
4941
|
+
const [, key, valueWithComment] = match;
|
|
4942
|
+
const inlineCommentMatch = valueWithComment.match(
|
|
4943
|
+
/^([^#]*?)\s*#\s*(.+)$/
|
|
4944
|
+
);
|
|
4945
|
+
let value;
|
|
4946
|
+
let comment = pendingComment;
|
|
4947
|
+
if (inlineCommentMatch) {
|
|
4948
|
+
value = inlineCommentMatch[1].trim();
|
|
4949
|
+
comment = inlineCommentMatch[2].trim();
|
|
4950
|
+
} else {
|
|
4951
|
+
value = valueWithComment.trim();
|
|
4952
|
+
}
|
|
4953
|
+
const cleanValue = value.replace(/^["']|["']$/g, "");
|
|
4954
|
+
const variable = { key, value: cleanValue };
|
|
4955
|
+
if (comment) {
|
|
4956
|
+
variable.comment = comment;
|
|
4957
|
+
}
|
|
4958
|
+
variables.push(variable);
|
|
4959
|
+
pendingComment = void 0;
|
|
4960
|
+
}
|
|
4961
|
+
}
|
|
4962
|
+
return variables;
|
|
4963
|
+
}
|
|
3491
4964
|
|
|
3492
4965
|
// src/commands/sync.ts
|
|
3493
4966
|
import { writeFile as writeFile4 } from "fs/promises";
|
|
@@ -3521,151 +4994,29 @@ async function syncCommand() {
|
|
|
3521
4994
|
const trimmed = line.trim();
|
|
3522
4995
|
return trimmed && !trimmed.startsWith("#") && trimmed.includes("=");
|
|
3523
4996
|
}).length;
|
|
3524
|
-
console.log(`\u2705 Synced .env file (${varCount} variables)`);
|
|
3525
|
-
console.log(` Project: ${config.project}`);
|
|
3526
|
-
console.log(` Environment: ${config.environment}`);
|
|
3527
|
-
} catch (error) {
|
|
3528
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3529
|
-
console.error("\u274C Failed to sync .env file:", message);
|
|
3530
|
-
process.exit(1);
|
|
3531
|
-
}
|
|
3532
|
-
}
|
|
3533
|
-
|
|
3534
|
-
// src/commands/project.ts
|
|
3535
|
-
init_auth();
|
|
3536
|
-
async function projectCommand(args2) {
|
|
3537
|
-
const subcommand = args2[0];
|
|
3538
|
-
if (subcommand === "create") {
|
|
3539
|
-
await createProjectCommand(args2.slice(1));
|
|
3540
|
-
} else if (subcommand === "list" || subcommand === "ls") {
|
|
3541
|
-
await listProjectsCommand();
|
|
3542
|
-
} else {
|
|
3543
|
-
printProjectHelp();
|
|
3544
|
-
}
|
|
3545
|
-
}
|
|
3546
|
-
async function createProjectCommand(args2) {
|
|
3547
|
-
const flags = {};
|
|
3548
|
-
for (let i = 0; i < args2.length; i++) {
|
|
3549
|
-
if (args2[i].startsWith("-")) {
|
|
3550
|
-
const key = args2[i].replace(/^-+/, "");
|
|
3551
|
-
const value = args2[i + 1];
|
|
3552
|
-
if (value && !value.startsWith("-")) {
|
|
3553
|
-
flags[key] = value;
|
|
3554
|
-
i++;
|
|
3555
|
-
}
|
|
3556
|
-
}
|
|
3557
|
-
}
|
|
3558
|
-
const name = flags.n || flags.name || args2[0];
|
|
3559
|
-
const host = flags.host;
|
|
3560
|
-
if (!name) {
|
|
3561
|
-
console.error("Usage: jssm project create <name> [--host <api_url>]");
|
|
3562
|
-
console.error("\nOptions:");
|
|
3563
|
-
console.error(" -n, --name Project name");
|
|
3564
|
-
console.error(" --host API host URL (optional if config exists)");
|
|
3565
|
-
process.exit(1);
|
|
3566
|
-
}
|
|
3567
|
-
const authToken = await getAuthToken();
|
|
3568
|
-
if (!authToken) {
|
|
3569
|
-
console.error("\u274C Not logged in");
|
|
3570
|
-
console.error("\u{1F4A1} Run: jssm login");
|
|
3571
|
-
process.exit(1);
|
|
3572
|
-
}
|
|
3573
|
-
const globalConfig = await loadGlobalConfig();
|
|
3574
|
-
const projectConfig = await loadProjectConfig();
|
|
3575
|
-
const finalHost = host || projectConfig?.host || globalConfig.host;
|
|
3576
|
-
if (!finalHost) {
|
|
3577
|
-
console.error("\u274C Host is required");
|
|
3578
|
-
console.error("\u{1F4A1} Set globally: jssm config set host <url>");
|
|
3579
|
-
process.exit(1);
|
|
3580
|
-
}
|
|
3581
|
-
try {
|
|
3582
|
-
console.log(`\u{1F4E6} Creating project "${name}"...`);
|
|
3583
|
-
const project = await createProject(finalHost, authToken, name);
|
|
3584
|
-
console.log(`\u2705 Project "${name}" created successfully`);
|
|
3585
|
-
console.log(` ID: ${project._id}`);
|
|
3586
|
-
console.log(` Created: ${new Date(project.createdAt).toLocaleString()}`);
|
|
3587
|
-
console.log("\n\u{1F4A1} Next steps:");
|
|
3588
|
-
console.log(
|
|
3589
|
-
` - Run "jssm env create <env-name> -p ${name}" to create an environment`
|
|
3590
|
-
);
|
|
3591
|
-
console.log(
|
|
3592
|
-
` - Run "jssm init -p ${name} -e <env-name>" to configure CLI`
|
|
3593
|
-
);
|
|
3594
|
-
} catch (error) {
|
|
3595
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3596
|
-
console.error(`\u274C Failed to create project: ${message}`);
|
|
3597
|
-
process.exit(1);
|
|
3598
|
-
}
|
|
3599
|
-
}
|
|
3600
|
-
async function listProjectsCommand() {
|
|
3601
|
-
const authToken = await getAuthToken();
|
|
3602
|
-
if (!authToken) {
|
|
3603
|
-
console.error("\u274C Not logged in");
|
|
3604
|
-
console.error("\u{1F4A1} Run: jssm login");
|
|
3605
|
-
process.exit(1);
|
|
3606
|
-
}
|
|
3607
|
-
const globalConfig = await loadGlobalConfig();
|
|
3608
|
-
const projectConfig = await loadProjectConfig();
|
|
3609
|
-
const host = projectConfig?.host || globalConfig.host;
|
|
3610
|
-
if (!host) {
|
|
3611
|
-
console.error("\u274C Host is required");
|
|
3612
|
-
console.error("\u{1F4A1} Set globally: jssm config set host <url>");
|
|
3613
|
-
process.exit(1);
|
|
3614
|
-
}
|
|
3615
|
-
try {
|
|
3616
|
-
console.log("\u{1F4E6} Fetching projects...\n");
|
|
3617
|
-
const projects = await getProjects(host, authToken);
|
|
3618
|
-
if (projects.length === 0) {
|
|
3619
|
-
console.log("No projects found.");
|
|
3620
|
-
console.log("\u{1F4A1} Create one with: jssm project create <name>");
|
|
3621
|
-
return;
|
|
3622
|
-
}
|
|
3623
|
-
console.log(`Found ${projects.length} project(s):
|
|
3624
|
-
`);
|
|
3625
|
-
projects.forEach((project) => {
|
|
3626
|
-
console.log(` \u2022 ${project.name}`);
|
|
3627
|
-
console.log(` ID: ${project._id}`);
|
|
3628
|
-
console.log(
|
|
3629
|
-
` Created: ${new Date(project.createdAt).toLocaleString()}`
|
|
3630
|
-
);
|
|
3631
|
-
console.log("");
|
|
3632
|
-
});
|
|
4997
|
+
console.log(`\u2705 Synced .env file (${varCount} variables)`);
|
|
4998
|
+
console.log(` Project: ${config.project}`);
|
|
4999
|
+
console.log(` Environment: ${config.environment}`);
|
|
3633
5000
|
} catch (error) {
|
|
3634
5001
|
const message = error instanceof Error ? error.message : String(error);
|
|
3635
|
-
console.error(
|
|
5002
|
+
console.error("\u274C Failed to sync .env file:", message);
|
|
3636
5003
|
process.exit(1);
|
|
3637
5004
|
}
|
|
3638
5005
|
}
|
|
3639
|
-
function printProjectHelp() {
|
|
3640
|
-
console.log(`
|
|
3641
|
-
JSSM Project Management
|
|
3642
|
-
|
|
3643
|
-
Usage:
|
|
3644
|
-
jssm project <command> [options]
|
|
3645
|
-
|
|
3646
|
-
Commands:
|
|
3647
|
-
create Create a new project
|
|
3648
|
-
list List all projects (alias: ls)
|
|
3649
|
-
|
|
3650
|
-
Examples:
|
|
3651
|
-
jssm project create my-app
|
|
3652
|
-
jssm project list
|
|
3653
|
-
`);
|
|
3654
|
-
}
|
|
3655
5006
|
|
|
3656
|
-
// src/commands/
|
|
5007
|
+
// src/commands/project.ts
|
|
3657
5008
|
init_auth();
|
|
3658
|
-
async function
|
|
5009
|
+
async function projectCommand(args2) {
|
|
3659
5010
|
const subcommand = args2[0];
|
|
3660
5011
|
if (subcommand === "create") {
|
|
3661
|
-
await
|
|
5012
|
+
await createProjectCommand(args2.slice(1));
|
|
3662
5013
|
} else if (subcommand === "list" || subcommand === "ls") {
|
|
3663
|
-
await
|
|
5014
|
+
await listProjectsCommand();
|
|
3664
5015
|
} else {
|
|
3665
|
-
|
|
5016
|
+
printProjectHelp();
|
|
3666
5017
|
}
|
|
3667
5018
|
}
|
|
3668
|
-
async function
|
|
5019
|
+
async function createProjectCommand(args2) {
|
|
3669
5020
|
const flags = {};
|
|
3670
5021
|
for (let i = 0; i < args2.length; i++) {
|
|
3671
5022
|
if (args2[i].startsWith("-")) {
|
|
@@ -3678,18 +5029,12 @@ async function createEnvCommand(args2) {
|
|
|
3678
5029
|
}
|
|
3679
5030
|
}
|
|
3680
5031
|
const name = flags.n || flags.name || args2[0];
|
|
3681
|
-
const project = flags.p || flags.project;
|
|
3682
5032
|
const host = flags.host;
|
|
3683
5033
|
if (!name) {
|
|
3684
|
-
console.error(
|
|
3685
|
-
"Usage: jssm env create <name> -p <project> [--host <api_url>]"
|
|
3686
|
-
);
|
|
5034
|
+
console.error("Usage: jssm project create <name> [--host <api_url>]");
|
|
3687
5035
|
console.error("\nOptions:");
|
|
3688
|
-
console.error(" -n, --name
|
|
3689
|
-
console.error("
|
|
3690
|
-
console.error(
|
|
3691
|
-
" --host API host URL (optional if global config exists)"
|
|
3692
|
-
);
|
|
5036
|
+
console.error(" -n, --name Project name");
|
|
5037
|
+
console.error(" --host API host URL (optional if config exists)");
|
|
3693
5038
|
process.exit(1);
|
|
3694
5039
|
}
|
|
3695
5040
|
const authToken = await getAuthToken();
|
|
@@ -3700,56 +5045,32 @@ async function createEnvCommand(args2) {
|
|
|
3700
5045
|
}
|
|
3701
5046
|
const globalConfig = await loadGlobalConfig();
|
|
3702
5047
|
const projectConfig = await loadProjectConfig();
|
|
3703
|
-
const finalProject = project || projectConfig?.project;
|
|
3704
5048
|
const finalHost = host || projectConfig?.host || globalConfig.host;
|
|
3705
|
-
if (!finalProject) {
|
|
3706
|
-
console.error("\u274C Project name is required");
|
|
3707
|
-
console.error('\u{1F4A1} Either provide -p <project>, or run "jssm init" first');
|
|
3708
|
-
process.exit(1);
|
|
3709
|
-
}
|
|
3710
5049
|
if (!finalHost) {
|
|
3711
5050
|
console.error("\u274C Host is required");
|
|
3712
5051
|
console.error("\u{1F4A1} Set globally: jssm config set host <url>");
|
|
3713
5052
|
process.exit(1);
|
|
3714
5053
|
}
|
|
3715
5054
|
try {
|
|
5055
|
+
console.log(`\u{1F4E6} Creating project "${name}"...`);
|
|
5056
|
+
const project = await createProject(finalHost, authToken, name);
|
|
5057
|
+
console.log(`\u2705 Project "${name}" created successfully`);
|
|
5058
|
+
console.log(` ID: ${project._id}`);
|
|
5059
|
+
console.log(` Created: ${new Date(project.createdAt).toLocaleString()}`);
|
|
5060
|
+
console.log("\n\u{1F4A1} Next steps:");
|
|
3716
5061
|
console.log(
|
|
3717
|
-
|
|
3718
|
-
);
|
|
3719
|
-
const env = await createEnvironment(
|
|
3720
|
-
finalHost,
|
|
3721
|
-
authToken,
|
|
3722
|
-
finalProject,
|
|
3723
|
-
name
|
|
5062
|
+
` - Run "jssm env create <env-name> -p ${name}" to create an environment`
|
|
3724
5063
|
);
|
|
3725
|
-
console.log(`\u2705 Environment "${name}" created successfully`);
|
|
3726
|
-
console.log(` ID: ${env._id}`);
|
|
3727
|
-
console.log(` Project: ${finalProject}`);
|
|
3728
|
-
console.log(` Created: ${new Date(env.createdAt).toLocaleString()}`);
|
|
3729
|
-
console.log("\n\u{1F4A1} Next steps:");
|
|
3730
5064
|
console.log(
|
|
3731
|
-
` - Run "jssm init -p ${
|
|
5065
|
+
` - Run "jssm init -p ${name} -e <env-name>" to configure CLI`
|
|
3732
5066
|
);
|
|
3733
|
-
console.log(" - Add variables via the web UI or API");
|
|
3734
5067
|
} catch (error) {
|
|
3735
5068
|
const message = error instanceof Error ? error.message : String(error);
|
|
3736
|
-
console.error(`\u274C Failed to create
|
|
5069
|
+
console.error(`\u274C Failed to create project: ${message}`);
|
|
3737
5070
|
process.exit(1);
|
|
3738
5071
|
}
|
|
3739
5072
|
}
|
|
3740
|
-
async function
|
|
3741
|
-
const flags = {};
|
|
3742
|
-
for (let i = 0; i < args2.length; i++) {
|
|
3743
|
-
if (args2[i].startsWith("-")) {
|
|
3744
|
-
const key = args2[i].replace(/^-+/, "");
|
|
3745
|
-
const value = args2[i + 1];
|
|
3746
|
-
if (value && !value.startsWith("-")) {
|
|
3747
|
-
flags[key] = value;
|
|
3748
|
-
i++;
|
|
3749
|
-
}
|
|
3750
|
-
}
|
|
3751
|
-
}
|
|
3752
|
-
const project = flags.p || flags.project;
|
|
5073
|
+
async function listProjectsCommand() {
|
|
3753
5074
|
const authToken = await getAuthToken();
|
|
3754
5075
|
if (!authToken) {
|
|
3755
5076
|
console.error("\u274C Not logged in");
|
|
@@ -3758,52 +5079,50 @@ async function listEnvsCommand(args2) {
|
|
|
3758
5079
|
}
|
|
3759
5080
|
const globalConfig = await loadGlobalConfig();
|
|
3760
5081
|
const projectConfig = await loadProjectConfig();
|
|
3761
|
-
const finalProject = project || projectConfig?.project;
|
|
3762
5082
|
const host = projectConfig?.host || globalConfig.host;
|
|
3763
|
-
if (!
|
|
3764
|
-
console.error("\u274C
|
|
5083
|
+
if (!host) {
|
|
5084
|
+
console.error("\u274C Host is required");
|
|
3765
5085
|
console.error("\u{1F4A1} Set globally: jssm config set host <url>");
|
|
3766
5086
|
process.exit(1);
|
|
3767
5087
|
}
|
|
3768
5088
|
try {
|
|
3769
|
-
console.log(
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
console.log("
|
|
3774
|
-
console.log(
|
|
3775
|
-
`\u{1F4A1} Create one with: jssm env create <name> -p ${finalProject}`
|
|
3776
|
-
);
|
|
5089
|
+
console.log("\u{1F4E6} Fetching projects...\n");
|
|
5090
|
+
const projects = await getProjects(host, authToken);
|
|
5091
|
+
if (projects.length === 0) {
|
|
5092
|
+
console.log("No projects found.");
|
|
5093
|
+
console.log("\u{1F4A1} Create one with: jssm project create <name>");
|
|
3777
5094
|
return;
|
|
3778
5095
|
}
|
|
3779
|
-
console.log(`Found ${
|
|
5096
|
+
console.log(`Found ${projects.length} project(s):
|
|
3780
5097
|
`);
|
|
3781
|
-
|
|
3782
|
-
console.log(` \u2022 ${
|
|
3783
|
-
console.log(` ID: ${
|
|
3784
|
-
console.log(
|
|
5098
|
+
projects.forEach((project) => {
|
|
5099
|
+
console.log(` \u2022 ${project.name}`);
|
|
5100
|
+
console.log(` ID: ${project._id}`);
|
|
5101
|
+
console.log(
|
|
5102
|
+
` Created: ${new Date(project.createdAt).toLocaleString()}`
|
|
5103
|
+
);
|
|
3785
5104
|
console.log("");
|
|
3786
5105
|
});
|
|
3787
5106
|
} catch (error) {
|
|
3788
5107
|
const message = error instanceof Error ? error.message : String(error);
|
|
3789
|
-
console.error(`\u274C Failed to list
|
|
5108
|
+
console.error(`\u274C Failed to list projects: ${message}`);
|
|
3790
5109
|
process.exit(1);
|
|
3791
5110
|
}
|
|
3792
5111
|
}
|
|
3793
|
-
function
|
|
5112
|
+
function printProjectHelp() {
|
|
3794
5113
|
console.log(`
|
|
3795
|
-
JSSM
|
|
5114
|
+
JSSM Project Management
|
|
3796
5115
|
|
|
3797
5116
|
Usage:
|
|
3798
|
-
jssm
|
|
5117
|
+
jssm project <command> [options]
|
|
3799
5118
|
|
|
3800
5119
|
Commands:
|
|
3801
|
-
create Create a new
|
|
3802
|
-
list List all
|
|
5120
|
+
create Create a new project
|
|
5121
|
+
list List all projects (alias: ls)
|
|
3803
5122
|
|
|
3804
5123
|
Examples:
|
|
3805
|
-
jssm
|
|
3806
|
-
jssm
|
|
5124
|
+
jssm project create my-app
|
|
5125
|
+
jssm project list
|
|
3807
5126
|
`);
|
|
3808
5127
|
}
|
|
3809
5128
|
|
|
@@ -4081,6 +5400,22 @@ async function loginCommand() {
|
|
|
4081
5400
|
} else {
|
|
4082
5401
|
console.error(`
|
|
4083
5402
|
\u274C Login failed: ${result.error}`);
|
|
5403
|
+
if (result.isConnectionError && host !== DEFAULT_HOST) {
|
|
5404
|
+
console.log(`
|
|
5405
|
+
\u26A0\uFE0F Current host: ${host}`);
|
|
5406
|
+
console.log(` Default host: ${DEFAULT_HOST}`);
|
|
5407
|
+
const resetToDefault = await dist_default3({
|
|
5408
|
+
message: "Would you like to reset the host to default?",
|
|
5409
|
+
default: false
|
|
5410
|
+
});
|
|
5411
|
+
if (resetToDefault) {
|
|
5412
|
+
globalConfig.host = DEFAULT_HOST;
|
|
5413
|
+
await saveGlobalConfig(globalConfig);
|
|
5414
|
+
console.log(`
|
|
5415
|
+
\u2705 Host reset to default: ${DEFAULT_HOST}`);
|
|
5416
|
+
console.log(`\u{1F4A1} Please try logging in again with 'jssm login'`);
|
|
5417
|
+
}
|
|
5418
|
+
}
|
|
4084
5419
|
process.exit(1);
|
|
4085
5420
|
}
|
|
4086
5421
|
} catch (error) {
|
|
@@ -4165,6 +5500,22 @@ async function registerCommand() {
|
|
|
4165
5500
|
} else {
|
|
4166
5501
|
console.error(`
|
|
4167
5502
|
\u274C Registration failed: ${result.error}`);
|
|
5503
|
+
if (result.isConnectionError && host !== DEFAULT_HOST) {
|
|
5504
|
+
console.log(`
|
|
5505
|
+
\u26A0\uFE0F Current host: ${host}`);
|
|
5506
|
+
console.log(` Default host: ${DEFAULT_HOST}`);
|
|
5507
|
+
const resetToDefault = await dist_default3({
|
|
5508
|
+
message: "Would you like to reset the host to default?",
|
|
5509
|
+
default: false
|
|
5510
|
+
});
|
|
5511
|
+
if (resetToDefault) {
|
|
5512
|
+
globalConfig.host = DEFAULT_HOST;
|
|
5513
|
+
await saveGlobalConfig(globalConfig);
|
|
5514
|
+
console.log(`
|
|
5515
|
+
\u2705 Host reset to default: ${DEFAULT_HOST}`);
|
|
5516
|
+
console.log(`\u{1F4A1} Please try registering again with 'jssm register'`);
|
|
5517
|
+
}
|
|
5518
|
+
}
|
|
4168
5519
|
process.exit(1);
|
|
4169
5520
|
}
|
|
4170
5521
|
} catch (error) {
|
|
@@ -4190,10 +5541,378 @@ async function logoutCommand() {
|
|
|
4190
5541
|
console.log(`\u2705 Successfully logged out (was logged in as ${authData.user.email})`);
|
|
4191
5542
|
}
|
|
4192
5543
|
|
|
5544
|
+
// src/commands/token.ts
|
|
5545
|
+
init_auth();
|
|
5546
|
+
var import_chalk = __toESM(require_source(), 1);
|
|
5547
|
+
async function createToken(args2) {
|
|
5548
|
+
const auth = await loadAuthData();
|
|
5549
|
+
const globalConfig = await loadGlobalConfig();
|
|
5550
|
+
const host = globalConfig.host || DEFAULT_HOST;
|
|
5551
|
+
if (!auth) {
|
|
5552
|
+
console.error(import_chalk.default.red("Not logged in. Run: jssm login"));
|
|
5553
|
+
process.exit(1);
|
|
5554
|
+
}
|
|
5555
|
+
let project = "";
|
|
5556
|
+
let environment = "";
|
|
5557
|
+
let name = "";
|
|
5558
|
+
let expiresIn = "90d";
|
|
5559
|
+
for (let i = 0; i < args2.length; i++) {
|
|
5560
|
+
const arg = args2[i];
|
|
5561
|
+
if (arg === "-p" || arg === "--project") {
|
|
5562
|
+
project = args2[++i] || "";
|
|
5563
|
+
} else if (arg === "-e" || arg === "--env") {
|
|
5564
|
+
environment = args2[++i] || "";
|
|
5565
|
+
} else if (arg === "-n" || arg === "--name") {
|
|
5566
|
+
name = args2[++i] || "";
|
|
5567
|
+
} else if (arg === "--expires") {
|
|
5568
|
+
expiresIn = args2[++i] || "90d";
|
|
5569
|
+
}
|
|
5570
|
+
}
|
|
5571
|
+
if (!project || !environment) {
|
|
5572
|
+
try {
|
|
5573
|
+
const jssmConfig = JSON.parse(await Bun.file(".jssm").text());
|
|
5574
|
+
project = project || jssmConfig.project;
|
|
5575
|
+
environment = environment || jssmConfig.environment;
|
|
5576
|
+
} catch {
|
|
5577
|
+
}
|
|
5578
|
+
}
|
|
5579
|
+
if (!project) {
|
|
5580
|
+
console.error(
|
|
5581
|
+
import_chalk.default.red(
|
|
5582
|
+
"Project required. Use -p <project> or run from a directory with .jssm"
|
|
5583
|
+
)
|
|
5584
|
+
);
|
|
5585
|
+
process.exit(1);
|
|
5586
|
+
}
|
|
5587
|
+
if (!environment) {
|
|
5588
|
+
console.error(
|
|
5589
|
+
import_chalk.default.red(
|
|
5590
|
+
"Environment required. Use -e <env> or run from a directory with .jssm"
|
|
5591
|
+
)
|
|
5592
|
+
);
|
|
5593
|
+
process.exit(1);
|
|
5594
|
+
}
|
|
5595
|
+
if (!name) {
|
|
5596
|
+
name = `token-${Date.now()}`;
|
|
5597
|
+
}
|
|
5598
|
+
console.log(
|
|
5599
|
+
import_chalk.default.blue(`Creating service token for ${project}/${environment}...`)
|
|
5600
|
+
);
|
|
5601
|
+
try {
|
|
5602
|
+
const response = await fetch(
|
|
5603
|
+
`${host}/api/projects/${project}/envs/${environment}/tokens`,
|
|
5604
|
+
{
|
|
5605
|
+
method: "POST",
|
|
5606
|
+
headers: {
|
|
5607
|
+
"Content-Type": "application/json",
|
|
5608
|
+
Authorization: `Bearer ${auth.token}`
|
|
5609
|
+
},
|
|
5610
|
+
body: JSON.stringify({ name, expiresIn })
|
|
5611
|
+
}
|
|
5612
|
+
);
|
|
5613
|
+
if (!response.ok) {
|
|
5614
|
+
const error = await response.json();
|
|
5615
|
+
console.error(
|
|
5616
|
+
import_chalk.default.red(`Failed to create token: ${error.error}`)
|
|
5617
|
+
);
|
|
5618
|
+
process.exit(1);
|
|
5619
|
+
}
|
|
5620
|
+
const data = await response.json();
|
|
5621
|
+
console.log();
|
|
5622
|
+
console.log(import_chalk.default.green("\u2713 Service token created successfully!"));
|
|
5623
|
+
console.log();
|
|
5624
|
+
console.log(
|
|
5625
|
+
import_chalk.default.yellow(
|
|
5626
|
+
"\u26A0\uFE0F IMPORTANT: Save this token now! It will not be shown again."
|
|
5627
|
+
)
|
|
5628
|
+
);
|
|
5629
|
+
console.log();
|
|
5630
|
+
console.log(import_chalk.default.bold("Token:"), import_chalk.default.cyan(data.token));
|
|
5631
|
+
console.log();
|
|
5632
|
+
console.log(import_chalk.default.dim("Token ID:"), data.id);
|
|
5633
|
+
console.log(import_chalk.default.dim("Name:"), data.name);
|
|
5634
|
+
console.log(import_chalk.default.dim("Expires:"), data.expiresAt || "Never");
|
|
5635
|
+
console.log();
|
|
5636
|
+
console.log(import_chalk.default.blue("Usage in Dockerfile:"));
|
|
5637
|
+
console.log(import_chalk.default.dim(` ENV JSSM_SERVICE_TOKEN=${data.token}`));
|
|
5638
|
+
console.log(import_chalk.default.dim(` ENV JSSM_HOST=${host}`));
|
|
5639
|
+
} catch (error) {
|
|
5640
|
+
console.error(import_chalk.default.red(`Error: ${error.message}`));
|
|
5641
|
+
process.exit(1);
|
|
5642
|
+
}
|
|
5643
|
+
}
|
|
5644
|
+
async function listTokens(args2) {
|
|
5645
|
+
const auth = await loadAuthData();
|
|
5646
|
+
const globalConfig = await loadGlobalConfig();
|
|
5647
|
+
const host = globalConfig.host || DEFAULT_HOST;
|
|
5648
|
+
if (!auth) {
|
|
5649
|
+
console.error(import_chalk.default.red("Not logged in. Run: jssm login"));
|
|
5650
|
+
process.exit(1);
|
|
5651
|
+
}
|
|
5652
|
+
let project = "";
|
|
5653
|
+
let environment = "";
|
|
5654
|
+
for (let i = 0; i < args2.length; i++) {
|
|
5655
|
+
const arg = args2[i];
|
|
5656
|
+
if (arg === "-p" || arg === "--project") {
|
|
5657
|
+
project = args2[++i] || "";
|
|
5658
|
+
} else if (arg === "-e" || arg === "--env") {
|
|
5659
|
+
environment = args2[++i] || "";
|
|
5660
|
+
}
|
|
5661
|
+
}
|
|
5662
|
+
if (!project || !environment) {
|
|
5663
|
+
try {
|
|
5664
|
+
const jssmConfig = JSON.parse(await Bun.file(".jssm").text());
|
|
5665
|
+
project = project || jssmConfig.project;
|
|
5666
|
+
environment = environment || jssmConfig.environment;
|
|
5667
|
+
} catch {
|
|
5668
|
+
}
|
|
5669
|
+
}
|
|
5670
|
+
if (!project || !environment) {
|
|
5671
|
+
console.error(
|
|
5672
|
+
import_chalk.default.red(
|
|
5673
|
+
"Project and environment required. Use -p and -e or run from a directory with .jssm"
|
|
5674
|
+
)
|
|
5675
|
+
);
|
|
5676
|
+
process.exit(1);
|
|
5677
|
+
}
|
|
5678
|
+
try {
|
|
5679
|
+
const response = await fetch(
|
|
5680
|
+
`${host}/api/projects/${project}/envs/${environment}/tokens`,
|
|
5681
|
+
{
|
|
5682
|
+
headers: { Authorization: `Bearer ${auth.token}` }
|
|
5683
|
+
}
|
|
5684
|
+
);
|
|
5685
|
+
if (!response.ok) {
|
|
5686
|
+
const error = await response.json();
|
|
5687
|
+
console.error(
|
|
5688
|
+
import_chalk.default.red(`Failed to list tokens: ${error.error}`)
|
|
5689
|
+
);
|
|
5690
|
+
process.exit(1);
|
|
5691
|
+
}
|
|
5692
|
+
const data = await response.json();
|
|
5693
|
+
console.log(
|
|
5694
|
+
import_chalk.default.blue(`
|
|
5695
|
+
Service tokens for ${project}/${environment}:
|
|
5696
|
+
`)
|
|
5697
|
+
);
|
|
5698
|
+
if (data.tokens.length === 0) {
|
|
5699
|
+
console.log(import_chalk.default.dim("No tokens found."));
|
|
5700
|
+
} else {
|
|
5701
|
+
for (const token of data.tokens) {
|
|
5702
|
+
console.log(import_chalk.default.bold(token.name));
|
|
5703
|
+
console.log(import_chalk.default.dim(` ID: ${token.id}`));
|
|
5704
|
+
console.log(import_chalk.default.dim(` Prefix: ${token.tokenPrefix}`));
|
|
5705
|
+
console.log(
|
|
5706
|
+
import_chalk.default.dim(` Created: ${new Date(token.createdAt).toLocaleString()}`)
|
|
5707
|
+
);
|
|
5708
|
+
console.log(
|
|
5709
|
+
import_chalk.default.dim(
|
|
5710
|
+
` Expires: ${token.expiresAt ? new Date(token.expiresAt).toLocaleString() : "Never"}`
|
|
5711
|
+
)
|
|
5712
|
+
);
|
|
5713
|
+
console.log(
|
|
5714
|
+
import_chalk.default.dim(
|
|
5715
|
+
` Last used: ${token.lastUsedAt ? new Date(token.lastUsedAt).toLocaleString() : "Never"}`
|
|
5716
|
+
)
|
|
5717
|
+
);
|
|
5718
|
+
console.log();
|
|
5719
|
+
}
|
|
5720
|
+
}
|
|
5721
|
+
} catch (error) {
|
|
5722
|
+
console.error(import_chalk.default.red(`Error: ${error.message}`));
|
|
5723
|
+
process.exit(1);
|
|
5724
|
+
}
|
|
5725
|
+
}
|
|
5726
|
+
async function revokeToken(args2) {
|
|
5727
|
+
const auth = await loadAuthData();
|
|
5728
|
+
const globalConfig = await loadGlobalConfig();
|
|
5729
|
+
const host = globalConfig.host || DEFAULT_HOST;
|
|
5730
|
+
if (!auth) {
|
|
5731
|
+
console.error(import_chalk.default.red("Not logged in. Run: jssm login"));
|
|
5732
|
+
process.exit(1);
|
|
5733
|
+
}
|
|
5734
|
+
let project = "";
|
|
5735
|
+
let environment = "";
|
|
5736
|
+
let tokenId = "";
|
|
5737
|
+
for (let i = 0; i < args2.length; i++) {
|
|
5738
|
+
const arg = args2[i];
|
|
5739
|
+
if (arg === "-p" || arg === "--project") {
|
|
5740
|
+
project = args2[++i] || "";
|
|
5741
|
+
} else if (arg === "-e" || arg === "--env") {
|
|
5742
|
+
environment = args2[++i] || "";
|
|
5743
|
+
} else if (arg === "-t" || arg === "--token-id") {
|
|
5744
|
+
tokenId = args2[++i] || "";
|
|
5745
|
+
} else if (!arg.startsWith("-") && !tokenId) {
|
|
5746
|
+
tokenId = arg;
|
|
5747
|
+
}
|
|
5748
|
+
}
|
|
5749
|
+
if (!project || !environment) {
|
|
5750
|
+
try {
|
|
5751
|
+
const jssmConfig = JSON.parse(await Bun.file(".jssm").text());
|
|
5752
|
+
project = project || jssmConfig.project;
|
|
5753
|
+
environment = environment || jssmConfig.environment;
|
|
5754
|
+
} catch {
|
|
5755
|
+
}
|
|
5756
|
+
}
|
|
5757
|
+
if (!project || !environment) {
|
|
5758
|
+
console.error(import_chalk.default.red("Project and environment required."));
|
|
5759
|
+
process.exit(1);
|
|
5760
|
+
}
|
|
5761
|
+
if (!tokenId) {
|
|
5762
|
+
console.error(
|
|
5763
|
+
import_chalk.default.red("Token ID required. Use: jssm token revoke <token-id>")
|
|
5764
|
+
);
|
|
5765
|
+
process.exit(1);
|
|
5766
|
+
}
|
|
5767
|
+
try {
|
|
5768
|
+
const response = await fetch(
|
|
5769
|
+
`${host}/api/projects/${project}/envs/${environment}/tokens/${tokenId}`,
|
|
5770
|
+
{
|
|
5771
|
+
method: "DELETE",
|
|
5772
|
+
headers: { Authorization: `Bearer ${auth.token}` }
|
|
5773
|
+
}
|
|
5774
|
+
);
|
|
5775
|
+
if (!response.ok) {
|
|
5776
|
+
const error = await response.json();
|
|
5777
|
+
console.error(
|
|
5778
|
+
import_chalk.default.red(`Failed to revoke token: ${error.error}`)
|
|
5779
|
+
);
|
|
5780
|
+
process.exit(1);
|
|
5781
|
+
}
|
|
5782
|
+
console.log(import_chalk.default.green("\u2713 Token revoked successfully"));
|
|
5783
|
+
} catch (error) {
|
|
5784
|
+
console.error(import_chalk.default.red(`Error: ${error.message}`));
|
|
5785
|
+
process.exit(1);
|
|
5786
|
+
}
|
|
5787
|
+
}
|
|
5788
|
+
function showTokenHelp() {
|
|
5789
|
+
console.log(`
|
|
5790
|
+
${import_chalk.default.bold("JSSM Token Management")}
|
|
5791
|
+
|
|
5792
|
+
Manage service tokens for container-based secrets injection.
|
|
5793
|
+
|
|
5794
|
+
${import_chalk.default.bold("Commands:")}
|
|
5795
|
+
jssm token create Create a new service token
|
|
5796
|
+
jssm token list List all tokens for a project/environment
|
|
5797
|
+
jssm token revoke Revoke a token
|
|
5798
|
+
|
|
5799
|
+
${import_chalk.default.bold("Options:")}
|
|
5800
|
+
-p, --project <name> Project name
|
|
5801
|
+
-e, --env <name> Environment name
|
|
5802
|
+
-n, --name <name> Token name (for create)
|
|
5803
|
+
--expires <duration> Expiration: 30d, 90d, 1y, never (default: 90d)
|
|
5804
|
+
|
|
5805
|
+
${import_chalk.default.bold("Examples:")}
|
|
5806
|
+
# Create a token for production
|
|
5807
|
+
jssm token create -p my-app -e production -n "deploy-token"
|
|
5808
|
+
|
|
5809
|
+
# Create a token that never expires
|
|
5810
|
+
jssm token create -p my-app -e staging --expires never
|
|
5811
|
+
|
|
5812
|
+
# List all tokens
|
|
5813
|
+
jssm token list -p my-app -e production
|
|
5814
|
+
|
|
5815
|
+
# Revoke a token
|
|
5816
|
+
jssm token revoke <token-id> -p my-app -e production
|
|
5817
|
+
|
|
5818
|
+
${import_chalk.default.bold("Usage in Docker:")}
|
|
5819
|
+
ENV JSSM_SERVICE_TOKEN=jssm_xxx...
|
|
5820
|
+
ENV JSSM_HOST=https://jssm.example.com
|
|
5821
|
+
RUN wget -O /usr/local/bin/jssm-init \${JSSM_HOST}/scripts/jssm-init.sh && chmod +x /usr/local/bin/jssm-init
|
|
5822
|
+
ENTRYPOINT ["/usr/local/bin/jssm-init"]
|
|
5823
|
+
CMD ["node", "app.js"]
|
|
5824
|
+
`);
|
|
5825
|
+
}
|
|
5826
|
+
|
|
5827
|
+
// src/utils/versionCheck.ts
|
|
5828
|
+
var PACKAGE_NAME = "@saidulbadhon/jssm-cli";
|
|
5829
|
+
var CURRENT_VERSION = "1.5.5";
|
|
5830
|
+
async function getLatestVersion() {
|
|
5831
|
+
try {
|
|
5832
|
+
const response = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}`);
|
|
5833
|
+
if (!response.ok) {
|
|
5834
|
+
return null;
|
|
5835
|
+
}
|
|
5836
|
+
const data = await response.json();
|
|
5837
|
+
return data["dist-tags"]?.latest || null;
|
|
5838
|
+
} catch {
|
|
5839
|
+
return null;
|
|
5840
|
+
}
|
|
5841
|
+
}
|
|
5842
|
+
function isOlderVersion(version1, version2) {
|
|
5843
|
+
const v1Parts = version1.split(".").map(Number);
|
|
5844
|
+
const v2Parts = version2.split(".").map(Number);
|
|
5845
|
+
for (let i = 0; i < 3; i++) {
|
|
5846
|
+
const v1 = v1Parts[i] || 0;
|
|
5847
|
+
const v2 = v2Parts[i] || 0;
|
|
5848
|
+
if (v1 < v2)
|
|
5849
|
+
return true;
|
|
5850
|
+
if (v1 > v2)
|
|
5851
|
+
return false;
|
|
5852
|
+
}
|
|
5853
|
+
return false;
|
|
5854
|
+
}
|
|
5855
|
+
async function checkVersion(currentCommand) {
|
|
5856
|
+
const skipCommands = ["help", "--help", "-h", "--version", "-v", "version", void 0];
|
|
5857
|
+
if (skipCommands.includes(currentCommand)) {
|
|
5858
|
+
return true;
|
|
5859
|
+
}
|
|
5860
|
+
try {
|
|
5861
|
+
const latestVersion = await getLatestVersion();
|
|
5862
|
+
if (!latestVersion) {
|
|
5863
|
+
return true;
|
|
5864
|
+
}
|
|
5865
|
+
if (!isOlderVersion(CURRENT_VERSION, latestVersion)) {
|
|
5866
|
+
return true;
|
|
5867
|
+
}
|
|
5868
|
+
console.log("");
|
|
5869
|
+
console.log("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
|
|
5870
|
+
console.log("\u2551 \u26A0\uFE0F UPDATE REQUIRED \u2551");
|
|
5871
|
+
console.log("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563");
|
|
5872
|
+
console.log(`\u2551 Current version: ${CURRENT_VERSION.padEnd(40)}\u2551`);
|
|
5873
|
+
console.log(`\u2551 Latest version: ${latestVersion.padEnd(40)}\u2551`);
|
|
5874
|
+
console.log("\u2551 \u2551");
|
|
5875
|
+
console.log("\u2551 A new version of JSSM CLI is available! \u2551");
|
|
5876
|
+
console.log("\u2551 Please update to continue using the CLI. \u2551");
|
|
5877
|
+
console.log("\u2551 \u2551");
|
|
5878
|
+
console.log("\u2551 Run: npm install -g @saidulbadhon/jssm-cli@latest \u2551");
|
|
5879
|
+
console.log("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
|
|
5880
|
+
console.log("");
|
|
5881
|
+
const shouldUpdate = await dist_default3({
|
|
5882
|
+
message: "Do you want to update now?",
|
|
5883
|
+
default: true
|
|
5884
|
+
});
|
|
5885
|
+
if (shouldUpdate) {
|
|
5886
|
+
console.log("\n\u{1F4E6} To update, run:");
|
|
5887
|
+
console.log(" npm install -g @saidulbadhon/jssm-cli@latest");
|
|
5888
|
+
console.log("\nOr if you used a different package manager:");
|
|
5889
|
+
console.log(" yarn global add @saidulbadhon/jssm-cli@latest");
|
|
5890
|
+
console.log(" pnpm add -g @saidulbadhon/jssm-cli@latest");
|
|
5891
|
+
console.log(" bun add -g @saidulbadhon/jssm-cli@latest");
|
|
5892
|
+
console.log("");
|
|
5893
|
+
process.exit(0);
|
|
5894
|
+
} else {
|
|
5895
|
+
console.log("\n\u274C Update required to continue. Please update and try again.\n");
|
|
5896
|
+
process.exit(1);
|
|
5897
|
+
}
|
|
5898
|
+
return false;
|
|
5899
|
+
} catch {
|
|
5900
|
+
return true;
|
|
5901
|
+
}
|
|
5902
|
+
}
|
|
5903
|
+
function getCurrentVersion() {
|
|
5904
|
+
return CURRENT_VERSION;
|
|
5905
|
+
}
|
|
5906
|
+
|
|
4193
5907
|
// src/index.ts
|
|
4194
5908
|
var args = process.argv.slice(2);
|
|
4195
5909
|
var command = args[0];
|
|
4196
5910
|
async function main() {
|
|
5911
|
+
if (command === "--version" || command === "-v" || command === "version") {
|
|
5912
|
+
console.log(`jssm v${getCurrentVersion()}`);
|
|
5913
|
+
return;
|
|
5914
|
+
}
|
|
5915
|
+
await checkVersion(command);
|
|
4197
5916
|
switch (command) {
|
|
4198
5917
|
case "login":
|
|
4199
5918
|
await loginCommand();
|
|
@@ -4208,10 +5927,10 @@ async function main() {
|
|
|
4208
5927
|
await initCommand(args.slice(1));
|
|
4209
5928
|
break;
|
|
4210
5929
|
case "pull":
|
|
4211
|
-
await
|
|
5930
|
+
await pullCommand2(args.slice(1));
|
|
4212
5931
|
break;
|
|
4213
5932
|
case "push":
|
|
4214
|
-
await
|
|
5933
|
+
await pushCommand2(args.slice(1));
|
|
4215
5934
|
break;
|
|
4216
5935
|
case "sync":
|
|
4217
5936
|
await syncCommand();
|
|
@@ -4222,12 +5941,26 @@ async function main() {
|
|
|
4222
5941
|
case "project":
|
|
4223
5942
|
await projectCommand(args.slice(1));
|
|
4224
5943
|
break;
|
|
4225
|
-
case "env":
|
|
4226
|
-
await envCommand(args.slice(1));
|
|
4227
|
-
break;
|
|
4228
5944
|
case "config":
|
|
4229
5945
|
await configCommand(args.slice(1));
|
|
4230
5946
|
break;
|
|
5947
|
+
case "token": {
|
|
5948
|
+
const subCommand = args[1];
|
|
5949
|
+
switch (subCommand) {
|
|
5950
|
+
case "create":
|
|
5951
|
+
await createToken(args.slice(2));
|
|
5952
|
+
break;
|
|
5953
|
+
case "list":
|
|
5954
|
+
await listTokens(args.slice(2));
|
|
5955
|
+
break;
|
|
5956
|
+
case "revoke":
|
|
5957
|
+
await revokeToken(args.slice(2));
|
|
5958
|
+
break;
|
|
5959
|
+
default:
|
|
5960
|
+
showTokenHelp();
|
|
5961
|
+
}
|
|
5962
|
+
break;
|
|
5963
|
+
}
|
|
4231
5964
|
case "help":
|
|
4232
5965
|
case "--help":
|
|
4233
5966
|
case "-h":
|
|
@@ -4253,13 +5986,14 @@ Commands:
|
|
|
4253
5986
|
logout Logout from your account
|
|
4254
5987
|
init Initialize current directory (creates .jssm config file)
|
|
4255
5988
|
status Show current configuration
|
|
4256
|
-
pull Pull
|
|
4257
|
-
push Push
|
|
5989
|
+
pull Pull .env files from configured project
|
|
5990
|
+
push Push .env files to configured project
|
|
4258
5991
|
sync Sync variables to .env file
|
|
4259
5992
|
project Manage projects (create, list)
|
|
4260
|
-
env Manage environments (create, list)
|
|
4261
5993
|
config Manage global configuration (set, get, list)
|
|
5994
|
+
token Manage service tokens for container secrets (create, list, revoke)
|
|
4262
5995
|
help Show this help message
|
|
5996
|
+
--version Show CLI version
|
|
4263
5997
|
|
|
4264
5998
|
Setup (recommended):
|
|
4265
5999
|
# 1. Set global host and login
|
|
@@ -4267,35 +6001,43 @@ Setup (recommended):
|
|
|
4267
6001
|
jssm register # or: jssm login
|
|
4268
6002
|
|
|
4269
6003
|
# 2. Initialize a project directory (creates .jssm file)
|
|
4270
|
-
jssm init # Interactive mode - will prompt for project
|
|
6004
|
+
jssm init # Interactive mode - will prompt for project
|
|
4271
6005
|
|
|
4272
|
-
# 3. Pull and push
|
|
4273
|
-
jssm pull # Download
|
|
4274
|
-
jssm push # Upload
|
|
6006
|
+
# 3. Pull and push .env files
|
|
6007
|
+
jssm pull # Download .env files from backend
|
|
6008
|
+
jssm push # Upload .env files to backend
|
|
4275
6009
|
jssm sync # Sync variables to .env file
|
|
4276
6010
|
|
|
4277
6011
|
Quick Start (all-in-one):
|
|
4278
6012
|
# Initialize with all options (for one-off use)
|
|
4279
|
-
jssm init -p my-app
|
|
6013
|
+
jssm init -p my-app
|
|
4280
6014
|
|
|
4281
6015
|
Advanced:
|
|
4282
6016
|
# Manage global configuration
|
|
4283
6017
|
jssm config list
|
|
4284
6018
|
jssm config set host http://api.example.com
|
|
4285
6019
|
|
|
4286
|
-
# Create project
|
|
6020
|
+
# Create project
|
|
4287
6021
|
jssm project create my-app
|
|
4288
|
-
jssm env create staging -p my-app
|
|
4289
|
-
jssm env create production -p my-app
|
|
4290
6022
|
|
|
4291
|
-
# List
|
|
6023
|
+
# List projects
|
|
4292
6024
|
jssm project list
|
|
4293
|
-
|
|
6025
|
+
|
|
6026
|
+
Container Secrets (Docker/ECS/EKS):
|
|
6027
|
+
# Create a service token for container deployment
|
|
6028
|
+
jssm token create -p my-app -n "deploy-token"
|
|
6029
|
+
|
|
6030
|
+
# Use in Dockerfile
|
|
6031
|
+
ENV JSSM_SERVICE_TOKEN=jssm_xxx...
|
|
6032
|
+
ENV JSSM_HOST=https://jssm.example.com
|
|
6033
|
+
RUN wget -O /usr/local/bin/jssm-init \\$JSSM_HOST/scripts/jssm-init.sh
|
|
6034
|
+
ENTRYPOINT ["/usr/local/bin/jssm-init"]
|
|
6035
|
+
CMD ["node", "app.js"]
|
|
4294
6036
|
|
|
4295
6037
|
Note:
|
|
4296
6038
|
- Global config (~/.jssm/config) stores host and preferences
|
|
4297
6039
|
- Auth data (~/.jssm/auth) stores your login session
|
|
4298
|
-
- Project config (.jssm) stores project name
|
|
6040
|
+
- Project config (.jssm) stores project name
|
|
4299
6041
|
- Add .jssm to .gitignore (may contain sensitive overrides)
|
|
4300
6042
|
|
|
4301
6043
|
For more information, visit: https://github.com/yourusername/jssm
|