@nan0web/ui-cli 1.0.0 → 1.0.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.
Files changed (47) hide show
  1. package/README.md +2 -11
  2. package/package.json +17 -7
  3. package/src/CLI.js +141 -0
  4. package/src/Command.js +210 -0
  5. package/src/CommandError.js +35 -0
  6. package/src/CommandHelp.js +204 -0
  7. package/src/CommandMessage.js +181 -0
  8. package/src/CommandParser.js +217 -0
  9. package/src/InputAdapter.js +78 -149
  10. package/src/README.md.js +7 -6
  11. package/src/index.js +36 -14
  12. package/src/ui/index.js +3 -3
  13. package/src/ui/input.js +68 -11
  14. package/src/ui/next.js +30 -26
  15. package/src/ui/select.js +41 -31
  16. package/src/utils/parse.js +41 -0
  17. package/types/CLI.d.ts +44 -0
  18. package/types/Command.d.ts +72 -0
  19. package/types/CommandError.d.ts +19 -0
  20. package/types/CommandHelp.d.ts +85 -0
  21. package/types/CommandMessage.d.ts +65 -0
  22. package/types/CommandParser.d.ts +28 -0
  23. package/types/InputAdapter.d.ts +28 -85
  24. package/types/index.d.ts +12 -9
  25. package/types/ui/index.d.ts +2 -3
  26. package/types/ui/input.d.ts +50 -6
  27. package/types/ui/next.d.ts +11 -8
  28. package/types/ui/select.d.ts +50 -20
  29. package/types/utils/parse.d.ts +13 -0
  30. package/.editorconfig +0 -20
  31. package/CONTRIBUTING.md +0 -42
  32. package/docs/uk/README.md +0 -294
  33. package/playground/forms/addressForm.js +0 -37
  34. package/playground/forms/ageForm.js +0 -26
  35. package/playground/forms/profileForm.js +0 -33
  36. package/playground/forms/userForm.js +0 -36
  37. package/playground/main.js +0 -81
  38. package/playground/vocabs/en.js +0 -25
  39. package/playground/vocabs/index.js +0 -12
  40. package/playground/vocabs/uk.js +0 -25
  41. package/src/InputAdapter.test.js +0 -117
  42. package/src/ui/input.test.js +0 -27
  43. package/src/ui/select.test.js +0 -34
  44. package/system.md +0 -99
  45. package/tsconfig.json +0 -23
  46. package/types/test/ReadLine.d.ts +0 -1
  47. package/types/ui/errors.d.ts +0 -3
package/src/README.md.js CHANGED
@@ -1,6 +1,9 @@
1
+ /* eslint-disable no-unused-vars */
1
2
  import { describe, it, before, beforeEach } from "node:test"
2
3
  import assert from "node:assert/strict"
3
4
  import FS from "@nan0web/db-fs"
5
+ import Message from "@nan0web/co"
6
+ import { UIForm } from "@nan0web/ui"
4
7
  import { NoConsole } from "@nan0web/log"
5
8
  import {
6
9
  DatasetParser,
@@ -11,14 +14,12 @@ import {
11
14
  CLIInputAdapter as BaseCLIInputAdapter,
12
15
  CancelError,
13
16
  createInput,
14
- ask as baseAsk,
15
17
  Input,
18
+ pause,
19
+ ask as baseAsk,
16
20
  select as baseSelect,
17
21
  next as baseNext,
18
- pause,
19
22
  } from "./index.js"
20
- import { UIForm } from "@nan0web/ui"
21
- import Message from "@nan0web/co"
22
23
 
23
24
  async function ask(question) {
24
25
  if ("Full Name *: " === question) return "John Doe"
@@ -190,8 +191,8 @@ function testRender() {
190
191
  }
191
192
 
192
193
  const result = await adapter.requestSelect(config)
193
- console.info(result.value) // ← Message { body: "en", head: {} }
194
- assert.deepStrictEqual(console.output()[0][1], Message.from({ body: "en" }))
194
+ console.info(result) // ← en
195
+ assert.deepStrictEqual(console.output()[0][1], "en")
195
196
  })
196
197
 
