@oclif/core 3.11.0 → 3.11.1-dev.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.
@@ -37,4 +37,5 @@ export { Config, config } from './config';
37
37
  export { ExitError } from './exit';
38
38
  export { IPromptOptions } from './prompt';
39
39
  export { Table } from './styled';
40
+ export { colorize } from './theme';
40
41
  export { default as write } from './write';
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.write = exports.Table = exports.ExitError = exports.config = exports.Config = exports.ActionBase = exports.warn = exports.wait = exports.url = exports.tree = exports.trace = exports.table = exports.styledObject = exports.styledJSON = exports.styledHeader = exports.prompt = exports.progress = exports.logToStderr = exports.log = exports.info = exports.flush = exports.exit = exports.error = exports.done = exports.debug = exports.confirm = exports.anykey = exports.annotation = exports.action = exports.ux = void 0;
29
+ exports.write = exports.colorize = exports.Table = exports.ExitError = exports.config = exports.Config = exports.ActionBase = exports.warn = exports.wait = exports.url = exports.tree = exports.trace = exports.table = exports.styledObject = exports.styledJSON = exports.styledHeader = exports.prompt = exports.progress = exports.logToStderr = exports.log = exports.info = exports.flush = exports.exit = exports.error = exports.done = exports.debug = exports.confirm = exports.anykey = exports.annotation = exports.action = exports.ux = void 0;
30
30
  const chalk_1 = __importDefault(require("chalk"));
31
31
  const node_util_1 = require("node:util");
32
32
  const Errors = __importStar(require("../errors"));
@@ -177,5 +177,7 @@ var exit_1 = require("./exit");
177
177
  Object.defineProperty(exports, "ExitError", { enumerable: true, get: function () { return exit_1.ExitError; } });
178
178
  var styled_1 = require("./styled");
179
179
  Object.defineProperty(exports, "Table", { enumerable: true, get: function () { return styled_1.Table; } });
180
+ var theme_1 = require("./theme");
181
+ Object.defineProperty(exports, "colorize", { enumerable: true, get: function () { return theme_1.colorize; } });
180
182
  var write_2 = require("./write");
181
183
  Object.defineProperty(exports, "write", { enumerable: true, get: function () { return __importDefault(write_2).default; } });
@@ -0,0 +1,11 @@
1
+ import { StandardChalk, Theme, Themes } from '../interfaces/theme';
2
+ /**
3
+ * Add color to text.
4
+ * @param color color to use. Can be hex code (e.g. `#ff0000`), rgb (e.g. `rgb(255, 255, 255)`) or a chalk color (e.g. `red`)
5
+ * @param text string to colorize
6
+ * @returns colorized string
7
+ */
8
+ export declare function colorize(color: string | StandardChalk | undefined, text: string): string;
9
+ export declare function parseTheme(theme: Themes): Theme;
10
+ export declare function getColor(color: string): string;
11
+ export declare function getColor(color: StandardChalk): StandardChalk;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.getColor = exports.parseTheme = exports.colorize = void 0;
30
+ const chalk_1 = __importDefault(require("chalk"));
31
+ const Color = __importStar(require("color"));
32
+ const theme_1 = require("../interfaces/theme");
33
+ function isStandardChalk(color) {
34
+ return theme_1.STANDARD_CHALK.includes(color);
35
+ }
36
+ /**
37
+ * Add color to text.
38
+ * @param color color to use. Can be hex code (e.g. `#ff0000`), rgb (e.g. `rgb(255, 255, 255)`) or a chalk color (e.g. `red`)
39
+ * @param text string to colorize
40
+ * @returns colorized string
41
+ */
42
+ function colorize(color, text) {
43
+ if (isStandardChalk(color))
44
+ return chalk_1.default[color](text);
45
+ return color ? chalk_1.default.hex(color)(text) : text;
46
+ }
47
+ exports.colorize = colorize;
48
+ function parseTheme(theme) {
49
+ const themes = theme.themes ?? {};
50
+ const selected = theme.selected ? themes[theme.selected] ?? {} : {};
51
+ return Object.fromEntries(Object.entries(selected)
52
+ .map(([key, value]) => [key, getColor(value)])
53
+ .filter(([_, value]) => value));
54
+ }
55
+ exports.parseTheme = parseTheme;
56
+ function getColor(color) {
57
+ try {
58
+ // eslint-disable-next-line new-cap
59
+ return isStandardChalk(color) ? color : new Color.default(color).hex();
60
+ }
61
+ catch { }
62
+ }
63
+ exports.getColor = getColor;
package/lib/command.js CHANGED
@@ -37,6 +37,7 @@ const util_1 = require("./help/util");
37
37
  const Parser = __importStar(require("./parser"));
38
38
  const aggregate_flags_1 = require("./util/aggregate-flags");
39
39
  const fs_1 = require("./util/fs");
40
+ const ids_1 = require("./util/ids");
40
41
  const util_2 = require("./util/util");
41
42
  const pjson = (0, fs_1.requireJson)(__dirname, '..', 'package.json');
