@twin.org/cli-core 0.10.1-next.5 → 0.10.1-next.8
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/es/cliBase.js +31 -2
- package/dist/es/cliBase.js.map +1 -1
- package/dist/es/cliDisplay.js +20 -0
- package/dist/es/cliDisplay.js.map +1 -1
- package/dist/es/commands/global.js +16 -8
- package/dist/es/commands/global.js.map +1 -1
- package/dist/es/models/ICliOptions.js.map +1 -1
- package/dist/types/cliBase.d.ts +4 -2
- package/dist/types/cliDisplay.d.ts +7 -0
- package/dist/types/commands/global.d.ts +2 -2
- package/dist/types/models/ICliOptions.d.ts +6 -0
- package/docs/changelog.md +68 -0
- package/docs/reference/classes/CLIBase.md +4 -2
- package/docs/reference/classes/CLIDisplay.md +22 -0
- package/docs/reference/functions/initGlobalOptions.md +2 -2
- package/docs/reference/interfaces/ICliOptions.md +10 -0
- package/package.json +5 -5
package/dist/es/cliBase.js
CHANGED
|
@@ -1,22 +1,51 @@
|
|
|
1
1
|
// Copyright 2024 IOTA Stiftung.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
+
import path from "node:path";
|
|
3
4
|
import { Coerce, I18n, Is } from "@twin.org/core";
|
|
4
5
|
import { Command } from "commander";
|
|
5
6
|
import { CLIDisplay } from "./cliDisplay.js";
|
|
7
|
+
import { CLIUtils } from "./cliUtils.js";
|
|
6
8
|
import { addGlobalOptions, handleGlobalOptions, initGlobalOptions, initLocales } from "./commands/global.js";
|
|
7
9
|
/**
|
|
8
10
|
* The main entry point for the CLI.
|
|
9
11
|
*/
|
|
10
12
|
export class CLIBase {
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the locales entries to directories, an entry which is not an existing
|
|
15
|
+
* directory is treated as the name of an installed package and resolved to the
|
|
16
|
+
* locales folder of that package.
|
|
17
|
+
* @param localesDirectory The locales directories or package names.
|
|
18
|
+
* @returns The resolved locales directories.
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
static async resolveLocalesDirectories(localesDirectory) {
|
|
22
|
+
const entries = Is.array(localesDirectory) ? localesDirectory : [localesDirectory];
|
|
23
|
+
const resolved = [];
|
|
24
|
+
for (const entry of entries) {
|
|
25
|
+
if (await CLIUtils.dirExists(entry)) {
|
|
26
|
+
resolved.push(entry);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const packageRoot = await CLIUtils.findPackageRoot(entry, process.cwd());
|
|
30
|
+
if (Is.stringValue(packageRoot)) {
|
|
31
|
+
resolved.push(path.join(packageRoot, "locales"));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return resolved;
|
|
36
|
+
}
|
|
11
37
|
/**
|
|
12
38
|
* Execute the command line processing.
|
|
13
39
|
* @param options The options for the CLI.
|
|
14
|
-
* @param localesDirectory The
|
|
40
|
+
* @param localesDirectory The locales to load, each entry is either a path to a locales
|
|
41
|
+
* directory or the name of an installed package to take the locales from. Entries are
|
|
42
|
+
* merged in order, so later entries override earlier ones.
|
|
15
43
|
* @param argv The process arguments.
|
|
16
44
|
* @returns The exit code.
|
|
17
45
|
*/
|
|
18
46
|
async execute(options, localesDirectory, argv) {
|
|
19
|
-
|
|
47
|
+
CLIDisplay.setColorEnabled(!(options.noColor ?? false));
|
|
48
|
+
initGlobalOptions(await CLIBase.resolveLocalesDirectories(localesDirectory));
|
|
20
49
|
initLocales("en");
|
|
21
50
|
try {
|
|
22
51
|
process.title = options.title;
|
package/dist/es/cliBase.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cliBase.js","sourceRoot":"","sources":["../../src/cliBase.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Coerce, I18n, Is } from \"@twin.org/core\";\nimport { Command } from \"commander\";\nimport { CLIDisplay } from \"./cliDisplay.js\";\nimport {\n\taddGlobalOptions,\n\thandleGlobalOptions,\n\tinitGlobalOptions,\n\tinitLocales\n} from \"./commands/global.js\";\nimport type { ICliOptions } from \"./models/ICliOptions.js\";\n\n/**\n * The main entry point for the CLI.\n */\nexport abstract class CLIBase {\n\t/**\n\t * Execute the command line processing.\n\t * @param options The options for the CLI.\n\t * @param localesDirectory The path to load the locales from.\n\t * @param argv The process arguments.\n\t * @returns The exit code.\n\t */\n\tpublic async execute(\n\t\toptions: ICliOptions,\n\t\tlocalesDirectory: string,\n\t\targv: string[]\n\t): Promise<number> {\n\t\tinitGlobalOptions(localesDirectory);\n\t\tinitLocales(\"en\");\n\n\t\ttry {\n\t\t\tprocess.title = options.title;\n\n\t\t\tif (!argv.includes(\"--version\") && !argv.includes(\"-v\")) {\n\t\t\t\tCLIDisplay.header(options.title, options.version, options.icon);\n\t\t\t}\n\n\t\t\tconst program = new Command();\n\n\t\t\tlet outputWidth = options.overrideOutputWidth;\n\t\t\tlet outputErrWidth = options.overrideOutputWidth;\n\t\t\tif (Is.undefined(outputWidth) && process.stdout.isTTY) {\n\t\t\t\toutputWidth = process.stdout.columns;\n\t\t\t\toutputErrWidth = process.stderr.columns;\n\t\t\t}\n\n\t\t\tprogram\n\t\t\t\t.name(options.appName)\n\t\t\t\t.version(options.version)\n\t\t\t\t.usage(\"[command]\")\n\t\t\t\t.showHelpAfterError()\n\t\t\t\t.configureOutput({\n\t\t\t\t\twriteOut: str => CLIDisplay.write(str),\n\t\t\t\t\twriteErr: str => CLIDisplay.writeError(str),\n\t\t\t\t\tgetOutHelpWidth: () => outputWidth as number,\n\t\t\t\t\tgetErrHelpWidth: () => outputErrWidth as number,\n\t\t\t\t\toutputError: (str, write) => CLIDisplay.error(str.replace(/^error: /, \"\"), false)\n\t\t\t\t})\n\t\t\t\t.exitOverride(err => {\n\t\t\t\t\t// By default commander still calls process.exit on exit\n\t\t\t\t\t// which we don't want as we might have subsequent\n\t\t\t\t\t// processing to handle, so instead we throw the exit code\n\t\t\t\t\t// as a way to skip the process.exit call.\n\t\t\t\t\t// If the error code is commander.help then we return 0 as\n\t\t\t\t\t// we don't want displaying help to be an error.\n\t\t\t\t\t// eslint-disable-next-line no-restricted-syntax\n\t\t\t\t\tthrow new Error(err.code === \"commander.help\" ? \"0\" : err.exitCode.toString());\n\t\t\t\t});\n\n\t\t\tif (options.showDevToolWarning ?? false) {\n\t\t\t\tprogram.hook(\"preAction\", () =>\n\t\t\t\t\tCLIDisplay.warning(I18n.formatMessage(\"warn.common.devOnlyTool\"))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.configureRoot(program);\n\n\t\t\taddGlobalOptions(program, options.supportsLang ?? true, options.supportsEnvFiles ?? false);\n\n\t\t\t// We parse the options before building the command\n\t\t\t// in case the language has been set, then the\n\t\t\t// help for the options will be in the correct language.\n\t\t\tprogram.parseOptions(argv);\n\t\t\thandleGlobalOptions(program);\n\n\t\t\tconst commandCount = this.buildCommands(program);\n\t\t\tif (commandCount === 0) {\n\t\t\t\tprogram.usage(\" \");\n\t\t\t}\n\n\t\t\tawait program.parseAsync(argv);\n\t\t} catch (error) {\n\t\t\tCLIDisplay.spinnerStop();\n\n\t\t\tlet exitCode;\n\t\t\t// We have no control over the response from commander\n\t\t\t// so we have to do some checking and coercion here\n\t\t\t// to get a valid exit code.\n\t\t\t// eslint-disable-next-line no-restricted-syntax\n\t\t\tif (error instanceof Error) {\n\t\t\t\t// This error could be the exit code we errored with\n\t\t\t\t// from the exitOverride so parse and resolve with it\n\t\t\t\texitCode = Coerce.number(error.message);\n\t\t\t}\n\n\t\t\tif (Is.integer(exitCode)) {\n\t\t\t\treturn exitCode;\n\t\t\t}\n\t\t\tCLIDisplay.error(error);\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Configure any options or actions at the root program level.\n\t * @param program The root program command.\n\t */\n\tprotected configureRoot(program: Command): void {\n\t\tprogram.action(() => {\n\t\t\tprogram.help();\n\t\t});\n\t}\n\n\t/**\n\t * Get the commands for the CLI, override in derived class to supply your own.\n\t * @param program The main program that the commands will be added to.\n\t * @returns The commands for the CLI.\n\t */\n\tprotected getCommands(program: Command): Command[] {\n\t\treturn [];\n\t}\n\n\t/**\n\t * Build the commands for the CLI.\n\t * @param program The main program that the commands are added to.\n\t * @returns The number of commands added.\n\t * @internal\n\t */\n\tprivate buildCommands(program: Command): number {\n\t\tconst commands = this.getCommands(program);\n\n\t\tfor (const command of commands) {\n\t\t\tprogram.addCommand(command.copyInheritedSettings(program));\n\t\t}\n\n\t\treturn commands.length;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"cliBase.js","sourceRoot":"","sources":["../../src/cliBase.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport path from \"node:path\";\nimport { Coerce, I18n, Is } from \"@twin.org/core\";\nimport { Command } from \"commander\";\nimport { CLIDisplay } from \"./cliDisplay.js\";\nimport { CLIUtils } from \"./cliUtils.js\";\nimport {\n\taddGlobalOptions,\n\thandleGlobalOptions,\n\tinitGlobalOptions,\n\tinitLocales\n} from \"./commands/global.js\";\nimport type { ICliOptions } from \"./models/ICliOptions.js\";\n\n/**\n * The main entry point for the CLI.\n */\nexport abstract class CLIBase {\n\t/**\n\t * Resolve the locales entries to directories, an entry which is not an existing\n\t * directory is treated as the name of an installed package and resolved to the\n\t * locales folder of that package.\n\t * @param localesDirectory The locales directories or package names.\n\t * @returns The resolved locales directories.\n\t * @internal\n\t */\n\tprivate static async resolveLocalesDirectories(\n\t\tlocalesDirectory: string | string[]\n\t): Promise<string[]> {\n\t\tconst entries = Is.array<string>(localesDirectory) ? localesDirectory : [localesDirectory];\n\t\tconst resolved: string[] = [];\n\n\t\tfor (const entry of entries) {\n\t\t\tif (await CLIUtils.dirExists(entry)) {\n\t\t\t\tresolved.push(entry);\n\t\t\t} else {\n\t\t\t\tconst packageRoot = await CLIUtils.findPackageRoot(entry, process.cwd());\n\t\t\t\tif (Is.stringValue(packageRoot)) {\n\t\t\t\t\tresolved.push(path.join(packageRoot, \"locales\"));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn resolved;\n\t}\n\n\t/**\n\t * Execute the command line processing.\n\t * @param options The options for the CLI.\n\t * @param localesDirectory The locales to load, each entry is either a path to a locales\n\t * directory or the name of an installed package to take the locales from. Entries are\n\t * merged in order, so later entries override earlier ones.\n\t * @param argv The process arguments.\n\t * @returns The exit code.\n\t */\n\tpublic async execute(\n\t\toptions: ICliOptions,\n\t\tlocalesDirectory: string | string[],\n\t\targv: string[]\n\t): Promise<number> {\n\t\tCLIDisplay.setColorEnabled(!(options.noColor ?? false));\n\n\t\tinitGlobalOptions(await CLIBase.resolveLocalesDirectories(localesDirectory));\n\t\tinitLocales(\"en\");\n\n\t\ttry {\n\t\t\tprocess.title = options.title;\n\n\t\t\tif (!argv.includes(\"--version\") && !argv.includes(\"-v\")) {\n\t\t\t\tCLIDisplay.header(options.title, options.version, options.icon);\n\t\t\t}\n\n\t\t\tconst program = new Command();\n\n\t\t\tlet outputWidth = options.overrideOutputWidth;\n\t\t\tlet outputErrWidth = options.overrideOutputWidth;\n\t\t\tif (Is.undefined(outputWidth) && process.stdout.isTTY) {\n\t\t\t\toutputWidth = process.stdout.columns;\n\t\t\t\toutputErrWidth = process.stderr.columns;\n\t\t\t}\n\n\t\t\tprogram\n\t\t\t\t.name(options.appName)\n\t\t\t\t.version(options.version)\n\t\t\t\t.usage(\"[command]\")\n\t\t\t\t.showHelpAfterError()\n\t\t\t\t.configureOutput({\n\t\t\t\t\twriteOut: str => CLIDisplay.write(str),\n\t\t\t\t\twriteErr: str => CLIDisplay.writeError(str),\n\t\t\t\t\tgetOutHelpWidth: () => outputWidth as number,\n\t\t\t\t\tgetErrHelpWidth: () => outputErrWidth as number,\n\t\t\t\t\toutputError: (str, write) => CLIDisplay.error(str.replace(/^error: /, \"\"), false)\n\t\t\t\t})\n\t\t\t\t.exitOverride(err => {\n\t\t\t\t\t// By default commander still calls process.exit on exit\n\t\t\t\t\t// which we don't want as we might have subsequent\n\t\t\t\t\t// processing to handle, so instead we throw the exit code\n\t\t\t\t\t// as a way to skip the process.exit call.\n\t\t\t\t\t// If the error code is commander.help then we return 0 as\n\t\t\t\t\t// we don't want displaying help to be an error.\n\t\t\t\t\t// eslint-disable-next-line no-restricted-syntax\n\t\t\t\t\tthrow new Error(err.code === \"commander.help\" ? \"0\" : err.exitCode.toString());\n\t\t\t\t});\n\n\t\t\tif (options.showDevToolWarning ?? false) {\n\t\t\t\tprogram.hook(\"preAction\", () =>\n\t\t\t\t\tCLIDisplay.warning(I18n.formatMessage(\"warn.common.devOnlyTool\"))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.configureRoot(program);\n\n\t\t\taddGlobalOptions(program, options.supportsLang ?? true, options.supportsEnvFiles ?? false);\n\n\t\t\t// We parse the options before building the command\n\t\t\t// in case the language has been set, then the\n\t\t\t// help for the options will be in the correct language.\n\t\t\tprogram.parseOptions(argv);\n\t\t\thandleGlobalOptions(program);\n\n\t\t\tconst commandCount = this.buildCommands(program);\n\t\t\tif (commandCount === 0) {\n\t\t\t\tprogram.usage(\" \");\n\t\t\t}\n\n\t\t\tawait program.parseAsync(argv);\n\t\t} catch (error) {\n\t\t\tCLIDisplay.spinnerStop();\n\n\t\t\tlet exitCode;\n\t\t\t// We have no control over the response from commander\n\t\t\t// so we have to do some checking and coercion here\n\t\t\t// to get a valid exit code.\n\t\t\t// eslint-disable-next-line no-restricted-syntax\n\t\t\tif (error instanceof Error) {\n\t\t\t\t// This error could be the exit code we errored with\n\t\t\t\t// from the exitOverride so parse and resolve with it\n\t\t\t\texitCode = Coerce.number(error.message);\n\t\t\t}\n\n\t\t\tif (Is.integer(exitCode)) {\n\t\t\t\treturn exitCode;\n\t\t\t}\n\t\t\tCLIDisplay.error(error);\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Configure any options or actions at the root program level.\n\t * @param program The root program command.\n\t */\n\tprotected configureRoot(program: Command): void {\n\t\tprogram.action(() => {\n\t\t\tprogram.help();\n\t\t});\n\t}\n\n\t/**\n\t * Get the commands for the CLI, override in derived class to supply your own.\n\t * @param program The main program that the commands will be added to.\n\t * @returns The commands for the CLI.\n\t */\n\tprotected getCommands(program: Command): Command[] {\n\t\treturn [];\n\t}\n\n\t/**\n\t * Build the commands for the CLI.\n\t * @param program The main program that the commands are added to.\n\t * @returns The number of commands added.\n\t * @internal\n\t */\n\tprivate buildCommands(program: Command): number {\n\t\tconst commands = this.getCommands(program);\n\n\t\tfor (const command of commands) {\n\t\t\tprogram.addCommand(command.copyInheritedSettings(program));\n\t\t}\n\n\t\treturn commands.length;\n\t}\n}\n"]}
|
package/dist/es/cliDisplay.js
CHANGED
|
@@ -13,6 +13,12 @@ export class CLIDisplay {
|
|
|
13
13
|
* @internal
|
|
14
14
|
*/
|
|
15
15
|
static _spinnerIntervalId;
|
|
16
|
+
/**
|
|
17
|
+
* The colour level detected from the environment, captured before any override
|
|
18
|
+
* so that colour can be restored after being disabled.
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
static _detectedColorLevel = chalk.level;
|
|
16
22
|
/**
|
|
17
23
|
* The default output method for writing standard messages.
|
|
18
24
|
* @param buffer The message to output.
|
|
@@ -30,6 +36,20 @@ export class CLIDisplay {
|
|
|
30
36
|
clearLine(process.stdout, 0);
|
|
31
37
|
cursorTo(process.stdout, 0);
|
|
32
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* Enable or disable colourised output. When disabled the display methods emit
|
|
41
|
+
* plain text with no ANSI escape sequences, otherwise the colour support
|
|
42
|
+
* detected from the environment is used.
|
|
43
|
+
* @param enabled Whether to colourise the output.
|
|
44
|
+
*/
|
|
45
|
+
static setColorEnabled(enabled) {
|
|
46
|
+
if (enabled) {
|
|
47
|
+
chalk.level = CLIDisplay._detectedColorLevel;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
chalk.level = 0;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
33
53
|
/**
|
|
34
54
|
* Display the header for the CLI.
|
|
35
55
|
* @param title The title of the CLI.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cliDisplay.js","sourceRoot":"","sources":["../../src/cliDisplay.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { clearLine, cursorTo } from \"node:readline\";\nimport { inspect } from \"node:util\";\nimport { Coerce, ErrorHelper, I18n, Is } from \"@twin.org/core\";\nimport chalk from \"chalk\";\n\n/**\n * Display utilities for the CLI.\n */\nexport class CLIDisplay {\n\t/**\n\t * The interval ID for the spinner.\n\t * @internal\n\t */\n\tprivate static _spinnerIntervalId: ReturnType<typeof setTimeout> | number | undefined;\n\n\t/**\n\t * The default output method for writing standard messages.\n\t * @param buffer The message to output.\n\t */\n\tpublic static write: (buffer: string | Uint8Array) => void = buffer =>\n\t\tprocess.stdout.write(buffer);\n\n\t/**\n\t * The default output method for writing error messages.\n\t * @param buffer The message to output.\n\t */\n\tpublic static writeError: (buffer: string | Uint8Array) => void = buffer =>\n\t\tprocess.stderr.write(buffer);\n\n\t/**\n\t * The default output method for clearing the current line.\n\t */\n\tpublic static clearLine: () => void = () => {\n\t\tclearLine(process.stdout, 0);\n\t\tcursorTo(process.stdout, 0);\n\t};\n\n\t/**\n\t * Display the header for the CLI.\n\t * @param title The title of the CLI.\n\t * @param version The version of the CLI.\n\t * @param icon The icon for the CLI.\n\t */\n\tpublic static header(title: string, version: string, icon: string): void {\n\t\tconst titleVersion = `${title} v${version}`;\n\t\tCLIDisplay.write(`${icon} ${chalk.underline.bold.blue(titleVersion)}\\n`);\n\t\tCLIDisplay.write(\"\\n\");\n\t}\n\n\t/**\n\t * Display an error message.\n\t * @param error The error to display.\n\t * @param lineBreaks Whether to add a line break after the error.\n\t * @param options Options for formatting the error.\n\t * @param options.includeStack Whether to include the stack trace in the output, defaults to false.\n\t * @param options.includeAdditional Whether to include additional error information in the output, defaults to false.\n\t */\n\tpublic static error(\n\t\terror: unknown,\n\t\tlineBreaks: boolean = true,\n\t\toptions: { includeStack?: boolean; includeAdditional?: boolean } = {}\n\t): void {\n\t\tCLIDisplay.writeError(\"❗ \");\n\t\tCLIDisplay.writeError(chalk.red(I18n.formatMessage(\"cli.progress.error\")));\n\t\tif (lineBreaks) {\n\t\t\tCLIDisplay.writeError(\"\\n\");\n\t\t}\n\n\t\tconst formatted = ErrorHelper.localizeErrors(error);\n\t\tCLIDisplay.writeError(chalk.red(formatted.map(e => `\\t${e.message}`).join(\"\\n\")));\n\n\t\tif (options.includeAdditional) {\n\t\t\tfor (const err of formatted) {\n\t\t\t\tif (Is.arrayValue(err.additional)) {\n\t\t\t\t\tCLIDisplay.writeError(chalk.red(`\\n\\t\\t${err.additional.join(\"\\n\\t\\t\")}\\n`));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (options.includeStack) {\n\t\t\tCLIDisplay.writeError(\"\\n\");\n\t\t\tCLIDisplay.writeError(\"\\n-----DEBUG STACK START-----\\n\\n\");\n\t\t\tfor (const err of formatted) {\n\t\t\t\tif (Is.stringValue(err.stack)) {\n\t\t\t\t\tCLIDisplay.writeError(`${err.stack}\\n`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tCLIDisplay.writeError(\"\\n-----DEBUG STACK END-----\\n\");\n\t\t}\n\n\t\tif (lineBreaks) {\n\t\t\tCLIDisplay.writeError(\"\\n\");\n\t\t}\n\t}\n\n\t/**\n\t * Display an error message in simple form.\n\t * @param error The error to display.\n\t */\n\tpublic static errorMessage(error: string): void {\n\t\tCLIDisplay.writeError(\"❗ \");\n\t\tCLIDisplay.writeError(chalk.red(error));\n\t\tCLIDisplay.writeError(\"\\n\");\n\t}\n\n\t/**\n\t * Display a section.\n\t * @param label The label for the section.\n\t */\n\tpublic static section(label: string): void {\n\t\tCLIDisplay.write(chalk.hex(\"#FFA500\").bold.underline(label));\n\t\tCLIDisplay.write(\"\\n\\n\");\n\t}\n\n\t/**\n\t * Display a value with a label.\n\t * @param label The label for the value.\n\t * @param value The value to display.\n\t * @param indentLevel The level of indentation.\n\t */\n\tpublic static value(label: string, value: unknown, indentLevel: number = 0): void {\n\t\tCLIDisplay.write(\"\\t\".repeat(indentLevel));\n\t\tif (Is.stringValue(label)) {\n\t\t\tCLIDisplay.write(chalk.hex(\"#FFA500\").bold(`${label}: `));\n\t\t}\n\t\tCLIDisplay.write(Coerce.string(value) ?? \"\");\n\t\tCLIDisplay.write(\"\\n\");\n\t}\n\n\t/**\n\t * Display a task with a label.\n\t * @param label The label for the value.\n\t * @param task The task to display.\n\t */\n\tpublic static task(label: string, task?: string): void {\n\t\tCLIDisplay.write(\"➡️ \");\n\t\tif (Is.empty(task)) {\n\t\t\tCLIDisplay.write(chalk.cyan(label));\n\t\t} else {\n\t\t\tCLIDisplay.write(chalk.cyan(`${label}: `));\n\t\t\tCLIDisplay.write(task);\n\t\t}\n\t\tCLIDisplay.write(\"\\n\");\n\t}\n\n\t/**\n\t * Display a break.\n\t */\n\tpublic static break(): void {\n\t\tCLIDisplay.write(\"\\n\");\n\t}\n\n\t/**\n\t * Display formatted and colorized JSON.\n\t * @param obj The object to display.\n\t */\n\tpublic static json(obj: unknown): void {\n\t\tCLIDisplay.write(inspect(obj, false, null, true));\n\t\tCLIDisplay.write(\"\\n\");\n\t}\n\n\t/**\n\t * Display a warning.\n\t * @param label The label for the warning.\n\t */\n\tpublic static warning(label: string): void {\n\t\tCLIDisplay.write(\"⚠️ \");\n\t\tCLIDisplay.write(chalk.hex(\"#FFA500\").bold(label));\n\t\tCLIDisplay.write(\"\\n\\n\");\n\t}\n\n\t/**\n\t * Display the processing is done.\n\t */\n\tpublic static done(): void {\n\t\tCLIDisplay.write(\"🎉 \");\n\t\tCLIDisplay.write(chalk.greenBright.bold(I18n.formatMessage(\"cli.progress.done\")));\n\t\tCLIDisplay.write(\"\\n\");\n\t}\n\n\t/**\n\t * Start the spinner.\n\t * @param i18nMessage The message to display with the spinner.\n\t * @param spinnerCharacters The characters to use in the spinner.\n\t * @param interval The interval for the spinner.\n\t */\n\tpublic static spinnerStart(\n\t\ti18nMessage: string = \"cli.progress.pleaseWait\",\n\t\tspinnerCharacters: string[] = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"],\n\t\tinterval: number = 100\n\t): void {\n\t\tlet spinnerIndex = 0;\n\t\tif (CLIDisplay._spinnerIntervalId) {\n\t\t\tclearInterval(CLIDisplay._spinnerIntervalId);\n\t\t}\n\t\tCLIDisplay._spinnerIntervalId = setInterval(() => {\n\t\t\tCLIDisplay.clearLine();\n\t\t\tCLIDisplay.write(\n\t\t\t\t`${spinnerCharacters[spinnerIndex++ % spinnerCharacters.length]} ${I18n.formatMessage(i18nMessage)}`\n\t\t\t);\n\t\t}, interval);\n\t}\n\n\t/**\n\t * Stop the spinner.\n\t */\n\tpublic static spinnerStop(): void {\n\t\tif (CLIDisplay._spinnerIntervalId) {\n\t\t\tclearInterval(CLIDisplay._spinnerIntervalId);\n\t\t\tCLIDisplay._spinnerIntervalId = undefined;\n\t\t}\n\t\tCLIDisplay.clearLine();\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"cliDisplay.js","sourceRoot":"","sources":["../../src/cliDisplay.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { clearLine, cursorTo } from \"node:readline\";\nimport { inspect } from \"node:util\";\nimport { Coerce, ErrorHelper, I18n, Is } from \"@twin.org/core\";\nimport chalk from \"chalk\";\n\n/**\n * Display utilities for the CLI.\n */\nexport class CLIDisplay {\n\t/**\n\t * The interval ID for the spinner.\n\t * @internal\n\t */\n\tprivate static _spinnerIntervalId: ReturnType<typeof setTimeout> | number | undefined;\n\n\t/**\n\t * The colour level detected from the environment, captured before any override\n\t * so that colour can be restored after being disabled.\n\t * @internal\n\t */\n\tprivate static readonly _detectedColorLevel = chalk.level;\n\n\t/**\n\t * The default output method for writing standard messages.\n\t * @param buffer The message to output.\n\t */\n\tpublic static write: (buffer: string | Uint8Array) => void = buffer =>\n\t\tprocess.stdout.write(buffer);\n\n\t/**\n\t * The default output method for writing error messages.\n\t * @param buffer The message to output.\n\t */\n\tpublic static writeError: (buffer: string | Uint8Array) => void = buffer =>\n\t\tprocess.stderr.write(buffer);\n\n\t/**\n\t * The default output method for clearing the current line.\n\t */\n\tpublic static clearLine: () => void = () => {\n\t\tclearLine(process.stdout, 0);\n\t\tcursorTo(process.stdout, 0);\n\t};\n\n\t/**\n\t * Enable or disable colourised output. When disabled the display methods emit\n\t * plain text with no ANSI escape sequences, otherwise the colour support\n\t * detected from the environment is used.\n\t * @param enabled Whether to colourise the output.\n\t */\n\tpublic static setColorEnabled(enabled: boolean): void {\n\t\tif (enabled) {\n\t\t\tchalk.level = CLIDisplay._detectedColorLevel;\n\t\t} else {\n\t\t\tchalk.level = 0;\n\t\t}\n\t}\n\n\t/**\n\t * Display the header for the CLI.\n\t * @param title The title of the CLI.\n\t * @param version The version of the CLI.\n\t * @param icon The icon for the CLI.\n\t */\n\tpublic static header(title: string, version: string, icon: string): void {\n\t\tconst titleVersion = `${title} v${version}`;\n\t\tCLIDisplay.write(`${icon} ${chalk.underline.bold.blue(titleVersion)}\\n`);\n\t\tCLIDisplay.write(\"\\n\");\n\t}\n\n\t/**\n\t * Display an error message.\n\t * @param error The error to display.\n\t * @param lineBreaks Whether to add a line break after the error.\n\t * @param options Options for formatting the error.\n\t * @param options.includeStack Whether to include the stack trace in the output, defaults to false.\n\t * @param options.includeAdditional Whether to include additional error information in the output, defaults to false.\n\t */\n\tpublic static error(\n\t\terror: unknown,\n\t\tlineBreaks: boolean = true,\n\t\toptions: { includeStack?: boolean; includeAdditional?: boolean } = {}\n\t): void {\n\t\tCLIDisplay.writeError(\"❗ \");\n\t\tCLIDisplay.writeError(chalk.red(I18n.formatMessage(\"cli.progress.error\")));\n\t\tif (lineBreaks) {\n\t\t\tCLIDisplay.writeError(\"\\n\");\n\t\t}\n\n\t\tconst formatted = ErrorHelper.localizeErrors(error);\n\t\tCLIDisplay.writeError(chalk.red(formatted.map(e => `\\t${e.message}`).join(\"\\n\")));\n\n\t\tif (options.includeAdditional) {\n\t\t\tfor (const err of formatted) {\n\t\t\t\tif (Is.arrayValue(err.additional)) {\n\t\t\t\t\tCLIDisplay.writeError(chalk.red(`\\n\\t\\t${err.additional.join(\"\\n\\t\\t\")}\\n`));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (options.includeStack) {\n\t\t\tCLIDisplay.writeError(\"\\n\");\n\t\t\tCLIDisplay.writeError(\"\\n-----DEBUG STACK START-----\\n\\n\");\n\t\t\tfor (const err of formatted) {\n\t\t\t\tif (Is.stringValue(err.stack)) {\n\t\t\t\t\tCLIDisplay.writeError(`${err.stack}\\n`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tCLIDisplay.writeError(\"\\n-----DEBUG STACK END-----\\n\");\n\t\t}\n\n\t\tif (lineBreaks) {\n\t\t\tCLIDisplay.writeError(\"\\n\");\n\t\t}\n\t}\n\n\t/**\n\t * Display an error message in simple form.\n\t * @param error The error to display.\n\t */\n\tpublic static errorMessage(error: string): void {\n\t\tCLIDisplay.writeError(\"❗ \");\n\t\tCLIDisplay.writeError(chalk.red(error));\n\t\tCLIDisplay.writeError(\"\\n\");\n\t}\n\n\t/**\n\t * Display a section.\n\t * @param label The label for the section.\n\t */\n\tpublic static section(label: string): void {\n\t\tCLIDisplay.write(chalk.hex(\"#FFA500\").bold.underline(label));\n\t\tCLIDisplay.write(\"\\n\\n\");\n\t}\n\n\t/**\n\t * Display a value with a label.\n\t * @param label The label for the value.\n\t * @param value The value to display.\n\t * @param indentLevel The level of indentation.\n\t */\n\tpublic static value(label: string, value: unknown, indentLevel: number = 0): void {\n\t\tCLIDisplay.write(\"\\t\".repeat(indentLevel));\n\t\tif (Is.stringValue(label)) {\n\t\t\tCLIDisplay.write(chalk.hex(\"#FFA500\").bold(`${label}: `));\n\t\t}\n\t\tCLIDisplay.write(Coerce.string(value) ?? \"\");\n\t\tCLIDisplay.write(\"\\n\");\n\t}\n\n\t/**\n\t * Display a task with a label.\n\t * @param label The label for the value.\n\t * @param task The task to display.\n\t */\n\tpublic static task(label: string, task?: string): void {\n\t\tCLIDisplay.write(\"➡️ \");\n\t\tif (Is.empty(task)) {\n\t\t\tCLIDisplay.write(chalk.cyan(label));\n\t\t} else {\n\t\t\tCLIDisplay.write(chalk.cyan(`${label}: `));\n\t\t\tCLIDisplay.write(task);\n\t\t}\n\t\tCLIDisplay.write(\"\\n\");\n\t}\n\n\t/**\n\t * Display a break.\n\t */\n\tpublic static break(): void {\n\t\tCLIDisplay.write(\"\\n\");\n\t}\n\n\t/**\n\t * Display formatted and colorized JSON.\n\t * @param obj The object to display.\n\t */\n\tpublic static json(obj: unknown): void {\n\t\tCLIDisplay.write(inspect(obj, false, null, true));\n\t\tCLIDisplay.write(\"\\n\");\n\t}\n\n\t/**\n\t * Display a warning.\n\t * @param label The label for the warning.\n\t */\n\tpublic static warning(label: string): void {\n\t\tCLIDisplay.write(\"⚠️ \");\n\t\tCLIDisplay.write(chalk.hex(\"#FFA500\").bold(label));\n\t\tCLIDisplay.write(\"\\n\\n\");\n\t}\n\n\t/**\n\t * Display the processing is done.\n\t */\n\tpublic static done(): void {\n\t\tCLIDisplay.write(\"🎉 \");\n\t\tCLIDisplay.write(chalk.greenBright.bold(I18n.formatMessage(\"cli.progress.done\")));\n\t\tCLIDisplay.write(\"\\n\");\n\t}\n\n\t/**\n\t * Start the spinner.\n\t * @param i18nMessage The message to display with the spinner.\n\t * @param spinnerCharacters The characters to use in the spinner.\n\t * @param interval The interval for the spinner.\n\t */\n\tpublic static spinnerStart(\n\t\ti18nMessage: string = \"cli.progress.pleaseWait\",\n\t\tspinnerCharacters: string[] = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"],\n\t\tinterval: number = 100\n\t): void {\n\t\tlet spinnerIndex = 0;\n\t\tif (CLIDisplay._spinnerIntervalId) {\n\t\t\tclearInterval(CLIDisplay._spinnerIntervalId);\n\t\t}\n\t\tCLIDisplay._spinnerIntervalId = setInterval(() => {\n\t\t\tCLIDisplay.clearLine();\n\t\t\tCLIDisplay.write(\n\t\t\t\t`${spinnerCharacters[spinnerIndex++ % spinnerCharacters.length]} ${I18n.formatMessage(i18nMessage)}`\n\t\t\t);\n\t\t}, interval);\n\t}\n\n\t/**\n\t * Stop the spinner.\n\t */\n\tpublic static spinnerStop(): void {\n\t\tif (CLIDisplay._spinnerIntervalId) {\n\t\t\tclearInterval(CLIDisplay._spinnerIntervalId);\n\t\t\tCLIDisplay._spinnerIntervalId = undefined;\n\t\t}\n\t\tCLIDisplay.clearLine();\n\t}\n}\n"]}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// Copyright 2024 IOTA Stiftung.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0.
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { I18n, Is } from "@twin.org/core";
|
|
4
|
+
import { I18n, Is, ObjectHelper } from "@twin.org/core";
|
|
5
5
|
import * as dotenv from "dotenv";
|
|
6
6
|
import { CLIDisplay } from "../cliDisplay.js";
|
|
7
7
|
import { CLIUtils } from "../cliUtils.js";
|
|
8
|
-
let
|
|
8
|
+
let localesDirs;
|
|
9
9
|
/**
|
|
10
10
|
* Initialize the global options.
|
|
11
|
-
* @param localesDirectory The path to load the locales from.
|
|
11
|
+
* @param localesDirectory The path, or paths, to load the locales from.
|
|
12
12
|
*/
|
|
13
13
|
export function initGlobalOptions(localesDirectory) {
|
|
14
|
-
|
|
14
|
+
localesDirs = Is.array(localesDirectory) ? localesDirectory : [localesDirectory];
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* Add the global options.
|
|
@@ -51,10 +51,18 @@ export function handleGlobalOptions(command) {
|
|
|
51
51
|
* @internal
|
|
52
52
|
*/
|
|
53
53
|
export function initLocales(locale) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
// Merged in order so that later directories override earlier ones, matching
|
|
55
|
+
// the precedence the merge-locales tool uses when it builds a combined file.
|
|
56
|
+
let merged;
|
|
57
|
+
for (const localesDir of localesDirs) {
|
|
58
|
+
const localePath = path.join(localesDir, `${locale}.json`);
|
|
59
|
+
const localeContent = CLIUtils.readJsonFileSync(localePath);
|
|
60
|
+
if (Is.objectValue(localeContent)) {
|
|
61
|
+
merged = Is.empty(merged) ? localeContent : ObjectHelper.merge(merged, localeContent);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (Is.objectValue(merged)) {
|
|
65
|
+
I18n.addDictionary(locale, merged);
|
|
58
66
|
I18n.setLocale(locale);
|
|
59
67
|
}
|
|
60
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global.js","sourceRoot":"","sources":["../../../src/commands/global.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,EAAE,EAA0B,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"global.js","sourceRoot":"","sources":["../../../src/commands/global.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport path from \"node:path\";\nimport { I18n, Is, ObjectHelper, type ILocaleDictionary } from \"@twin.org/core\";\nimport type { Command } from \"commander\";\nimport * as dotenv from \"dotenv\";\nimport { CLIDisplay } from \"../cliDisplay.js\";\nimport { CLIUtils } from \"../cliUtils.js\";\n\nlet localesDirs: string[];\n\n/**\n * Initialize the global options.\n * @param localesDirectory The path, or paths, to load the locales from.\n */\nexport function initGlobalOptions(localesDirectory: string | string[]): void {\n\tlocalesDirs = Is.array<string>(localesDirectory) ? localesDirectory : [localesDirectory];\n}\n\n/**\n * Add the global options.\n * @param program The program to add the options to.\n * @param supportsLang Whether the CLI supports different languages.\n * @param supportsEnvFiles Whether the CLI supports loading env files\n */\nexport function addGlobalOptions(\n\tprogram: Command,\n\tsupportsLang: boolean,\n\tsupportsEnvFiles: boolean\n): void {\n\tif (supportsLang) {\n\t\tprogram.option(\n\t\t\tI18n.formatMessage(\"cli.options.lang.param\"),\n\t\t\tI18n.formatMessage(\"cli.options.lang.description\"),\n\t\t\t\"en\"\n\t\t);\n\t}\n\n\tif (supportsEnvFiles) {\n\t\tprogram.option(\n\t\t\tI18n.formatMessage(\"cli.options.load-env.param\"),\n\t\t\tI18n.formatMessage(\"cli.options.load-env.description\")\n\t\t);\n\t}\n}\n\n/**\n * Handle the global options.\n * @param command The command to use for context.\n * @internal\n */\nexport function handleGlobalOptions(command: Command): void {\n\tconst globalOpts = command.optsWithGlobals();\n\n\tif (Is.stringValue(globalOpts?.lang)) {\n\t\tinitLocales(globalOpts.lang);\n\t}\n\n\tconst loadEnv: string[] = globalOpts?.loadEnv;\n\tif (Is.arrayValue(loadEnv)) {\n\t\tconst resolvedEnv = loadEnv.map(e => path.resolve(e));\n\t\tCLIDisplay.task(I18n.formatMessage(\"cli.progress.loadingEnvFiles\"), resolvedEnv.join(\", \"));\n\t\tCLIDisplay.break();\n\t\tdotenv.config({ path: resolvedEnv, quiet: true });\n\t}\n}\n\n/**\n * Initialize the locales for the CLI.\n * @param locale The locale to use.\n * @internal\n */\nexport function initLocales(locale: string): void {\n\t// Merged in order so that later directories override earlier ones, matching\n\t// the precedence the merge-locales tool uses when it builds a combined file.\n\tlet merged: ILocaleDictionary | undefined;\n\n\tfor (const localesDir of localesDirs) {\n\t\tconst localePath = path.join(localesDir, `${locale}.json`);\n\t\tconst localeContent = CLIUtils.readJsonFileSync<ILocaleDictionary>(localePath);\n\t\tif (Is.objectValue(localeContent)) {\n\t\t\tmerged = Is.empty(merged) ? localeContent : ObjectHelper.merge(merged, localeContent);\n\t\t}\n\t}\n\n\tif (Is.objectValue(merged)) {\n\t\tI18n.addDictionary(locale, merged);\n\t\tI18n.setLocale(locale);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ICliOptions.js","sourceRoot":"","sources":["../../../src/models/ICliOptions.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n/**\n * Options for the CLI.\n */\nexport interface ICliOptions {\n\t/**\n\t * The title of the CLI.\n\t */\n\ttitle: string;\n\n\t/**\n\t * The name of the app used to execute it.\n\t */\n\tappName: string;\n\n\t/**\n\t * The version of the app.\n\t */\n\tversion: string;\n\n\t/**\n\t * The icon for the CLI as an emoji character.\n\t */\n\ticon: string;\n\n\t/**\n\t * Supports different languages.\n\t */\n\tsupportsLang?: boolean;\n\n\t/**\n\t * Supports the loading of env files.\n\t */\n\tsupportsEnvFiles?: boolean;\n\n\t/**\n\t * Override the default output width.\n\t */\n\toverrideOutputWidth?: number;\n\n\t/**\n\t * Show a warning that this is a dev tool and not for production use.\n\t */\n\tshowDevToolWarning?: boolean;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ICliOptions.js","sourceRoot":"","sources":["../../../src/models/ICliOptions.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n/**\n * Options for the CLI.\n */\nexport interface ICliOptions {\n\t/**\n\t * The title of the CLI.\n\t */\n\ttitle: string;\n\n\t/**\n\t * The name of the app used to execute it.\n\t */\n\tappName: string;\n\n\t/**\n\t * The version of the app.\n\t */\n\tversion: string;\n\n\t/**\n\t * The icon for the CLI as an emoji character.\n\t */\n\ticon: string;\n\n\t/**\n\t * Supports different languages.\n\t */\n\tsupportsLang?: boolean;\n\n\t/**\n\t * Supports the loading of env files.\n\t */\n\tsupportsEnvFiles?: boolean;\n\n\t/**\n\t * Override the default output width.\n\t */\n\toverrideOutputWidth?: number;\n\n\t/**\n\t * Show a warning that this is a dev tool and not for production use.\n\t */\n\tshowDevToolWarning?: boolean;\n\n\t/**\n\t * Disable colourised output, so that all output is plain text with no ANSI\n\t * escape sequences, defaults to false which uses the colour support detected\n\t * from the environment.\n\t */\n\tnoColor?: boolean;\n}\n"]}
|
package/dist/types/cliBase.d.ts
CHANGED
|
@@ -7,11 +7,13 @@ export declare abstract class CLIBase {
|
|
|
7
7
|
/**
|
|
8
8
|
* Execute the command line processing.
|
|
9
9
|
* @param options The options for the CLI.
|
|
10
|
-
* @param localesDirectory The
|
|
10
|
+
* @param localesDirectory The locales to load, each entry is either a path to a locales
|
|
11
|
+
* directory or the name of an installed package to take the locales from. Entries are
|
|
12
|
+
* merged in order, so later entries override earlier ones.
|
|
11
13
|
* @param argv The process arguments.
|
|
12
14
|
* @returns The exit code.
|
|
13
15
|
*/
|
|
14
|
-
execute(options: ICliOptions, localesDirectory: string, argv: string[]): Promise<number>;
|
|
16
|
+
execute(options: ICliOptions, localesDirectory: string | string[], argv: string[]): Promise<number>;
|
|
15
17
|
/**
|
|
16
18
|
* Configure any options or actions at the root program level.
|
|
17
19
|
* @param program The root program command.
|
|
@@ -16,6 +16,13 @@ export declare class CLIDisplay {
|
|
|
16
16
|
* The default output method for clearing the current line.
|
|
17
17
|
*/
|
|
18
18
|
static clearLine: () => void;
|
|
19
|
+
/**
|
|
20
|
+
* Enable or disable colourised output. When disabled the display methods emit
|
|
21
|
+
* plain text with no ANSI escape sequences, otherwise the colour support
|
|
22
|
+
* detected from the environment is used.
|
|
23
|
+
* @param enabled Whether to colourise the output.
|
|
24
|
+
*/
|
|
25
|
+
static setColorEnabled(enabled: boolean): void;
|
|
19
26
|
/**
|
|
20
27
|
* Display the header for the CLI.
|
|
21
28
|
* @param title The title of the CLI.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
/**
|
|
3
3
|
* Initialize the global options.
|
|
4
|
-
* @param localesDirectory The path to load the locales from.
|
|
4
|
+
* @param localesDirectory The path, or paths, to load the locales from.
|
|
5
5
|
*/
|
|
6
|
-
export declare function initGlobalOptions(localesDirectory: string): void;
|
|
6
|
+
export declare function initGlobalOptions(localesDirectory: string | string[]): void;
|
|
7
7
|
/**
|
|
8
8
|
* Add the global options.
|
|
9
9
|
* @param program The program to add the options to.
|
|
@@ -34,4 +34,10 @@ export interface ICliOptions {
|
|
|
34
34
|
* Show a warning that this is a dev tool and not for production use.
|
|
35
35
|
*/
|
|
36
36
|
showDevToolWarning?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Disable colourised output, so that all output is plain text with no ANSI
|
|
39
|
+
* escape sequences, defaults to false which uses the colour support detected
|
|
40
|
+
* from the environment.
|
|
41
|
+
*/
|
|
42
|
+
noColor?: boolean;
|
|
37
43
|
}
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,73 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.10.1-next.8](https://github.com/iotaledger/twin-framework/compare/cli-core-v0.10.1-next.7...cli-core-v0.10.1-next.8) (2026-09-21)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* dev tools ([#500](https://github.com/iotaledger/twin-framework/issues/500)) ([0879e55](https://github.com/iotaledger/twin-framework/commit/0879e558c71dca5e992d14914c6bde560a191df2))
|
|
9
|
+
* improve error formatting ([#313](https://github.com/iotaledger/twin-framework/issues/313)) ([5a19623](https://github.com/iotaledger/twin-framework/commit/5a196231bcbf088bf9ba92a93b7478d3b8c5593f))
|
|
10
|
+
* improve node_modules location detection ([#486](https://github.com/iotaledger/twin-framework/issues/486)) ([c786853](https://github.com/iotaledger/twin-framework/commit/c7868538e9074f789577c0ab55552f3bcec0ef0e))
|
|
11
|
+
* improve signatures ([bcc21ae](https://github.com/iotaledger/twin-framework/commit/bcc21aed3e10a264ef5c8515bde8dcac8a05c719))
|
|
12
|
+
* improve signatures ([cdd24be](https://github.com/iotaledger/twin-framework/commit/cdd24be6fb898d33955b6f2f93c3ddbd73582269))
|
|
13
|
+
* linting and dependency update ([676b4e9](https://github.com/iotaledger/twin-framework/commit/676b4e9d9bce158065200bbf875bb31da81d166d))
|
|
14
|
+
* timeout return type ([4b40b23](https://github.com/iotaledger/twin-framework/commit/4b40b23a7e6b073c7e96cbccc1d41ba7caed2556))
|
|
15
|
+
* typescript 6 update ([1d10f31](https://github.com/iotaledger/twin-framework/commit/1d10f31e6516ec622773f45e88af82fe749b384a))
|
|
16
|
+
* update dependencies ([4da77ab](https://github.com/iotaledger/twin-framework/commit/4da77ab30f499e52825ac5a76f51436ceb59c26e))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
* ensure __decorate is defined for decorators ([103a563](https://github.com/iotaledger/twin-framework/commit/103a563ce01ebdef6240d2e590e7b026e8692684))
|
|
22
|
+
* export the json locales for cli-core ([188b47d](https://github.com/iotaledger/twin-framework/commit/188b47d3339deb42d08c32715909337749fb0e4a))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Dependencies
|
|
26
|
+
|
|
27
|
+
* The following workspace dependencies were updated
|
|
28
|
+
* dependencies
|
|
29
|
+
* @twin.org/core bumped from 0.10.1-next.7 to 0.10.1-next.8
|
|
30
|
+
* @twin.org/nameof bumped from 0.10.1-next.7 to 0.10.1-next.8
|
|
31
|
+
* devDependencies
|
|
32
|
+
* @twin.org/nameof-transformer bumped from 0.10.1-next.7 to 0.10.1-next.8
|
|
33
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.10.1-next.7 to 0.10.1-next.8
|
|
34
|
+
|
|
35
|
+
## [0.10.1-next.7](https://github.com/iotaledger/twin-framework/compare/cli-core-v0.10.1-next.6...cli-core-v0.10.1-next.7) (2026-09-21)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### Features
|
|
39
|
+
|
|
40
|
+
* dev tools ([#500](https://github.com/iotaledger/twin-framework/issues/500)) ([0879e55](https://github.com/iotaledger/twin-framework/commit/0879e558c71dca5e992d14914c6bde560a191df2))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
### Dependencies
|
|
44
|
+
|
|
45
|
+
* The following workspace dependencies were updated
|
|
46
|
+
* dependencies
|
|
47
|
+
* @twin.org/core bumped from 0.10.1-next.6 to 0.10.1-next.7
|
|
48
|
+
* @twin.org/nameof bumped from 0.10.1-next.6 to 0.10.1-next.7
|
|
49
|
+
* devDependencies
|
|
50
|
+
* @twin.org/nameof-transformer bumped from 0.10.1-next.6 to 0.10.1-next.7
|
|
51
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.10.1-next.6 to 0.10.1-next.7
|
|
52
|
+
|
|
53
|
+
## [0.10.1-next.6](https://github.com/iotaledger/twin-framework/compare/cli-core-v0.10.1-next.5...cli-core-v0.10.1-next.6) (2026-09-21)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
### Miscellaneous Chores
|
|
57
|
+
|
|
58
|
+
* **cli-core:** Synchronize repo versions
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
### Dependencies
|
|
62
|
+
|
|
63
|
+
* The following workspace dependencies were updated
|
|
64
|
+
* dependencies
|
|
65
|
+
* @twin.org/core bumped from 0.10.1-next.5 to 0.10.1-next.6
|
|
66
|
+
* @twin.org/nameof bumped from 0.10.1-next.5 to 0.10.1-next.6
|
|
67
|
+
* devDependencies
|
|
68
|
+
* @twin.org/nameof-transformer bumped from 0.10.1-next.5 to 0.10.1-next.6
|
|
69
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.10.1-next.5 to 0.10.1-next.6
|
|
70
|
+
|
|
3
71
|
## [0.10.1-next.5](https://github.com/iotaledger/twin-framework/compare/cli-core-v0.10.1-next.4...cli-core-v0.10.1-next.5) (2026-09-18)
|
|
4
72
|
|
|
5
73
|
|
|
@@ -30,9 +30,11 @@ The options for the CLI.
|
|
|
30
30
|
|
|
31
31
|
##### localesDirectory
|
|
32
32
|
|
|
33
|
-
`string`
|
|
33
|
+
`string` \| `string`[]
|
|
34
34
|
|
|
35
|
-
The
|
|
35
|
+
The locales to load, each entry is either a path to a locales
|
|
36
|
+
directory or the name of an installed package to take the locales from. Entries are
|
|
37
|
+
merged in order, so later entries override earlier ones.
|
|
36
38
|
|
|
37
39
|
##### argv
|
|
38
40
|
|
|
@@ -66,6 +66,28 @@ The default output method for clearing the current line.
|
|
|
66
66
|
|
|
67
67
|
## Methods
|
|
68
68
|
|
|
69
|
+
### setColorEnabled() {#setcolorenabled}
|
|
70
|
+
|
|
71
|
+
> `static` **setColorEnabled**(`enabled`): `void`
|
|
72
|
+
|
|
73
|
+
Enable or disable colourised output. When disabled the display methods emit
|
|
74
|
+
plain text with no ANSI escape sequences, otherwise the colour support
|
|
75
|
+
detected from the environment is used.
|
|
76
|
+
|
|
77
|
+
#### Parameters
|
|
78
|
+
|
|
79
|
+
##### enabled
|
|
80
|
+
|
|
81
|
+
`boolean`
|
|
82
|
+
|
|
83
|
+
Whether to colourise the output.
|
|
84
|
+
|
|
85
|
+
#### Returns
|
|
86
|
+
|
|
87
|
+
`void`
|
|
88
|
+
|
|
89
|
+
***
|
|
90
|
+
|
|
69
91
|
### header() {#header}
|
|
70
92
|
|
|
71
93
|
> `static` **header**(`title`, `version`, `icon`): `void`
|
|
@@ -65,3 +65,13 @@ Override the default output width.
|
|
|
65
65
|
> `optional` **showDevToolWarning?**: `boolean`
|
|
66
66
|
|
|
67
67
|
Show a warning that this is a dev tool and not for production use.
|
|
68
|
+
|
|
69
|
+
***
|
|
70
|
+
|
|
71
|
+
### noColor? {#nocolor}
|
|
72
|
+
|
|
73
|
+
> `optional` **noColor?**: `boolean`
|
|
74
|
+
|
|
75
|
+
Disable colourised output, so that all output is plain text with no ANSI
|
|
76
|
+
escape sequences, defaults to false which uses the colour support detected
|
|
77
|
+
from the environment.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/cli-core",
|
|
3
|
-
"version": "0.10.1-next.
|
|
3
|
+
"version": "0.10.1-next.8",
|
|
4
4
|
"description": "Core classes for building a CLI",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
"node": ">=24.0.0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@twin.org/core": "0.10.1-next.
|
|
18
|
-
"@twin.org/nameof": "0.10.1-next.
|
|
19
|
-
"chalk": "
|
|
17
|
+
"@twin.org/core": "0.10.1-next.8",
|
|
18
|
+
"@twin.org/nameof": "0.10.1-next.8",
|
|
19
|
+
"chalk": "6.0.0",
|
|
20
20
|
"commander": "15.0.0",
|
|
21
|
-
"dotenv": "
|
|
21
|
+
"dotenv": "18.0.1"
|
|
22
22
|
},
|
|
23
23
|
"main": "./dist/es/index.js",
|
|
24
24
|
"types": "./dist/types/index.d.ts",
|