@stacksjs/cli 0.59.11 → 0.61.1

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 CHANGED
@@ -20,6 +20,100 @@ function cli(name, options) {
20
20
  }
21
21
  return new CAC(name || "buddy");
22
22
  }
23
+ // src/run.ts
24
+ import {ExitCode as ExitCode2} from "@stacksjs/types";
25
+
26
+ // src/console.ts
27
+ import {log, logger} from "@stacksjs/logging";
28
+ import prompts from "prompts";
29
+
30
+ class Prompt {
31
+ required;
32
+ constructor() {
33
+ this.required = false;
34
+ }
35
+ require() {
36
+ this.required = true;
37
+ return this;
38
+ }
39
+ isRequired() {
40
+ return this.required;
41
+ }
42
+ async select(message, options) {
43
+ if (this.isRequired())
44
+ return logger.prompt(message, {
45
+ ...options,
46
+ type: "select",
47
+ required: true
48
+ });
49
+ return logger.prompt(message, { ...options, type: "select" });
50
+ }
51
+ async checkbox(message, options) {
52
+ if (this.isRequired())
53
+ return logger.prompt(message, {
54
+ ...options,
55
+ type: "multiselect",
56
+ required: true
57
+ });
58
+ return logger.prompt(message, { ...options, type: "multiselect" });
59
+ }
60
+ async confirm(message, options) {
61
+ if (this.isRequired())
62
+ return logger.prompt(message, {
63
+ ...options,
64
+ type: "confirm",
65
+ required: true
66
+ });
67
+ return logger.prompt(message, { ...options, type: "confirm" });
68
+ }
69
+ async input(message, options) {
70
+ if (this.isRequired())
71
+ return logger.prompt(message, {
72
+ ...options,
73
+ type: "text",
74
+ required: true
75
+ });
76
+ return logger.prompt(message, { ...options, type: "text" });
77
+ }
78
+ async password(message, options) {
79
+ if (this.isRequired())
80
+ return logger.prompt(message, {
81
+ ...options,
82
+ type: "password",
83
+ required: true
84
+ });
85
+ return logger.prompt(message, { ...options, type: "password" });
86
+ }
87
+ async number(message, options) {
88
+ if (this.isRequired())
89
+ return logger.prompt(message, {
90
+ ...options,
91
+ type: "numeral",
92
+ required: true
93
+ });
94
+ return logger.prompt(message, { ...options, type: "numeral" });
95
+ }
96
+ async multiselect(message, options) {
97
+ if (this.isRequired())
98
+ return logger.prompt(message, {
99
+ ...options,
100
+ type: "multiselect",
101
+ required: true
102
+ });
103
+ return logger.prompt(message, { ...options, type: "multiselect" });
104
+ }
105
+ async autocomplete(message, options) {
106
+ if (this.isRequired())
107
+ return logger.prompt(message, {
108
+ ...options,
109
+ type: "autocomplete",
110
+ required: true
111
+ });
112
+ return logger.prompt(message, { ...options, type: "autocomplete" });
113
+ }
114
+ }
115
+ var prompt = () => new Prompt;
116
+
23
117
  // src/exec.ts
24
118
  import process2 from "process";
25
119
  import {err, handleError, ok} from "@stacksjs/error-handling";
