@oclif/core 3.19.6 → 3.20.0

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.
@@ -44,7 +44,7 @@ const fs_1 = require("../util/fs");
44
44
  const os_1 = require("../util/os");
45
45
  const util_2 = require("../util/util");
46
46
  const plugin_loader_1 = __importDefault(require("./plugin-loader"));
47
- const ts_node_1 = require("./ts-node");
47
+ const ts_path_1 = require("./ts-path");
48
48
  const util_3 = require("./util");
49
49
  // eslint-disable-next-line new-cap
50
50
  const debug = (0, util_3.Debug)();
@@ -485,7 +485,7 @@ class Config {
485
485
  const marker = performance_1.Performance.mark(performance_1.OCLIF_MARKER_OWNER, `config.runHook#${p.name}(${hook})`);
486
486
  try {
487
487
  /* eslint-disable no-await-in-loop */
488
- const { filePath, isESM, module } = await (0, module_loader_1.loadWithData)(p, await (0, ts_node_1.tsPath)(p.root, hook, p));
488
+ const { filePath, isESM, module } = await (0, module_loader_1.loadWithData)(p, await (0, ts_path_1.tsPath)(p.root, hook, p));
489
489
  debug('start', isESM ? '(import)' : '(require)', filePath);
490
490
  const result = timeout
491
491
  ? await withTimeout(timeout, search(module).call(context, { ...opts, config: this, context }))
@@ -1,3 +1,3 @@
1
1
  export { Config } from './config';
2
2
  export { Plugin } from './plugin';
3
- export { tsPath } from './ts-node';
3
+ export { tsPath } from './ts-path';
@@ -5,5 +5,5 @@ var config_1 = require("./config");
5
5
  Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return config_1.Config; } });
6
6
  var plugin_1 = require("./plugin");
7
7
  Object.defineProperty(exports, "Plugin", { enumerable: true, get: function () { return plugin_1.Plugin; } });
8
- var ts_node_1 = require("./ts-node");
9
- Object.defineProperty(exports, "tsPath", { enumerable: true, get: function () { return ts_node_1.tsPath; } });
8
+ var ts_path_1 = require("./ts-path");
9
+ Object.defineProperty(exports, "tsPath", { enumerable: true, get: function () { return ts_path_1.tsPath; } });
@@ -14,7 +14,7 @@ const cache_command_1 = require("../util/cache-command");
14
14
  const find_root_1 = require("../util/find-root");
15
15
  const fs_1 = require("../util/fs");
16
16
  const util_1 = require("../util/util");
17
- const ts_node_1 = require("./ts-node");
17
+ const ts_path_1 = require("./ts-path");
18
18
  const util_2 = require("./util");
19
19
  const _pjson = (0, fs_1.requireJson)(__dirname, '..', '..', 'package.json');
