diff --git a/examples/cli/index.js b/examples/cli/index.js index 1eaa185..861e557 100755 --- a/examples/cli/index.js +++ b/examples/cli/index.js @@ -3,8 +3,10 @@ import fs from 'fs' import path from 'path' import { Command, Shell } from '../../src/index.js' +import { fileURLToPath } from 'url' +const __dirname = path.dirname(fileURLToPath(import.meta.url)) -const pkg = JSON.parse(fs.readFileSync('./package.json')) +const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, './package.json'))) const shell = new Shell({ name: Object.keys(pkg.bin)[0], @@ -109,6 +111,20 @@ shell.add(new Command({ } })) + +shell.add(new Command({ + name: 'doc', + description: 'Output the metadoc of this shell.', + handler () { + console.log(shell.data) + } +})) + +shell.use((data, next) => { + console.log('This middleware runs on very command.') + next() +}) + const cmd = process.argv.slice(2).join(' ').trim() // console.log(cmd) shell.exec(cmd).catch(e => console.log(e.message || e)) diff --git a/package.json b/package.json index 827ccc5..c612d22 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@author.io/shell", - "version": "1.1.9", + "version": "1.2.0", "description": "A micro-framework for creating CLI-like experiences. This supports Node.js and browsers.", "main": "src/index.js", "scripts": { diff --git a/src/command.js b/src/command.js index 98d2f8b..9bdea0b 100644 --- a/src/command.js +++ b/src/command.js @@ -107,6 +107,31 @@ export default class Command { } } + get data () { + const commands = {} + + Array.from(this.#processors.values()).forEach(cmd => { + let data = cmd.data + const name = data.name + delete data.name + commands[name] = data + }) + + const data = { + name: this.#name, + description: this.description, + help: this.help, + usage: this.usage, + aliases: this.#aliases || [], + flags: this.#flagConfig || {}, + handler: (this.#fn || this.#defaultHandler).toString(), + commands, + middleware: this.#middleware.data + } + + return data + } + set tableWidth(value) { this.#tableWidth = value this.#processors.forEach(cmd => cmd.tableWidth = value) diff --git a/src/middleware.js b/src/middleware.js index 3604e68..62f8657 100644 --- a/src/middleware.js +++ b/src/middleware.js @@ -2,10 +2,14 @@ const last = a => a[a.length - 1] const reduce = a => a.slice(0, -1) export default class Middleware { - constructor () { this.size = 0 } + constructor () { Object.defineProperty(this, '_data', { enumerable: false, value: [] }) } + + get size () { return this._data.length } + + get data () { return this._data } use (method) { - this.size++ + this._data.push(method.toString()) this.run = ((stack) => (...args) => stack(...reduce(args), () => { const next = last(args) method.apply(this, [...reduce(args), next.bind.apply(next, [null, ...reduce(args)])]) diff --git a/src/shell.js b/src/shell.js index 0bddb08..635712a 100644 --- a/src/shell.js +++ b/src/shell.js @@ -59,6 +59,31 @@ export default class Shell { } } + get data () { + const commands = {} + + Array.from(this.#processors.values()).forEach(cmd => { + let data = cmd.data + const name = data.name + delete data.name + commands[name] = data + }) + + return { + name: this.name, + description: this.description, + version: this.version, + commands, + middleware: this.#middleware.data, + help: this.help, + usage: this.usage, + defaultHandler: this.#defaultHandler.toString(), + authohelp: this.#autohelp, + runtime: this.#runtime, + maxHistoryItems: this.#maxHistoryItems + } + } + get version () { return this.#version || 'Unknown' } diff --git a/test/unit/01-sanity/01-sanity.js b/test/unit/01-sanity/01-sanity.js index 418f2ee..6e5ac0f 100644 --- a/test/unit/01-sanity/01-sanity.js +++ b/test/unit/01-sanity/01-sanity.js @@ -23,7 +23,7 @@ test('Sanity Check - Command', t => { cb && cb() } }) - + console.log('>>', mirror.xdata) t.ok(mirror instanceof Command, 'Command initialized successfully.') const CLI = new Shell({ @@ -40,11 +40,8 @@ test('Sanity Check - Command', t => { t.ok(CLI instanceof Shell, 'Shell initialized with commands successfully.') - let defaultHandlerFires = false - - CLI.exec('test', data => defaultHandlerFires = true) - - t.ok(defaultHandlerFires, 'Default handler fires.') - - t.end() + CLI.exec('test').then(data => { + t.pass('Default handler fires.') + t.end() + }).catch(e => t.fail(e.message)) })