@sapphire/cli 1.2.1-next.ff0796a.0 → 1.3.0-next.b97aeac.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  import { componentsFolder } from '#constants';
2
2
  import { CreateFileFromTemplate } from '#functions/CreateFileFromTemplate';
3
3
  import { fileExists } from '#functions/FileExists';
4
- import { Spinner } from '#functions/Spinner';
5
- import { fromAsync, isErr } from '@sapphire/result';
4
+ import { Spinner } from '@favware/colorette-spinner';
5
+ import { Result } from '@sapphire/result';
6
6
  import { blueBright, red } from 'colorette';
7
7
  import findUp from 'find-up';
8
8
  import { load } from 'js-yaml';
@@ -38,8 +38,7 @@ export default async (component, name) => {
38
38
  const spinner = new Spinner(`Creating a ${component.toLowerCase()}`).start();
39
39
  const fail = (error, additionalExecution) => {
40
40
  spinner.error({ text: error });
41
- if (additionalExecution)
42
- additionalExecution();
41
+ additionalExecution?.();
43
42
  process.exit(1);
44
43
  };
45
44
  const configLoc = await fetchConfig();
@@ -50,12 +49,14 @@ export default async (component, name) => {
50
49
  if (!config) {
51
50
  return fail("Can't parse the Sapphire CLI config.");
52
51
  }
53
- const result = await fromAsync(async () => createComponent(component, name, config, configLoc.replace(/.sapphirerc.(json|yml)/g, '')));
54
- if (isErr(result)) {
55
- return fail(result.error.message, () => console.log(red(result.error.message)));
56
- }
57
- spinner.success();
58
- console.log(blueBright('Done!'));
59
- process.exit(0);
52
+ const result = await Result.fromAsync(() => createComponent(component, name, config, configLoc.replace(/.sapphirerc.(json|yml)/g, '')));
53
+ return result.match({
54
+ ok: () => {
55
+ spinner.success();
56
+ console.log(blueBright('Done!'));
57
+ process.exit(0);
58
+ },
59
+ err: (error) => fail(error.message, () => console.log(red(error.message)))
60
+ });
60
61
  };
61
62
  //# sourceMappingURL=generate.js.map
@@ -2,9 +2,9 @@ import { repoUrl } from '#constants';
2
2
  import { CommandExists } from '#functions/CommandExists';
3
3
  import { CreateFileFromTemplate } from '#functions/CreateFileFromTemplate';
4
4
  import { fileExists } from '#functions/FileExists';
5
- import { Spinner } from '#functions/Spinner';
6
5
  import { PromptNew } from '#prompts/PromptNew';
7
- import { fromAsync, isErr, isOk } from '@sapphire/result';
6
+ import { Spinner } from '@favware/colorette-spinner';
7
+ import { Result } from '@sapphire/result';
8
8
  import { blueBright, red } from 'colorette';
9
9
  import { execa } from 'execa';
10
10
  import { cp, readFile, rm, writeFile } from 'node:fs/promises';
@@ -16,18 +16,15 @@ async function editPackageJson(location, name) {
16
16
  if (!output)
17
17
  throw new Error("Can't read file.");
18
18
  output.name = name;
19
- const result = await fromAsync(() => writeFile(pjLocation, JSON.stringify(output, null, 2)));
20
- return isOk(result);
19
+ const result = await Result.fromAsync(() => writeFile(pjLocation, JSON.stringify(output, null, 2)));
20
+ return result.isOk();
21
21
  }
22
22
  async function installDeps(location, pm, verbose) {
23
- const result = await fromAsync(() => execa(pm.toLowerCase(), ['install'], {
23
+ const value = await execa(pm.toLowerCase(), ['install'], {
24
24
  stdio: verbose ? 'inherit' : undefined,
25
25
  cwd: `./${location}/`
26
- }));
27
- if (isErr(result)) {
28
- throw result.error;
29
- }
30
- if (result.value.exitCode !== 0) {
26
+ });
27
+ if (value.exitCode !== 0) {
31
28
  throw new Error('An unknown error occurred while installing the dependencies. Try running Sapphire CLI with "--verbose" flag.');
32
29
  }
33
30
  const oppositeLockfile = `./${location}/${pm === 'npm' ? 'yarn.lock' : 'package-lock.json'}`;
@@ -41,14 +38,11 @@ async function configureYarnRc(location, name, value) {
41
38
  return true;
42
39
  }
43
40
  async function installYarnV3(location, verbose) {
44
- const result = await fromAsync(() => execa('yarn', ['set', 'version', 'berry'], {
41
+ const value = await execa('yarn', ['set', 'version', 'berry'], {
45
42
  stdio: verbose ? 'inherit' : undefined,
46
43
  cwd: `./${location}/`
47
- }));
48
- if (isErr(result)) {
49
- throw result.error;
50
- }
51
- if (result.value.exitCode !== 0) {
44
+ });
45
+ if (value.exitCode !== 0) {
52
46
  throw new Error('An unknown error occurred while installing Yarn v3. Try running Sapphire CLI with "--verbose" flag.');
53
47
  }
54
48
  await Promise.all([
@@ -68,23 +62,22 @@ async function initializeGitRepo(location) {
68
62
  }
69
63
  async function runJob(job, name) {
70
64
  const spinner = new Spinner(name).start();
71
- const result = await fromAsync(async () => job());
72
- if (isErr(result)) {
73
- spinner.error({ text: red(result.error.message) });
74
- console.error(red(result.error.message));
75
- throw result.error;
76
- }
77
- spinner.success();
78
- return true;
65
+ const result = await Result.fromAsync(() => job());
66
+ return result.match({
67
+ ok: () => {
68
+ spinner.success();
69
+ return true;
70
+ },
71
+ err: (error) => {
72
+ spinner.error({ text: red(error.message) });
73
+ console.error(red(error.message));
74
+ throw error;
75
+ }
76
+ });
79
77
  }
80
78
  async function cloneRepo(location, verbose) {
81
- const result = await fromAsync(async () => execa('git', ['clone', repoUrl, `${location}/ghr`], {
82
- stdio: verbose ? 'inherit' : undefined
83
- }));
84
- if (isErr(result)) {
85
- throw result.error;
86
- }
87
- if (result.value.exitCode !== 0) {
79
+ const value = await execa('git', ['clone', repoUrl, `${location}/ghr`], { stdio: verbose ? 'inherit' : undefined });
80
+ if (value.exitCode !== 0) {
88
81
  throw new Error('An unknown error occurred while cloning the repository. Try running Sapphire CLI with "--verbose" flag.');
89
82
  }
90
83
  return true;
@@ -22,14 +22,14 @@
22
22
  SOFTWARE.
23
23
  */
24
24
  import { fileExists } from '#functions/FileExists';
25
- import { fromAsync, isErr } from '@sapphire/result';
25
+ import { Result } from '@sapphire/result';
26
26
  import { execa } from 'execa';
27
27
  import { constants } from 'node:fs';
28
28
  import { access } from 'node:fs/promises';
29
29
  const windows = process.platform === 'win32';
30
30
  async function isExecutable(command) {
31
- const result = await fromAsync(() => access(command, constants.X_OK));
32
- return isErr(result);
31
+ const result = await Result.fromAsync(() => access(command, constants.X_OK));
32
+ return result.isErr();
33
33
  }
34
34
  function cleanWindowsCommand(input) {
35
35
  if (/[^A-Za-z0-9_\/:=-]/.test(input)) {
@@ -44,22 +44,22 @@ async function commandExistsUnix(command) {
44
44
  return true;
45
45
  }
46
46
  }
47
- const result = await fromAsync(() => execa('which', [command]));
48
- if (isErr(result)) {
49
- return false;
50
- }
51
- return Boolean(result.value.stdout);
47
+ const result = await Result.fromAsync(() => execa('which', [command]));
48
+ return result.match({
49
+ err: () => false,
50
+ ok: (value) => Boolean(value.stdout)
51
+ });
52
52
  }
53
53
  const invalidWindowsCommandNameRegex = /[\x00-\x1f<>:"|?*]/;
54
54
  async function commandExistsWindows(command) {
55
55
  if (invalidWindowsCommandNameRegex.test(command)) {
56
56
  return false;
57
57
  }
58
- const result = await fromAsync(async () => execa('where', [cleanWindowsCommand(command)]));
59
- if (isErr(result)) {
60
- return fileExists(command);
61
- }
62
- return true;
58
+ const result = await Result.fromAsync(async () => execa('where', [cleanWindowsCommand(command)]));
59
+ return result.match({
60
+ err: () => fileExists(command),
61
+ ok: () => true
62
+ });
63
63
  }
64
64
  export async function CommandExists(command) {
65
65
  return windows ? commandExistsWindows(command) : commandExistsUnix(command);
@@ -1,7 +1,7 @@
1
- import { fromAsync, isOk } from '@sapphire/result';
1
+ import { Result } from '@sapphire/result';
2
2
  import { access } from 'node:fs/promises';
3
3
  export async function fileExists(filePath) {
4
- const result = await fromAsync(() => access(filePath));
5
- return isOk(result);
4
+ const result = await Result.fromAsync(() => access(filePath));
5
+ return result.isOk();
6
6
  }
7
7
  //# sourceMappingURL=FileExists.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapphire/cli",
3
- "version": "1.2.1-next.ff0796a.0",
3
+ "version": "1.3.0-next.b97aeac.0",
4
4
  "description": "CLI for Sapphire Framework",
5
5
  "author": "@sapphire",
6
6
  "license": "MIT",
@@ -38,9 +38,10 @@
38
38
  "postpack": "pinst --enable"
39
39
  },
40
40
  "dependencies": {
41
- "@sapphire/result": "^1.1.1",
42
- "colorette": "^2.0.16",
43
- "commander": "^9.2.0",
41
+ "@favware/colorette-spinner": "^1.0.0",
42
+ "@sapphire/result": "^2.0.1",
43
+ "colorette": "^2.0.19",
44
+ "commander": "^9.4.0",
44
45
  "execa": "^6.1.0",
45
46
  "find-up": "^5.0.0",
46
47
  "js-yaml": "^4.1.0",
@@ -48,30 +49,30 @@
48
49
  "tslib": "^2.4.0"
49
50
  },
50
51
  "devDependencies": {
51
- "@commitlint/cli": "^16.3.0",
52
- "@commitlint/config-conventional": "^16.2.4",
53
- "@favware/cliff-jumper": "^1.8.0",
52
+ "@commitlint/cli": "^17.0.3",
53
+ "@commitlint/config-conventional": "^17.0.3",
54
+ "@favware/cliff-jumper": "^1.8.5",
54
55
  "@favware/npm-deprecate": "^1.0.4",
55
- "@sapphire/eslint-config": "^4.3.5",
56
+ "@sapphire/eslint-config": "^4.3.7",
56
57
  "@sapphire/prettier-config": "^1.4.3",
57
58
  "@sapphire/ts-config": "^3.3.4",
58
59
  "@types/js-yaml": "^4.0.5",
59
- "@types/node": "^17.0.33",
60
- "@types/prompts": "^2.0.14",
61
- "@typescript-eslint/eslint-plugin": "^5.23.0",
62
- "@typescript-eslint/parser": "^5.23.0",
60
+ "@types/node": "^18.0.1",
61
+ "@types/prompts": "^2.4.0",
62
+ "@typescript-eslint/eslint-plugin": "^5.30.7",
63
+ "@typescript-eslint/parser": "^5.30.7",
63
64
  "cz-conventional-changelog": "^3.3.0",
64
- "eslint": "^8.15.0",
65
+ "eslint": "^8.20.0",
65
66
  "eslint-config-prettier": "^8.5.0",
66
- "eslint-plugin-prettier": "^4.0.0",
67
- "globby": "^13.1.1",
67
+ "eslint-plugin-prettier": "^4.2.1",
68
+ "globby": "^13.1.2",
68
69
  "husky": "^8.0.1",
69
- "lint-staged": "^12.4.1",
70
+ "lint-staged": "^13.0.3",
70
71
  "pinst": "^3.0.0",
71
- "prettier": "^2.6.2",
72
+ "prettier": "^2.7.1",
72
73
  "pretty-quick": "^3.1.3",
73
- "ts-node": "^10.7.0",
74
- "typescript": "^4.6.4"
74
+ "ts-node": "^10.9.1",
75
+ "typescript": "^4.7.4"
75
76
  },
76
77
  "resolutions": {
77
78
  "ansi-regex": "^5.0.1",
@@ -116,5 +117,5 @@
116
117
  "access": "public"
117
118
  },
118
119
  "prettier": "@sapphire/prettier-config",
119
- "packageManager": "yarn@3.2.1"
120
+ "packageManager": "yarn@3.2.2"
120
121
  }
@@ -0,0 +1,25 @@
1
+ { "category": "commands" }
2
+ ---
3
+ const { Command } = require('@sapphire/framework')
4
+
5
+ class UserCommand extends Command {
6
+ constructor(context, options) {
7
+ super(context, {
8
+ ...options,
9
+ name: 'command'
10
+ });
11
+ }
12
+
13
+ registerApplicationCommands(registry) {
14
+ registry.registerContextMenuCommand({
15
+ name: this.name,
16
+ type: 'MESSAGE'
17
+ })
18
+ }
19
+
20
+ async contextMenuRun(interaction) {
21
+ return await interaction.reply({content: "Hello world!"})
22
+ }
23
+ }
24
+
25
+ exports.UserCommand = UserCommand;
@@ -0,0 +1,20 @@
1
+ { "category": "commands" }
2
+ ---
3
+ import { ApplyOptions } from '@sapphire/decorators';
4
+ import { Command } from '@sapphire/framework';
5
+
6
+ @ApplyOptions<Command.Options>({
7
+ description: 'A basic contextMenu command'
8
+ })
9
+ export class UserCommand extends Command {
10
+ public override registerApplicationCommands(registry: Command.Registry) {
11
+ registry.registerContextMenuCommand({
12
+ name: this.name,
13
+ type: 'MESSAGE'
14
+ })
15
+ }
16
+
17
+ public async contextMenuRun(interaction: Command.ContextMenuInteraction) {
18
+ return await interaction.reply({content: "Hello world!"});
19
+ }
20
+ }
@@ -0,0 +1,26 @@
1
+ { "category": "commands" }
2
+ ---
3
+ const { Command } = require('@sapphire/framework')
4
+
5
+ class UserCommand extends Command {
6
+ constructor(context, options) {
7
+ super(context, {
8
+ ...options,
9
+ name: 'command',
10
+ description: 'A basic slash command'
11
+ });
12
+ }
13
+
14
+ registerApplicationCommands(registry) {
15
+ registry.registerChatInputCommand({
16
+ name: this.name,
17
+ description: this.description
18
+ })
19
+ }
20
+
21
+ async chatInputRun(interaction) {
22
+ return await interaction.reply({content: "Hello world!"})
23
+ }
24
+ }
25
+
26
+ exports.UserCommand = UserCommand;
@@ -0,0 +1,20 @@
1
+ { "category": "commands" }
2
+ ---
3
+ import { ApplyOptions } from '@sapphire/decorators';
4
+ import { Command } from '@sapphire/framework';
5
+
6
+ @ApplyOptions<Command.Options>({
7
+ description: 'A basic slash command'
8
+ })
9
+ export class UserCommand extends Command {
10
+ public override registerApplicationCommands(registry: Command.Registry) {
11
+ registry.registerChatInputCommand({
12
+ name: this.name,
13
+ description: this.description
14
+ })
15
+ }
16
+
17
+ public async chatInputRun(interaction: Command.ChatInputInteraction) {
18
+ return await interaction.reply({content: "Hello world!"});
19
+ }
20
+ }
@@ -1,122 +0,0 @@
1
- import * as colorette from 'colorette';
2
- import tty from 'node:tty';
3
- /**
4
- * A very minimal terminal spinner
5
- *
6
- * @license ISC
7
- * @copyright 2021 Usman Yunusov <usman.iunusov@gmail.com>
8
- * @see https://github.com/usmanyunusov/nanospinner/blob/master/index.js
9
- */
10
- export class Spinner {
11
- #isCI = process.env.CI ||
12
- process.env.WT_SESSION ||
13
- process.env.ConEmuTask === '{cmd::Cmder}' ||
14
- process.env.TERM_PROGRAM === 'vscode' ||
15
- process.env.TERM === 'xterm-256color' ||
16
- process.env.TERM === 'alacritty';
17
- #isTTY = tty.isatty(1) && process.env.TERM !== 'dumb' && !('CI' in process.env);
18
- #supportUnicode = process.platform === 'win32' ? this.#isCI : process.env.TERM !== 'linux';
19
- #symbols = {
20
- frames: this.#isTTY ? (this.#supportUnicode ? ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'] : ['-', '\\', '|', '/']) : ['-'],
21
- tick: this.#supportUnicode ? '✔' : '√',
22
- cross: this.#supportUnicode ? '✖' : '×'
23
- };
24
- #text = '';
25
- #current = 0;
26
- #interval = 50;
27
- #stream = process.stderr;
28
- #frames = this.#symbols.frames;
29
- #color = 'greenBright';
30
- #lines = 0;
31
- #timer;
32
- constructor(text, options) {
33
- this.#text = text ?? this.#text;
34
- this.#interval = options?.interval ?? this.#interval;
35
- this.#stream = options?.stream ?? this.#stream;
36
- if (options?.frames && options?.frames.length) {
37
- this.#frames = options.frames;
38
- }
39
- this.#color = options?.color ?? this.#color;
40
- }
41
- clear() {
42
- this.write('\x1b[1G');
43
- for (let i = 0; i < this.#lines; i++) {
44
- i > 0 && this.write('\x1b[1A');
45
- this.write('\x1b[2K\x1b[1G');
46
- }
47
- this.#lines = 0;
48
- return this;
49
- }
50
- error(options) {
51
- const mark = colorette.red(this.#symbols.cross);
52
- return this.stop({ mark, ...options });
53
- }
54
- reset() {
55
- this.#current = 0;
56
- this.#lines = 0;
57
- if (this.#timer) {
58
- clearTimeout(this.#timer);
59
- }
60
- return this;
61
- }
62
- spin() {
63
- this.render();
64
- this.#current = ++this.#current % this.#frames.length;
65
- return this;
66
- }
67
- start(opts = {}) {
68
- this.#timer && this.reset();
69
- return this.update({ text: opts.text, color: opts.color }).loop();
70
- }
71
- stop(opts = {}) {
72
- if (this.#timer) {
73
- clearTimeout(this.#timer);
74
- }
75
- const mark = colorette[opts.color || this.#color](this.#frames[this.#current]);
76
- const optsMark = opts.mark && opts.color ? colorette[opts.color](opts.mark) : opts.mark;
77
- this.write(`${optsMark || mark} ${opts.text || this.#text}\n`, true);
78
- return this.#isTTY ? this.write(`\x1b[?25h`) : this;
79
- }
80
- success(opts = {}) {
81
- const mark = colorette.green(this.#symbols.tick);
82
- return this.stop({ mark, ...opts });
83
- }
84
- update(opts = {}) {
85
- this.#text = opts.text || this.#text;
86
- this.#interval = opts?.interval ?? this.#interval;
87
- this.#stream = opts?.stream ?? this.#stream;
88
- if (opts?.frames && opts?.frames.length) {
89
- this.#frames = opts.frames;
90
- }
91
- this.#color = opts?.color ?? this.#color;
92
- if (this.#frames.length - 1 < this.#current) {
93
- this.#current = 0;
94
- }
95
- return this;
96
- }
97
- loop() {
98
- this.#isTTY && (this.#timer = setTimeout(() => this.loop(), this.#interval));
99
- return this.spin();
100
- }
101
- write(str, clear = false) {
102
- if (clear && this.#isTTY) {
103
- this.clear();
104
- }
105
- this.#stream.write(str);
106
- return this;
107
- }
108
- render() {
109
- const mark = colorette[this.#color](this.#frames[this.#current]);
110
- let str = `${mark} ${this.#text}`;
111
- this.#isTTY ? this.write(`\x1b[?25l`) : (str += '\n');
112
- this.write(str, true);
113
- this.#isTTY && (this.#lines = this.getLines(str, this.#stream.columns));
114
- }
115
- getLines(str = '', width = 80) {
116
- return str
117
- .replace(/\u001b[^m]*?m/g, '')
118
- .split('\n')
119
- .reduce((col, line) => (col += Math.max(1, Math.ceil(line.length / width))), 0);
120
- }
121
- }
122
- //# sourceMappingURL=Spinner.js.map