20
20
  function topicsToArray(input, base) {
@@ -261,7 +261,7 @@ class Plugin {
261
261
  async getCommandsDir() {
262
262
  if (this.commandsDir)
263
263
  return this.commandsDir;
264
- this.commandsDir = await (0, ts_node_1.tsPath)(this.root, this.pjson.oclif.commands, this);
264
+ this.commandsDir = await (0, ts_path_1.tsPath)(this.root, this.pjson.oclif.commands, this);
265
265
  return this.commandsDir;
266
266
  }
267
267
  warn(err, scope) {
@@ -13,9 +13,50 @@ const read_tsconfig_1 = require("../util/read-tsconfig");
13
13
  const util_1 = require("../util/util");
14
14
  const util_2 = require("./util");
15
15
  // eslint-disable-next-line new-cap
16
- const debug = (0, util_2.Debug)('ts-node');
16
+ const debug = (0, util_2.Debug)('ts-path');
17
17
  exports.TS_CONFIGS = {};
18
18
  const REGISTERED = new Set();
19
+ function determineRuntime() {
20
+ /**
21
+ * Examples:
22
+ * #!/usr/bin/env bun
23
+ * bun bin/run.js
24
+ * bun bin/dev.js
25
+ */
26
+ if (process.execPath.split(node_path_1.sep).includes('bun'))
27
+ return 'bun';
28
+ /**
29
+ * Examples:
30
+ * #!/usr/bin/env node
31
+ * #!/usr/bin/env node --loader ts-node/esm --experimental-specifier-resolution=node --no-warnings
32
+ * node bin/run.js
33
+ * node bin/dev.js
34
+ */
35
+ if (process.execArgv.length === 0)
36
+ return 'node';
37
+ /**
38
+ * Examples:
39
+ * #!/usr/bin/env ts-node
40
+ * #!/usr/bin/env node_modules/.bin/ts-node
41
+ * ts-node bin/run.js
42
+ * ts-node bin/dev.js
43
+ */
44
+ if (process.execArgv[0] === '--require' && process.execArgv[1].split(node_path_1.sep).includes('ts-node'))
45
+ return 'ts-node';
46
+ if (process.execArgv[0].split(node_path_1.sep).includes('ts-node'))
47
+ return 'ts-node';
48
+ /**
49
+ * Examples:
50
+ * #!/usr/bin/env tsx
51
+ * #!/usr/bin/env node_modules/.bin/tsx
52
+ * tsx bin/run.js
53
+ * tsx bin/dev.js
54
+ */
55
+ if (process.execArgv[0] === '--require' && process.execArgv[1].split(node_path_1.sep).includes('tsx'))
56
+ return 'tsx';
57
+ return 'node';
58
+ }
59
+ const RUN_TIME = determineRuntime();
19
60
  function isErrno(error) {
20
61
  return 'code' in error && error.code === 'ENOENT';
21
62
  }
@@ -23,22 +64,23 @@ async function loadTSConfig(root) {
23
64
  try {
24
65
  if (exports.TS_CONFIGS[root])
25
66
  return exports.TS_CONFIGS[root];
26
- exports.TS_CONFIGS[root] = await (0, read_tsconfig_1.readTSConfig)(root);
67
+ const tsconfig = await (0, read_tsconfig_1.readTSConfig)(root);
68
+ if (!tsconfig)
69
+ return;
70
+ debug('tsconfig: %O', tsconfig);
71
+ exports.TS_CONFIGS[root] = tsconfig;
27
72
  return exports.TS_CONFIGS[root];
28
73
  }
29
74
  catch (error) {
30
75
  if (isErrno(error))
31
76
  return;
32
- debug(`Could not parse tsconfig.json. Skipping ts-node registration for ${root}.`);
77
+ debug(`Could not parse tsconfig.json. Skipping typescript path lookup for ${root}.`);
33
78
  (0, errors_1.memoizedWarn)(`Could not parse tsconfig.json for ${root}. Falling back to compiled source.`);
34
79
  }
35
80
  }
36
- async function registerTSNode(root) {
37
- const tsconfig = await loadTSConfig(root);
38
- if (!tsconfig)
39
- return;
81
+ async function registerTSNode(root, tsconfig) {
40
82
  if (REGISTERED.has(root))
41
- return tsconfig;
83
+ return;
42
84
  debug('registering ts-node at', root);
43
85
  const tsNodePath = require.resolve('ts-node', { paths: [root, __dirname] });
44
86
  debug('ts-node path:', tsNodePath);
@@ -87,11 +129,9 @@ async function registerTSNode(root) {
87
129
  skipProject: true,
88
130
  transpileOnly: true,
89
131
  };
132
+ debug('ts-node options: %O', conf);
90
133
  tsNode.register(conf);
91
134
  REGISTERED.add(root);
92
- debug('tsconfig: %O', tsconfig);
93
- debug('ts-node options: %O', conf);
94
- return tsconfig;
95
135
  }
96
136
  /**
97
137
  * Skip ts-node registration for ESM plugins in production.
@@ -121,17 +161,22 @@ function cannotUseTsNode(root, plugin, isProduction) {
121
161
  if (plugin?.moduleType !== 'module' || isProduction)
122
162
  return false;
123
163
  const nodeMajor = Number.parseInt(process.version.replace('v', '').split('.')[0], 10);
124
- const tsNodeExecIsUsed = process.execArgv[0] === '--require' && process.execArgv[1].split(node_path_1.sep).includes(`ts-node`);
125
- return tsNodeExecIsUsed && nodeMajor >= 20;
164
+ return RUN_TIME === 'ts-node' && nodeMajor >= 20;
126
165
  }
127
166
  /**
128
167
  * Determine the path to the source file from the compiled ./lib files
129
168
  */
130
169
  async function determinePath(root, orig) {
131
- const tsconfig = await registerTSNode(root);
170
+ const tsconfig = await loadTSConfig(root);
132
171
  if (!tsconfig)
133
172
  return orig;
134
- debug(`determining path for ${orig}`);
173
+ debug(`Determining path for ${orig}`);
174
+ if (RUN_TIME === 'tsx' || RUN_TIME === 'bun') {
175
+ debug(`Skipping ts-node registration for ${root} because the runtime is: ${RUN_TIME}`);
176
+ }
177
+ else {
178
+ await registerTSNode(root, tsconfig);
179
+ }
135
180
  const { baseUrl, outDir, rootDir, rootDirs } = tsconfig.compilerOptions;
136
181
  const rootDirPath = rootDir ?? (rootDirs ?? [])[0] ?? baseUrl;
137
182
  if (!rootDirPath) {
@@ -171,24 +216,25 @@ async function tsPath(root, orig, plugin) {
171
216
  return orig;
172
217
  orig = orig.startsWith(root) ? orig : (0, node_path_1.join)(root, orig);
173
218
  // NOTE: The order of these checks matter!
174
- if (settings_1.settings.tsnodeEnabled === false) {
175
- debug(`Skipping ts-node registration for ${root} because tsNodeEnabled is explicitly set to false`);
219
+ const enableAutoTranspile = settings_1.settings.enableAutoTranspile ?? settings_1.settings.tsnodeEnabled;
220
+ if (enableAutoTranspile === false) {
221
+ debug(`Skipping typescript path lookup for ${root} because enableAutoTranspile is explicitly set to false`);
176
222
  return orig;
177
223
  }
178
224
  const isProduction = (0, util_1.isProd)();
179
225
  // Do not skip ts-node registration if the plugin is linked
180
- if (settings_1.settings.tsnodeEnabled === undefined && isProduction && plugin?.type !== 'link') {
181
- debug(`Skipping ts-node registration for ${root} because NODE_ENV is NOT "test" or "development"`);
226
+ if (enableAutoTranspile === undefined && isProduction && plugin?.type !== 'link') {
227
+ debug(`Skipping typescript path lookup for ${root} because NODE_ENV is NOT "test" or "development"`);
182
228
  return orig;
183
229
  }
184
230
  if (cannotTranspileEsm(rootPlugin, plugin, isProduction)) {
185
- debug(`Skipping ts-node registration for ${root} because it's an ESM module (NODE_ENV: ${process.env.NODE_ENV}, root plugin module type: ${rootPlugin?.moduleType})`);
231
+ debug(`Skipping typescript path lookup for ${root} because it's an ESM module (NODE_ENV: ${process.env.NODE_ENV}, root plugin module type: ${rootPlugin?.moduleType})`);
186
232
  if (plugin?.type === 'link')
187
233
  (0, errors_1.memoizedWarn)(`${plugin?.name} is a linked ESM module and cannot be auto-transpiled. Existing compiled source will be used instead.`);
188
234
  return orig;
189
235
  }
190
236
  if (cannotUseTsNode(root, plugin, isProduction)) {
191
- debug(`Skipping ts-node registration for ${root} because ts-node is run in node version ${process.version}"`);
237
+ debug(`Skipping typescript path lookup for ${root} because ts-node is run in node version ${process.version}"`);
192
238
  (0, errors_1.memoizedWarn)(`ts-node executable cannot transpile ESM in Node 20. Existing compiled source will be used instead. See https://github.com/oclif/core/issues/817.`);
193
239
  return orig;
194
240
  }
package/lib/main.js CHANGED
@@ -38,6 +38,11 @@ async function run(argv, options) {
38
38
  await performance_1.Performance.collect();
39
39
  performance_1.Performance.debug();
40
40
  };
41
+ const showHelp = async (argv) => {
42
+ const Help = await (0, help_1.loadHelpClass)(config);
43
+ const help = new Help(config, config.pjson.oclif.helpOptions ?? config.pjson.helpOptions);
44
+ await help.showHelp(argv);
45
+ };
41
46
  debug(`process.execPath: ${process.execPath}`);
42
47
  debug(`process.execArgv: ${process.execArgv}`);
43
48
  debug('process.argv: %O', process.argv);
@@ -58,9 +63,7 @@ async function run(argv, options) {
58
63
  }
59
64
  // display help version if applicable
60
65
  if ((0, exports.helpAddition)(argv, config)) {
61
- const Help = await (0, help_1.loadHelpClass)(config);
62
- const help = new Help(config, config.pjson.oclif.helpOptions ?? config.pjson.helpOptions);
63
- await help.showHelp(argv);
66
+ await showHelp(argv);
64
67
  await collectPerf();
65
68
  return;
66
69
  }
@@ -68,8 +71,11 @@ async function run(argv, options) {
68
71
  const cmd = config.findCommand(id);
69
72
  if (!cmd) {
70
73
  const topic = config.flexibleTaxonomy ? null : config.findTopic(id);
71
- if (topic)
72
- return config.runCommand('help', [id]);
74
+ if (topic) {
75
+ await showHelp([id]);
76
+ await collectPerf();
77
+ return;
78
+ }
73
79
  if (config.pjson.oclif.default) {
74
80
  id = config.pjson.oclif.default;
75
81
  argvSlice = argv;
@@ -4,7 +4,7 @@ exports.isPathModule = exports.loadWithDataFromManifest = exports.loadWithData =
4
4
  const node_fs_1 = require("node:fs");
5
5
  const node_path_1 = require("node:path");
6
6
  const node_url_1 = require("node:url");
7
- const ts_node_1 = require("./config/ts-node");
7
+ const ts_path_1 = require("./config/ts-path");
8
8
  const errors_1 = require("./errors");
9
9
  const fs_1 = require("./util/fs");
10
10
  const getPackageType = require('get-package-type');
@@ -164,7 +164,7 @@ async function resolvePath(config, modulePath) {
164
164
  }
165
165
  catch {
166
166
  filePath =
167
- (isPlugin(config) ? await (0, ts_node_1.tsPath)(config.root, modulePath, config) : await (0, ts_node_1.tsPath)(config.root, modulePath)) ??
167
+ (isPlugin(config) ? await (0, ts_path_1.tsPath)(config.root, modulePath, config) : await (0, ts_path_1.tsPath)(config.root, modulePath)) ??
168
168
  modulePath;
169
169
  let fileExists = false;
170
170
  let isDirectory = false;
package/lib/settings.d.ts CHANGED
@@ -9,7 +9,7 @@ export type Settings = {
9
9
  /**
10
10
  * Show additional debug output without DEBUG. Mainly shows stackstraces.
11
11
  *
12
- * Useful to set in the ./bin/dev script.
12
+ * Useful to set in the ./bin/dev.js script.
13
13
  * oclif.settings.debug = true;
14
14
  */
15
15
  debug?: boolean;
@@ -25,15 +25,18 @@ export type Settings = {
25
25
  */
26
26
  performanceEnabled?: boolean;
27
27
  /**
28
- * Try to use ts-node to load typescript source files instead of
29
- * javascript files.
28
+ * Try to use ts-node to load typescript source files instead of javascript files.
29
+ * Defaults to true in development and test environments (e.g. using bin/dev.js or
30
+ * NODE_ENV=development or NODE_ENV=test).
30
31
  *
31
- * NOTE: This requires registering ts-node first.
32
- * require('ts-node').register();
33
- *
34
- * Environment Variable:
35
- * NODE_ENV=development
32
+ * @deprecated use enableAutoTranspile instead.
36
33
  */
37
34
  tsnodeEnabled?: boolean;
35
+ /**
36
+ * Enable automatic transpilation of TypeScript files to JavaScript.
37
+ *
38
+ * Defaults to true in development and test environments (e.g. using bin/dev.js or NODE_ENV=development or NODE_ENV=test).
39
+ */
40
+ enableAutoTranspile?: boolean;
38
41
  };
39
42
  export declare const settings: Settings;
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.19.6",
4
+ "version": "3.20.0",
5
5
  "author": "Salesforce",
6
6
  "bugs": "https://github.com/oclif/core/issues",
7
7
  "dependencies": {
@@ -64,10 +64,10 @@
64
64
  "commitlint": "^17.8.1",
65
65
  "cross-env": "^7.0.3",
66
66
  "eslint": "^8.56.0",
67
- "eslint-config-oclif": "^5.0.0",
68
- "eslint-config-oclif-typescript": "^3.0.47",
67
+ "eslint-config-oclif": "^5.0.2",
68
+ "eslint-config-oclif-typescript": "^3.0.48",
69
69
  "eslint-config-prettier": "^9.1.0",
70
- "fancy-test": "^3.0.1",
70
+ "fancy-test": "^3.0.11",
71
71
  "globby": "^11.1.0",
72
72
  "husky": "^8",
73
73
  "lint-staged": "^14.0.1",
@@ -78,7 +78,7 @@
78
78
  "shx": "^0.3.4",
79
79
  "sinon": "^16.1.3",
80
80
  "ts-node": "^10.9.2",
81
- "tsd": "^0.30.4",
81
+ "tsd": "^0.30.6",
82
82
  "typescript": "^5"
83
83
  },
84
84
  "engines": {
@@ -127,7 +127,7 @@
127
127
  "test:circular-deps": "madge lib/ -c",
128
128
  "test:debug": "nyc mocha --debug-brk --inspect \"test/**/*.test.ts\"",
129
129
  "test:integration": "mocha --forbid-only \"test/**/*.integration.ts\" --parallel --timeout 1200000",
130
- "test:esm-cjs": "cross-env DEBUG=integration:* ts-node test/integration/esm-cjs.ts",
130
+ "test:interoperability": "cross-env DEBUG=integration:* ts-node test/integration/interop.ts",
131
131
  "test:perf": "ts-node test/perf/parser.perf.ts",
132
132
  "test:dev": "nyc mocha \"test/**/*.test.ts\"",
133
133
  "test": "nyc mocha --forbid-only \"test/**/*.test.ts\""
File without changes