diff --git a/packages/edge/src/commands/edge/drivers/prune.ts b/packages/edge/src/commands/edge/drivers/prune.ts deleted file mode 100644 index a309924b..00000000 --- a/packages/edge/src/commands/edge/drivers/prune.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Flags } from '@oclif/core' - -import { EdgeCommand } from '../../../lib/edge-command' -import { chooseHub, getDriverDevices } from '../../../lib/commands/drivers-util' -import { FormatAndWriteItemConfig, askForBoolean, formatAndWriteItem } from '@smartthings/cli-lib' -import { InstalledDriver } from '@smartthings/core-sdk' - - -export default class DriversPruneCommand extends EdgeCommand { - static description = 'uninstall unused edge drivers from a hub' + - this.apiDocsURL('uninstallDriver') // TODO: update - - static flags = { - ...EdgeCommand.flags, - hub: Flags.string({ - char: 'H', - description: 'hub id', - helpValue: '', - }), - } - - static args = [{ - name: 'driverId', - description: 'id of driver to uninstall', - }] - - async run(): Promise { - const hubId = await chooseHub(this, 'Select a hub to uninstall from.', this.flags.hub, - { useConfigDefault: true }) - - const installedDrivers = await this.client.hubdevices.listInstalled(hubId) - const isDefined = (item?: string): item is string => item != null - const inUseDriverIds = (await getDriverDevices(this.client)) - .map(info => info.driverId) - .filter(isDefined) - .flat() - - // LAN drivers can be automatically re-installed so we don't allow pruning them. - // no ocean currents here :-) - const defaultLANDrivers = (await this.client.drivers.listDefault()) - .filter(driver => driver.permissions?.find(permission => permission.name === 'lan')) - .map(driver => driver.driverId) - const prunableDrivers = installedDrivers - .filter(driver => !inUseDriverIds.includes(driver.driverId)) - .filter(driver => !defaultLANDrivers.includes(driver.driverId)) - - if (prunableDrivers.length === 0) { - console.log('No unused drivers found.') - } else { - console.log(`Found ${prunableDrivers.length} unused drivers.`) - const config: FormatAndWriteItemConfig = { - tableFieldDefinitions: [ - 'driverId', - 'name', - { prop: 'description', skipEmpty: true }, - 'version', - 'channelId', - 'developer', - { prop: 'vendorSupportInformation', skipEmpty: true }, - ], - } - for (const prunableDriver of prunableDrivers) { - console.log('\n\nFound unused driver:') - await formatAndWriteItem(this, config, prunableDriver) - const doUninstall = await askForBoolean(`Uninstall ${prunableDriver.name} driver?`, { default: false }) - if (doUninstall) { - await this.client.hubdevices.uninstallDriver(prunableDriver.driverId, hubId) - this.log(`driver ${prunableDriver.driverId} uninstalled from hub ${hubId}`) - } else { - console.log(`Left driver ${prunableDriver.name} installed.`) - } - } - } - } -} diff --git a/src/commands/edge/drivers/prune.ts b/src/commands/edge/drivers/prune.ts new file mode 100644 index 00000000..97dafb66 --- /dev/null +++ b/src/commands/edge/drivers/prune.ts @@ -0,0 +1,90 @@ +import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' + + +import { type InstalledDriver } from '@smartthings/core-sdk' + +import { booleanInput } from '../../../lib/user-query.js' +import { apiCommand, apiCommandBuilder, type APICommandFlags, apiDocsURL } from '../../../lib/command/api-command.js' +import { formatAndWriteItem, type FormatAndWriteItemConfig } from '../../../lib/command/format.js' +import { getDriverDevices } from '../../../lib/command/util/edge-drivers.js' +import { chooseHub } from '../../../lib/command/util/hubs-choose.js' + + +export type CommandArgs = + & APICommandFlags + & { + hub?: string + } + +const command = 'edge:drivers:prune' + +const describe = 'uninstall unused edge drivers from a hub' + +const builder = (yargs: Argv): Argv => + apiCommandBuilder(yargs) + .option('hub', { alias: 'H', describe: 'hub id', type: 'string' }) + .example([ + ['$0 edge:drivers:prune', 'prompt for a hub and prune its drivers'], + [ + '$0 edge:drivers:prune --hub b0cd47c6-2bbd-45f7-9726-6dcd374b8eb3' + + 'prune drivers on the specified hub', + ], + ]) + .epilog(apiDocsURL('uninstallDriver')) + +const handler = async (argv: ArgumentsCamelCase): Promise => { + const command = await apiCommand(argv) + + const hubId = await chooseHub( + command, + argv.hub, + { promptMessage: 'Select a hub to prune drivers on.', useConfigDefault: true }, + ) + + const installedDrivers = await command.client.hubdevices.listInstalled(hubId) + const isDefined = (item?: string): item is string => item != null + const inUseDriverIds = (await getDriverDevices(command.client)) + .map(info => info.driverId) + .filter(isDefined) + .flat() + + // LAN drivers can be automatically re-installed so we don't allow pruning them. + // no ocean currents here :-) + const defaultLANDrivers = (await command.client.drivers.listDefault()) + .filter(driver => driver.permissions?.find(permission => permission.name === 'lan')) + .map(driver => driver.driverId) + const prunableDrivers = installedDrivers + .filter(driver => !inUseDriverIds.includes(driver.driverId)) + .filter(driver => !defaultLANDrivers.includes(driver.driverId)) + + if (prunableDrivers.length === 0) { + console.log('No unused drivers found.') + } else { + console.log(`Found ${prunableDrivers.length} unused drivers.`) + const config: FormatAndWriteItemConfig = { + tableFieldDefinitions: [ + 'driverId', + 'name', + { prop: 'description', skipEmpty: true }, + 'version', + 'channelId', + 'developer', + { prop: 'vendorSupportInformation', skipEmpty: true }, + ], + } + for (const prunableDriver of prunableDrivers) { + console.log('\n\nFound unused driver:') + await formatAndWriteItem(command, config, prunableDriver) + const doUninstall = await booleanInput(`Uninstall ${prunableDriver.name} driver?`, { default: false }) + if (doUninstall) { + await command.client.hubdevices.uninstallDriver(prunableDriver.driverId, hubId) + console.log(`Driver ${prunableDriver.driverId} uninstalled from hub ${hubId}.`) + } else { + console.log(`Left driver ${prunableDriver.name} installed.`) + } + } + } +} + +const cmd: CommandModule = { command, describe, builder, handler } +export default cmd diff --git a/src/commands/index.ts b/src/commands/index.ts index b50623b6..82c9c502 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -78,6 +78,7 @@ import edgeDriversInstallCommand from './edge/drivers/install.js' import edgeDriversInstalledCommand from './edge/drivers/installed.js' import edgeDriversLogcatCommand from './edge/drivers/logcat.js' import edgeDriversPackageCommand from './edge/drivers/package.js' +import edgeDriversPruneCommand from './edge/drivers/prune.js' import edgeDriversSwitchCommand from './edge/drivers/switch.js' import edgeDriversUninstallCommand from './edge/drivers/uninstall.js' import installedappsCommand from './installedapps.js' @@ -211,6 +212,7 @@ export const commands: CommandModule[] = [ edgeDriversInstalledCommand, edgeDriversLogcatCommand, edgeDriversPackageCommand, + edgeDriversPruneCommand, edgeDriversSwitchCommand, edgeDriversUninstallCommand, installedappsCommand,