@oclif/core 3.0.0-beta.9 → 3.0.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.
Files changed (142) hide show
  1. package/README.md +4 -2
  2. package/flush.d.ts +3 -0
  3. package/flush.js +1 -0
  4. package/handle.js +1 -0
  5. package/lib/args.d.ts +2 -2
  6. package/lib/args.js +17 -18
  7. package/lib/{ux → cli-ux}/action/base.d.ts +19 -21
  8. package/lib/{ux → cli-ux}/action/base.js +126 -120
  9. package/lib/{ux → cli-ux}/action/simple.js +25 -30
  10. package/lib/{ux → cli-ux}/action/spinner.d.ts +9 -7
  11. package/lib/{ux → cli-ux}/action/spinner.js +45 -37
  12. package/lib/{ux → cli-ux}/action/spinners.js +187 -187
  13. package/lib/cli-ux/action/types.d.ts +5 -0
  14. package/lib/cli-ux/action/types.js +2 -0
  15. package/lib/{ux → cli-ux}/config.d.ts +5 -5
  16. package/lib/{ux → cli-ux}/config.js +17 -17
  17. package/lib/{ux → cli-ux}/exit.js +3 -0
  18. package/lib/cli-ux/flush.d.ts +1 -0
  19. package/lib/cli-ux/flush.js +28 -0
  20. package/lib/cli-ux/index.d.ts +39 -0
  21. package/lib/{ux → cli-ux}/index.js +74 -88
  22. package/lib/{ux → cli-ux}/list.js +3 -3
  23. package/lib/{ux → cli-ux}/prompt.d.ts +3 -3
  24. package/lib/{ux → cli-ux}/prompt.js +35 -25
  25. package/lib/{ux → cli-ux}/stream.d.ts +6 -6
  26. package/lib/{ux → cli-ux}/stream.js +11 -10
  27. package/lib/cli-ux/styled/index.d.ts +4 -0
  28. package/lib/cli-ux/styled/index.js +11 -0
  29. package/lib/{ux → cli-ux}/styled/object.js +7 -9
  30. package/lib/{ux → cli-ux}/styled/table.d.ts +10 -10
  31. package/lib/{ux → cli-ux}/styled/table.js +130 -133
  32. package/lib/{ux → cli-ux}/styled/tree.js +11 -13
  33. package/lib/cli-ux/wait.js +5 -0
  34. package/lib/command.d.ts +82 -88
  35. package/lib/command.js +196 -175
  36. package/lib/config/config.d.ts +89 -90
  37. package/lib/config/config.js +466 -566
  38. package/lib/config/index.d.ts +0 -1
  39. package/lib/config/index.js +1 -3
  40. package/lib/config/plugin-loader.d.ts +12 -12
  41. package/lib/config/plugin-loader.js +72 -56
  42. package/lib/config/plugin.d.ts +25 -24
  43. package/lib/config/plugin.js +188 -154
  44. package/lib/config/ts-node.d.ts +2 -1
  45. package/lib/config/ts-node.js +71 -58
  46. package/lib/config/util.d.ts +1 -11
  47. package/lib/config/util.js +6 -59
  48. package/lib/errors/config.d.ts +1 -1
  49. package/lib/errors/config.js +6 -6
  50. package/lib/errors/errors/cli.d.ts +7 -7
  51. package/lib/errors/errors/cli.js +20 -16
  52. package/lib/errors/errors/exit.d.ts +1 -4
  53. package/lib/errors/errors/exit.js +1 -1
  54. package/lib/errors/errors/module-load.d.ts +1 -4
  55. package/lib/errors/errors/module-load.js +1 -1
  56. package/lib/errors/errors/pretty-print.d.ts +1 -1
  57. package/lib/errors/errors/pretty-print.js +12 -10
  58. package/lib/errors/handle.d.ts +12 -2
  59. package/lib/errors/handle.js +26 -14
  60. package/lib/errors/index.d.ts +10 -10
  61. package/lib/errors/index.js +25 -24
  62. package/lib/errors/logger.d.ts +2 -2
  63. package/lib/errors/logger.js +14 -13
  64. package/lib/execute.d.ts +6 -6
  65. package/lib/execute.js +10 -9
  66. package/lib/flags.d.ts +103 -32
  67. package/lib/flags.js +79 -45
  68. package/lib/help/command.d.ts +16 -14
  69. package/lib/help/command.js +178 -163
  70. package/lib/help/docopts.d.ts +5 -5
  71. package/lib/help/docopts.js +50 -54
  72. package/lib/help/formatter.d.ts +37 -37
  73. package/lib/help/formatter.js +66 -55
  74. package/lib/help/index.d.ts +25 -21
  75. package/lib/help/index.js +169 -147
  76. package/lib/help/root.d.ts +1 -1
  77. package/lib/help/root.js +15 -17
  78. package/lib/help/util.d.ts +2 -8
  79. package/lib/help/util.js +8 -28
  80. package/lib/index.d.ts +19 -20
  81. package/lib/index.js +37 -43
  82. package/lib/interfaces/config.d.ts +67 -66
  83. package/lib/interfaces/errors.d.ts +5 -5
  84. package/lib/interfaces/help.d.ts +17 -17
  85. package/lib/interfaces/hooks.d.ts +49 -49
  86. package/lib/interfaces/index.d.ts +7 -7
  87. package/lib/interfaces/manifest.d.ts +1 -1
  88. package/lib/interfaces/parser.d.ts +175 -51
  89. package/lib/interfaces/pjson.d.ts +45 -41
  90. package/lib/interfaces/plugin.d.ts +47 -41
  91. package/lib/interfaces/s3-manifest.d.ts +7 -7
  92. package/lib/interfaces/topic.d.ts +1 -1
  93. package/lib/interfaces/ts-config.d.ts +7 -7
  94. package/lib/main.d.ts +2 -2
  95. package/lib/main.js +16 -16
  96. package/lib/module-loader.d.ts +67 -77
  97. package/lib/module-loader.js +183 -150
  98. package/lib/parser/errors.d.ts +7 -7
  99. package/lib/parser/errors.js +29 -22
  100. package/lib/parser/help.js +5 -5
  101. package/lib/parser/index.js +2 -2
  102. package/lib/parser/parse.d.ts +9 -6
  103. package/lib/parser/parse.js +253 -221
  104. package/lib/parser/validate.js +53 -33
  105. package/lib/performance.d.ts +43 -32
  106. package/lib/performance.js +133 -91
  107. package/lib/screen.js +2 -2
  108. package/lib/settings.d.ts +11 -12
  109. package/lib/settings.js +2 -2
  110. package/lib/util/aggregate-flags.d.ts +2 -0
  111. package/lib/util/aggregate-flags.js +13 -0
  112. package/lib/util/cache-command.d.ts +3 -0
  113. package/lib/util/cache-command.js +109 -0
  114. package/lib/util/cache-default-value.d.ts +2 -0
  115. package/lib/util/cache-default-value.js +28 -0
  116. package/lib/util/ensure-arg-object.d.ts +12 -0
  117. package/lib/util/ensure-arg-object.js +14 -0
  118. package/lib/util/fs.d.ts +7 -0
  119. package/lib/util/fs.js +54 -0
  120. package/lib/util/os.d.ts +19 -0
  121. package/lib/util/os.js +28 -0
  122. package/lib/{util.d.ts → util/util.d.ts} +7 -16
  123. package/lib/util/util.js +98 -0
  124. package/package.json +35 -37
  125. package/lib/util.js +0 -126
  126. package/lib/ux/flush.d.ts +0 -1
  127. package/lib/ux/flush.js +0 -27
  128. package/lib/ux/index.d.ts +0 -58
  129. package/lib/ux/styled/index.d.ts +0 -6
  130. package/lib/ux/styled/index.js +0 -13
  131. package/lib/ux/styled/json.d.ts +0 -1
  132. package/lib/ux/styled/json.js +0 -15
  133. package/lib/ux/wait.js +0 -7
  134. package/lib/{ux → cli-ux}/action/simple.d.ts +4 -4
  135. package/lib/{ux → cli-ux}/action/spinners.d.ts +117 -117
  136. package/lib/{ux → cli-ux}/exit.d.ts +2 -2
  137. package/lib/{ux → cli-ux}/list.d.ts +0 -0
  138. package/lib/{ux → cli-ux}/styled/object.d.ts +0 -0
  139. package/lib/{ux → cli-ux}/styled/progress.d.ts +0 -0
  140. package/lib/{ux → cli-ux}/styled/progress.js +0 -0
  141. package/lib/{ux → cli-ux}/styled/tree.d.ts +1 -1
  142. /package/lib/{ux → cli-ux}/wait.d.ts +0 -0