197
198
  /**
package/src/index.js CHANGED
@@ -1,25 +1,47 @@
1
- import CLIInputAdapter from './InputAdapter.js'
2
- import { select, next, pause, createInput, ask, Input } from './ui/index.js'
3
- import { CancelError } from '@nan0web/ui/core'
1
+ import CLIInputAdapter from "./InputAdapter.js"
2
+ import { CancelError } from "@nan0web/ui/core"
3
+ import CLI from "./CLI.js"
4
+ import Command from "./Command.js"
5
+ import CommandError from "./CommandError.js"
6
+ import CommandMessage from "./CommandMessage.js"
7
+ import CommandParser from "./CommandParser.js"
8
+ import CommandHelp from "./CommandHelp.js"
9
+ export { str2argv } from "./utils/parse.js"
4
10
 
5
- // Export CLI input adapter
6
11
  export {
7
- CLIInputAdapter,
8
- CancelError,
9
- createInput,
10
- ask,
11
- Input,
12
12
  select,
13
13
  next,
14
14
  pause,
15
+ createInput,
16
+ ask,
17
+ Input,
18
+ } from "./ui/index.js"
19
+
20
+ /** @typedef {import("./CommandHelp.js").CommandHelpField} CommandHelpField */
21
+
22
+ export {
23
+ CLI,
24
+ CLIInputAdapter,
25
+ CancelError,
26
+
27
+ /** @deprecated */
28
+ Command,
29
+ /** @deprecated */
30
+ CommandError,
31
+ /** @deprecated */
32
+ CommandMessage,
33
+
34
+ CommandParser,
35
+ CommandHelp,
15
36
  }
16
37
 
17
- // Export renderers for CLI components
18
38
  export const renderers = new Map([
19
- ['UIProcess', (data) => {
20
- // Render process information in CLI
21
- return `${data.title || 'Process'}: ${data.status || 'running'}`
22
- }],
39
+ [
40
+ "UIProcess",
41
+ data => {
42
+ return `${data.title || "Process"}: ${data.status || "running"}`
43
+ },
44
+ ],
23
45
  ])
24
46
 
25
47
  export default CLIInputAdapter
package/src/ui/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { CancelError } from '@nan0web/ui/core'
2
- export { Input, ask, createInput } from "./input.js"
3
- export { select } from "./select.js"
1
+ export { Input } from "./input.js"
2
+ export { createInput, ask } from "./input.js"
3
+ export { select, default as baseSelect } from "./select.js"
4
4
  export { next, pause } from "./next.js"
package/src/ui/input.js CHANGED
@@ -1,33 +1,80 @@
1
+ /**
2
+ * Input module – provides utilities to read user input from the console.
3
+ *
4
+ * @module ui/input
5
+ */
6
+
1
7
  import { createInterface } from "node:readline"
2
8
  import { stdin, stdout } from "node:process"
3
9
 
10
+ /**
11
+ * @typedef {Function} InputFn
12
+ * @param {string} question - Prompt displayed to the user.
13
+ * @param {Function|boolean} [loop=false] - Loop control or validator.
14
+ * @param {Function|false} [nextQuestion=false] - Function to compute the next prompt.
15
+ * @returns {Promise<Input>} Resolves with an {@link Input} instance containing the answer.
16
+ */
17
+
18
+ /**
19
+ * Represents a line of user input.
20
+ *
21
+ * @class
22
+ * @property {string} value – The raw answer string.
23
+ * @property {string[]} stops – Words that trigger cancellation.
24
+ * @property {boolean} cancelled – True when the answer matches a stop word.
25
+ */
4
26
  export class Input {
27
+ /** @type {string} */
5
28
  value = ""
29
+ /** @type {string[]} */
6
30
  stops = []
7
31
  #cancelled = false
32
+
33
+ /**
34
+ * Create a new {@link Input} instance.
35
+ *
36
+ * @param {Object} [input={}] - Optional initial values.
37
+ * @param {string} [input.value] - Initial answer string.
38
+ * @param {boolean} [input.cancelled] - Initial cancel flag.
39
+ * @param {string|string[]} [input.stops] - Words that trigger cancellation.
40
+ */
8
41
  constructor(input = {}) {
9
42
  const {
10
43
  value = this.value,
11
44
  cancelled = this.#cancelled,
12
45
  stops = [],
13
46
  } = input
47
+
14
48
  this.value = String(value)
15
- this.stops = stops.map(String)
49
+
50
+ const normalizedStops = Array.isArray(stops) ? stops : [stops].filter(Boolean)
51
+ this.stops = normalizedStops.map(String)
52
+
16
53
  this.#cancelled = Boolean(cancelled)
17
54
  }
55
+
56
+ /**
57
+ * Returns whether the input has been cancelled either explicitly or via a stop word.
58
+ *
59
+ * @returns {boolean}
60
+ */
18
61
  get cancelled() {
19
62
  return this.#cancelled || this.stops.includes(this.value)
20
63
  }
64
+
65
+ /** @returns {string} The raw answer value. */
21
66
  toString() {
22
67
  return this.value
23
68
  }
24
69
  }