42
43
  /**
@@ -260,12 +261,12 @@ class Command {
260
261
  warnIfCommandDeprecated() {
261
262
  const [id] = (0, util_1.normalizeArgv)(this.config);
262
263
  if (this.ctor.deprecateAliases && this.ctor.aliases.includes(id)) {
263
- const cmdName = (0, util_1.toConfiguredId)(this.ctor.id, this.config);
264
- const aliasName = (0, util_1.toConfiguredId)(id, this.config);
264
+ const cmdName = (0, ids_1.toConfiguredId)(this.ctor.id, this.config);
265
+ const aliasName = (0, ids_1.toConfiguredId)(id, this.config);
265
266
  this.warn((0, util_1.formatCommandDeprecationWarning)(aliasName, { to: cmdName }));
266
267
  }
267
268
  if (this.ctor.state === 'deprecated') {
268
- const cmdName = (0, util_1.toConfiguredId)(this.ctor.id, this.config);
269
+ const cmdName = (0, ids_1.toConfiguredId)(this.ctor.id, this.config);
269
270
  this.warn((0, util_1.formatCommandDeprecationWarning)(cmdName, this.ctor.deprecationOptions));
270
271
  }
271
272
  }
@@ -2,6 +2,7 @@ import { Command } from '../command';
2
2
  import { Hook, Hooks, PJSON, Topic } from '../interfaces';
3
3
  import { ArchTypes, Config as IConfig, LoadOptions, PlatformTypes, VersionDetails } from '../interfaces/config';
4
4
  import { Plugin as IPlugin, Options } from '../interfaces/plugin';
5
+ import { Theme, Themes } from '../interfaces/theme';
5
6
  export declare class Config implements IConfig {
6
7
  options: Options;
7
8
  arch: ArchTypes;
@@ -25,6 +26,7 @@ export declare class Config implements IConfig {
25
26
  plugins: Map<string, IPlugin>;
26
27
  root: string;
27
28
  shell: string;
29
+ theme?: Theme;
28
30
  topicSeparator: ' ' | ':';
29
31
  userAgent: string;
30
32
  userPJSON?: PJSON.User;
@@ -90,6 +92,11 @@ export declare class Config implements IConfig {
90
92
  loadPluginsAndCommands(opts?: {
91
93
  force: boolean;
92
94
  }): Promise<void>;
95
+ loadThemes(): Promise<{
96
+ file: string;
97
+ activeTheme: Theme | undefined;
98
+ themes: Themes | undefined;
99
+ }>;
93
100
  protected macosCacheDir(): string | undefined;
94
101
  runCommand<T = unknown>(id: string, argv?: string[], cachedCommand?: Command.Loadable | null): Promise<T>;
95
102
  runHook<T extends keyof Hooks>(event: T, opts: Hooks[T]['options'], timeout?: number, captureErrors?: boolean): Promise<Hook.Result<Hooks[T]['return']>>;
@@ -33,6 +33,7 @@ const node_os_1 = require("node:os");
33
33
  const node_path_1 = require("node:path");
34
34
  const node_url_1 = require("node:url");
35
35
  const cli_ux_1 = require("../cli-ux");
36
+ const theme_1 = require("../cli-ux/theme");
36
37
  const errors_1 = require("../errors");
37
38
  const util_1 = require("../help/util");
38
39
  const module_loader_1 = require("../module-loader");
@@ -105,6 +106,7 @@ class Config {
105
106
  plugins = new Map();
106
107
  root;
107
108
  shell;
109
+ theme;
108
110
  topicSeparator = ':';
109
111
  userAgent;
110
112
  userPJSON;
@@ -296,6 +298,10 @@ class Config {
296
298
  this.errlog = (0, node_path_1.join)(this.cacheDir, 'error.log');
297
299
  this.binPath = this.scopedEnvVar('BINPATH');
298
300
  this.npmRegistry = this.scopedEnvVar('NPM_REGISTRY') || this.pjson.oclif.npmRegistry;
301
+ if (!this.scopedEnvVarTrue('DISABLE_THEME')) {
302
+ const { activeTheme } = await this.loadThemes();
303
+ this.theme = activeTheme;
304
+ }
299
305
  this.pjson.oclif.update = this.pjson.oclif.update || {};
300
306
  this.pjson.oclif.update.node = this.pjson.oclif.update.node || {};
301
307
  const s3 = this.pjson.oclif.update.s3 || {};
@@ -351,6 +357,18 @@ class Config {
351
357
  this.warn(error);
352
358
  }
353
359
  }
360
+ async loadThemes() {
361
+ const themesFile = this.pjson.oclif.themesFile
362
+ ? (0, node_path_1.resolve)(this.root, this.pjson.oclif.themesFile)
363
+ : (0, node_path_1.resolve)(this.configDir, 'themes.json');
364
+ const themes = await (0, fs_1.safeReadJson)(themesFile);
365
+ const activeTheme = themes ? (0, theme_1.parseTheme)(themes) : undefined;
366
+ return {
367
+ activeTheme,
368
+ file: themesFile,
369
+ themes,
370
+ };
371
+ }
354
372
  macosCacheDir() {
355
373
  return (this.platform === 'darwin' && (0, node_path_1.join)(this.home, 'Library', 'Caches', this.dirname)) || undefined;
356
374
  }
@@ -537,7 +555,7 @@ class Config {
537
555
  .map((alias) => [alias.replaceAll('@', '').replaceAll(/[/-]/g, '_'), k].join('_').toUpperCase());
538
556
  }
539
557
  scopedEnvVarTrue(k) {
540
- const v = process.env[this.scopedEnvVarKeys(k).find((k) => process.env[k])];
558
+ const v = this.scopedEnvVar(k);
541
559
  return v === '1' || v === 'true';
542
560
  }
543
561
  warn(err, scope) {
@@ -6,7 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.CommandHelp = void 0;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
8
  const strip_ansi_1 = __importDefault(require("strip-ansi"));
9
+ const theme_1 = require("../cli-ux/theme");
9
10
  const ensure_arg_object_1 = require("../util/ensure-arg-object");
11
+ const ids_1 = require("../util/ids");
10
12
  const util_1 = require("../util/util");
11
13
  const docopts_1 = require("./docopts");
12
14
  const formatter_1 = require("./formatter");
@@ -14,11 +16,6 @@ const formatter_1 = require("./formatter");
14
16
  // written on any platform, that may use \r\n or \n, will be
15
17
  // split on any platform, not just the os specific EOL at runtime.
16
18
  const POSSIBLE_LINE_FEED = /\r\n|\n/;
17
- let { dim } = chalk_1.default;
18
- if (process.env.ConEmuANSI === 'ON') {
19
- // eslint-disable-next-line unicorn/consistent-destructuring
20
- dim = chalk_1.default.gray;
21
- }
22
19
  class CommandHelp extends formatter_1.HelpFormatter {
23
20
  command;
24
21
  config;
@@ -32,7 +29,13 @@ class CommandHelp extends formatter_1.HelpFormatter {
32
29
  aliases(aliases) {
33
30
  if (!aliases || aliases.length === 0)
34
31
  return;
35
- const body = aliases.map((a) => ['$', this.config.bin, a].join(' ')).join('\n');
32
+ const body = aliases
33
+ .map((a) => [
34
+ (0, theme_1.colorize)(this.config?.theme?.dollarSign, '$'),
35
+ (0, theme_1.colorize)(this.config?.theme?.bin, this.config.bin),
36
+ (0, theme_1.colorize)(this.config?.theme?.alias, a),
37
+ ].join(' '))
38
+ .join('\n');
36
39
  return body;
37
40
  }
38
41
  arg(arg) {
@@ -48,10 +51,13 @@ class CommandHelp extends formatter_1.HelpFormatter {
48
51
  const name = a.name.toUpperCase();
49
52
  let description = a.description || '';
50
53
  if (a.default)
51
- description = `[default: ${a.default}] ${description}`;
54
+ description = `${(0, theme_1.colorize)(this.config?.theme?.flagDefaultValue, `[default: ${a.default}]`)} ${description}`;
52
55
  if (a.options)
53
- description = `(${a.options.join('|')}) ${description}`;
54
- return [name, description ? dim(description) : undefined];
56
+ description = `${(0, theme_1.colorize)(this.config?.theme?.flagOptions, `(${a.options.join('|')})`)} ${description}`;
57
+ return [
58
+ (0, theme_1.colorize)(this.config?.theme?.flag, name),
59
+ description ? (0, theme_1.colorize)(this.config?.theme?.sectionDescription, description) : undefined,
60
+ ];
55
61
  });
56
62
  }
57
63
  defaultUsage() {
@@ -134,7 +140,7 @@ class CommandHelp extends formatter_1.HelpFormatter {
134
140
  labels.push(`--${flag.name.trim()}`);
135
141
  }
136
142
  }
137
- label = labels.join(flag.char ? ', ' : ' ');
143
+ label = labels.join((0, theme_1.colorize)(this.config?.theme?.flagSeparator, flag.char ? ', ' : ' '));
138
144
  }
139
145
  if (flag.type === 'option') {
140
146
  let value = flag.helpValue || (this.opts.showFlagNameInTitle ? flag.name : '<value>');
@@ -154,19 +160,19 @@ class CommandHelp extends formatter_1.HelpFormatter {
154
160
  return;
155
161
  const noChar = flags.reduce((previous, current) => previous && current.char === undefined, true);
156
162
  return flags.map((flag) => {
157
- let left = this.flagHelpLabel(flag);
163
+ let left = (0, theme_1.colorize)(this.config?.theme?.flag, this.flagHelpLabel(flag));
158
164
  if (noChar)
159
165
  left = left.replace(' ', '');
160
166
  let right = flag.summary || flag.description || '';
161
167
  if (flag.type === 'option' && flag.default) {
162
- right = `[default: ${flag.default}] ${right}`;
168
+ right = `${(0, theme_1.colorize)(this.config?.theme?.flagDefaultValue, `[default: ${flag.default}]`)} ${right}`;
163
169
  }
164
170
  if (flag.required)
165
- right = `(required) ${right}`;
171
+ right = `${(0, theme_1.colorize)(this.config?.theme?.flagRequired, '(required)')} ${right}`;
166
172
  if (flag.type === 'option' && flag.options && !flag.helpValue && !this.opts.showFlagOptionsInTitle) {
167
- right += `\n<options: ${flag.options.join('|')}>`;
173
+ right += (0, theme_1.colorize)(this.config?.theme?.flagOptions, `\n<options: ${flag.options.join('|')}>`);
168
174
  }
169
- return [left, dim(right.trim())];
175
+ return [left, (0, theme_1.colorize)(this.config?.theme?.sectionDescription, right.trim())];
170
176
  });
171
177
  }
172
178
  flagsDescriptions(flags) {
@@ -274,11 +280,16 @@ class CommandHelp extends formatter_1.HelpFormatter {
274
280
  ];
275
281
  }
276
282
  usage() {
277
- const { usage } = this.command;
283
+ const { id, usage } = this.command;
284
+ const standardId = (0, ids_1.toStandardizedId)(id, this.config);
278
285
  const body = (usage ? (0, util_1.castArray)(usage) : [this.defaultUsage()])
279
286
  .map((u) => {
280
287
  const allowedSpacing = this.opts.maxWidth - this.indentSpacing;
281
- const line = `$ ${this.config.bin} ${u}`.trim();
288
+ const dollarSign = (0, theme_1.colorize)(this.config?.theme?.dollarSign, '$');
289
+ const bin = (0, theme_1.colorize)(this.config?.theme?.bin, this.config.bin);
290
+ const command = (0, theme_1.colorize)(this.config?.theme?.command, '<%= command.id %>');
291
+ const commandDescription = (0, theme_1.colorize)(this.config?.theme?.sectionDescription, u.replace('<%= command.id %>', '').replace(standardId, '').trim());
292
+ const line = `${dollarSign} ${bin} ${command} ${commandDescription}`.trim();
282
293
  if (line.length > allowedSpacing) {
283
294
  const splitIndex = line.slice(0, Math.max(0, allowedSpacing)).lastIndexOf(' ');
284
295
  return (line.slice(0, Math.max(0, splitIndex)) +
@@ -292,14 +303,15 @@ class CommandHelp extends formatter_1.HelpFormatter {
292
303
  }
293
304
  formatIfCommand(example) {
294
305
  example = this.render(example);
306
+ const dollarSign = (0, theme_1.colorize)(this.config?.theme?.dollarSign, '$');
295
307
  if (example.startsWith(this.config.bin))
296
- return dim(`$ ${example}`);
308
+ return `${dollarSign} ${example}`;
297
309
  if (example.startsWith(`$ ${this.config.bin}`))
298
- return dim(example);
310
+ return `${dollarSign}${example.replace(`$`, '')}`;
299
311
  return example;
300
312
  }
301
313
  isCommand(example) {
302
- return (0, strip_ansi_1.default)(this.formatIfCommand(example)).startsWith(`$ ${this.config.bin}`);
314
+ return (0, strip_ansi_1.default)(this.formatIfCommand(example)).startsWith(`${(0, theme_1.colorize)(this.config?.theme?.dollarSign, '$')} ${this.config.bin}`);
303
315
  }
304
316
  }
305
317
  exports.CommandHelp = CommandHelp;
@@ -10,6 +10,7 @@ const string_width_1 = __importDefault(require("string-width"));
10
10
  const strip_ansi_1 = __importDefault(require("strip-ansi"));
11
11
  const widest_line_1 = __importDefault(require("widest-line"));
12
12
  const wrap_ansi_1 = __importDefault(require("wrap-ansi"));
13
+ const theme_1 = require("../cli-ux/theme");
13
14
  const screen_1 = require("../screen");
14
15
  const util_1 = require("./util");
15
16
  class HelpFormatter {
@@ -154,8 +155,8 @@ class HelpFormatter {
154
155
  .map(([left, right]) => [this.render(left), right && this.render(right)]);
155
156
  }
156
157
  const output = [
157
- chalk_1.default.bold(header),
158
- this.indent(Array.isArray(newBody) ? this.renderList(newBody, { indentation: 2, stripAnsi: this.opts.stripAnsi }) : newBody),
158
+ (0, theme_1.colorize)(this.config?.theme?.sectionHeader, chalk_1.default.bold(header)),
159
+ (0, theme_1.colorize)(this.config?.theme?.sectionDescription, this.indent(Array.isArray(newBody) ? this.renderList(newBody, { indentation: 2, stripAnsi: this.opts.stripAnsi }) : newBody)),
159
160
  ].join('\n');
160
161
  return this.opts.stripAnsi ? (0, strip_ansi_1.default)(output) : output;
161
162
  }
package/lib/help/index.js CHANGED
@@ -6,10 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.loadHelpClass = exports.Help = exports.HelpBase = exports.standardizeIDFromArgv = exports.normalizeArgv = exports.getHelpFlagAdditions = exports.CommandHelp = void 0;
7
7
  const node_util_1 = require("node:util");
8
8
  const strip_ansi_1 = __importDefault(require("strip-ansi"));
9
+ const theme_1 = require("../cli-ux/theme");
9
10
  const write_1 = __importDefault(require("../cli-ux/write"));
10
11
  const errors_1 = require("../errors");
11
12
  const module_loader_1 = require("../module-loader");
12
13
  const cache_default_value_1 = require("../util/cache-default-value");
14
+ const ids_1 = require("../util/ids");
13
15
  const util_1 = require("../util/util");
14
16
  const command_1 = require("./command");
15
17
  const formatter_1 = require("./formatter");
@@ -87,7 +89,11 @@ class Help extends HelpBase {
87
89
  .map((c) => {
88
90
  if (this.config.topicSeparator !== ':')
89
91
  c.id = c.id.replaceAll(':', this.config.topicSeparator);
90
- return [c.id, this.summary(c)];
92
+ const summary = this.summary(c);
93
+ return [
94
+ (0, theme_1.colorize)(this.config?.theme?.command, c.id),
95
+ summary && (0, theme_1.colorize)(this.config?.theme?.sectionDescription, (0, strip_ansi_1.default)(summary)),
96
+ ];
91
97
  }), {
92
98
  indentation: 2,
93
99
  spacer: '\n',
@@ -107,9 +113,10 @@ class Help extends HelpBase {
107
113
  if (this.config.topicSeparator !== ':')
108
114
  topicID = topicID.replaceAll(':', this.config.topicSeparator);
109
115
  let output = (0, util_1.compact)([
110
- summary,
111
- this.section(this.opts.usageHeader || 'USAGE', `$ ${this.config.bin} ${topicID}`),
112
- description && this.section('DESCRIPTION', this.wrap(description)),
116
+ (0, theme_1.colorize)(this.config?.theme?.commandSummary, summary),
117
+ this.section(this.opts.usageHeader || 'USAGE', `${(0, theme_1.colorize)(this.config?.theme?.dollarSign, '$')} ${(0, theme_1.colorize)(this.config?.theme?.bin, this.config.bin)} ${topicID}`),
118
+ description &&
119
+ this.section('DESCRIPTION', this.wrap((0, theme_1.colorize)(this.config?.theme?.sectionDescription, description))),
113
120
  ]).join('\n\n');
114
121
  if (this.opts.stripAnsi)
115
122
  output = (0, strip_ansi_1.default)(output);
@@ -121,7 +128,10 @@ class Help extends HelpBase {
121
128
  const body = this.renderList(topics.map((c) => {
122
129
  if (this.config.topicSeparator !== ':')
123
130
  c.name = c.name.replaceAll(':', this.config.topicSeparator);
124
- return [c.name, c.description && this.render(c.description.split('\n')[0])];
131
+ return [
132
+ (0, theme_1.colorize)(this.config?.theme?.topic, c.name),
133
+ c.description && this.render((0, theme_1.colorize)(this.config?.theme?.sectionDescription, c.description.split('\n')[0])),
134
+ ];
125
135
  }), {
126
136
  indentation: 2,
127
137
  spacer: '\n',
@@ -144,13 +154,13 @@ class Help extends HelpBase {
144
154
  const state = this.config.pjson?.oclif?.state || plugin?.pjson?.oclif?.state || command.state;
145
155
  if (state) {
146
156
  this.log(state === 'deprecated'
147
- ? `${(0, util_2.formatCommandDeprecationWarning)((0, util_2.toConfiguredId)(name, this.config), command.deprecationOptions)}\n`
157
+ ? `${(0, util_2.formatCommandDeprecationWarning)((0, ids_1.toConfiguredId)(name, this.config), command.deprecationOptions)}\n`
148
158
  : `This command is in ${state}.\n`);
149
159
  }
150
160
  if (command.deprecateAliases && command.aliases.includes(name)) {
151
161
  const actualCmd = this.config.commands.find((c) => c.aliases.includes(name));
152
162
  const opts = { ...command.deprecationOptions, ...(actualCmd ? { to: actualCmd.id } : {}) };
153
- this.log(`${(0, util_2.formatCommandDeprecationWarning)((0, util_2.toConfiguredId)(name, this.config), opts)}\n`);
163
+ this.log(`${(0, util_2.formatCommandDeprecationWarning)((0, ids_1.toConfiguredId)(name, this.config), opts)}\n`);
154
164
  }
155
165
  const summary = this.summary(command);
156
166
  if (summary) {
@@ -274,8 +284,8 @@ class Help extends HelpBase {
274
284
  }
275
285
  summary(c) {
276
286
  if (c.summary)
277
- return this.render(c.summary.split('\n')[0]);
278
- return c.description && this.render(c.description).split('\n')[0];
287
+ return (0, theme_1.colorize)(this.config?.theme?.commandSummary, this.render(c.summary.split('\n')[0]));
288
+ return c.description && (0, theme_1.colorize)(this.config?.theme?.commandSummary, this.render(c.description).split('\n')[0]);
279
289
  }
280
290
  /*
281
291
  * _topics is to work around Interfaces.topics mistakenly including commands that do
package/lib/help/root.js CHANGED
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const strip_ansi_1 = __importDefault(require("strip-ansi"));
7
+ const theme_1 = require("../cli-ux/theme");
7
8
  const util_1 = require("../util/util");
8
9
  const formatter_1 = require("./formatter");
9
10
  class RootHelp extends formatter_1.HelpFormatter {
@@ -20,22 +21,27 @@ class RootHelp extends formatter_1.HelpFormatter {
20
21
  description = description.split('\n').slice(1).join('\n');
21
22
  if (!description)
22
23
  return;
23
- return this.section('DESCRIPTION', this.wrap(description));
24
+ return this.section('DESCRIPTION', this.wrap((0, theme_1.colorize)(this.config?.theme?.sectionDescription, description)));
24
25
  }
25
26
  root() {
26
27
  let description = this.config.pjson.oclif.description || this.config.pjson.description || '';
27
28
  description = this.render(description);
28
29
  description = description.split('\n')[0];
29
- let output = (0, util_1.compact)([description, this.version(), this.usage(), this.description()]).join('\n\n');
30
+ let output = (0, util_1.compact)([
31
+ (0, theme_1.colorize)(this.config?.theme?.commandSummary, description),
32
+ this.version(),
33
+ this.usage(),
34
+ this.description(),
35
+ ]).join('\n\n');
30
36
  if (this.opts.stripAnsi)
31
37
  output = (0, strip_ansi_1.default)(output);
32
38
  return output;
33
39
  }
34
40
  usage() {
35
- return this.section(this.opts.usageHeader || 'USAGE', this.wrap(`$ ${this.config.bin} [COMMAND]`));
41
+ return this.section(this.opts.usageHeader || 'USAGE', this.wrap(`${(0, theme_1.colorize)(this.config?.theme?.dollarSign, '$')} ${(0, theme_1.colorize)(this.config?.theme?.bin, this.config.bin)} ${(0, theme_1.colorize)(this.config?.theme?.sectionDescription, '[COMMAND]')}`));
36
42
  }
37
43
  version() {
38
- return this.section('VERSION', this.wrap(this.config.userAgent));
44
+ return this.section('VERSION', this.wrap((0, theme_1.colorize)(this.config?.theme?.version, this.config.userAgent)));
39
45
  }
40
46
  }
41
47
  exports.default = RootHelp;
@@ -1,7 +1,5 @@
1
1
  import { Deprecation, Config as IConfig } from '../interfaces';
2
2
  export declare function template(context: any): (t: string) => string;
3
- export declare function toStandardizedId(commandID: string, config: IConfig): string;
4
- export declare function toConfiguredId(commandID: string, config: IConfig): string;
5
3
  export declare function standardizeIDFromArgv(argv: string[], config: IConfig): string[];
6
4
  export declare function getHelpFlagAdditions(config: IConfig): string[];
7
5
  export declare function formatFlagDeprecationWarning(flag: string, opts: Deprecation | true): string;
package/lib/help/util.js CHANGED
@@ -23,9 +23,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.normalizeArgv = exports.formatCommandDeprecationWarning = exports.formatFlagDeprecationWarning = exports.getHelpFlagAdditions = exports.standardizeIDFromArgv = exports.toConfiguredId = exports.toStandardizedId = exports.template = void 0;
26
+ exports.normalizeArgv = exports.formatCommandDeprecationWarning = exports.formatFlagDeprecationWarning = exports.getHelpFlagAdditions = exports.standardizeIDFromArgv = exports.template = void 0;
27
27
  const ejs = __importStar(require("ejs"));
28
28
  const util_1 = require("../config/util");
29
+ const ids_1 = require("../util/ids");
29
30
  function template(context) {
30
31
  function render(t) {
31
32
  return ejs.render(t, context);
@@ -69,22 +70,13 @@ function collateSpacedCmdIDFromArgs(argv, config) {
69
70
  }
70
71
  return argv; // ID is argv[0]
71
72
  }
72
- function toStandardizedId(commandID, config) {
73
- return commandID.replaceAll(new RegExp(config.topicSeparator, 'g'), ':');
74
- }
75
- exports.toStandardizedId = toStandardizedId;
76
- function toConfiguredId(commandID, config) {
77
- const defaultTopicSeparator = ':';
78
- return commandID.replaceAll(new RegExp(defaultTopicSeparator, 'g'), config.topicSeparator || defaultTopicSeparator);
79
- }
80
- exports.toConfiguredId = toConfiguredId;
81
73
  function standardizeIDFromArgv(argv, config) {
82
74
  if (argv.length === 0)
83
75
  return argv;
84
76
  if (config.topicSeparator === ' ')
85
77
  argv = collateSpacedCmdIDFromArgs(argv, config);
86
78
  else if (config.topicSeparator !== ':')
87
- argv[0] = toStandardizedId(argv[0], config);
79
+ argv[0] = (0, ids_1.toStandardizedId)(argv[0], config);
88
80
  return argv;
89
81
  }
90
82
  exports.standardizeIDFromArgv = standardizeIDFromArgv;
package/lib/index.d.ts CHANGED
@@ -10,7 +10,6 @@ export { execute } from './execute';
10
10
  export * as Flags from './flags';
11
11
  export { CommandHelp, Help, HelpBase, loadHelpClass } from './help';
12
12
  export { HelpSection, HelpSectionKeyValueTable, HelpSectionRenderer } from './help/formatter';
13
- export { toConfiguredId, toStandardizedId } from './help/util';
14
13
  export * as Interfaces from './interfaces';
15
14
  export { Hook } from './interfaces/hooks';
16
15
  export { run } from './main';
@@ -18,3 +17,4 @@ export * as ModuleLoader from './module-loader';
18
17
  export * as Parser from './parser';
19
18
  export { Performance } from './performance';
20
19
  export { Settings, settings } from './settings';
20
+ export { toConfiguredId, toStandardizedId } from './util/ids';
package/lib/index.js CHANGED
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.settings = exports.Performance = exports.Parser = exports.ModuleLoader = exports.run = exports.Interfaces = exports.toStandardizedId = exports.toConfiguredId = exports.loadHelpClass = exports.HelpBase = exports.Help = exports.CommandHelp = exports.Flags = exports.execute = exports.handle = exports.Errors = exports.Plugin = exports.Config = exports.Command = exports.stdout = exports.stderr = exports.flush = exports.ux = exports.Args = void 0;
29
+ exports.toStandardizedId = exports.toConfiguredId = exports.settings = exports.Performance = exports.Parser = exports.ModuleLoader = exports.run = exports.Interfaces = exports.loadHelpClass = exports.HelpBase = exports.Help = exports.CommandHelp = exports.Flags = exports.execute = exports.handle = exports.Errors = exports.Plugin = exports.Config = exports.Command = exports.stdout = exports.stderr = exports.flush = exports.ux = exports.Args = void 0;
30
30
  const write_1 = __importDefault(require("./cli-ux/write"));
31
31
  function checkCWD() {
32
32
  try {
@@ -43,8 +43,7 @@ exports.Args = __importStar(require("./args"));
43
43
  exports.ux = __importStar(require("./cli-ux"));
44
44
  var flush_1 = require("./cli-ux/flush");
45
45
  Object.defineProperty(exports, "flush", { enumerable: true, get: function () { return flush_1.flush; } });
46
- // Remove these in the next major version
47
- var stream_1 = require("./cli-ux/stream");
46
+ var stream_1 = require("./cli-ux/stream"); // Remove these in the next major version
48
47
  Object.defineProperty(exports, "stderr", { enumerable: true, get: function () { return stream_1.stderr; } });
49
48
  Object.defineProperty(exports, "stdout", { enumerable: true, get: function () { return stream_1.stdout; } });
50
49
  var command_1 = require("./command");
@@ -63,9 +62,6 @@ Object.defineProperty(exports, "CommandHelp", { enumerable: true, get: function
63
62
  Object.defineProperty(exports, "Help", { enumerable: true, get: function () { return help_1.Help; } });
64
63
  Object.defineProperty(exports, "HelpBase", { enumerable: true, get: function () { return help_1.HelpBase; } });
65
64
  Object.defineProperty(exports, "loadHelpClass", { enumerable: true, get: function () { return help_1.loadHelpClass; } });
66
- var util_1 = require("./help/util");
67
- Object.defineProperty(exports, "toConfiguredId", { enumerable: true, get: function () { return util_1.toConfiguredId; } });
68
- Object.defineProperty(exports, "toStandardizedId", { enumerable: true, get: function () { return util_1.toStandardizedId; } });
69
65
  exports.Interfaces = __importStar(require("./interfaces"));
70
66
  var main_1 = require("./main");
71
67
  Object.defineProperty(exports, "run", { enumerable: true, get: function () { return main_1.run; } });
@@ -75,3 +71,6 @@ var performance_1 = require("./performance");
75
71
  Object.defineProperty(exports, "Performance", { enumerable: true, get: function () { return performance_1.Performance; } });
76
72
  var settings_1 = require("./settings");
77
73
  Object.defineProperty(exports, "settings", { enumerable: true, get: function () { return settings_1.settings; } });
74
+ var ids_1 = require("./util/ids");
75
+ Object.defineProperty(exports, "toConfiguredId", { enumerable: true, get: function () { return ids_1.toConfiguredId; } });
76
+ Object.defineProperty(exports, "toStandardizedId", { enumerable: true, get: function () { return ids_1.toStandardizedId; } });
@@ -3,6 +3,7 @@ import { Command } from '../command';
3
3
  import { Hook, Hooks } from './hooks';
4
4
  import { PJSON } from './pjson';
5
5
  import { Options, Plugin } from './plugin';
6
+ import { Theme } from './theme';
6
7
  import { Topic } from './topic';
7
8
  export type LoadOptions = Config | Options | string | undefined;
8
9
  export type PlatformTypes = 'wsl' | NodeJS.Platform;
@@ -121,6 +122,7 @@ export interface Config {
121
122
  * active shell
122
123
  */
