diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2a62696d..b158462b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -664,8 +664,8 @@ packages: resolution: {integrity: sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ==} dev: true - /@types/node@20.8.9: - resolution: {integrity: sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==} + /@types/node@20.8.10: + resolution: {integrity: sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==} dependencies: undici-types: 5.26.5 dev: true @@ -838,8 +838,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001558 - electron-to-chromium: 1.4.569 + caniuse-lite: 1.0.30001559 + electron-to-chromium: 1.4.572 node-releases: 2.0.13 update-browserslist-db: 1.0.13(browserslist@4.22.1) dev: true @@ -882,8 +882,8 @@ packages: engines: {node: '>=6'} dev: true - /caniuse-lite@1.0.30001558: - resolution: {integrity: sha512-/Et7DwLqpjS47JPEcz6VnxU9PwcIdVi0ciLXRWBQdj1XFye68pSQYpV0QtPTfUKWuOaEig+/Vez2l74eDc1tPQ==} + /caniuse-lite@1.0.30001559: + resolution: {integrity: sha512-cPiMKZgqgkg5LY3/ntGeLFUpi6tzddBNS58A4tnTgQw1zON7u2sZMU7SzOeVH4tj20++9ggL+V6FDOFMTaFFYA==} dev: true /chai@4.3.10: @@ -1021,8 +1021,8 @@ packages: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true - /electron-to-chromium@1.4.569: - resolution: {integrity: sha512-LsrJjZ0IbVy12ApW3gpYpcmHS3iRxH4bkKOW98y1/D+3cvDUWGcbzbsFinfUS8knpcZk/PG/2p/RnkMCYN7PVg==} + /electron-to-chromium@1.4.572: + resolution: {integrity: sha512-RlFobl4D3ieetbnR+2EpxdzFl9h0RAJkPK3pfiwMug2nhBin2ZCsGIAJWdpNniLz43sgXam/CgipOmvTA+rUiA==} dev: true /emoji-regex@10.3.0: @@ -1862,8 +1862,8 @@ packages: - supports-color dev: true - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} dev: true @@ -2155,7 +2155,7 @@ packages: /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 dev: true /uuid@8.3.2: @@ -2172,7 +2172,7 @@ packages: convert-source-map: 2.0.0 dev: true - /vite-node@0.34.6(@types/node@20.8.9): + /vite-node@0.34.6(@types/node@20.8.10): resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} engines: {node: '>=v14.18.0'} hasBin: true @@ -2182,7 +2182,7 @@ packages: mlly: 1.4.2 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.5.0(@types/node@20.8.9) + vite: 4.5.0(@types/node@20.8.10) transitivePeerDependencies: - '@types/node' - less @@ -2194,7 +2194,7 @@ packages: - terser dev: true - /vite@4.5.0(@types/node@20.8.9): + /vite@4.5.0(@types/node@20.8.10): resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -2222,7 +2222,7 @@ packages: terser: optional: true dependencies: - '@types/node': 20.8.9 + '@types/node': 20.8.10 esbuild: 0.18.20 postcss: 8.4.31 rollup: 3.29.4 @@ -2263,7 +2263,7 @@ packages: dependencies: '@types/chai': 4.3.9 '@types/chai-subset': 1.3.4 - '@types/node': 20.8.9 + '@types/node': 20.8.10 '@vitest/expect': 0.34.6 '@vitest/runner': 0.34.6 '@vitest/snapshot': 0.34.6 @@ -2282,8 +2282,8 @@ packages: strip-literal: 1.3.0 tinybench: 2.5.1 tinypool: 0.7.0 - vite: 4.5.0(@types/node@20.8.9) - vite-node: 0.34.6(@types/node@20.8.9) + vite: 4.5.0(@types/node@20.8.10) + vite-node: 0.34.6(@types/node@20.8.10) why-is-node-running: 2.2.2 transitivePeerDependencies: - less diff --git a/src/cli.js b/src/cli.js index 8bab96e8..f1df58b8 100644 --- a/src/cli.js +++ b/src/cli.js @@ -211,6 +211,7 @@ export class CLI { applyCommandConfig(this, cmdName, cmd, conf); if (conf.platforms) { + this.debugLogger.trace(`Detected conf.platforms applying config for "${cmd.name()}", overriding createHelp()`); this.command.createHelp = () => { return Object.assign(new TiHelp(this, conf.platforms), this.command.configureHelp()); }; @@ -548,6 +549,10 @@ export class CLI { await program.parseAsync(); this.debugLogger.trace('Finished parsing arguments first pass'); + if (this.command === program && program.args.length) { + throw new TiError(`Unknown command "${program.args[0]}"`, { showHelp: true }); + } + // reset hooks const resetHooksAndOptionHandlers = ctx => { ctx._lifeCycleHooks = {}; @@ -612,6 +617,8 @@ export class CLI { const platformConf = this.command.conf.platforms[this.argv.platform]; this.argv.$platform = this.argv.platform; + + // set platform context this.command.platform = { conf: platformConf }; @@ -688,23 +695,6 @@ export class CLI { // TODO: Prompt for missing required options - // // any keys in the conf object that aren't explicitly 'flags', - // // 'options', 'args', or 'subcommands' is probably a option branch - // // that changes the available flags/options - // const skipRegExp = /^(flags|options|args|subcommands)$/; - // const optionBranches = Object.keys(conf) - // .filter(name => conf.options && conf.options[name] && !skipRegExp.test(name)) - // .sort((a, b) => { - // // if we have multiple option groups, then try to process them in order - // if (!conf.options[a] || !conf.options[a].order) { - // return 1; - // } - // if (!conf.options[b] || !conf.options[b].order) { - // return -1; - // } - // return conf.options[b].order - conf.options[a].order; - // }); - // for (const name of optionBranches) { // const option = conf.options[name]; // const optionBranch = conf[name]; @@ -785,7 +775,7 @@ export class CLI { cmdName, config: this.config, cwd, - logger: this.debugLogger, + logger: this.logger, promptingEnabled: this.promptingEnabled, selectedSdk: this.argv.sdk }); @@ -878,6 +868,13 @@ export class CLI { this.debugLogger.trace(`Importing: ${commandFile}`); cmd.module = (await import(commandFile)) || {}; + // check if this command is compatible with this version of the CLI + if (cmd.module.cliVersion && !version.satisfies(this.version, cmd.module.cliVersion)) { + throw new TiError(`Command "${cmdName}" incompatible with this version of the CLI`, { + after: `Requires version ${cmd.module.cliVersion}, currently ${this.version}` + }); + } + if (typeof cmd.module.extendedDesc === 'string') { desc = cmd.module.extendedDesc; } else if (desc) { @@ -900,6 +897,7 @@ export class CLI { } if (conf.platforms) { + this.debugLogger.trace(`Detected conf.platforms loading "${cmdName}", overriding createHelp()`); this.command.createHelp = () => { return Object.assign(new TiHelp(this, conf.platforms), this.command.configureHelp()); }; diff --git a/src/commands/info.js b/src/commands/info.js index 16ac76b0..6a21a223 100644 --- a/src/commands/info.js +++ b/src/commands/info.js @@ -80,7 +80,7 @@ export async function run(logger, config, cli) { ({ data, platformInfo - } = await detect(logger, config, cli, types)); + } = await detect(cli.debugLogger, config, cli, types)); } finally { busy?.stop(); } diff --git a/src/commands/module.js b/src/commands/module.js index 9d018f0b..a07e3501 100644 --- a/src/commands/module.js +++ b/src/commands/module.js @@ -50,7 +50,11 @@ export function config(logger, config, cli) { * @param {Function} finished - Callback when the command finishes */ export async function run(logger, config, cli) { - const action = cli.command.name(); + let action = cli.command.name(); + if (action === 'list' && cli.command.args.length) { + action = cli.command.args[0]; + cli.command = cli.command.parent; + } for (const [name, subcommand] of Object.entries(ModuleSubcommands)) { if (action === name || action === subcommand.alias) { await ModuleSubcommands[name].fn(logger, config, cli); @@ -145,7 +149,7 @@ ModuleSubcommands.list = { } } - const results = await detect(searchPaths, config, logger); + const results = await detect(searchPaths, config, cli.debugLogger); if (isJson) { logger.log(JSON.stringify(results, null, '\t')); diff --git a/src/commands/sdk.js b/src/commands/sdk.js index 2d484bd2..ec3b1711 100644 --- a/src/commands/sdk.js +++ b/src/commands/sdk.js @@ -53,7 +53,11 @@ export function config(logger, config, cli) { * @param {CLI} cli - The CLI instance */ export async function run(logger, config, cli) { - const action = cli.command.name(); + let action = cli.command.name(); + if (action === 'list' && cli.command.args.length) { + action = cli.command.args[0]; + cli.command = cli.command.parent; + } for (const [name, subcommand] of Object.entries(SdkSubcommands)) { if (action === name || action === subcommand.alias) { await SdkSubcommands[name].fn(logger, config, cli); diff --git a/src/util/prompt.js b/src/util/prompt.js index 40e739b5..45f6bb9f 100644 --- a/src/util/prompt.js +++ b/src/util/prompt.js @@ -6,6 +6,11 @@ export async function prompt(opts) { const { default: prompts } = await import('prompts'); const { prompt } = prompts; + + if (Array.isArray(opts)) { + return await prompt(opts); + } + const { value } = await prompt({ ...opts, name: 'value' diff --git a/src/util/setup-screens.js b/src/util/setup-screens.js index d9c33f3d..d62d4991 100644 --- a/src/util/setup-screens.js +++ b/src/util/setup-screens.js @@ -103,10 +103,9 @@ export class SetupScreens { } Exit` ); - const { value } = await prompt({ + const value = await prompt({ type: 'text', - message: 'Where do you want to go?', - name: 'value' + message: 'Where do you want to go?' }); const next = lookup[value]; @@ -124,7 +123,7 @@ export class SetupScreens { busy.start(); try { - ({ data } = await detect(this.logger, this.config, this.cli, { all: true })); + ({ data } = await detect(this.cli.debugLogger, this.config, this.cli, { all: true })); } finally { busy.stop(); } @@ -209,7 +208,7 @@ export class SetupScreens { } try { - ({ data } = await detect(this.logger, this.config, this.cli, { all: true })); + ({ data } = await detect(this.cli.debugLogger, this.config, this.cli, { all: true })); data.titaniumCLI.latest = await request('https://registry.npmjs.org/-/package/titanium/dist-tags') .then(res => res.body.json()) @@ -287,7 +286,7 @@ export class SetupScreens { busy.start(); try { - ({ data } = await detect(this.logger, this.config, this.cli, { all: true })); + ({ data } = await detect(this.cli.debugLogger, this.config, this.cli, { all: true })); } finally { busy.stop(); } @@ -714,7 +713,7 @@ export class SetupScreens { busy.start(); try { - ({ data } = await detect(this.logger, this.config, this.cli, { all: true })); + ({ data } = await detect(this.cli.debugLogger, this.config, this.cli, { all: true })); } finally { busy.stop(); } @@ -797,7 +796,7 @@ export class SetupScreens { busy.start(); try { - ({ data } = await detect(this.logger, this.config, this.cli, { all: true })); + ({ data } = await detect(this.cli.debugLogger, this.config, this.cli, { all: true })); } finally { busy.stop(); } diff --git a/src/util/tisdk.js b/src/util/tisdk.js index ed6174ec..2336198b 100644 --- a/src/util/tisdk.js +++ b/src/util/tisdk.js @@ -193,13 +193,12 @@ export async function initSDK({ cmdName, config, cwd, logger, promptingEnabled, } } - ({ sdkVersion } = await prompt({ + sdkVersion = await prompt({ type: 'select', message: 'Which Titanium SDK would you like to use?', - name: 'sdkVersion', initial: sdk ? choices.find(s => s.name === sdk.name)?.name : undefined, choices - })); + }); if (sdkVersion === undefined) { // sigint