@@ -1,18 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validate = void 0;
4
+ const util_1 = require("../util/util");
4
5
  const errors_1 = require("./errors");
5
- const util_1 = require("../config/util");
6
6
  async function validate(parse) {
7
7
  let cachedResolvedFlags;
8
8
  function validateArgs() {
9
9
  if (parse.output.nonExistentFlags?.length > 0) {
10
- throw new errors_1.NonExistentFlagsError({ parse, flags: parse.output.nonExistentFlags });
10
+ throw new errors_1.NonExistentFlagsError({ flags: parse.output.nonExistentFlags, parse });
11
11
  }
12
12
  const maxArgs = Object.keys(parse.input.args).length;
13
13
  if (parse.input.strict && parse.output.argv.length > maxArgs) {
14
14
  const extras = parse.output.argv.slice(maxArgs);
15
- throw new errors_1.UnexpectedArgsError({ parse, args: extras });
15
+ throw new errors_1.UnexpectedArgsError({ args: extras, parse });
16
16
  }
17
17
  const missingRequiredArgs = [];
18
18
  let hasOptional = false;
@@ -23,7 +23,7 @@ async function validate(parse) {
23
23
  else if (hasOptional) {
24
24
  // (required arg) check whether an optional has occurred before
25
25
  // optionals should follow required, not before
26
- throw new errors_1.InvalidArgsSpecError({ parse, args: parse.input.args });
26
+ throw new errors_1.InvalidArgsSpecError({ args: parse.input.args, parse });
27
27
  }
28
28
  if (arg.required && !parse.output.args[name] && parse.output.args[name] !== 0) {
29
29
  missingRequiredArgs.push(arg);
@@ -33,31 +33,31 @@ async function validate(parse) {
33
33
  const flagsWithMultiple = Object.entries(parse.input.flags)
34
34
  .filter(([_, flagDef]) => flagDef.type === 'option' && Boolean(flagDef.multiple))
35
35
  .map(([name]) => name);
36
- throw new errors_1.RequiredArgsError({ parse, args: missingRequiredArgs, flagsWithMultiple });
36
+ throw new errors_1.RequiredArgsError({ args: missingRequiredArgs, flagsWithMultiple, parse });
37
37
  }
38
38
  }
39
39
  async function validateFlags() {
40
40
  const promises = Object.entries(parse.input.flags).flatMap(([name, flag]) => {
41
41
  if (parse.output.flags[name] !== undefined) {
42
42
  return [
43
- ...flag.relationships ? validateRelationships(name, flag) : [],
44
- ...flag.dependsOn ? [validateDependsOn(name, flag.dependsOn)] : [],
45
- ...flag.exclusive ? [validateExclusive(name, flag.exclusive)] : [],
46
- ...flag.exactlyOne ? [validateExactlyOne(name, flag.exactlyOne)] : [],
43
+ ...(flag.relationships ? validateRelationships(name, flag) : []),
44
+ ...(flag.dependsOn ? [validateDependsOn(name, flag.dependsOn)] : []),
45
+ ...(flag.exclusive ? [validateExclusive(name, flag.exclusive)] : []),
46
+ ...(flag.exactlyOne ? [validateExactlyOne(name, flag.exactlyOne)] : []),
47
47
  ];
48
48
  }
49
49
  if (flag.required) {
50
- return [{ status: 'failed', name, validationFn: 'required', reason: `Missing required flag ${name}` }];
50
+ return [{ name, reason: `Missing required flag ${name}`, status: 'failed', validationFn: 'required' }];
51
51
  }
52
52
  if (flag.exactlyOne && flag.exactlyOne.length > 0) {
53
53
  return [validateAcrossFlags(flag)];
54
54
  }
55
55
  return [];
56
56
  });
57
- const results = (await Promise.all(promises));
58
- const failed = results.filter(r => r.status === 'failed');
57
+ const results = await Promise.all(promises);
58
+ const failed = results.filter((r) => r.status === 'failed');
59
59
  if (failed.length > 0)
60
- throw new errors_1.FailedFlagValidationError({ parse, failed });
60
+ throw new errors_1.FailedFlagValidationError({ failed, parse });
61
61
  }
62
62
  async function resolveFlags(flags) {
63
63
  if (cachedResolvedFlags)
@@ -70,21 +70,21 @@ async function validate(parse) {
70
70
  return result ? [flag.name, parse.output.flags[flag.name]] : null;
71
71
  });
72
72
  const resolved = await Promise.all(promises);
73
- cachedResolvedFlags = Object.fromEntries(resolved.filter(r => r !== null));
73
+ cachedResolvedFlags = Object.fromEntries(resolved.filter((r) => r !== null));
74
74
  return cachedResolvedFlags;
75
75
  }
76
- const getPresentFlags = (flags) => Object.keys(flags).filter(key => key !== undefined);
76
+ const getPresentFlags = (flags) => Object.keys(flags).filter((key) => key !== undefined);
77
77
  function validateAcrossFlags(flag) {
78
78
  const base = { name: flag.name, validationFn: 'validateAcrossFlags' };
79
79
  const intersection = Object.entries(parse.input.flags)
80
- .map(entry => entry[0]) // array of flag names
81
- .filter(flagName => parse.output.flags[flagName] !== undefined) // with values
82
- .filter(flagName => flag.exactlyOne && flag.exactlyOne.includes(flagName)); // and in the exactlyOne list
80
+ .map((entry) => entry[0]) // array of flag names
81
+ .filter((flagName) => parse.output.flags[flagName] !== undefined) // with values
82
+ .filter((flagName) => flag.exactlyOne && flag.exactlyOne.includes(flagName)); // and in the exactlyOne list
83
83
  if (intersection.length === 0) {
84
84
  // the command's exactlyOne may or may not include itself, so we'll use Set to add + de-dupe
85
- const deduped = (0, util_1.uniq)(flag.exactlyOne?.map(flag => `--${flag}`) ?? []).join(', ');
85
+ const deduped = (0, util_1.uniq)(flag.exactlyOne?.map((flag) => `--${flag}`) ?? []).join(', ');
86
86
  const reason = `Exactly one of the following must be provided: ${deduped}`;
87
- return { ...base, status: 'failed', reason };
87
+ return { ...base, reason, status: 'failed' };
88
88
  }
89
89
  return { ...base, status: 'success' };
90
90
  }
@@ -100,7 +100,11 @@ async function validate(parse) {
100
100
  continue;
101
101
  if (parse.output.flags[flag] !== undefined) {
102
102
  const flagValue = parse.output.metadata.flags?.[flag]?.defaultHelp ?? parse.output.flags[flag];
103
- return { ...base, status: 'failed', reason: `--${flag}=${flagValue} cannot also be provided when using --${name}` };
103
+ return {
104
+ ...base,
105
+ reason: `--${flag}=${flagValue} cannot also be provided when using --${name}`,
106
+ status: 'failed',
107
+ };
104
108
  }
105
109
  }
106
110
  return { ...base, status: 'success' };
@@ -111,7 +115,7 @@ async function validate(parse) {
111
115
  const keys = getPresentFlags(resolved);
112
116
  for (const flag of keys) {
113
117
  if (flag !== name && parse.output.flags[flag] !== undefined) {
114
- return { ...base, status: 'failed', reason: `--${flag} cannot also be provided when using --${name}` };
118
+ return { ...base, reason: `--${flag} cannot also be provided when using --${name}`, status: 'failed' };
115
119
  }
116
120
  }
117
121
  return { ...base, status: 'success' };
@@ -119,10 +123,16 @@ async function validate(parse) {
119
123
  async function validateDependsOn(name, flags) {
120
124
  const base = { name, validationFn: 'validateDependsOn' };
121
125
  const resolved = await resolveFlags(flags);
122
- const foundAll = Object.values(resolved).every(val => val !== undefined);
126
+ const foundAll = Object.values(resolved).every((val) => val !== undefined);
123
127
  if (!foundAll) {
124
- const formattedFlags = Object.keys(resolved).map(f => `--${f}`).join(', ');
125
- return { ...base, status: 'failed', reason: `All of the following must be provided when using --${name}: ${formattedFlags}` };
128
+ const formattedFlags = Object.keys(resolved)
129
+ .map((f) => `--${f}`)
130
+ .join(', ');
131
+ return {
132
+ ...base,
133
+ reason: `All of the following must be provided when using --${name}: ${formattedFlags}`,
134
+ status: 'failed',
135
+ };
126
136
  }
127
137
  return { ...base, status: 'success' };
128
138
  }
@@ -131,24 +141,34 @@ async function validate(parse) {
131
141
  const resolved = await resolveFlags(flags);
132
142
  const foundAtLeastOne = Object.values(resolved).some(Boolean);
133
143
  if (!foundAtLeastOne) {
134
- const formattedFlags = Object.keys(resolved).map(f => `--${f}`).join(', ');
135
- return { ...base, status: 'failed', reason: `One of the following must be provided when using --${name}: ${formattedFlags}` };
144
+ const formattedFlags = Object.keys(resolved)
145
+ .map((f) => `--${f}`)
146
+ .join(', ');
147
+ return {
148
+ ...base,
149
+ reason: `One of the following must be provided when using --${name}: ${formattedFlags}`,
150
+ status: 'failed',
151
+ };
136
152
  }
137
153
  return { ...base, status: 'success' };
138
154
  }
139
155
  function validateRelationships(name, flag) {
140
- return ((flag.relationships ?? []).map(relationship => {
156
+ return (flag.relationships ?? []).map((relationship) => {
141
157
  switch (relationship.type) {
142
- case 'all':
158
+ case 'all': {
143
159
  return validateDependsOn(name, relationship.flags);
144
- case 'some':
160
+ }
161
+ case 'some': {
145
162
  return validateSome(name, relationship.flags);
146
- case 'none':
163
+ }
164
+ case 'none': {
147
165
  return validateExclusive(name, relationship.flags);
148
- default:
166
+ }
167
+ default: {
149
168
  throw new Error(`Unknown relationship type: ${relationship.type}`);
169
+ }
150
170
  }
151
- }));
171
+ });
152
172
  }
153
173
  validateArgs();
154
174
  return validateFlags();
@@ -1,53 +1,50 @@
1
- type Details = Record<string, string | boolean | number | string[]>;
1
+ type Details = Record<string, boolean | number | string | string[]>;
2
2
  type PerfResult = {
3
- name: string;
4
- duration: number;
5
3
  details: Details;
6
- module: string;
4
+ duration: number;
7
5
  method: string | undefined;
6
+ module: string;
7
+ name: string;
8
8
  scope: string | undefined;
9
9
  };
10
10
  type PerfHighlights = {
11
- configLoadTime: number;
12
- runTime: number;
13
- initTime: number;
14
- commandLoadTime: number;
15
- pluginLoadTimes: Record<string, number>;
16
- corePluginsLoadTime: number;
17
- userPluginsLoadTime: number;
18
- linkedPluginsLoadTime: number;
19
11
  hookRunTimes: Record<string, Record<string, number>>;
12
+ 'oclif.commandLoadMs': number;
13
+ 'oclif.commandRunMs': number;
14
+ 'oclif.configLoadMs': number;
15
+ 'oclif.corePluginsLoadMs': number;
16
+ 'oclif.initHookMs': number;
17
+ 'oclif.initMs': number;
18
+ 'oclif.linkedPluginsLoadMs': number;
19
+ 'oclif.postrunHookMs': number;
20
+ 'oclif.prerunHookMs': number;
21
+ 'oclif.runMs': number;
22
+ 'oclif.userPluginsLoadMs': number;
23
+ pluginLoadTimes: Record<string, {
24
+ details: Details;
25
+ duration: number;
26
+ }>;
20
27
  };
28
+ export declare const OCLIF_MARKER_OWNER = "@oclif/core";
21
29
  declare class Marker {
30
+ owner: string;
22
31
  name: string;
23
32
  details: Details;
24
- module: string;
33
+ private startMarker;
34
+ private stopMarker;
25
35
  method: string;
36
+ module: string;
26
37
  scope: string;
27
38
  stopped: boolean;
28
- private startMarker;
29
- private stopMarker;
30
- constructor(name: string, details?: Details);
39
+ constructor(owner: string, name: string, details?: Details);
31
40
  addDetails(details: Details): void;
32
- stop(): void;
33
41
  measure(): void;
42
+ stop(): void;
34
43
  }
35
- export default class Performance {
36
- private static markers;
44
+ export declare class Performance {
45
+ private static _oclifPerf;
37
46
  private static _results;
38
- private static _highlights;
39
- static get enabled(): boolean;
40
- static get results(): PerfResult[];
41
- static getResult(name: string): PerfResult | undefined;
42
- static get highlights(): PerfHighlights;
43
- /**
44
- * Add a new performance marker
45
- *
46
- * @param name Name of the marker. Use `module.method#scope` format
47
- * @param details Arbitrary details to attach to the marker
48
- * @returns Marker instance
49
- */
50
- static mark(name: string, details?: Details): Marker | undefined;
47
+ private static markers;
51
48
  /**
52
49
  * Collect performance results into static Performance.results
53
50
  *
@@ -59,5 +56,19 @@ export default class Performance {
59
56
  * @returns void
60
57
  */
61
58
  static debug(): void;
59
+ static get enabled(): boolean;
60
+ static getResult(owner: string, name: string): PerfResult | undefined;
61
+ /**
62
+ * Add a new performance marker
63
+ *
64
+ * @param owner An npm package like `@oclif/core` or `@salesforce/source-tracking`
65
+ * @param name Name of the marker. Use `module.method#scope` format
66
+ * @param details Arbitrary details to attach to the marker
67
+ * @returns Marker instance
68
+ */
69
+ static mark(owner: string, name: string, details?: Details): Marker | undefined;
70
+ static get oclifPerf(): PerfHighlights | Record<string, never>;
71
+ /** returns a map of owner, PerfResult[]. Excludes oclif PerfResult, which you can get from oclifPerf */
72
+ static get results(): Map<string, PerfResult[]>;
62
73
  }
63
74
  export {};
@@ -1,12 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const perf_hooks_1 = require("perf_hooks");
3
+ exports.Performance = exports.OCLIF_MARKER_OWNER = void 0;
4
+ const node_perf_hooks_1 = require("node:perf_hooks");
4
5
  const settings_1 = require("./settings");
6
+ exports.OCLIF_MARKER_OWNER = '@oclif/core';
5
7
  class Marker {
6
- constructor(name, details = {}) {
8
+ owner;
9
+ name;
10
+ details;
11
+ startMarker;
12
+ stopMarker;
13
+ method;
14
+ module;
15
+ scope;
16
+ stopped = false;
17
+ constructor(owner, name, details = {}) {
18
+ this.owner = owner;
7
19
  this.name = name;
8
20
  this.details = details;
9
- this.stopped = false;
10
21
  this.startMarker = `${this.name}-start`;
11
22
  this.stopMarker = `${this.name}-stop`;
12
23
  const [caller, scope] = name.split('#');
@@ -14,54 +25,25 @@ class Marker {
14
25
  this.module = module;
15
26
  this.method = method;
16
27
  this.scope = scope;
17
- perf_hooks_1.performance.mark(this.startMarker);
28
+ node_perf_hooks_1.performance.mark(this.startMarker);
18
29
  }
19
30
  addDetails(details) {
20
31
  this.details = { ...this.details, ...details };
21
32
  }
33
+ measure() {
34
+ node_perf_hooks_1.performance.measure(this.name, this.startMarker, this.stopMarker);
35
+ }
22
36
  stop() {
23
37
  this.stopped = true;
24
- perf_hooks_1.performance.mark(this.stopMarker);
25
- }
26
- measure() {
27
- perf_hooks_1.performance.measure(this.name, this.startMarker, this.stopMarker);
38
+ node_perf_hooks_1.performance.mark(this.stopMarker);
28
39
  }
29
40
  }
30
41
  class Performance {
31
- static get enabled() {
32
- return settings_1.default.performanceEnabled ?? false;
33
- }
34
- static get results() {
35
- if (!Performance.enabled)
36
- return [];
37
- if (Performance._results.length > 0)
38
- return Performance._results;
39
- throw new Error('Perf results not available. Did you forget to call await Performance.collect()?');
40
- }
41
- static getResult(name) {
42
- return Performance.results.find(r => r.name === name);
43
- }
44
- static get highlights() {
45
- if (!Performance.enabled)
46
- return {};
47
- if (Performance._highlights)
48
- return Performance._highlights;
49
- throw new Error('Perf results not available. Did you forget to call await Performance.collect()?');
50
- }
51
- /**
52
- * Add a new performance marker
53
- *
54
- * @param name Name of the marker. Use `module.method#scope` format
55
- * @param details Arbitrary details to attach to the marker
56
- * @returns Marker instance
57
- */
58
- static mark(name, details = {}) {
59
- if (!Performance.enabled)
60
- return;
61
- const marker = new Marker(name, details);
62
- Performance.markers[marker.name] = marker;
63
- return marker;
64
- }
42
+ static _oclifPerf;
43
+ /* Key: marker.owner */
44
+ static _results = new Map();
45
+ /* Key: marker.name */
46
+ static markers = new Map();
65
47
  /**
66
48
  * Collect performance results into static Performance.results
67
49
  *
@@ -70,36 +52,41 @@ class Performance {
70
52
  static async collect() {
71
53
  if (!Performance.enabled)
72
54
  return;
73
- if (Performance._results.length > 0)
55
+ if (Performance._results.size > 0)
74
56
  return;
75
- const markers = Object.values(Performance.markers);
57
+ const markers = [...Performance.markers.values()];
76
58
  if (markers.length === 0)
77
59
  return;
78
- for (const marker of markers.filter(m => !m.stopped)) {
60
+ for (const marker of markers.filter((m) => !m.stopped)) {
79
61
  marker.stop();
80
62
  }
81
- return new Promise(resolve => {
82
- const perfObserver = new perf_hooks_1.PerformanceObserver(items => {
63
+ return new Promise((resolve) => {
64
+ const perfObserver = new node_perf_hooks_1.PerformanceObserver((items) => {
83
65
  for (const entry of items.getEntries()) {
84
- if (Performance.markers[entry.name]) {
85
- const marker = Performance.markers[entry.name];
86
- Performance._results.push({
87
- name: entry.name,
88
- module: marker.module,
66
+ const marker = Performance.markers.get(entry.name);
67
+ if (marker) {
68
+ const result = {
69
+ details: marker.details,
70
+ duration: entry.duration,
89
71
  method: marker.method,
72
+ module: marker.module,
73
+ name: entry.name,
90
74
  scope: marker.scope,
91
- duration: entry.duration,
92
- details: marker.details,
93
- });
75
+ };
76
+ const existing = Performance._results.get(marker.owner) ?? [];
77
+ Performance._results.set(marker.owner, [...existing, result]);
94
78
  }
95
79
  }
96
- const command = Performance.results.find(r => r.name.startsWith('config.runCommand'));
97
- const commandLoadTime = command ? Performance.getResult(`plugin.findCommand#${command.details.plugin}.${command.details.command}`)?.duration ?? 0 : 0;
98
- const pluginLoadTimes = Object.fromEntries(Performance.results
80
+ const oclifResults = Performance._results.get(exports.OCLIF_MARKER_OWNER) ?? [];
81
+ const command = oclifResults.find((r) => r.name.startsWith('config.runCommand'));
82
+ const commandLoadTime = command
83
+ ? Performance.getResult(exports.OCLIF_MARKER_OWNER, `plugin.findCommand#${command.details.plugin}.${command.details.command}`)?.duration ?? 0
84
+ : 0;
85
+ const pluginLoadTimes = Object.fromEntries(oclifResults
99
86
  .filter(({ name }) => name.startsWith('plugin.load#'))
100
87
  .sort((a, b) => b.duration - a.duration)
101
- .map(({ scope, duration }) => [scope, duration]));
102
- const hookRunTimes = Performance.results
88
+ .map(({ details, duration, scope }) => [scope, { details, duration }]));
89
+ const hookRunTimes = oclifResults
103
90
  .filter(({ name }) => name.startsWith('config.runHook#'))
104
91
  .reduce((acc, perfResult) => {
105
92
  const event = perfResult.details.event;
@@ -116,24 +103,28 @@ class Performance {
116
103
  }
117
104
  return acc;
118
105
  }, {});
119
- const pluginLoadTimeByType = Object.fromEntries(Performance.results
106
+ const pluginLoadTimeByType = Object.fromEntries(oclifResults
120
107
  .filter(({ name }) => name.startsWith('config.loadPlugins#'))
121
108
  .sort((a, b) => b.duration - a.duration)
122
- .map(({ scope, duration }) => [scope, duration]));
123
- Performance._highlights = {
124
- configLoadTime: Performance.getResult('config.load')?.duration ?? 0,
125
- runTime: Performance.getResult('main.run')?.duration ?? 0,
126
- initTime: Performance.getResult('main.run#init')?.duration ?? 0,
127
- commandLoadTime,
128
- pluginLoadTimes,
109
+ .map(({ duration, scope }) => [scope, duration]));
110
+ Performance._oclifPerf = {
129
111
  hookRunTimes,
130
- corePluginsLoadTime: pluginLoadTimeByType.core ?? 0,
131
- userPluginsLoadTime: pluginLoadTimeByType.user ?? 0,
132
- linkedPluginsLoadTime: pluginLoadTimeByType.link ?? 0,
112
+ 'oclif.commandLoadMs': commandLoadTime,
113
+ 'oclif.commandRunMs': oclifResults.find(({ name }) => name.startsWith('config.runCommand#'))?.duration ?? 0,
114
+ 'oclif.configLoadMs': Performance.getResult(exports.OCLIF_MARKER_OWNER, 'config.load')?.duration ?? 0,
115
+ 'oclif.corePluginsLoadMs': pluginLoadTimeByType.core ?? 0,
116
+ 'oclif.initHookMs': hookRunTimes.init?.total ?? 0,
117
+ 'oclif.initMs': Performance.getResult(exports.OCLIF_MARKER_OWNER, 'main.run#init')?.duration ?? 0,
118
+ 'oclif.linkedPluginsLoadMs': pluginLoadTimeByType.link ?? 0,
119
+ 'oclif.postrunHookMs': hookRunTimes.postrun?.total ?? 0,
120
+ 'oclif.prerunHookMs': hookRunTimes.prerun?.total ?? 0,
121
+ 'oclif.runMs': Performance.getResult(exports.OCLIF_MARKER_OWNER, 'main.run')?.duration ?? 0,
122
+ 'oclif.userPluginsLoadMs': pluginLoadTimeByType.user ?? 0,
123
+ pluginLoadTimes,
133
124
  };
134
125
  resolve();
135
126
  });
136
- perfObserver.observe({ entryTypes: ['measure'], buffered: true });
127
+ perfObserver.observe({ buffered: true, entryTypes: ['measure'] });
137
128
  for (const marker of markers) {
138
129
  try {
139
130
  marker.measure();
@@ -142,7 +133,7 @@ class Performance {
142
133
  // ignore
143
134
  }
144
135
  }
145
- perf_hooks_1.performance.clearMarks();
136
+ node_perf_hooks_1.performance.clearMarks();
146
137
  });
147
138
  }
148
139
  /**
@@ -152,27 +143,78 @@ class Performance {
152
143
  static debug() {
153
144
  if (!Performance.enabled)
154
145
  return;
155
- const debug = require('debug')('perf');
156
- debug('Init Time: %sms', Performance.highlights.initTime.toFixed(4));
157
- debug('Config Load Time: %sms', Performance.highlights.configLoadTime.toFixed(4));
158
- debug('Command Load Time: %sms', Performance.highlights.commandLoadTime.toFixed(4));
159
- debug('Execution Time: %sms', Performance.highlights.runTime.toFixed(4));
160
- debug('Core Plugin Load Time: %sms', Performance.highlights.corePluginsLoadTime.toFixed(4));
161
- debug('User Plugin Load Time: %sms', Performance.highlights.userPluginsLoadTime.toFixed(4));
162
- debug('Linked Plugin Load Time: %sms', Performance.highlights.linkedPluginsLoadTime.toFixed(4));
163
- debug('Plugin Load Times:');
164
- for (const [plugin, duration] of Object.entries(Performance.highlights.pluginLoadTimes)) {
165
- debug(` ${plugin}: ${duration.toFixed(4)}ms`);
146
+ const oclifDebug = require('debug')('oclif-perf');
147
+ oclifDebug('Total Time: %sms', Performance.oclifPerf['oclif.runMs'].toFixed(4));
148
+ oclifDebug('Init Time: %sms', Performance.oclifPerf['oclif.initMs'].toFixed(4));
149
+ oclifDebug('Config Load Time: %sms', Performance.oclifPerf['oclif.configLoadMs'].toFixed(4));
150
+ oclifDebug(' Plugins Load Time: %sms', Performance.getResult(exports.OCLIF_MARKER_OWNER, 'config.loadAllPlugins')?.duration.toFixed(4) ?? 0);
151
+ oclifDebug(' Commands Load Time: %sms', Performance.getResult(exports.OCLIF_MARKER_OWNER, 'config.loadAllCommands')?.duration.toFixed(4) ?? 0);
152
+ oclifDebug('Core Plugin Load Time: %sms', Performance.oclifPerf['oclif.corePluginsLoadMs'].toFixed(4));
153
+ oclifDebug('User Plugin Load Time: %sms', Performance.oclifPerf['oclif.userPluginsLoadMs'].toFixed(4));
154
+ oclifDebug('Linked Plugin Load Time: %sms', Performance.oclifPerf['oclif.linkedPluginsLoadMs'].toFixed(4));
155
+ oclifDebug('Plugin Load Times:');
156
+ for (const [plugin, result] of Object.entries(Performance.oclifPerf.pluginLoadTimes)) {
157
+ if (result.details.hasManifest) {
158
+ oclifDebug(` ${plugin}: ${result.duration.toFixed(4)}ms`);
159
+ }
160
+ else {
161
+ oclifDebug(` ${plugin}: ${result.duration.toFixed(4)}ms (no manifest!)`);
162
+ }
166
163
  }
167
- debug('Hook Run Times:');
168
- for (const [event, runTimes] of Object.entries(Performance.highlights.hookRunTimes)) {
169
- debug(` ${event}:`);
164
+ oclifDebug('Hook Run Times:');
165
+ for (const [event, runTimes] of Object.entries(Performance.oclifPerf.hookRunTimes)) {
166
+ oclifDebug(` ${event}:`);
170
167
  for (const [plugin, duration] of Object.entries(runTimes)) {
171
- debug(` ${plugin}: ${duration.toFixed(4)}ms`);
168
+ oclifDebug(` ${plugin}: ${duration.toFixed(4)}ms`);
169
+ }
170
+ }
171
+ oclifDebug('Command Load Time: %sms', Performance.oclifPerf['oclif.commandLoadMs'].toFixed(4));
172
+ oclifDebug('Command Run Time: %sms', Performance.oclifPerf['oclif.commandRunMs'].toFixed(4));
173
+ const nonCoreDebug = require('debug')('non-oclif-perf');
174
+ const nonCorePerf = Performance.results;
175
+ if (nonCorePerf.size > 0) {
176
+ nonCoreDebug('Non-Core Performance Measurements:');
177
+ for (const [owner, results] of nonCorePerf) {
178
+ nonCoreDebug(` ${owner}:`);
179
+ for (const result of results) {
180
+ nonCoreDebug(` ${result.name}: ${result.duration.toFixed(4)}ms`);
181
+ }
172
182
  }
173
183
  }
174
184
  }
185
+ static get enabled() {
186
+ return settings_1.settings.performanceEnabled ?? false;
187
+ }
188
+ static getResult(owner, name) {
189
+ return Performance._results.get(owner)?.find((r) => r.name === name);
190
+ }
191
+ /**
192
+ * Add a new performance marker
193
+ *
194
+ * @param owner An npm package like `@oclif/core` or `@salesforce/source-tracking`
195
+ * @param name Name of the marker. Use `module.method#scope` format
196
+ * @param details Arbitrary details to attach to the marker
197
+ * @returns Marker instance
198
+ */
199
+ static mark(owner, name, details = {}) {
200
+ if (!Performance.enabled)
201
+ return;
202
+ const marker = new Marker(owner, name, details);
203
+ Performance.markers.set(marker.name, marker);
204
+ return marker;
205
+ }
206
+ static get oclifPerf() {
207
+ if (!Performance.enabled)
208
+ return {};
209
+ if (Performance._oclifPerf)
210
+ return Performance._oclifPerf;
211
+ throw new Error('Perf results not available. Did you forget to call await Performance.collect()?');
212
+ }
213
+ /** returns a map of owner, PerfResult[]. Excludes oclif PerfResult, which you can get from oclifPerf */
214
+ static get results() {
215
+ if (!Performance.enabled)
216
+ return new Map();
217
+ return new Map([...Performance._results.entries()].filter(([owner]) => owner !== exports.OCLIF_MARKER_OWNER));
218
+ }
175
219
  }
176
- exports.default = Performance;
177
- Performance.markers = {};
178
- Performance._results = [];
220
+ exports.Performance = Performance;
package/lib/screen.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.errtermwidth = exports.stdtermwidth = void 0;
4
- const stream_1 = require("./ux/stream");
4
+ const stream_1 = require("./cli-ux/stream");
5
5
  const settings_1 = require("./settings");
6
6
  function termwidth(stream) {
7
7
  if (!stream.isTTY) {
@@ -16,6 +16,6 @@ function termwidth(stream) {
16
16
  }
17
17
  return width;
18
18
  }
19
- const columns = Number.parseInt(process.env.OCLIF_COLUMNS, 10) || settings_1.default.columns;
19
+ const columns = Number.parseInt(process.env.OCLIF_COLUMNS, 10) || settings_1.settings.columns;
20
20
  exports.stdtermwidth = columns || termwidth(stream_1.stdout);
21
21
  exports.errtermwidth = columns || termwidth(stream_1.stderr);
package/lib/settings.d.ts CHANGED
@@ -1,4 +1,11 @@
1
1
  export type Settings = {
2
+ /**
3
+ * Set the terminal width to a specified number of columns (characters)
4
+ *
5
+ * Environment Variable:
6
+ * OCLIF_COLUMNS=80
7
+ */
8
+ columns?: number;
2
9
  /**
3
10
  * Show additional debug output without DEBUG. Mainly shows stackstraces.
4
11
  *
@@ -13,12 +20,10 @@ export type Settings = {
13
20
  */
14
21
  errlog?: string;
15
22
  /**
16
- * Set the terminal width to a specified number of columns (characters)
17
- *
18
- * Environment Variable:
19
- * OCLIF_COLUMNS=80
23
+ * Enable performance tracking. Resulting data is available in the `perf` property of the `Config` class.
24
+ * This will be overridden by the `enablePerf` property passed into Config constructor.
20
25
  */
21
- columns?: number;
26
+ performanceEnabled?: boolean;
22
27
  /**
23
28
  * Try to use ts-node to load typescript source files instead of
24
29
  * javascript files.
@@ -30,11 +35,5 @@ export type Settings = {
30
35
  * NODE_ENV=development
31
36
  */
32
37
  tsnodeEnabled?: boolean;
33
- /**
34
- * Enable performance tracking. Resulting data is available in the `perf` property of the `Config` class.
35
- * This will be overridden by the `enablePerf` property passed into Config constructor.
36
- */
37
- performanceEnabled?: boolean;
38
38
  };
39
- declare const settings: Settings;
40
- export default settings;
39
+ export declare const settings: Settings;
package/lib/settings.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.settings = void 0;
3
4
  // Set global.oclif to the new object if it wasn't set before
4
5
  if (!global.oclif)
5
6
  global.oclif = {};
6
- const settings = global.oclif;
7
- exports.default = settings;
7
+ exports.settings = global.oclif;
@@ -0,0 +1,2 @@
1
+ import { FlagInput, FlagOutput } from '../interfaces/parser';
2
+ export declare function aggregateFlags<F extends FlagOutput, B extends FlagOutput>(flags: FlagInput<F> | undefined, baseFlags: FlagInput<B> | undefined, enableJsonFlag: boolean | undefined): FlagInput<F>;