123
124
  readonly shell: string;
125
+ readonly theme?: Theme;
124
126
  topicSeparator: ' ' | ':';
125
127
  readonly topics: Topic[];
126
128
  /**
@@ -10,5 +10,6 @@ export type { Arg, BooleanFlag, CustomOptions, Deprecation, Flag, FlagDefinition
10
10
  export type { PJSON } from './pjson';
11
11
  export type { Options, Plugin, PluginOptions } from './plugin';
12
12
  export type { S3Manifest } from './s3-manifest';
13
+ export type { Theme, Themes } from './theme';
13
14
  export type { Topic } from './topic';
14
15
  export type { TSConfig } from './ts-config';
@@ -49,6 +49,7 @@ export declare namespace PJSON {
49
49
  repositoryPrefix?: string;
50
50
  schema?: number;
51
51
  state?: 'beta' | 'deprecated' | string;
52
+ themesFile?: string;
52
53
  topicSeparator?: ' ' | ':';
53
54
  topics?: {
54
55
  [k: string]: {
@@ -0,0 +1,26 @@
1
+ export declare const STANDARD_CHALK: readonly ["white", "black", "blue", "yellow", "green", "red", "magenta", "cyan", "gray", "blackBright", "redBright", "greenBright", "yellowBright", "blueBright", "magentaBright", "cyanBright", "whiteBright", "bgBlack", "bgRed", "bgGreen", "bgYellow", "bgBlue", "bgMagenta", "bgCyan", "bgWhite", "bgGray", "bgBlackBright", "bgRedBright", "bgGreenBright", "bgYellowBright", "bgBlueBright", "bgMagentaBright", "bgCyanBright", "bgWhiteBright", "bold", "underline", "dim", "italic", "strikethrough"];
2
+ export type StandardChalk = (typeof STANDARD_CHALK)[number];
3
+ export declare const THEME_KEYS: readonly ["alias", "bin", "command", "commandSummary", "dollarSign", "flag", "flagDefaultValue", "flagOptions", "flagRequired", "flagSeparator", "flagType", "sectionDescription", "sectionHeader", "topic", "version"];
4
+ export type ThemeKey = (typeof THEME_KEYS)[number];
5
+ export type Theme = {
6
+ [key: string | ThemeKey]: string | StandardChalk | undefined;
7
+ alias?: string | StandardChalk;
8
+ bin?: string | StandardChalk;
9
+ command?: string | StandardChalk;
10
+ commandSummary?: string | StandardChalk;
11
+ dollarSign?: string | StandardChalk;
12
+ flag?: string | StandardChalk;
13
+ flagDefaultValue?: string | StandardChalk;
14
+ flagOptions?: string | StandardChalk;
15
+ flagRequired?: string | StandardChalk;
16
+ flagSeparator?: string | StandardChalk;
17
+ flagType?: string | StandardChalk;
18
+ sectionDescription?: string | StandardChalk;
19
+ sectionHeader?: string | StandardChalk;
20
+ topic?: string | StandardChalk;
21
+ version?: string | StandardChalk;
22
+ };
23
+ export type Themes = {
24
+ selected?: string;
25
+ themes?: Record<string, Record<string, string>>;
26
+ };
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.THEME_KEYS = exports.STANDARD_CHALK = void 0;
4
+ // chalk doesn't export a list of standard colors, so we have to supply our own
5
+ exports.STANDARD_CHALK = [
6
+ 'white',
7
+ 'black',
8
+ 'blue',
9
+ 'yellow',
10
+ 'green',
11
+ 'red',
12
+ 'magenta',
13
+ 'cyan',
14
+ 'gray',
15
+ 'blackBright',
16
+ 'redBright',
17
+ 'greenBright',
18
+ 'yellowBright',
19
+ 'blueBright',
20
+ 'magentaBright',
21
+ 'cyanBright',
22
+ 'whiteBright',
23
+ 'bgBlack',
24
+ 'bgRed',
25
+ 'bgGreen',
26
+ 'bgYellow',
27
+ 'bgBlue',
28
+ 'bgMagenta',
29
+ 'bgCyan',
30
+ 'bgWhite',
31
+ 'bgGray',
32
+ 'bgBlackBright',
33
+ 'bgRedBright',
34
+ 'bgGreenBright',
35
+ 'bgYellowBright',
36
+ 'bgBlueBright',
37
+ 'bgMagentaBright',
38
+ 'bgCyanBright',
39
+ 'bgWhiteBright',
40
+ 'bold',
41
+ 'underline',
42
+ 'dim',
43
+ 'italic',
44
+ 'strikethrough',
45
+ ];
46
+ exports.THEME_KEYS = [
47
+ 'alias',
48
+ 'bin',
49
+ 'command',
50
+ 'commandSummary',
51
+ 'dollarSign',
52
+ 'flag',
53
+ 'flagDefaultValue',
54
+ 'flagOptions',
55
+ 'flagRequired',
56
+ 'flagSeparator',
57
+ 'flagType',
58
+ 'sectionDescription',
59
+ 'sectionHeader',
60
+ 'topic',
61
+ 'version',
62
+ ];
@@ -0,0 +1,3 @@
1
+ import { Config } from '../interfaces';
2
+ export declare function toStandardizedId(commandID: string, config: Config): string;
3
+ export declare function toConfiguredId(commandID: string, config: Config): string;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toConfiguredId = exports.toStandardizedId = void 0;
4
+ function toStandardizedId(commandID, config) {
5
+ return commandID.replaceAll(new RegExp(config.topicSeparator, 'g'), ':');
6
+ }
7
+ exports.toStandardizedId = toStandardizedId;
8
+ function toConfiguredId(commandID, config) {
9
+ const defaultTopicSeparator = ':';
10
+ return commandID.replaceAll(new RegExp(defaultTopicSeparator, 'g'), config.topicSeparator || defaultTopicSeparator);
11
+ }
12
+ exports.toConfiguredId = toConfiguredId;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oclif/core",
3
3
  "description": "base library for oclif CLIs",
4
- "version": "3.11.0",
4
+ "version": "3.11.1-dev.1",
5
5
  "author": "Salesforce",
6
6
  "bugs": "https://github.com/oclif/core/issues",
7
7
  "dependencies": {
@@ -11,6 +11,7 @@
11
11
  "chalk": "^4.1.2",
12
12
  "clean-stack": "^3.0.1",
13
13
  "cli-progress": "^3.12.0",
14
+ "color": "^4.2.3",
14
15
  "debug": "^4.3.4",
15
16
  "ejs": "^3.1.9",
16
17
  "get-package-type": "^0.1.0",
@@ -44,7 +45,8 @@
44
45
  "@types/chai-as-promised": "^7.1.8",
45
46
  "@types/clean-stack": "^2.1.1",
46
47
  "@types/cli-progress": "^3.11.0",
47
- "@types/debug": "^4.1.12",
48
+ "@types/color": "^3.0.5",
49
+ "@types/debug": "^4.1.10",
48
50
  "@types/ejs": "^3.1.3",
49
51
  "@types/indent-string": "^4.0.1",
50
52
  "@types/js-yaml": "^3.12.7",
@@ -107,6 +109,7 @@
107
109
  "access": "public"
108
110
  },
109
111
  "scripts": {
112
+ "build:dev": "shx rm -rf lib && tsc --sourceMap",
110
113
  "build": "shx rm -rf lib && tsc",
111
114
  "commitlint": "commitlint",
112
115
  "compile": "tsc",
@@ -117,9 +120,11 @@
117
120
  "prepare": "husky install",
118
121
  "pretest": "yarn build && tsc -p test --noEmit --skipLibCheck",
119
122
  "test:circular-deps": "madge lib/ -c",
123
+ "test:debug": "nyc mocha --debug-brk --inspect \"test/**/*.test.ts\"",
120
124
  "test:e2e": "mocha --forbid-only \"test/**/*.e2e.ts\" --parallel --timeout 1200000",
121
125
  "test:esm-cjs": "cross-env DEBUG=e2e:* ts-node test/integration/esm-cjs.ts",
122
126
  "test:perf": "ts-node test/perf/parser.perf.ts",
127
+ "test:dev": "nyc mocha \"test/**/*.test.ts\"",
123
128
  "test": "nyc mocha --forbid-only \"test/**/*.test.ts\""
124
129
  },
125
130
  "types": "lib/index.d.ts"