Comparing version 7.0.0-beta4 to 7.0.0-beta5
{ | ||
"name": "titanium", | ||
"version": "7.0.0-beta4", | ||
"version": "7.0.0-beta5", | ||
"author": "TiDev, Inc. <npm@tidev.io>", | ||
@@ -28,3 +28,3 @@ "description": "Command line interface for building Titanium SDK apps", | ||
"semver": "7.5.4", | ||
"undici": "6.3.0", | ||
"undici": "6.4.0", | ||
"which": "4.0.0", | ||
@@ -37,3 +37,3 @@ "wrap-ansi": "9.0.0", | ||
"@reporters/github": "1.5.4", | ||
"@vitest/coverage-istanbul": "1.2.0", | ||
"@vitest/coverage-istanbul": "1.2.1", | ||
"c8": "9.1.0", | ||
@@ -40,0 +40,0 @@ "eslint": "8.56.0", |
237
src/cli.js
@@ -88,2 +88,7 @@ import chalk from 'chalk'; | ||
/** | ||
* A map of discovered custom commands. | ||
*/ | ||
customCommands = {}; | ||
/** | ||
* The Titanium CLI config object. | ||
@@ -159,5 +164,12 @@ * @type {Object} | ||
/** | ||
* A set to track loaded custom paths. | ||
* @type {Set} | ||
*/ | ||
scannedCustomPaths = new Set(); | ||
constructor() { | ||
const pkgJsonFile = join(dirname(fileURLToPath(import.meta.url)), '../package.json'); | ||
const { version } = fs.readJsonSync(pkgJsonFile); | ||
this.name = 'Titanium Command-Line Interface'; | ||
@@ -463,4 +475,8 @@ this.copyright = 'Copyright TiDev, Inc. 4/7/2022-Present. All Rights Reserved.'; | ||
}); | ||
if (r instanceof Promise) { | ||
r.then(resolve).catch(reject); | ||
} else if (run.length < 4) { | ||
// run doesn't expect a `callback()` | ||
resolve(); | ||
} | ||
@@ -486,79 +502,2 @@ }); | ||
/** | ||
* If the current command is the "build" command, this function will check | ||
* if the "build" command has a `--platform` option (which is should), then | ||
* prompt for the platform is not explicitly passed in. | ||
* | ||
* Finally, the platform specific options and flags are added to the | ||
* Commander.js "build" command context so that the second parse will | ||
* pick up the newly defined options/flags. | ||
* | ||
* @returns {Promise} | ||
* @access private | ||
*/ | ||
async initBuildPlatform() { | ||
const cmdName = this.command.name(); | ||
if (cmdName !== 'build') { | ||
return; | ||
} | ||
const platformOption = this.command.conf?.options?.platform; | ||
if (!platformOption) { | ||
return; | ||
} | ||
this.debugLogger.trace(`Processing --platform option: ${this.argv.platform || 'not specified'}`); | ||
try { | ||
if (!this.argv.platform) { | ||
throw new TiError('Missing required option: --platform <name>', { | ||
after: `Available Platforms:\n${ | ||
platformOption.values | ||
.map(v => ` ${cyan(v)}`) | ||
.join('\n') | ||
}` | ||
}); | ||
} else if (!platformOption.skipValueCheck && !platformOption.values.includes(this.argv.platform)) { | ||
throw new TiError(`Invalid platform "${this.argv.$originalPlatform || this.argv.platform}"`, { | ||
code: 'INVALID_PLATFORM' | ||
}); | ||
} | ||
} catch (e) { | ||
if (!this.promptingEnabled) { | ||
throw e; | ||
} | ||
if (platformOption.values.length > 1 || e.code === 'INVALID_PLATFORM') { | ||
this.logger.banner(); | ||
if (e.code === 'INVALID_PLATFORM') { | ||
this.logger.error(e.message); | ||
} | ||
this.argv.platform = await prompt({ | ||
type: 'select', | ||
message: 'Please select a valid platform:', | ||
choices: platformOption.values.map(v => ({ label: v, value: v })) | ||
}); | ||
this.debugLogger.trace(`Selecting platform "${this.argv.platform}"`); | ||
} else { | ||
this.argv.platform = platformOption.values[0]; | ||
this.debugLogger.trace(`Auto-selecting platform "${this.argv.platform}"`); | ||
} | ||
} | ||
const platformConf = this.command.conf.platforms[this.argv.platform]; | ||
this.argv.$platform = this.argv.platform; | ||
// set platform context | ||
this.command.platform = { | ||
conf: platformConf | ||
}; | ||
this.debugLogger.trace('Applying platform config...'); | ||
applyCommandConfig(this, cmdName, this.command, platformConf); | ||
await this.scanHooks(expand(this.sdk.path, this.argv.platform, 'cli', 'hooks')); | ||
} | ||
/** | ||
* The main pipeline for running the CLI. | ||
@@ -657,2 +596,79 @@ * | ||
/** | ||
* If the current command is the "build" command, this function will check | ||
* if the "build" command has a `--platform` option (which is should), then | ||
* prompt for the platform is not explicitly passed in. | ||
* | ||
* Finally, the platform specific options and flags are added to the | ||
* Commander.js "build" command context so that the second parse will | ||
* pick up the newly defined options/flags. | ||
* | ||
* @returns {Promise} | ||
* @access private | ||
*/ | ||
async initBuildPlatform() { | ||
const cmdName = this.command.name(); | ||
if (cmdName !== 'build') { | ||
return; | ||
} | ||
const platformOption = this.command.conf?.options?.platform; | ||
if (!platformOption) { | ||
return; | ||
} | ||
this.debugLogger.trace(`Processing --platform option: ${this.argv.platform || 'not specified'}`); | ||
try { | ||
if (!this.argv.platform) { | ||
throw new TiError('Missing required option: --platform <name>', { | ||
after: `Available Platforms:\n${ | ||
platformOption.values | ||
.map(v => ` ${cyan(v)}`) | ||
.join('\n') | ||
}` | ||
}); | ||
} else if (!platformOption.skipValueCheck && !platformOption.values.includes(this.argv.platform)) { | ||
throw new TiError(`Invalid platform "${this.argv.$originalPlatform || this.argv.platform}"`, { | ||
code: 'INVALID_PLATFORM' | ||
}); | ||
} | ||
} catch (e) { | ||
if (!this.promptingEnabled) { | ||
throw e; | ||
} | ||
if (platformOption.values.length > 1 || e.code === 'INVALID_PLATFORM') { | ||
this.logger.banner(); | ||
if (e.code === 'INVALID_PLATFORM') { | ||
this.logger.error(e.message); | ||
} | ||
this.argv.platform = await prompt({ | ||
type: 'select', | ||
message: 'Please select a valid platform:', | ||
choices: platformOption.values.map(v => ({ label: v, value: v })) | ||
}); | ||
this.debugLogger.trace(`Selecting platform "${this.argv.platform}"`); | ||
} else { | ||
this.argv.platform = platformOption.values[0]; | ||
this.debugLogger.trace(`Auto-selecting platform "${this.argv.platform}"`); | ||
} | ||
} | ||
const platformConf = this.command.conf.platforms[this.argv.platform]; | ||
this.argv.$platform = this.argv.platform; | ||
// set platform context | ||
this.command.platform = { | ||
conf: platformConf | ||
}; | ||
this.debugLogger.trace('Applying platform config...'); | ||
applyCommandConfig(this, cmdName, this.command, platformConf); | ||
await this.scanHooks(expand(this.sdk.path, this.argv.platform, 'cli', 'hooks')); | ||
} | ||
/** | ||
* Initialize the global Commander.js context and add the commands. | ||
@@ -717,2 +733,3 @@ * | ||
} | ||
this.loadCustomCommands(); | ||
} catch (e) { | ||
@@ -722,3 +739,6 @@ throw new Error(`Failed to parse --config: ${e.message}`); | ||
}) | ||
.on('option:config-file', file => this.config.load(file)) | ||
.on('option:config-file', file => { | ||
this.config.load(file); | ||
this.loadCustomCommands(); | ||
}) | ||
.on('option:project-dir', dir => program.setOptionValue('projectDir', expand(dir))); | ||
@@ -738,2 +758,5 @@ | ||
// load custom commands in `paths.commands` from the config file | ||
this.loadCustomCommands(); | ||
program.title = 'Global'; | ||
@@ -842,4 +865,14 @@ | ||
let desc = commands[cmdName] || sdkCommands[cmdName]; | ||
if (!desc) { | ||
let commandFile; | ||
let desc = ''; | ||
if (commands[cmdName]) { | ||
desc = commands[cmdName]; | ||
commandFile = join(import.meta.url, `../commands/${cmdName}.js`); | ||
} else if (sdkCommands[cmdName]) { | ||
desc = sdkCommands[cmdName]; | ||
commandFile = pathToFileURL(join(this.sdk.path, `cli/commands/${cmdName}.js`)); | ||
} else if (this.customCommands[cmdName]) { | ||
commandFile = pathToFileURL(this.customCommands[cmdName]); | ||
} else { | ||
this.debugLogger.warn(`Unknown command "${cmdName}"`); | ||
@@ -849,6 +882,2 @@ return; | ||
const commandFile = sdkCommands[cmdName] | ||
? pathToFileURL(join(this.sdk.path, `cli/commands/${cmdName}.js`)) | ||
: join(import.meta.url, `../commands/${cmdName}.js`); | ||
// load the command | ||
@@ -911,2 +940,42 @@ this.debugLogger.trace(`Importing: ${commandFile}`); | ||
/** | ||
* Loads any custom commands found in `paths.commands`. | ||
*/ | ||
loadCustomCommands() { | ||
// load any custom commands | ||
const customCommandPaths = ticonfig.get('paths.commands'); | ||
if (Array.isArray(customCommandPaths)) { | ||
const jsRE = /\.js$/; | ||
const ignoreRE = /^[._]/; | ||
for (let p of customCommandPaths) { | ||
if (this.scannedCustomPaths.has(p)) { | ||
continue; | ||
} | ||
this.scannedCustomPaths.add(p); | ||
try { | ||
p = expand(p); | ||
const isDir = fs.statSync(p).isDirectory(); | ||
const files = isDir ? fs.readdirSync(p) : [p]; | ||
for (const filename of files) { | ||
const file = isDir ? join(p, filename) : filename; | ||
if (!ignoreRE.test(filename) && fs.existsSync(file) && (fs.statSync(file)).isFile() && jsRE.test(file)) { | ||
const name = basename(file).replace(jsRE, ''); | ||
this.debugLogger.trace(`Found custom command "${name}"`); | ||
this.customCommands[name] = file; | ||
program | ||
.command(name) | ||
.allowUnknownOption() | ||
.action((...args) => this.executeCommand(args)); | ||
} | ||
} | ||
} catch { | ||
// squelch | ||
} | ||
} | ||
} | ||
} | ||
/** | ||
* Detect and load the Titanium SDK, prompt if necessary, update the | ||
@@ -913,0 +982,0 @@ * development environment info and CLI banner, and load the SDK hooks. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
197110
5838
+ Addedundici@6.4.0(transitive)
- Removedundici@6.3.0(transitive)
Updatedundici@6.4.0