@@ -28,15 +122,15 @@ async function exec(command, options) {
28
122
  const cmd = Array.isArray(command) ? command : command.match(/(?:[^\s"]+|"[^"]*")+/g);
29
123
  if (!cmd)
30
124
  return err(handleError(`Failed to parse command: ${cmd}`, options));
31
- log2.debug("exec:", Array.isArray(command) ? command.join(" ") : command);
32
- log2.debug("cmd:", cmd);
33
- log2.debug("exec options:", options);
125
+ log.debug("exec:", Array.isArray(command) ? command.join(" ") : command);
126
+ log.debug("cmd:", cmd);
127
+ log.debug("exec options:", options);
34
128
  const proc = Bun.spawn(cmd, {
35
129
  ...options,
36
130
  stdout: options?.silent || options?.quiet ? "ignore" : options?.stdin ? options.stdin : options?.stdout || "inherit",
37
131
  stderr: options?.silent || options?.quiet ? "ignore" : options?.stderr || "inherit",
38
132
  detached: options?.background || false,
39
- cwd: options?.cwd || import.meta.dir,
133
+ cwd: options?.cwd || process2.cwd(),
40
134
  onExit(subprocess, exitCode, signalCode, error) {
41
135
  exitHandler("spawn", subprocess, exitCode, signalCode, error);
42
136
  }
@@ -53,11 +147,11 @@ async function exec(command, options) {
53
147
  return err(handleError(`Failed to execute command: ${cmd.join(" ")}`));
54
148
  }
55
149
  async function execSync(command, options) {
56
- log2.debug("Running ExecSync:", command);
57
- log2.debug("ExecSync Options:", options);
150
+ log.debug("Running ExecSync:", command);
151
+ log.debug("ExecSync Options:", options);
58
152
  const cmd = Array.isArray(command) ? command : command.match(/(?:[^\s"]+|"[^"]*")+/g);
59
153
  if (!cmd) {
60
- log2.error(`Failed to parse command: ${cmd}`, options);
154
+ log.error(`Failed to parse command: ${cmd}`, options);
61
155
  process2.exit(ExitCode.FatalError);
62
156
  }
63
157
  const proc = Bun.spawnSync(cmd, {
@@ -65,7 +159,7 @@ async function execSync(command, options) {
65
159
  stdin: options?.stdin ?? "inherit",
66
160
  stdout: options?.stdout ?? "pipe",
67
161
  stderr: options?.stderr ?? "inherit",
68
- cwd: options?.cwd ?? import.meta.dir,
162
+ cwd: options?.cwd ?? process2.cwd(),
69
163
  onExit(subprocess, exitCode, signalCode, error) {
70
164
  exitHandler("spawnSync", subprocess, exitCode, signalCode, error);
71
165
  }
@@ -73,12 +167,12 @@ async function execSync(command, options) {
73
167
  return proc.stdout.toString();
74
168
  }
75
169
  var exitHandler = function(type, subprocess, exitCode, signalCode, error) {
76
- log2.debug(`exitHandler: ${type}`);
77
- log2.debug("subprocess", subprocess);
78
- log2.debug("exitCode", exitCode);
79
- log2.debug("signalCode", signalCode);
170
+ log.debug(`exitHandler: ${type}`);
171
+ log.debug("subprocess", subprocess);
172
+ log.debug("exitCode", exitCode);
173
+ log.debug("signalCode", signalCode);
80
174
  if (error) {
81
- log2.error(error);
175
+ log.error(error);
82
176
  process2.exit(ExitCode.FatalError);
83
177
  }
84
178
  if (exitCode !== ExitCode.Success && exitCode)
@@ -415,86 +509,33 @@ var quotes = collect([
415
509
  "Security is mostly a superstition. Life is either a daring adventure or nothing."
416
510
  ]);
417
511
 
418
- // src/console.ts
419
- import {log as log2, logger} from "@stacksjs/logging";
420
- import prompts from "prompts";
421
-
422
- class Prompt {
423
- required;
424
- constructor() {
425
- this.required = false;
426
- }
427
- require() {
428
- this.required = true;
429
- return this;
430
- }
431
- isRequired() {
432
- return this.required;
433
- }
434
- async select(message, options) {
435
- if (this.isRequired())
436
- return logger.prompt(message, { ...options, type: "select", required: true });
437
- return logger.prompt(message, { ...options, type: "select" });
438
- }
439
- async checkbox(message, options) {
440
- if (this.isRequired())
441
- return logger.prompt(message, { ...options, type: "multiselect", required: true });
442
- return logger.prompt(message, { ...options, type: "multiselect" });
443
- }
444
- async confirm(message, options) {
445
- if (this.isRequired())
446
- return logger.prompt(message, { ...options, type: "confirm", required: true });
447
- return logger.prompt(message, { ...options, type: "confirm" });
448
- }
449
- async input(message, options) {
450
- if (this.isRequired())
451
- return logger.prompt(message, { ...options, type: "text", required: true });
452
- return logger.prompt(message, { ...options, type: "text" });
453
- }
454
- async password(message, options) {
455
- if (this.isRequired())
456
- return logger.prompt(message, { ...options, type: "password", required: true });
457
- return logger.prompt(message, { ...options, type: "password" });
458
- }
459
- async number(message, options) {
460
- if (this.isRequired())
461
- return logger.prompt(message, { ...options, type: "numeral", required: true });
462
- return logger.prompt(message, { ...options, type: "numeral" });
463
- }
464
- async multiselect(message, options) {
465
- if (this.isRequired())
466
- return logger.prompt(message, { ...options, type: "multiselect", required: true });
467
- return logger.prompt(message, { ...options, type: "multiselect" });
468
- }
469
- async autocomplete(message, options) {
470
- if (this.isRequired())
471
- return logger.prompt(message, { ...options, type: "autocomplete", required: true });
472
- return logger.prompt(message, { ...options, type: "autocomplete" });
473
- }
474
- }
475
- var prompt = () => new Prompt;
476
-
477
512
  // src/run.ts
478
513
  async function runCommand(command, options) {
479
- log2.debug("runCommand:", command);
480
- log2.debug("options:", options);
514
+ log.debug("runCommand:", command);
515
+ log.debug("options:", options);
481
516
  return await exec(command, options);
482
517
  }
483
518
  async function runProcess(command, options) {
484
- log2.debug("runProcess:", italic(command));
485
- log2.debug("runProcess Options:", options);
519
+ log.debug("runProcess:", italic(command));
520
+ log.debug("runProcess Options:", options);
486
521
  return await exec(command, options);
487
522
  }
488
523
  async function runCommandSync(command, options) {
489
- log2.debug("runCommandSync:", italic(command));
490
- log2.debug("runCommandSync Options:", options);
524
+ log.debug("runCommandSync:", italic(command));
525
+ log.debug("runCommandSync Options:", options);
491
526
  const result = await execSync(command, options);
492
527
  return result;
493
528
  }
494
529
  async function runCommands(commands, options) {
495
530
  const results = [];
496
- for (const command of commands)
497
- results.push(await runCommand(command, options));
531
+ for (const command of commands) {
532
+ const result = await runCommand(command, options);
533
+ if (result.isErr()) {
534
+ log.error(result.error);
535
+ process.exit(ExitCode2.FatalError);
536
+ }
537
+ results.push(result);
538
+ }
498
539
  return results;
499
540
  }
500
541
 
@@ -524,13 +565,12 @@ var command = {
524
565
  }
525
566
  };
526
567
  // src/helpers.ts
527
- import {config as config2} from "@stacksjs/config";
528
568
  import {handleError as handleError2} from "@stacksjs/error-handling";
529
- import {log as log3} from "@stacksjs/logging";
530
- import {ExitCode as ExitCode2} from "@stacksjs/types";
569
+ import {log as log2} from "@stacksjs/logging";
570
+ import {ExitCode as ExitCode3} from "@stacksjs/types";
531
571
  import {bgCyan as bgCyan2, bold as bold2, cyan as cyan2, dim as dim2, gray as gray2, green as green2, italic as italic2} from "kolorist";
532
572
  // package.json
533
- var version = "0.59.11";
573
+ var version = "0.61.1";
534
574
 
535
575
  // src/helpers.ts
536
576
  async function intro(command2, options) {
@@ -540,10 +580,7 @@ async function intro(command2, options) {
540
580
  console.log(cyan2(bold2("Stacks CLI")) + dim2(` v${version}`));
541
581
  console.log();
542
582
  }
543
- let msg = `Running ${bgCyan2(italic2(bold2(` ${command2} `)))}`;
544
- if (command2 === "buddy deploy")
545
- msg = `Running ${bgCyan2(italic2(bold2(` ${command2} `)))} for ${bold2(`${config2.app.name}`)} ${italic2(`via ${config2.app.url}`)}`;
546
- log3.info(msg);
583
+ log2.info(`Running ${bgCyan2(italic2(bold2(` ${command2} `)))}`);
547
584
  if (options?.showPerformance === false || options?.quiet)
548
585
  return resolve(0);
549
586
  return resolve(performance.now());
@@ -566,24 +603,25 @@ function outro(text, options, error) {
566
603
  time = Math.round(time * 100) / 100;
567
604
  }
568
605
  if (opts.quiet === true)
569
- return resolve(ExitCode2.Success);
606
+ return resolve(ExitCode3.Success);
570
607
  if (error)
571
- log3.error(`[${time.toFixed(2)}${opts.useSeconds ? "s" : "ms"}] Failed`);
608
+ log2.error(`[${time.toFixed(2)}${opts.useSeconds ? "s" : "ms"}] Failed`);
572
609
  else if (opts.type === "info")
573
- log3.info(`${dim2(gray2(`[${time.toFixed(2)}${opts.useSeconds ? "s" : "ms"}]`))} ${opts.message ?? "Complete"}`);
610
+ log2.info(`${dim2(gray2(`[${time.toFixed(2)}${opts.useSeconds ? "s" : "ms"}]`))} ${opts.message ?? "Complete"}`);
574
611
  else
575
- log3.success(`${dim2(gray2(bold2(`[${time.toFixed(2)}${opts.useSeconds ? "s" : "ms"}]`)))} ${bold2(green2(opts.message ?? "Complete"))}`);
612
+ log2.success(`${dim2(gray2(bold2(`[${time.toFixed(2)}${opts.useSeconds ? "s" : "ms"}]`)))} ${bold2(green2(opts.message ?? "Complete"))}`);
576
613
  } else {
577
614
  if (opts?.type === "info")
578
- log3.info(text);
615
+ log2.info(text);
579
616
  else if (opts?.type === "success" && opts?.quiet !== true)
580
- log3.success(text);
617
+ log2.success(text);
581
618
  }
582
- return resolve(ExitCode2.Success);
619
+ return resolve(ExitCode3.Success);
583
620
  });
584
621
  }
585
622
  // src/parse.ts
586
623
  import process3 from "process";
624
+ import {log as log3} from "@stacksjs/logging";
587
625
  var isLongOption = function(arg) {
588
626
  if (!arg)
589
627
  return false;
@@ -606,7 +644,7 @@ var parseLongOption = function(arg, argv2, index, options) {
606
644
  const [key, value] = arg.slice(2).split("=");
607
645
  if (value !== undefined) {
608
646
  options[key] = parseValue(value);
609
- } else if (index + 1 < argv2.length && !argv2[index + 1].startsWith("-")) {
647
+ } else if (index + 1 < argv2.length && !argv2[index + 1]?.startsWith("-")) {
610
648
  options[key] = argv2[index + 1];
611
649
  index++;
612
650
  } else {
@@ -623,7 +661,7 @@ var parseShortOption = function(arg, argv2, index, options) {
623
661
  options[key[j]] = parseValue(value);
624
662
  } else {
625
663
  for (let j = 0;j < key.length; j++) {
626
- if (index + 1 < argv2.length && j === key.length - 1 && !argv2[index + 1].startsWith("-")) {
664
+ if (index + 1 < argv2.length && j === key.length - 1 && !argv2[index + 1]?.startsWith("-")) {
627
665
  options[key[j]] = parseValue(argv2[index + 1]);
628
666
  index++;
629
667
  } else {
@@ -696,9 +734,9 @@ function buddyOptions(options) {
696
734
  options.shift();
697
735
  }
698
736
  if (options?.verbose) {
699
- log.debug("process.argv", process3.argv);
700
- log.debug("process.argv.slice(2)", process3.argv.slice(2));
701
- log.debug("options inside buddyOptions", options);
737
+ log3.debug("process.argv", process3.argv);
738
+ log3.debug("process.argv.slice(2)", process3.argv.slice(2));
739
+ log3.debug("options inside buddyOptions", options);
702
740
  }
703
741
  return options.join(" ");
704
742
  }
@@ -731,7 +769,7 @@ export {
731
769
  outro,
732
770
  magenta,
733
771
  logger,
734
- log2 as log,
772
+ log,
735
773
  link,
736
774
  lightYellow,
737
775
  lightRed,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/cli",
3
3
  "type": "module",
4
- "version": "0.59.11",
4
+ "version": "0.61.1",
5
5
  "description": "TypeScript framework for CLI artisans. Build beautiful console apps with ease.",
6
6
  "author": "Chris Breuer",
7
7
  "license": "MIT",
@@ -57,7 +57,8 @@
57
57
  "prepublishOnly": "bun run build"
58
58
  },
59
59
  "peerDependencies": {
60
- "@antfu/install-pkg": "^0.3.1",
60
+ "@antfu/install-pkg": "^0.3.3",
61
+ "@clack/prompts": "^0.7.0",
61
62
  "@stacksjs/config": "latest",
62
63
  "@stacksjs/error-handling": "latest",
63
64
  "@stacksjs/logging": "latest",
@@ -71,7 +72,8 @@
71
72
  "prompts": "^2.4.2"
72
73
  },
73
74
  "dependencies": {
74
- "@antfu/install-pkg": "^0.3.1",
75
+ "@antfu/install-pkg": "^0.3.3",
76
+ "@clack/prompts": "^0.7.0",
75
77
  "@stacksjs/collections": "latest",
76
78
  "@stacksjs/config": "latest",
77
79
  "@stacksjs/error-handling": "latest",
@@ -1,5 +1,5 @@
1
- import type { ExecaReturnValue } from 'execa'
2
1
  import { installPackage as installPkg } from '@antfu/install-pkg'
2
+ import type { ExecaReturnValue } from 'execa'
3
3
 
4
4
  interface InstallPackageOptions {
5
5
  cwd?: string
@@ -18,9 +18,8 @@ interface InstallPackageOptions {
18
18
  * @param options - The options to pass to the install.The options to pass to the install.
19
19
  * @returns The result of the install.
20
20
  */
21
- export async function installPackage(name: string, options?: InstallPackageOptions): Promise<ExecaReturnValue<string>> {
22
- if (options)
23
- return await installPkg(name, options)
21
+ export async function installPackage(name: string, options?: InstallPackageOptions) {
22
+ if (options) return await installPkg(name, options)
24
23
 
25
24
  return await installPkg(name, { silent: true })
26
25
  }
@@ -33,8 +32,7 @@ export async function installPackage(name: string, options?: InstallPackageOptio
33
32
  * @returns The result of the install.
34
33
  */
35
34
  export async function installStack(name: string, options?: InstallPackageOptions) {
36
- if (options)
37
- return await installPkg(`@stacksjs/${name}`, options)
35
+ if (options) return await installPkg(`@stacksjs/${name}`, options)
38
36
 
39
37
  return await installPkg(`@stacksjs/${name}`, { silent: true })
40
38
  }
package/src/console.ts CHANGED
@@ -19,56 +19,88 @@ export class Prompt {
19
19
 
20
20
  async select(message: any, options: any) {
21
21
  if (this.isRequired())
22
- return logger.prompt(message, { ...options, type: 'select', required: true })
22
+ return logger.prompt(message, {
23
+ ...options,
24
+ type: 'select',
25
+ required: true,
26
+ })
23
27
 
24
28
  return logger.prompt(message, { ...options, type: 'select' })
25
29
  }
26
30
 
27
31
  async checkbox(message: any, options: any) {
28
32
  if (this.isRequired())
29
- return logger.prompt(message, { ...options, type: 'multiselect', required: true })
33
+ return logger.prompt(message, {
34
+ ...options,
35
+ type: 'multiselect',
36
+ required: true,
37
+ })
30
38
 
31
39
  return logger.prompt(message, { ...options, type: 'multiselect' })
32
40
  }
33
41
 
34
42
  async confirm(message: any, options: any) {
35
43
  if (this.isRequired())
36
- return logger.prompt(message, { ...options, type: 'confirm', required: true })
44
+ return logger.prompt(message, {
45
+ ...options,
46
+ type: 'confirm',
47
+ required: true,
48
+ })
37
49
 
38
50
  return logger.prompt(message, { ...options, type: 'confirm' })
39
51
  }
40
52
 
41
53
  async input(message: any, options: any) {
42
54
  if (this.isRequired())
43
- return logger.prompt(message, { ...options, type: 'text', required: true })
55
+ return logger.prompt(message, {
56
+ ...options,
57
+ type: 'text',
58
+ required: true,
59
+ })
44
60
 
45
61
  return logger.prompt(message, { ...options, type: 'text' })
46
62
  }
47
63
 
48
64
  async password(message: any, options: any) {
49
65
  if (this.isRequired())
50
- return logger.prompt(message, { ...options, type: 'password', required: true })
66
+ return logger.prompt(message, {
67
+ ...options,
68
+ type: 'password',
69
+ required: true,
70
+ })
51
71
 
52
72
  return logger.prompt(message, { ...options, type: 'password' })
53
73
  }
54
74
 
55
75
  async number(message: any, options: any) {
56
76
  if (this.isRequired())
57
- return logger.prompt(message, { ...options, type: 'numeral', required: true })
77
+ return logger.prompt(message, {
78
+ ...options,
79
+ type: 'numeral',
80
+ required: true,
81
+ })
58
82
 
59
83
  return logger.prompt(message, { ...options, type: 'numeral' })
60
84
  }
61
85
 
62
86
  async multiselect(message: any, options: any) {
63
87
  if (this.isRequired())
64
- return logger.prompt(message, { ...options, type: 'multiselect', required: true })
88
+ return logger.prompt(message, {
89
+ ...options,
90
+ type: 'multiselect',
91
+ required: true,
92
+ })
65
93
 
66
94
  return logger.prompt(message, { ...options, type: 'multiselect' })
67
95
  }
68
96
 
69
97
  async autocomplete(message: any, options: any) {
70
98
  if (this.isRequired())
71
- return logger.prompt(message, { ...options, type: 'autocomplete', required: true })
99
+ return logger.prompt(message, {
100
+ ...options,
101
+ type: 'autocomplete',
102
+ required: true,
103
+ })
72
104
 
73
105
  return logger.prompt(message, { ...options, type: 'autocomplete' })
74
106
  }
package/src/exec.ts CHANGED
@@ -25,12 +25,9 @@ import { log } from './'
25
25
  * ```
26
26
  */
27
27
  export async function exec(command: string | string[], options?: CliOptions): Promise<Result<Subprocess, Error>> {
28
- const cmd = Array.isArray(command)
29
- ? command
30
- : command.match(/(?:[^\s"]+|"[^"]*")+/g)
28
+ const cmd = Array.isArray(command) ? command : command.match(/(?:[^\s"]+|"[^"]*")+/g)
31
29
 
32
- if (!cmd)
33
- return err(handleError(`Failed to parse command: ${cmd}`, options))
30
+ if (!cmd) return err(handleError(`Failed to parse command: ${cmd}`, options))
34
31
 
35
32
  log.debug('exec:', Array.isArray(command) ? command.join(' ') : command)
36
33
  log.debug('cmd:', cmd)
@@ -38,10 +35,11 @@ export async function exec(command: string | string[], options?: CliOptions): Pr
38
35
 
39
36
  const proc = Bun.spawn(cmd, {
40
37
  ...options,
41
- stdout: (options?.silent || options?.quiet) ? 'ignore' : (options?.stdin ? options.stdin : (options?.stdout || 'inherit')),
42
- stderr: (options?.silent || options?.quiet) ? 'ignore' : (options?.stderr || 'inherit'),
38
+ stdout:
39
+ options?.silent || options?.quiet ? 'ignore' : options?.stdin ? options.stdin : options?.stdout || 'inherit',
40
+ stderr: options?.silent || options?.quiet ? 'ignore' : options?.stderr || 'inherit',
43
41
  detached: options?.background || false,
44
- cwd: options?.cwd || import.meta.dir,
42
+ cwd: options?.cwd || process.cwd(),
45
43
  // env: { ...e, ...options?.env },
46
44
  onExit(subprocess, exitCode, signalCode, error) {
47
45
  exitHandler('spawn', subprocess, exitCode, signalCode, error)
@@ -60,8 +58,7 @@ export async function exec(command: string | string[], options?: CliOptions): Pr
60
58
  }
61
59
 
62
60
  const exited = await proc.exited
63
- if (exited === ExitCode.Success)
64
- return ok(proc)
61
+ if (exited === ExitCode.Success) return ok(proc)
65
62
 
66
63
  return err(handleError(`Failed to execute command: ${cmd.join(' ')}`))
67
64
  }
@@ -86,9 +83,7 @@ export async function execSync(command: string | string[], options?: CliOptions)
86
83
  log.debug('Running ExecSync:', command)
87
84
  log.debug('ExecSync Options:', options)
88
85
 
89
- const cmd = Array.isArray(command)
90
- ? command
91
- : command.match(/(?:[^\s"]+|"[^"]*")+/g)
86
+ const cmd = Array.isArray(command) ? command : command.match(/(?:[^\s"]+|"[^"]*")+/g)
92
87
 
93
88
  if (!cmd) {
94
89
  log.error(`Failed to parse command: ${cmd}`, options)
@@ -100,7 +95,7 @@ export async function execSync(command: string | string[], options?: CliOptions)
100
95
  stdin: options?.stdin ?? 'inherit',
101
96
  stdout: options?.stdout ?? 'pipe',
102
97
  stderr: options?.stderr ?? 'inherit',
103
- cwd: options?.cwd ?? import.meta.dir,
98
+ cwd: options?.cwd ?? process.cwd(),
104
99
  // env: { ...Bun.env, ...options?.env },
105
100
  onExit(subprocess, exitCode, signalCode, error) {
106
101
  exitHandler('spawnSync', subprocess, exitCode, signalCode, error)
@@ -122,6 +117,5 @@ function exitHandler(type: 'spawn' | 'spawnSync', subprocess, exitCode, signalCo
122
117
  process.exit(ExitCode.FatalError)
123
118
  }
124
119
 
125
- if (exitCode !== ExitCode.Success && exitCode)
126
- process.exit(exitCode)
120
+ if (exitCode !== ExitCode.Success && exitCode) process.exit(exitCode)
127
121
  }
package/src/helpers.ts CHANGED
@@ -1,5 +1,3 @@
1
- /* eslint-disable no-console */
2
- import { config } from '@stacksjs/config'
3
1
  import { handleError } from '@stacksjs/error-handling'
4
2
  import { log } from '@stacksjs/logging'
5
3
  import type { IntroOptions, OutroOptions } from '@stacksjs/types'
@@ -18,14 +16,9 @@ export async function intro(command: string, options?: IntroOptions): Promise<nu
18
16
  console.log()
19
17
  }
20
18
 
21
- let msg = `Running ${bgCyan(italic(bold(` ${command} `)))}`
22
- if (command === 'buddy deploy')
23
- msg = `Running ${bgCyan(italic(bold(` ${command} `)))} for ${bold(`${config.app.name}`)} ${italic(`via ${config.app.url}`)}`
19
+ log.info(`Running ${bgCyan(italic(bold(` ${command} `)))}`)
24
20
 
25
- log.info(msg)
26
-
27
- if (options?.showPerformance === false || options?.quiet)
28
- return resolve(0)
21
+ if (options?.showPerformance === false || options?.quiet) return resolve(0)
29
22
 
30
23
  return resolve(performance.now())
31
24
  })
@@ -44,8 +37,7 @@ export function outro(text: string, options?: OutroOptions, error?: Error | stri
44
37
  opts.message = options?.message || text
45
38
 
46
39
  return new Promise((resolve) => {
47
- if (error)
48
- return handleError(error)
40
+ if (error) return handleError(error)
49
41
 
50
42
  if (opts?.startTime) {
51
43
  let time = performance.now() - opts.startTime
@@ -55,24 +47,21 @@ export function outro(text: string, options?: OutroOptions, error?: Error | stri
55
47
  time = Math.round(time * 100) / 100 // https://stackoverflow.com/a/11832950/7811162
56
48
  }
57
49
 
58
- if (opts.quiet === true)
59
- return resolve(ExitCode.Success)
50
+ if (opts.quiet === true) return resolve(ExitCode.Success)
60
51
 
61
- if (error)
62
- log.error(`[${time.toFixed(2)}${opts.useSeconds ? 's' : 'ms'}] Failed`)
52
+ if (error) log.error(`[${time.toFixed(2)}${opts.useSeconds ? 's' : 'ms'}] Failed`)
63
53
  else if (opts.type === 'info')
64
54
  log.info(`${dim(gray(`[${time.toFixed(2)}${opts.useSeconds ? 's' : 'ms'}]`))} ${opts.message ?? 'Complete'}`)
65
55
  else
66
- log.success(`${dim(gray(bold(`[${time.toFixed(2)}${opts.useSeconds ? 's' : 'ms'}]`)))} ${bold(green(opts.message ?? 'Complete'))}`)
67
- }
68
-
69
- else {
70
- if (opts?.type === 'info')
71
- log.info(text)
72
-
56
+ log.success(
57
+ `${dim(gray(bold(`[${time.toFixed(2)}${opts.useSeconds ? 's' : 'ms'}]`)))} ${bold(
58
+ green(opts.message ?? 'Complete'),
59
+ )}`,
60
+ )
61
+ } else {
62
+ if (opts?.type === 'info') log.info(text)
73
63
  // the following condition triggers in the case of "Cleaned up" messages
74
- else if (opts?.type === 'success' && opts?.quiet !== true)
75
- log.success(text)
64
+ else if (opts?.type === 'success' && opts?.quiet !== true) log.success(text)
76
65
  }
77
66
 
78
67
  return resolve(ExitCode.Success)
package/src/parse.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import process from 'node:process'
2
+ import { log } from '@stacksjs/logging'
2
3
 
3
4
  interface ParsedArgv {
4
5
  args: string[]
@@ -8,8 +9,7 @@ interface ParsedArgv {
8
9
  }
9
10
 
10
11
  function isLongOption(arg?: string): boolean {
11
- if (!arg)
12
- return false
12
+ if (!arg) return false
13
13
 
14
14
  return arg.startsWith('--')
15
15
  }
@@ -19,52 +19,53 @@ function isShortOption(arg: string): boolean {
19
19
  }
20
20
 
21
21
  function parseValue(value: string): string | boolean | number {
22
- if (value === 'true')
23
- return true
22
+ if (value === 'true') return true
24
23
 
25
- if (value === 'false')
26
- return false
24
+ if (value === 'false') return false
27
25
 
28
26
  const numberValue = Number.parseFloat(value)
29
- if (!Number.isNaN(numberValue))
30
- return numberValue
27
+ if (!Number.isNaN(numberValue)) return numberValue
31
28
 
32
29
  return value.replace(/"/g, '')
33
30
  }
34
31
 
35
- function parseLongOption(arg: string, argv: string[], index: number, options: { [k: string]: string | boolean | number }): number {
32
+ function parseLongOption(
33
+ arg: string,
34
+ argv: string[],
35
+ index: number,
36
+ options: { [k: string]: string | boolean | number },
37
+ ): number {
36
38
  const [key, value] = arg.slice(2).split('=')
37
39
  if (value !== undefined) {
38
40
  options[key as string] = parseValue(value)
39
- }
40
- else if (index + 1 < argv.length && !argv[index + 1]!.startsWith('-')) {
41
+ } else if (index + 1 < argv.length && !argv[index + 1]?.startsWith('-')) {
41
42
  options[key as string] = argv[index + 1] as string
42
43
  index++
43
- }
44
- else {
44
+ } else {
45
45
  options[key as string] = true
46
46
  }
47
47
  return index
48
48
  }
49
49
 
50
- function parseShortOption(arg: string, argv: string[], index: number, options: { [k: string]: string | boolean | number }): number {
50
+ function parseShortOption(
51
+ arg: string,
52
+ argv: string[],
53
+ index: number,
54
+ options: { [k: string]: string | boolean | number },
55
+ ): number {
51
56
  const [key, value] = arg.slice(1).split('=')
52
57
 
53
58
  // Check if key is undefined and handle it
54
- if (key === undefined)
55
- return index
59
+ if (key === undefined) return index
56
60
 
57
61
  if (value !== undefined && key !== undefined) {
58
- for (let j = 0; j < key.length; j++)
59
- options[key[j] as string] = parseValue(value)
60
- }
61
- else {
62
+ for (let j = 0; j < key.length; j++) options[key[j] as string] = parseValue(value)
63
+ } else {
62
64
  for (let j = 0; j < key.length; j++) {
63
- if (index + 1 < argv.length && j === key.length - 1 && !argv[index + 1]!.startsWith('-')) {
64
- options[key[j] as string] = parseValue(argv[index + 1]!)
65
+ if (index + 1 < argv.length && j === key.length - 1 && !argv[index + 1]?.startsWith('-')) {
66
+ options[key[j] as string] = parseValue(argv[index + 1] as string)
65
67
  index++
66
- }
67
- else {
68
+ } else {
68
69
  options[key[j] as string] = true
69
70
  }
70
71
  }
@@ -74,30 +75,24 @@ function parseShortOption(arg: string, argv: string[], index: number, options: {
74
75
  }
75
76
 
76
77
  export function parseArgv(argv?: string[]): ParsedArgv {
77
- if (argv === undefined)
78
- argv = process.argv.slice(2)
78
+ if (argv === undefined) argv = process.argv.slice(2)
79
79
 
80
80
  const args: string[] = []
81
81
  const options: { [k: string]: string | boolean | number } = {}
82
82
 
83
83
  for (let i = 0; i < argv.length; i++) {
84
84
  const arg = argv[i]
85
- if (!arg)
86
- continue
87
- if (isLongOption(arg))
88
- i = parseLongOption(arg, argv, i, options)
89
- else if (isShortOption(arg))
90
- i = parseShortOption(arg, argv, i, options)
91
- else
92
- args.push(arg)
85
+ if (!arg) continue
86
+ if (isLongOption(arg)) i = parseLongOption(arg, argv, i, options)
87
+ else if (isShortOption(arg)) i = parseShortOption(arg, argv, i, options)
88
+ else args.push(arg)
93
89
  }
94
90
 
95
91
  return { args, options }
96
92
  }
97
93
 
98
94
  export function parseArgs(argv?: string[]): string[] {
99
- if (argv === undefined)
100
- argv = process.argv.slice(2)
95
+ if (argv === undefined) argv = process.argv.slice(2)
101
96
 
102
97
  return parseArgv(argv).args
103
98
  }
@@ -119,38 +114,35 @@ export function parseOptions(options?: CliOptions): CliOptions {
119
114
  const key = arg.substring(2) // remove the --
120
115
  const camelCaseKey = key.replace(
121
116
  /-([a-z])/gi,
122
- g => (g[1] ? g[1].toUpperCase() : ''), // convert kebab-case to camelCase
117
+ (g) => (g[1] ? g[1].toUpperCase() : ''), // convert kebab-case to camelCase
123
118
  )
124
119
 
125
- if (i + 1 < args.length) { // if the next arg exists
126
- if (args[i + 1] === 'true' || args[i + 1] === 'false') { // if the next arg is a boolean
120
+ if (i + 1 < args.length) {
121
+ // if the next arg exists
122
+ if (args[i + 1] === 'true' || args[i + 1] === 'false') {
123
+ // if the next arg is a boolean
127
124
  options[camelCaseKey] = args[i + 1] === 'true' // set the value to the boolean
128
125
  i++
129
- }
130
- else {
126
+ } else {
131
127
  options[camelCaseKey] = args[i + 1]
132
128
  i++
133
129
  }
134
- }
135
- else {
130
+ } else {
136
131
  options[camelCaseKey] = true
137
132
  }
138
133
  }
139
134
  }
140
135
 
141
136
  // if options has no keys, return undefined, e.g. `buddy release`
142
- if (Object.keys(options).length === 0)
143
- return { dryRun: false, quiet: false, verbose: false }
137
+ if (Object.keys(options).length === 0) return { dryRun: false, quiet: false, verbose: false }
144
138
 
145
139
  // convert the string 'true' or 'false' to a boolean
146
140
  Object.keys(options).forEach((key) => {
147
- if (!options)
148
- return { dryRun: false, quiet: false, verbose: false }
141
+ if (!options) return { dryRun: false, quiet: false, verbose: false }
149
142
 
150
143
  const value = options[key]
151
144
 
152
- if (value === 'true' || value === 'false')
153
- options[key] = value === 'true'
145
+ if (value === 'true' || value === 'false') options[key] = value === 'true'
154
146
  })
155
147
 
156
148
  return options
@@ -165,8 +157,7 @@ export function buddyOptions(options?: any): string {
165
157
  options = Array.from(new Set(options))
166
158
  // delete the 0 element if it does not start with a -
167
159
  // e.g. is used when buddy changelog --dry-run is used
168
- if (options[0] && !options[0].startsWith('-'))
169
- options.shift()
160
+ if (options[0] && !options[0].startsWith('-')) options.shift()
170
161
  }
171
162
 
172
163
  if (options?.verbose) {
package/src/run.ts CHANGED
@@ -1,8 +1,9 @@
1
- import type { CliOptions, CommandError, Subprocess } from '@stacksjs/types'
2
1
  import type { Result } from '@stacksjs/error-handling'
2
+ import type { CliOptions, CommandError, Subprocess } from '@stacksjs/types'
3
+ import { ExitCode } from '@stacksjs/types'
4
+ import { log } from './console'
3
5
  import { exec, execSync } from './exec'
4
6
  import { italic } from './utils'
5
- import { log } from './console'
6
7
 
7
8
  /**
8
9
  * Run a command.
@@ -92,8 +93,16 @@ export async function runCommandSync(command: string, options?: CliOptions): Pro
92
93
  export async function runCommands(commands: string[], options?: CliOptions) {
93
94
  const results = []
94
95
 
95
- for (const command of commands)
96
- results.push(await runCommand(command, options))
96
+ for (const command of commands) {
97
+ const result = await runCommand(command, options)
98
+
99
+ if (result.isErr()) {
100
+ log.error(result.error)
101
+ process.exit(ExitCode.FatalError)
102
+ }
103
+
104
+ results.push(result)
105
+ }
97
106
 
98
107
  return results
99
108
  }
package/src/utils.ts CHANGED
@@ -63,7 +63,8 @@ export {
63
63
  stripColors,
64
64
  } from 'kolorist'
65
65
 
66
- export const quotes = collect([ // could be queried from any API or database
66
+ export const quotes = collect([
67
+ // could be queried from any API or database
67
68
  'The best way to get started is to quit talking and begin doing.',
68
69
  'The pessimist sees difficulty in every opportunity. The optimist sees opportunity in every difficulty.',
69
70
  'Don’t let yesterday take up too much of today.',
@@ -1 +0,0 @@
1
- export * from './install';
@@ -1,27 +0,0 @@
1
- import type { ExecaReturnValue } from 'execa';
2
- interface InstallPackageOptions {
3
- cwd?: string;
4
- dev?: boolean;
5
- silent?: boolean;
6
- packageManager?: string;
7
- packageManagerVersion?: string;
8
- preferOffline?: boolean;
9
- additionalArgs?: string[];
10
- }
11
- /**
12
- * Install an npm package.
13
- *
14
- * @param name - The package name to install.
15
- * @param options - The options to pass to the install.The options to pass to the install.
16
- * @returns The result of the install.
17
- */
18
- export declare function installPackage(name: string, options?: InstallPackageOptions): Promise<ExecaReturnValue<string>>;
19
- /**
20
- * Install a Stack into your project.
21
- *
22
- * @param name - The Stack name to install.
23
- * @param options - The options to pass to the install.
24
- * @returns The result of the install.
25
- */
26
- export declare function installStack(name: string, options?: InstallPackageOptions): Promise<ExecaReturnValue<string>>;
27
- export {};
package/dist/cli.d.ts DELETED
@@ -1,12 +0,0 @@
1
- import { CAC } from 'cac';
2
- export interface ParsedArgv {
3
- args: ReadonlyArray<string>;
4
- options: {
5
- [k: string]: any;
6
- };
7
- }
8
- interface CliOptions {
9
- name?: string;
10
- }
11
- export declare function cli(name?: string | CliOptions, options?: CliOptions): CAC;
12
- export { CAC };
package/dist/command.d.ts DELETED
@@ -1,33 +0,0 @@
1
- import type { CliOptions } from '@stacksjs/types';
2
- type CommandOptionTuple = [string, string, {
3
- default: boolean;
4
- }];
5
- interface CommandOptionObject {
6
- name: string;
7
- description: string;
8
- default: boolean | string;
9
- }
10
- type CommandOptions = CommandOptionTuple | CommandOptionObject[];
11
- interface Options {
12
- name: string;
13
- description: string;
14
- active: boolean;
15
- options: CommandOptions;
16
- run: (options?: CliOptions) => Promise<any>;
17
- onFail: (error: Error) => void;
18
- onSuccess: () => void;
19
- }
20
- export declare class Command {
21
- name: Options['name'];
22
- description: Options['description'];
23
- options: Options['options'];
24
- run: Options['run'];
25
- onFail: Options['onFail'];
26
- onSuccess: Options['onSuccess'];
27
- constructor({ name, description, options, run, onFail, onSuccess }: Options);
28
- }
29
- export declare const command: {
30
- run: (command: string, options?: any) => Promise<Result<Subprocess, CommandError>>;
31
- runSync: (command: string, options?: any) => Promise<Result<Subprocess, CommandError>>;
32
- };
33
- export {};
package/dist/console.d.ts DELETED
@@ -1,18 +0,0 @@
1
- import { log, logger } from '@stacksjs/logging';
2
- import prompts from 'prompts';
3
- export declare class Prompt {
4
- private required;
5
- constructor();
6
- require(): this;
7
- isRequired(): boolean;
8
- select(message: any, options: any): Promise<any>;
9
- checkbox(message: any, options: any): Promise<any>;
10
- confirm(message: any, options: any): Promise<any>;
11
- input(message: any, options: any): Promise<any>;
12
- password(message: any, options: any): Promise<any>;
13
- number(message: any, options: any): Promise<any>;
14
- multiselect(message: any, options: any): Promise<any>;
15
- autocomplete(message: any, options: any): Promise<any>;
16
- }
17
- export { prompts, logger, log };
18
- export declare const prompt: () => Prompt;
package/dist/exec.d.ts DELETED
@@ -1,40 +0,0 @@
1
- import { type Result } from '@stacksjs/error-handling';
2
- import type { CliOptions, Subprocess } from '@stacksjs/types';
3
- /**
4
- * Execute a command.
5
- *
6
- * @param command The command to execute.
7
- * @param options The options to pass to the command.
8
- * @returns The result of the command.
9
- * @example
10
- * ```ts
11
- * const result = await exec('ls')
12
- *
13
- * if (result.isErr())
14
- * console.error(result.error)
15
- * else
16
- * console.log(result)
17
- * ```
18
- * @example
19
- * ```ts
20
- * const result = await exec('ls', { cwd: '/home' })
21
- * ```
22
- */
23
- export declare function exec(command: string | string[], options?: CliOptions): Promise<Result<Subprocess, Error>>;
24
- /**
25
- * Execute a command and return result.
26
- *
27
- * @param command The command to execute.
28
- * @returns The result of the command.
29
- * @example
30
- * ```ts
31
- * const output = execSync('ls')
32
- *
33
- * console.log(output)
34
- * ```
35
- * @example
36
- * ```ts
37
- * const output = execSync('ls', { cwd: '/home' })
38
- * ```
39
- */
40
- export declare function execSync(command: string | string[], options?: CliOptions): Promise<string>;
package/dist/helpers.d.ts DELETED
@@ -1,9 +0,0 @@
1
- import type { IntroOptions, OutroOptions } from '@stacksjs/types';
2
- /**
3
- * Prints the intro message.
4
- */
5
- export declare function intro(command: string, options?: IntroOptions): Promise<number>;
6
- /**
7
- * Prints the outro message.
8
- */
9
- export declare function outro(text: string, options?: OutroOptions, error?: Error | string): Promise<unknown>;
package/dist/index.d.ts DELETED
@@ -1,10 +0,0 @@
1
- export * from './actions';
2
- export * from './cli';
3
- export * from './command';
4
- export * from './console';
5
- export * from './helpers';
6
- export * from './parse';
7
- export * from './exec';
8
- export * from './run';
9
- export * from './spinner';
10
- export * from './utils';
package/dist/parse.d.ts DELETED
@@ -1,17 +0,0 @@
1
- interface ParsedArgv {
2
- args: string[];
3
- options: {
4
- [k: string]: string | boolean | number;
5
- };
6
- }
7
- export declare function parseArgv(argv?: string[]): ParsedArgv;
8
- export declare function parseArgs(argv?: string[]): string[];
9
- interface CliOptions {
10
- dryRun?: boolean;
11
- quiet?: boolean;
12
- verbose?: boolean;
13
- [k: string]: string | boolean | number | undefined;
14
- }
15
- export declare function parseOptions(options?: CliOptions): CliOptions;
16
- export declare function buddyOptions(options?: any): string;
17
- export {};
package/dist/run.d.ts DELETED
@@ -1,63 +0,0 @@
1
- import type { CliOptions, CommandError, Subprocess } from '@stacksjs/types';
2
- import type { Result } from '@stacksjs/error-handling';
3
- /**
4
- * Run a command.
5
- *
6
- * @param command The command to run.
7
- * @param options The options to pass to the command.
8
- * @returns The result of the command.
9
- * @example
10
- * ```ts
11
- * const result = await runCommand('ls')
12
- *
13
- * if (result.isErr())
14
- * console.error(result.error)
15
- * else
16
- * console.log(result)
17
- * ```
18
- * @example
19
- * ```ts
20
- * const result = await runCommand('ls', { cwd: '/home' })
21
- *
22
- * if (result.isErr())
23
- * console.error(result.error)
24
- * else
25
- * console.log(result)
26
- * ```
27
- */
28
- export declare function runCommand(command: string, options?: CliOptions): Promise<Result<Subprocess, CommandError>>;
29
- export declare function runProcess(command: string, options?: CliOptions): Promise<Result<Subprocess, CommandError>>;
30
- /**
31
- * Run a command.
32
- *
33
- * @param command The command to run.
34
- * @param options The options to pass to the command.
35
- * @returns The result of the command.
36
- * @example
37
- * ```ts
38
- * const result = runCommandSync('ls')
39
- *
40
- * if (result.isErr())
41
- * console.error(result.error)
42
- * else
43
- * console.log(result)
44
- * ```
45
- * @example
46
- * ```ts
47
- * const result = runCommandSync('ls', { cwd: '/home' })
48
- *
49
- * if (result.isErr())
50
- * console.error(result.error)
51
- * else
52
- * console.log(result)
53
- * ```
54
- */
55
- export declare function runCommandSync(command: string, options?: CliOptions): Promise<string>;
56
- /**
57
- * Run many commands.
58
- *
59
- * @param commands The command to run.
60
- * @param options The options to pass to the command.
61
- * @returns The result of the command.
62
- */
63
- export declare function runCommands(commands: string[], options?: CliOptions): Promise<any[]>;
package/dist/spinner.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import ora from 'ora';
2
- export declare const spinner: typeof ora;
package/dist/utils.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export * as kolorist from 'kolorist';
2
- export { stripAnsi, centerAlign, rightAlign, leftAlign, align, box, colors, getColor, colorize, } from 'consola/utils';
3
- export { ansi256Bg, bgBlack, bgBlue, bgCyan, bgGray, bgGreen, bgLightBlue, bgLightCyan, bgLightGray, bgLightGreen, bgLightMagenta, bgLightRed, bgLightYellow, bgMagenta, bgRed, bgWhite, bgYellow, black, blue, bold, cyan, dim, gray, green, hidden, inverse, italic, lightBlue, lightCyan, lightGray, lightGreen, lightMagenta, lightRed, lightYellow, link, magenta, red, reset, strikethrough, underline, white, yellow, ansi256, trueColor, trueColorBg, stripColors, } from 'kolorist';
4
- export declare const quotes: any;