diff --git a/package.json b/package.json index f5ec41a2..8599a6b5 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "npm": "10.5.0", "npm-package-arg": "^11.0.2", "npm-run-path": "^5.3.0", + "object-treeify": "^4.0.1", "semver": "^7.6.0", "validate-npm-package-name": "^5.0.0", "yarn": "^1.22.22" diff --git a/src/commands/plugins/index.ts b/src/commands/plugins/index.ts index bf4ebb1b..89699206 100644 --- a/src/commands/plugins/index.ts +++ b/src/commands/plugins/index.ts @@ -1,11 +1,16 @@ -import {Command, Flags, Interfaces, Plugin, ux} from '@oclif/core' +import {Command, Flags, Interfaces, Plugin} from '@oclif/core' import chalk from 'chalk' +// @ts-expect-error because object-treeify does not have types: https://github.com/blackflux/object-treeify/issues/1077 +import treeify from 'object-treeify' import Plugins from '../../plugins.js' import {sortBy} from '../../util.js' type JitPlugin = {name: string; type: string; version: string} type PluginsJson = Array +interface RecursiveTree { + [key: string]: RecursiveTree | string +} export default class PluginsIndex extends Command { static description = 'List installed plugins.' @@ -54,10 +59,9 @@ export default class PluginsIndex extends Command { } private createTree(plugin: Plugin) { - const tree = ux.tree() + const tree: RecursiveTree = {} for (const p of plugin.children) { - const name = this.formatPlugin(p) - tree.insert(name, this.createTree(p)) + tree[this.formatPlugin(p)] = this.createTree(p) } return tree @@ -68,7 +72,7 @@ export default class PluginsIndex extends Command { this.log(this.formatPlugin(plugin)) if (plugin.children && plugin.children.length > 0) { const tree = this.createTree(plugin) - tree.display() + this.log(treeify(tree)) } } } diff --git a/src/commands/plugins/inspect.ts b/src/commands/plugins/inspect.ts index 776c5724..60dcd572 100644 --- a/src/commands/plugins/inspect.ts +++ b/src/commands/plugins/inspect.ts @@ -1,7 +1,9 @@ -import {Args, Command, Flags, Plugin, ux} from '@oclif/core' +import {Args, Command, Flags, Plugin} from '@oclif/core' import chalk from 'chalk' import {readFile} from 'node:fs/promises' import {dirname, join, sep} from 'node:path' +// @ts-expect-error because object-treeify does not have types: https://github.com/blackflux/object-treeify/issues/1077 +import treeify from 'object-treeify' import {determineLogLevel} from '../../log-level.js' import Plugins from '../../plugins.js' @@ -19,7 +21,7 @@ function trimUntil(fsPath: string, part: string): string { return parts.slice(0, partIndex + 1).join(sep) } -type Dependencies = Record +type Dependencies = Record type PluginWithDeps = Omit< Plugin, | '_commandsDir' @@ -103,37 +105,33 @@ export default class PluginsInspect extends Command { async inspect(pluginName: string, verbose = false): Promise { const plugin = this.findPlugin(pluginName) - const tree = ux.tree() - const pluginHeader = chalk.bold.cyan(plugin.name) - tree.insert(pluginHeader) - tree.nodes[pluginHeader].insert(`version ${plugin.version}`) - if (plugin.tag) tree.nodes[pluginHeader].insert(`tag ${plugin.tag}`) - if (plugin.pjson.homepage) tree.nodes[pluginHeader].insert(`homepage ${plugin.pjson.homepage}`) - tree.nodes[pluginHeader].insert(`location ${plugin.root}`) - - tree.nodes[pluginHeader].insert('commands') - const commands = sortBy(plugin.commandIDs, (c) => c) - for (const cmd of commands) tree.nodes[pluginHeader].nodes.commands.insert(cmd) - - const dependencies = {...plugin.pjson.dependencies} - - tree.nodes[pluginHeader].insert('dependencies') - const deps = sortBy(Object.keys(dependencies), (d) => d) + const dependencies: Record = {} const depsJson: Dependencies = {} - for (const dep of deps) { + for (const dep of sortBy(Object.keys({...plugin.pjson.dependencies}), (d) => d)) { // eslint-disable-next-line no-await-in-loop const {pkgPath, version} = await this.findDep(plugin, dep) if (!version) continue - const from = dependencies[dep] ?? null + const from = plugin.pjson.dependencies?.[dep] const versionMsg = chalk.dim(from ? `${from} => ${version}` : version) const msg = verbose ? `${dep} ${versionMsg} ${pkgPath}` : `${dep} ${versionMsg}` - tree.nodes[pluginHeader].nodes.dependencies.insert(msg) + dependencies[msg] = null depsJson[dep] = {from, version} } - if (!this.jsonEnabled()) tree.display() + const tree = { + [chalk.bold.cyan(plugin.name)]: { + [`version ${plugin.version}`]: null, + ...(plugin.tag ? {[`tag ${plugin.tag}`]: null} : {}), + ...(plugin.pjson.homepage ? {[`homepage ${plugin.pjson.homepage}`]: null} : {}), + [`location ${plugin.root}`]: null, + commands: Object.fromEntries(sortBy(plugin.commandIDs, (c) => c).map((id) => [id, null])), + dependencies, + }, + } + + this.log(treeify(tree)) return {...plugin, deps: depsJson} } diff --git a/yarn.lock b/yarn.lock index dd5ae2b1..b9dc12e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5657,6 +5657,11 @@ object-treeify@^1.1.33: resolved "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz" integrity sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A== +object-treeify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/object-treeify/-/object-treeify-4.0.1.tgz#f91a7dec795d8275886e7f1bd78408f6975be825" + integrity sha512-Y6tg5rHfsefSkfKujv2SwHulInROy/rCL5F4w0QOWxut8AnxYxf0YmNhTh95Zfyxpsudo66uqkux0ACFnyMSgQ== + object.assign@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0"