@oclif/core 3.17.0 → 3.18.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.
@@ -1,5 +1,5 @@
1
1
  import { Plugin, TSConfig } from '../interfaces';
2
- export declare const TS_CONFIGS: Record<string, TSConfig>;
2
+ export declare const TS_CONFIGS: Record<string, TSConfig | undefined>;
3
3
  /**
4
4
  * Convert a path from the compiled ./lib files to the ./src typescript source
5
5
  * this is for developing typescript plugins/CLIs
@@ -9,6 +9,7 @@ const cache_1 = __importDefault(require("../cache"));
9
9
  const errors_1 = require("../errors");
10
10
  const settings_1 = require("../settings");
11
11
  const fs_1 = require("../util/fs");
12
+ const read_tsconfig_1 = require("../util/read-tsconfig");
12
13
  const util_1 = require("../util/util");
13
14
  const util_2 = require("./util");
14
15
  // eslint-disable-next-line new-cap
@@ -22,7 +23,7 @@ async function loadTSConfig(root) {
22
23
  try {
23
24
  if (exports.TS_CONFIGS[root])
24
25
  return exports.TS_CONFIGS[root];
25
- exports.TS_CONFIGS[root] = await (0, fs_1.readTSConfig)((0, node_path_1.join)(root, 'tsconfig.json'));
26
+ exports.TS_CONFIGS[root] = await (0, read_tsconfig_1.readTSConfig)(root);
26
27
  return exports.TS_CONFIGS[root];
27
28
  }
28
29
  catch (error) {
package/lib/flags.d.ts CHANGED
@@ -2,6 +2,23 @@
2
2
  import { URL } from 'node:url';
3
3
  import { BooleanFlag, CustomOptions, FlagDefinition, OptionFlag } from './interfaces';
4
4
  type NotArray<T> = T extends Array<any> ? never : T;
5
+ /**
6
+ * Create a custom flag.
7
+ *
8
+ * @example
9
+ * type Id = string
10
+ * type IdOpts = { startsWith: string; length: number }
11
+ *
12
+ * export const myFlag = custom<Id, IdOpts>({
13
+ * parse: async (input, opts) => {
14
+ * if (input.startsWith(opts.startsWith) && input.length === opts.length) {
15
+ * return input
16
+ * }
17
+ *
18
+ * throw new Error('Invalid id')
19
+ * },
20
+ * })
21
+ */
5
22
  export declare function custom<T = string, P extends CustomOptions = CustomOptions>(defaults: Partial<OptionFlag<T[], P>> & {
6
23
  multiple: true;
7
24
  } & ({
@@ -42,7 +59,18 @@ export declare function custom<T = string, P extends CustomOptions = CustomOptio
42
59
  multiple: false;
43
60
  requiredOrDefaulted: false;
44
61
  }>;
62
+ /**
63
+ * A boolean flag. Defaults to `false` unless default is set to `true`.
64
+ *
65
+ * - `allowNo` option allows `--no-` prefix to negate boolean flag.
66
+ */
45
67
  export declare function boolean<T = boolean>(options?: Partial<BooleanFlag<T>>): BooleanFlag<T>;
68
+ /**
69
+ * An integer flag. Throws an error if the provided value is not a valid integer.
70
+ *
71
+ * - `min` option allows to set a minimum value.
72
+ * - `max` option allows to set a maximum value.
73
+ */
46
74
  export declare const integer: FlagDefinition<number, {
47
75
  max?: number | undefined;
48
76
  min?: number | undefined;
@@ -50,12 +78,22 @@ export declare const integer: FlagDefinition<number, {
50
78
  multiple: false;
51
79
  requiredOrDefaulted: false;
52
80
  }>;
81
+ /**
82
+ * A directory flag.
83
+ *
84
+ * - `exists` option allows you to throw an error if the directory does not exist.
85
+ */
53
86
  export declare const directory: FlagDefinition<string, {
54
87
  exists?: boolean | undefined;
55
88
  }, {
56
89
  multiple: false;
57
90
  requiredOrDefaulted: false;
58
91
  }>;
92
+ /**
93
+ * A file flag.
94
+ *
95
+ * - `exists` option allows you to throw an error if the file does not exist.
96
+ */
59
97
  export declare const file: FlagDefinition<string, {
60
98
  exists?: boolean | undefined;
61
99
  }, {
@@ -63,20 +101,44 @@ export declare const file: FlagDefinition<string, {
63
101
  requiredOrDefaulted: false;
64
102
  }>;
65
103
  /**
66
- * Initializes a string as a URL. Throws an error
67
- * if the string is not a valid URL.
104
+ * A URL flag that converts the provided value is a string.
105
+ *
106
+ * Throws an error if the string is not a valid URL.
68
107
  */
69
108
  export declare const url: FlagDefinition<URL, CustomOptions, {
70
109
  multiple: false;
71
110
  requiredOrDefaulted: false;
72
111
  }>;
112
+ /**
113
+ * A string flag.
114
+ */
73
115
  export declare const string: FlagDefinition<string, CustomOptions, {
74
116
  multiple: false;
75
117
  requiredOrDefaulted: false;
76
118
  }>;
119
+ /**
120
+ * Version flag that will print the CLI version and exit.
121
+ */
77
122
  export declare const version: (opts?: Partial<BooleanFlag<boolean>>) => BooleanFlag<void>;
123
+ /**
124
+ * A help flag that will print the CLI help and exit.
125
+ */
78
126
  export declare const help: (opts?: Partial<BooleanFlag<boolean>>) => BooleanFlag<void>;
79
127
  type ReadonlyElementOf<T extends ReadonlyArray<unknown>> = T[number];
128
+ /**
129
+ * Create a custom flag that infers the flag type from the provided options.
130
+ *
131
+ * The provided `options` must be a readonly array in order for type inference to work.
132
+ *
133
+ * @example
134
+ * export default class MyCommand extends Command {
135
+ * static flags = {
136
+ * name: Flags.option({
137
+ * options: ['foo', 'bar'] as const,
138
+ * })(),
139
+ * }
140
+ * }
141
+ */
80
142
  export declare function option<T extends readonly string[], P extends CustomOptions>(defaults: Partial<OptionFlag<ReadonlyElementOf<T>[], P>> & {
81
143
  multiple: true;
82
144
  options: T;
package/lib/flags.js CHANGED
@@ -5,23 +5,6 @@ const node_url_1 = require("node:url");
5
5
  const errors_1 = require("./errors");
6
6
  const help_1 = require("./help");
7
7
  const fs_1 = require("./util/fs");
8
- /**
9
- * Create a custom flag.
10
- *
11
- * @example
12
- * type Id = string
13
- * type IdOpts = { startsWith: string; length: number };
14
- *
15
- * export const myFlag = custom<Id, IdOpts>({
16
- * parse: async (input, opts) => {
17
- * if (input.startsWith(opts.startsWith) && input.length === opts.length) {
18
- * return input
19
- * }
20
- *
21
- * throw new Error('Invalid id')
22
- * },
23
- * })
24
- */
25
8
  function custom(defaults) {
26
9
  return (options = {}) => ({
27
10
  parse: async (input, _ctx, _opts) => input,
@@ -33,6 +16,11 @@ function custom(defaults) {
33
16
  });
34
17
  }
35
18
  exports.custom = custom;
19
+ /**
20
+ * A boolean flag. Defaults to `false` unless default is set to `true`.
21
+ *
22
+ * - `allowNo` option allows `--no-` prefix to negate boolean flag.
23
+ */
36
24
  function boolean(options = {}) {
37
25
  return {
38
26
  parse: async (b, _) => b,
@@ -42,6 +30,12 @@ function boolean(options = {}) {
42
30
  };
43
31
  }
44
32
  exports.boolean = boolean;
33
+ /**
34
+ * An integer flag. Throws an error if the provided value is not a valid integer.
35
+ *
36
+ * - `min` option allows to set a minimum value.
37
+ * - `max` option allows to set a maximum value.
38
+ */
45
39
  exports.integer = custom({
46
40
  async parse(input, _, opts) {
47
41
  if (!/^-?\d+$/.test(input))
@@ -54,6 +48,11 @@ exports.integer = custom({
54
48
  return num;
55
49
  },
56
50
  });
51
+ /**
52
+ * A directory flag.
53
+ *
54
+ * - `exists` option allows you to throw an error if the directory does not exist.
55
+ */
57
56
  exports.directory = custom({
58
57
  async parse(input, _, opts) {
59
58
  if (opts.exists)
@@ -61,6 +60,11 @@ exports.directory = custom({
61
60
  return input;
62
61
  },
63
62
  });
63
+ /**
64
+ * A file flag.
65
+ *
66
+ * - `exists` option allows you to throw an error if the file does not exist.
67
+ */
64
68
  exports.file = custom({
65
69
  async parse(input, _, opts) {
66
70
  if (opts.exists)
@@ -69,8 +73,9 @@ exports.file = custom({
69
73
  },
70
74
  });
71
75
  /**
72
- * Initializes a string as a URL. Throws an error
73
- * if the string is not a valid URL.
76
+ * A URL flag that converts the provided value is a string.
77
+ *
78
+ * Throws an error if the string is not a valid URL.
74
79
  */
75
80
  exports.url = custom({
76
81
  async parse(input) {
@@ -82,7 +87,13 @@ exports.url = custom({
82
87
  }
83
88
  },
84
89
  });
90
+ /**
91
+ * A string flag.
92
+ */
85
93
  exports.string = custom();
94
+ /**
95
+ * Version flag that will print the CLI version and exit.
96
+ */
86
97
  const version = (opts = {}) => boolean({
87
98
  description: 'Show CLI version.',
88
99
  ...opts,
@@ -92,6 +103,9 @@ const version = (opts = {}) => boolean({
92
103
  },
93
104
  });
94
105
  exports.version = version;
106
+ /**
107
+ * A help flag that will print the CLI help and exit.
108
+ */
95
109
  const help = (opts = {}) => boolean({
96
110
  description: 'Show CLI help.',
97
111
  ...opts,
@@ -102,18 +116,6 @@ const help = (opts = {}) => boolean({
102
116
  },
103
117
  });
104
118
  exports.help = help;
105
- /**
106
- * Create a custom flag that infers the flag type from the provided options.
107
- *
108
- * @example
109
- * export default class MyCommand extends Command {
110
- * static flags = {
111
- * name: Flags.option({
112
- * options: ['foo', 'bar'] as const,
113
- * })(),
114
- * }
115
- * }
116
- */
117
119
  function option(defaults) {
118
120
  return (options = {}) => ({
119
121
  parse: async (input, _ctx, _opts) => input,
package/lib/util/fs.d.ts CHANGED
@@ -18,4 +18,3 @@ export declare function readJsonSync(path: string, parse: false): string;
18
18
  export declare function readJsonSync<T = unknown>(path: string, parse?: true): T;
19
19
  export declare function safeReadJson<T>(path: string): Promise<T | undefined>;
20
20
  export declare function existsSync(path: string): boolean;
21
- export declare function readTSConfig(path: string): Promise<any>;
package/lib/util/fs.js CHANGED
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readTSConfig = exports.existsSync = exports.safeReadJson = exports.readJsonSync = exports.readJson = exports.fileExists = exports.dirExists = exports.requireJson = void 0;
3
+ exports.existsSync = exports.safeReadJson = exports.readJsonSync = exports.readJson = exports.fileExists = exports.dirExists = exports.requireJson = void 0;
4
4
  const node_fs_1 = require("node:fs");
5
5
  const promises_1 = require("node:fs/promises");
6
6
  const node_path_1 = require("node:path");
7
- const util_1 = require("./util");
8
7
  function requireJson(...pathParts) {
9
8
  return JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(...pathParts), 'utf8'));
10
9
  }
@@ -70,10 +69,3 @@ function existsSync(path) {
70
69
  return (0, node_fs_1.existsSync)(path);
71
70
  }
72
71
  exports.existsSync = existsSync;
73
- async function readTSConfig(path) {
74
- const { parse } = await import('tsconfck');
75
- const result = await parse(path);
76
- const tsNodeOpts = (0, util_1.mergeNestedObjects)(result.extended ?? [result], 'tsconfig.ts-node');
77
- return { ...result.tsconfig, 'ts-node': tsNodeOpts };
78
- }
79
- exports.readTSConfig = readTSConfig;
@@ -0,0 +1,2 @@
1
+ import { TSConfig } from '../interfaces';
2
+ export declare function readTSConfig(root: string, tsconfigName?: string): Promise<TSConfig | undefined>;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.readTSConfig = void 0;
7
+ const debug_1 = __importDefault(require("debug"));
8
+ const promises_1 = require("node:fs/promises");
9
+ const node_path_1 = require("node:path");
10
+ const errors_1 = require("../errors");
11
+ const util_1 = require("./util");
12
+ const debug = (0, debug_1.default)('read-tsconfig');
13
+ function resolve(root, name) {
14
+ try {
15
+ return require.resolve(name, { paths: [root] });
16
+ }
17
+ catch {
18
+ // return undefined
19
+ }
20
+ }
21
+ async function upUntil(path, test) {
22
+ let result;
23
+ try {
24
+ result = await test(path);
25
+ }
26
+ catch {
27
+ result = false;
28
+ }
29
+ if (result)
30
+ return path;
31
+ const parent = (0, node_path_1.dirname)(path);
32
+ if (parent === path)
33
+ return;
34
+ return upUntil(parent, test);
35
+ }
36
+ async function readTSConfig(root, tsconfigName = 'tsconfig.json') {
37
+ const found = [];
38
+ let typescript;
39
+ try {
40
+ typescript = require('typescript');
41
+ }
42
+ catch {
43
+ try {
44
+ typescript = require(root + '/node_modules/typescript');
45
+ }
46
+ catch { }
47
+ }
48
+ if (!typescript) {
49
+ (0, errors_1.memoizedWarn)('Could not find typescript. Please ensure that typescript is a devDependency. Falling back to compiled source.');
50
+ return;
51
+ }
52
+ const read = async (path) => {
53
+ const localRoot = await upUntil(path, async (p) =>
54
+ // eslint-disable-next-line unicorn/no-await-expression-member
55
+ (await (0, promises_1.readdir)(p)).includes('package.json'));
56
+ if (!localRoot)
57
+ return;
58
+ try {
59
+ const contents = await (0, promises_1.readFile)(path, 'utf8');
60
+ const parsed = typescript?.parseConfigFileTextToJson(path, contents).config;
61
+ found.push(parsed);
62
+ if (parsed.extends) {
63
+ if (parsed.extends.startsWith('.')) {
64
+ const nextPath = resolve(localRoot, parsed.extends);
65
+ return nextPath ? read(nextPath) : undefined;
66
+ }
67
+ const resolved = resolve(localRoot, parsed.extends);
68
+ if (resolved)
69
+ return read(resolved);
70
+ }
71
+ return parsed;
72
+ }
73
+ catch (error) {
74
+ debug(error);
75
+ }
76
+ };
77
+ await read((0, node_path_1.join)(root, tsconfigName));
78
+ return {
79
+ compilerOptions: (0, util_1.mergeNestedObjects)(found, 'compilerOptions'),
80
+ 'ts-node': (0, util_1.mergeNestedObjects)(found, 'ts-node'),
81
+ };
82
+ }
83
+ exports.readTSConfig = readTSConfig;
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@oclif/core",
3
3
  "description": "base library for oclif CLIs",
4
- "version": "3.17.0",
4
+ "version": "3.18.1",
5
5
  "author": "Salesforce",
6
6
  "bugs": "https://github.com/oclif/core/issues",
7
7
  "dependencies": {
8
+ "@types/cli-progress": "^3.11.5",
8
9
  "ansi-escapes": "^4.3.2",
9
10
  "ansi-styles": "^4.3.0",
10
11
  "cardinal": "^2.1.1",
@@ -28,7 +29,6 @@
28
29
  "strip-ansi": "^6.0.1",
29
30
  "supports-color": "^8.1.1",
30
31
  "supports-hyperlinks": "^2.2.0",
31
- "tsconfck": "^3.0.0",
32
32
  "widest-line": "^3.1.0",
33
33
  "wordwrap": "^1.0.0",
34
34
  "wrap-ansi": "^7.0.0"
@@ -44,7 +44,6 @@
44
44
  "@types/chai": "^4.3.11",
45
45
  "@types/chai-as-promised": "^7.1.8",
46
46
  "@types/clean-stack": "^2.1.1",
47
- "@types/cli-progress": "^3.11.5",
48
47
  "@types/color": "^3.0.5",
49
48
  "@types/debug": "^4.1.10",
50
49
  "@types/ejs": "^3.1.5",
@@ -66,7 +65,7 @@
66
65
  "cross-env": "^7.0.3",
67
66
  "eslint": "^8.50.0",
68
67
  "eslint-config-oclif": "^5.0.0",
69
- "eslint-config-oclif-typescript": "^3.0.1",
68
+ "eslint-config-oclif-typescript": "^3.0.35",
70
69
  "eslint-config-prettier": "^9.0.0",
71
70
  "fancy-test": "^3.0.1",
72
71
  "globby": "^11.1.0",
@@ -121,8 +120,8 @@
121
120
  "pretest": "yarn build && tsc -p test --noEmit --skipLibCheck",
122
121
  "test:circular-deps": "madge lib/ -c",
123
122
  "test:debug": "nyc mocha --debug-brk --inspect \"test/**/*.test.ts\"",
124
- "test:e2e": "mocha --forbid-only \"test/**/*.e2e.ts\" --parallel --timeout 1200000",
125
- "test:esm-cjs": "cross-env DEBUG=e2e:* ts-node test/integration/esm-cjs.ts",
123
+ "test:integration": "mocha --forbid-only \"test/**/*.integration.ts\" --parallel --timeout 1200000",
124
+ "test:esm-cjs": "cross-env DEBUG=integration:* ts-node test/integration/esm-cjs.ts",
126
125
  "test:perf": "ts-node test/perf/parser.perf.ts",
127
126
  "test:dev": "nyc mocha \"test/**/*.test.ts\"",
128
127
  "test": "nyc mocha --forbid-only \"test/**/*.test.ts\""