25
70
 
26
71
  /**
27
- * Helper to ask a question
28
- * @param {string} question
72
+ * Prompt a question and return the trimmed answer.
73
+ *
74
+ * @param {string} question - Text displayed as a prompt.
75
+ * @returns {Promise<string>} User answer without surrounding whitespace.
29
76
  */
30
- export function ask(question) {
77
+ export async function ask(question) {
31
78
  return new Promise(resolve => {
32
79
  const rl = createInterface({ input: stdin, output: stdout, terminal: true })
33
80
  rl.question(question, answer => {
@@ -37,27 +84,37 @@ export function ask(question) {
37
84
  })
38
85
  }
39
86
 
87
+ /**
88
+ * Factory that creates a reusable async input handler.
89
+ *
90
+ * @param {string[]} [stops=[]] Words that trigger cancellation.
91
+ * @returns {InputFn} Async function that resolves to an {@link Input}.
92
+ */
40
93
  export function createInput(stops = []) {
41
94
  const input = new Input({ stops })
95
+
42
96
  /**
43
- * @param {string} question
44
- * @param {Function | boolean} [loop=false]
45
- * @param {Function | false} [nextQuestion=false]
97
+ * Internal handler used by the factory.
98
+ *
99
+ * @param {string} question - Prompt displayed to the user.
100
+ * @param {Function|boolean} [loop=false] - Loop‑control flag or validator.
101
+ * @param {Function|false} [nextQuestion=false] - Next prompt generator.
46
102
  * @returns {Promise<Input>}
47
103
  */
48
104
  async function fn(question, loop = false, nextQuestion = false) {
49
105
  while (true) {
50
106
  input.value = await ask(question)
107
+
51
108
  if (false === loop || input.cancelled) return input
52
109
  if (true === loop && input.value) return input
53
- if ("function" === typeof loop) {
110
+ if (typeof loop === "function") {
54
111
  if (!loop(input)) return input
55
112
  }
56
- if ("string" === typeof nextQuestion) question = nextQuestion
57
- if ("function" === typeof nextQuestion) question = nextQuestion(input)
113
+ if (typeof nextQuestion === "string") question = nextQuestion
114
+ if (typeof nextQuestion === "function") question = nextQuestion(input)
58
115
  }
59
116
  }
60
117
  return fn
61
118
  }
62
119
 
63
- export default createInput
120
+ export default createInput
package/src/ui/next.js CHANGED
@@ -1,42 +1,49 @@
1
+ /**
2
+ * Utility functions for handling pauses and key‑press continuations.
3
+ *
4
+ * @module ui/next
5
+ */
6
+
1
7
  import process from "node:process"
2
8
 
3
9
  /**
4
- * Make a pause.
5
- * @param {number} ms - Amount in miliseconds
6
- * @returns {Promise<void>}
10
+ * Pause execution for a given amount of milliseconds.
11
+ *
12
+ * @param {number} ms - Delay in milliseconds.
13
+ * @returns {Promise<true>} Resolves with `true` after the timeout.
7
14
  */
8
- const pause = async (ms) => new Promise((resolve) => setTimeout(resolve, ms))
15
+ export async function pause(ms) {
16
+ return new Promise(resolve => setTimeout(() => resolve(true), ms))
17
+ }
9
18
 
10
19
  /**
11
- * Waits for the confirmation message (input) from user
12
- * @param {string | string[] | undefined} conf - Confirmation message or one of messages if array or any if undefined.
13
- * @returns {Promise<string>}
20
+ * Wait for any key press (or a specific sequence).
21
+ *
22
+ * @param {string|string[]|undefined} [conf] - Expected key or sequence.
23
+ * @returns {Promise<string>} The captured key/sequence.
24
+ * @throws {Error} If stdin is already in raw mode.
14
25
  */
15
- const next = async (conf = undefined) => {
26
+ export async function next(conf = undefined) {
16
27
  return new Promise((resolve, reject) => {
17
28
  if (process.stdin.isRaw) {
18
- reject(new Error('stdin is already in raw mode'))
29
+ reject(new Error("stdin is already in raw mode"))
19
30
  return
20
31
  }
32
+ let buffer = ""
21
33
 
22
- let buffer = ''
23
-
24
- const onData = (chunk) => {
34
+ const onData = chunk => {
25
35
  const str = chunk.toString()
26
36
  buffer += str
27
37
 
28
- // Будь-яка клавіша
29
38
  if (conf === undefined) {
30
39
  cleanup()
31
40
  resolve(str)
32
- }
33
- else if (typeof conf === 'string') {
41
+ } else if (typeof conf === "string") {
34
42
  if (buffer === conf || buffer.endsWith(conf)) {
35
43
  cleanup()
36
44
  resolve(buffer)
37
45
  }
38
- }
39
- else if (Array.isArray(conf)) {
46
+ } else if (Array.isArray(conf)) {
40
47
  for (const seq of conf) {
41
48
  if (buffer === seq || buffer.endsWith(seq)) {
42
49
  cleanup()
@@ -47,24 +54,21 @@ const next = async (conf = undefined) => {
47
54
  }
48
55
  }
49
56
 
50
- const errorHandler = (err) => {
57
+ const errorHandler = err => {
51
58
  cleanup()
52
59
  reject(err)
53
60
  }
54
61
 
55
62
  const cleanup = () => {
56
- process.stdin.off('data', onData)
57
- process.stdin.off('error', errorHandler)
63
+ process.stdin.off("data", onData)
64
+ process.stdin.off("error", errorHandler)
58
65
  process.stdin.setRawMode(false)
59
66
  process.stdin.resume()
60
67
  }
61
68
 
62
69
  process.stdin.setRawMode(true)
63
70
  process.stdin.resume()
64
-
65
- process.stdin.once('error', errorHandler)
66
- process.stdin.on('data', onData)
71
+ process.stdin.once("error", errorHandler)
72
+ process.stdin.on("data", onData)
67
73
  })
68
- }
69
-
70
- export { next, pause }
74
+ }
package/src/ui/select.js CHANGED
@@ -1,20 +1,25 @@
1
- import createInput from "./input.js"
2
- import { CancelError } from '@nan0web/ui/core'
1
+ /**
2
+ * Select module renders a numbered list of options and returns the chosen value.
3
+ *
4
+ * @module ui/select
5
+ */
6
+
7
+ import { CancelError } from "@nan0web/ui/core"
8
+ import createInput, { ask as baseAsk } from "./input.js"
3
9
 
4
10
  /**
5
- * Generic selection prompt for CLI.
6
- * Automatically creates its own input handler.
11
+ * Configuration object for {@link select}.
7
12
  *
8
- * @param {Object} config
9
- * @param {string} config.title - Title shown before the list (e.g. "Select currency:")
10
- * @param {string} config.prompt - Main prompt text (e.g. "Choose (1-3): ")
11
- * @param {string} [config.invalidPrompt] - Retry message when input is invalid
12
- * @param {Array<string> | Map<string, string> | Array<{ label: string, value: string }>} config.options - List of displayable options
13
- * @param {Object} config.console - Logger (console.info, console.error, etc.)
14
- * @param {Function} [config.ask] - Input handler
13
+ * @typedef {Object} SelectConfig
14
+ * @property {string} title Title displayed above the options list.
15
+ * @property {string} prompt Prompt displayed for the answer.
16
+ * @property {Array|Map} options Collection of selectable items.
17
+ * @property {Object} console Console‑like object with an `info` method.
18
+ * @property {string[]} [stops=[]] Words that trigger cancellation.
19
+ * @property {import("./input.js").InputFn} [ask] Custom ask function (defaults to {@link createInput}).
20
+ * @property {string} [invalidPrompt="Invalid choice, try again: "] Message shown on invalid input.
15
21
  *
16
- * @returns {Promise<{ index: number, value: string | null }>} Selected option
17
- * @throws {CancelError} if the user cancels
22
+ * @returns {Promise<{index:number,value:any}>} Resolves with the selected index and its value.
18
23
  */
19
24
  export async function select({
20
25
  title,
@@ -22,36 +27,41 @@ export async function select({
22
27
  invalidPrompt = "Invalid choice, try again: ",
23
28
  options,
24
29
  console,
25
- ask = createInput(["0"]),
30
+ stops = [],
31
+ ask: initAsk,
26
32
  }) {
33
+ const ask = initAsk ?? createInput(stops)
34
+ // Normalise Map → Array of {label,value}
27
35
  if (options instanceof Map) {
28
36
  options = Array.from(options.entries()).map(([value, label]) => ({ label, value }))
29
37
  }
30
38
  if (!Array.isArray(options) || options.length === 0) {
31
39
  throw new Error("Options array is required and must not be empty")
32
40
  }
33
-
34
- /** @type {Array<{ label: string, value: string }>} */
35
- const list = options.map(el => "string" === typeof el ? ({ label: el, value: el }) : el)
41
+ const list = options.map(el =>
42
+ typeof el === "string" ? { label: el, value: el } : el,
43
+ )
36
44
 
37
45
  console.info(title)
38
- list.forEach(({ label }, i) => {
39
- console.info(` ${i + 1}) ${label}`)
40
- })
46
+ list.forEach(({ label }, i) => console.info(` ${i + 1}) ${label}`))
41
47
 
42
- const input = await ask(prompt, (input) => {
43
- const idx = Number(input.value) - 1
44
- return idx < 0 || idx >= list.length
45
- }, invalidPrompt)
48
+ let currentPrompt = prompt
46
49
 
47
- if (input.cancelled) {
48
- throw new CancelError()
49
- }
50
+ while (true) {
51
+ const answer = await ask(currentPrompt)
52
+
53
+ if (answer.cancelled) throw new CancelError()
54
+
55
+ const idx = Number(answer.value) - 1
50
56
 
51
- const index = Number(input.value) - 1
52
- return {
53
- index,
54
- value: list[index].value,
57
+ if (isNaN(idx) || idx < 0 || idx >= list.length) {
58
+ if (invalidPrompt) {
59
+ currentPrompt = invalidPrompt
60
+ continue
61
+ }
62
+ throw new Error("Incorrect value provided")
63
+ }
64
+ return { index: idx, value: list[idx].value }
55
65
  }
56
66
  }
57
67
 
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Utility functions for parsing command‑line strings.
3
+ *
4
+ * @module utils/parse
5
+ */
6
+
7
+ /**
8
+ * Parses a string into an argv array (handles quotes).
9
+ *
10
+ * @param {string} str - Raw command line.
11
+ * @returns {string[]} Tokenized arguments.
12
+ * @throws {Error} If a quote is left unmatched.
13
+ */
14
+ export function str2argv(str) {
15
+ const parts = []
16
+ let i = 0
17
+ str = String(str).trim()
18
+
19
+ while (i < str.length) {
20
+ while (i < str.length && str[i] === ' ') i++
21
+ if (i >= str.length) break
22
+
23
+ if (str[i] === '"' || str[i] === "'") {
24
+ const quote = str[i]
25
+ i++
26
+ let start = i
27
+ while (i < str.length && str[i] !== quote) i++
28
+ if (i < str.length) {
29
+ parts.push(str.slice(start, i))
30
+ i++
31
+ } else {
32
+ throw new Error(`Unmatched quote in argument: ${str}`)
33
+ }
34
+ } else {
35
+ let start = i
36
+ while (i < str.length && str[i] !== ' ') i++
37
+ parts.push(str.slice(start, i))
38
+ }
39
+ }
40
+ return parts
41
+ }
package/types/CLI.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Main CLI class.
3
+ */
4
+ export default class CLI {
5
+ /**
6
+ * Factory to create a CLI instance from various inputs.
7
+ *
8
+ * @param {CLI|Object} input - Existing CLI instance or configuration object.
9
+ * @returns {CLI}
10
+ * @throws {TypeError} If input is neither a CLI nor an object.
11
+ */
12
+ static from(input: CLI | any): CLI;
13
+ /**
14
+ * @param {Object} [input={}]
15
+ * @param {string[]} [input.argv] - Command‑line arguments (defaults to `process.argv.slice(2)`).
16
+ * @param {Object} [input.commands] - Map of command names to handlers.
17
+ * @param {Logger} [input.logger] - Optional logger instance.
18
+ * @param {Array<Function>} [input.Messages] - Message classes for root commands.
19
+ */
20
+ constructor(input?: {
21
+ argv?: string[] | undefined;
22
+ commands?: any;
23
+ logger?: Logger | undefined;
24
+ Messages?: Function[] | undefined;
25
+ } | undefined);
26
+ /** @type {string[]} */
27
+ argv: string[];
28
+ /** @type {Logger} */
29
+ logger: Logger;
30
+ /** @type {Array<Function>} */
31
+ Messages: Array<Function>;
32
+ /** @returns {Map<string,Function>} The command map. */
33
+ get commands(): Map<string, Function>;
34
+ /**
35
+ * Execute the CLI workflow.
36
+ *
37
+ * @param {Message} [msg] - Optional pre‑built message.
38
+ * @yields {OutputMessage|InputMessage}
39
+ */
40
+ run(msg?: Message | undefined): AsyncGenerator<any, void, unknown>;
41
+ #private;
42
+ }
43
+ import Logger from "@nan0web/log";
44
+ import { Message } from "@nan0web/co";
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Represents a command definition.
3
+ *
4
+ * @class
5
+ * @deprecated Use CLI instead
6
+ */
7
+ export default class Command {
8
+ /**
9
+ * @param {Object} config - Command configuration.
10
+ * @param {string} [config.name] - Command name.
11
+ * @param {string} [config.help] - Help description.
12
+ * @param {Object} [config.options] - Options map (`{ flag: [type, default, help] }`).
13
+ * @param {Function} [config.run] - Async generator handling execution.
14
+ * @param {Command[]} [config.children] - Sub‑commands.
15
+ */
16
+ constructor(config: {
17
+ name?: string | undefined;
18
+ help?: string | undefined;
19
+ options?: any;
20
+ run?: Function | undefined;
21
+ children?: Command[] | undefined;
22
+ });
23
+ /** @type {string} */ name: string;
24
+ /** @type {string} */ help: string;
25
+ /** @type {Object} */ options: any;
26
+ /** @type {Function} */ run: Function;
27
+ /** @type {Command[]} */ children: Command[];
28
+ /**
29
+ * Add a sub‑command.
30
+ *
31
+ * @param {Command} command - Sub‑command instance.
32
+ * @returns {this}
33
+ */
34
+ addSubcommand(command: Command): this;
35
+ /**
36
+ * Find a sub‑command by name.
37
+ *
38
+ * @param {string} name - Sub‑command name.
39
+ * @returns {Command|null}
40
+ */
41
+ findSubcommand(name: string): Command | null;
42
+ /**
43
+ * Parse argv into a {@link CommandMessage}.
44
+ *
45
+ * @param {string[]|string} argv - Arguments array or string.
46
+ * @returns {CommandMessage}
47
+ */
48
+ parse(argv: string[] | string): CommandMessage;
49
+ /**
50
+ * Generate a short help string.
51
+ *
52
+ * @returns {string}
53
+ */
54
+ generateHelp(): string;
55
+ /**
56
+ * Execute the command's run generator.
57
+ *
58
+ * @param {Message} message - Message passed to the runner.
59
+ * @yields {any}
60
+ * @throws {CommandError}
61
+ */
62
+ execute(message: Message): AsyncGenerator<any, void, any>;
63
+ /**
64
+ * Apply default values from the options definition to the parsed message.
65
+ *
66
+ * @param {CommandMessage} msg
67
+ * @private
68
+ */
69
+ private _applyDefaults;
70
+ }
71
+ import CommandMessage from "./CommandMessage.js";
72
+ import { Message } from "@nan0web/co";
@@ -0,0 +1,19 @@
1
+ /**
2
+ * CommandError – error class representing a failure during command execution.
3
+ *
4
+ * @module CommandError
5
+ */
6
+ /**
7
+ * @class
8
+ * @extends Error
9
+ */
10
+ export default class CommandError extends Error {
11
+ /**
12
+ * Creates a command execution error.
13
+ *
14
+ * @param {string} message - Message that opens the path.
15
+ * @param {Object} [data=null] - Data to help find correct resonance.
16
+ */
17
+ constructor(message: string, data?: any);
18
+ data: any;
19
+ }