diff --git a/package.json b/package.json index 4d43a66a..ee36b5b9 100644 --- a/package.json +++ b/package.json @@ -5,13 +5,11 @@ "author": "Jeff Dickey @jdxcode", "bugs": "https://github.com/anycli/config/issues", "dependencies": { - "cli-ux": "^3.3.13", "debug": "^3.1.0", "fs-extra": "^5.0.0", "fs-extra-debug": "^1.0.4", "globby": "^7.1.1", "load-json-file": "^4.0.0", - "lodash": "^4.17.4", "read-pkg": "^3.0.0" }, "devDependencies": { @@ -21,11 +19,9 @@ "@types/fs-extra": "^5.0.0", "@types/globby": "^6.1.0", "@types/load-json-file": "^2.0.7", - "@types/lodash": "^4.14.100", "@types/mocha": "^2.2.48", "@types/nock": "^9.1.2", "@types/node": "^9.4.0", - "@types/node-notifier": "^0.0.28", "@types/read-pkg": "^3.0.0", "chai": "^4.1.2", "concurrently": "^3.5.1", diff --git a/src/command.ts b/src/command.ts index 7bff2def..92b14443 100644 --- a/src/command.ts +++ b/src/command.ts @@ -1,7 +1,7 @@ import * as Parser from '@anycli/parser' -import * as _ from 'lodash' import * as Config from '.' +import {mapValues} from './util' export interface Command { id: string @@ -83,7 +83,7 @@ export namespace Command { usage: c.usage, hidden: c.hidden, aliases: c.aliases || [], - flags: _.mapValues(c.flags || {}, (flag, name) => { + flags: mapValues(c.flags || {}, (flag, name) => { if (flag.type === 'boolean') { return { name, @@ -103,7 +103,7 @@ export namespace Command { required: flag.required, helpValue: flag.helpValue, options: flag.options, - default: _.isFunction(flag.default) ? flag.default({options: {}, flags: {}}) : flag.default, + default: typeof flag.default === 'function' ? flag.default({options: {}, flags: {}}) : flag.default, } }), args: c.args ? c.args.map(a => ({ @@ -111,7 +111,7 @@ export namespace Command { description: a.description, required: a.required, options: a.options, - default: _.isFunction(a.default) ? a.default({}) : a.default, + default: typeof a.default === 'function' ? a.default({}) : a.default, hidden: a.hidden, })) : {} as Command['args'], } diff --git a/src/config.ts b/src/config.ts index 492e7d01..3133db60 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,4 +1,3 @@ -import cli from 'cli-ux' import * as os from 'os' import * as path from 'path' import * as readPkg from 'read-pkg' @@ -133,7 +132,7 @@ export class Config extends Plugin.Plugin implements IConfig { const devPlugins = this.pjson.anycli.devPlugins if (devPlugins) this.loadPlugins(this.root, devPlugins) } catch (err) { - cli.warn(err) + process.emitWarning(err) } try { @@ -142,7 +141,7 @@ export class Config extends Plugin.Plugin implements IConfig { if (!pjson.anycli) pjson.anycli = {schema: 1} this.loadPlugins(userPJSONPath, pjson.anycli.plugins) } catch (err) { - if (err.code !== 'ENOENT') cli.warn(err) + if (err.code !== 'ENOENT') process.emitWarning(err) } debug('config done') diff --git a/src/manifest.ts b/src/manifest.ts index 0b847516..995b2b86 100644 --- a/src/manifest.ts +++ b/src/manifest.ts @@ -1,6 +1,4 @@ -import cli from 'cli-ux' -import * as globby from 'globby' -import * as _ from 'lodash' +import * as Globby from 'globby' import * as path from 'path' import {Command} from './command' @@ -16,29 +14,32 @@ export namespace Manifest { export type FindCommandCB = (id: string) => Command.Class export function build(version: string, dir: string, findCommand: FindCommandCB): Manifest { + const globby: typeof Globby = require('globby') debug(`loading IDs from ${dir}`) const ids = globby.sync(['**/*.+(js|ts)', '!**/*.+(d.ts|test.ts|test.js)'], {cwd: dir}) .map(file => { const p = path.parse(file) const topics = p.dir.split('/') let command = p.name !== 'index' && p.name - return _([...topics, command]).compact().join(':') + return [...topics, command].filter(f => f).join(':') }) debug('found ids', ids) let commands = ids.map(id => { try { return [id, Command.toCached(findCommand(id))] } catch (err) { - cli.warn(err) + process.emitWarning(err) } }) return { version, - commands: _(commands) - .compact() - .fromPairs() - .value() + commands: commands + .filter((f): f is [string, Command] => !!f) + .reduce((commands, [id, c]) => { + commands[id] = c + return commands + }, {} as {[k: string]: Command}) } } } diff --git a/src/plugin.ts b/src/plugin.ts index 99ffcb14..e386c47e 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -1,7 +1,5 @@ -import cli from 'cli-ux' import * as fs from 'fs-extra' import * as loadJSON from 'load-json-file' -import * as _ from 'lodash' import * as path from 'path' import * as readPkg from 'read-pkg' import {inspect} from 'util' @@ -12,6 +10,7 @@ import {Manifest} from './manifest' import {PJSON} from './pjson' import {Topic} from './topic' import {tsPath} from './ts_node' +import {flatMap, mapValues} from './util' export interface Options { root: string @@ -118,7 +117,7 @@ export class Plugin implements IPlugin { this.valid = this.pjson.anycli.schema === 1 this._topics = topicsToArray(this.pjson.anycli.topics || {}) - this.hooks = _.mapValues(this.pjson.anycli.hooks || {}, _.castArray) + this.hooks = mapValues(this.pjson.anycli.hooks || {}, i => Array.isArray(i) ? i : [i]) this.manifest = this._manifest() this.loadPlugins(this.root, this.pjson.anycli.plugins || []) @@ -167,9 +166,9 @@ export class Plugin implements IPlugin { _findCommand(id: string): Command.Class { const search = (cmd: any) => { - if (_.isFunction(cmd.run)) return cmd + if (typeof cmd.run === 'function') return cmd if (cmd.default && cmd.default.run) return cmd.default - return Object.values(cmd).find((cmd: any) => _.isFunction(cmd.run)) + return Object.values(cmd).find((cmd: any) => typeof cmd.run === 'function') } const p = require.resolve(path.join(this.commandsDir!, ...id.split(':'))) debug('require', p) @@ -198,15 +197,15 @@ export class Plugin implements IPlugin { const p = tsPath(this.root, hook) debug('hook', event, p) const search = (m: any) => { - if (_.isFunction(m)) return m - if (m.default && _.isFunction(m.default)) return m.default - return Object.values(m).find((m: any) => _.isFunction(m)) + if (typeof m === 'function') return m + if (m.default && typeof m.default === 'function') return m.default + return Object.values(m).find((m: any) => typeof m === 'function') } await search(require(p))(opts) } catch (err) { if (err.code === 'EEXIT') throw err - cli.warn(err) + process.emitWarning(err) } }) promises.push(...this.plugins.map(p => p.runHook(event, opts))) @@ -225,13 +224,13 @@ export class Plugin implements IPlugin { const p = path.join(this.root, '.anycli.manifest.json') const manifest: Manifest = loadJSON.sync(p) if (manifest.version !== this.version) { - cli.warn(`Mismatched version in ${this.name} plugin manifest. Expected: ${this.version} Received: ${manifest.version}`) + process.emitWarning(`Mismatched version in ${this.name} plugin manifest. Expected: ${this.version} Received: ${manifest.version}`) } else { debug('using manifest from', p) return manifest } } catch (err) { - if (err.code !== 'ENOENT') cli.warn(err) + if (err.code !== 'ENOENT') process.emitWarning(err) } } if (!this.ignoreManifest) { @@ -259,7 +258,7 @@ export class Plugin implements IPlugin { } this.plugins.push(new Plugin(opts)) } catch (err) { - cli.warn(err) + process.emitWarning(err) } } return plugins @@ -270,9 +269,9 @@ function topicsToArray(input: any, base?: string): Topic[] { if (!input) return [] base = base ? `${base}:` : '' if (Array.isArray(input)) { - return input.concat(_.flatMap(input, t => topicsToArray(t.subtopics, `${base}${t.name}`))) + return input.concat(flatMap(input, t => topicsToArray(t.subtopics, `${base}${t.name}`))) } - return _.flatMap(Object.keys(input), k => { + return flatMap(Object.keys(input), k => { return [{...input[k], name: `${base}${k}`}].concat(topicsToArray(input[k].subtopics, `${base}${input[k].name}`)) }) } diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 00000000..d822b95b --- /dev/null +++ b/src/util.ts @@ -0,0 +1,11 @@ +export function flatMap(arr: T[], fn: (i: T) => U[]): U[] { + return arr.reduce((arr, i) => arr.concat(fn(i)), [] as U[]) +} + +export function mapValues(obj: {[P in keyof T]: T[P]}, fn: (i: T[keyof T], k: keyof T) => TResult): {[P in keyof T]: TResult} { + return Object.entries(obj) + .reduce((o, [k, v]) => { + o[k] = fn(v, k as any) + return o + }, {} as any) +} diff --git a/yarn.lock b/yarn.lock index cfda409b..71fe9c09 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21,10 +21,6 @@ tslint "^5.9.1" tslint-xo "^0.6.0" -"@heroku/linewrap@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@heroku/linewrap/-/linewrap-1.0.0.tgz#a9d4e99f0a3e423a899b775f5f3d6747a1ff15c6" - "@types/chai@^4.1.2": version "4.1.2" resolved "https://registry.npmjs.org/@types/chai/-/chai-4.1.2.tgz#f1af664769cfb50af805431c407425ed619daa21" @@ -57,10 +53,6 @@ version "2.0.7" resolved "https://registry.npmjs.org/@types/load-json-file/-/load-json-file-2.0.7.tgz#c887826f5230b7507d5230994d26315c6776be06" -"@types/lodash@^4.14.100": - version "4.14.100" - resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.100.tgz#f353dd9d3a9785638b6cb8023e6639097bd31969" - "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -75,12 +67,6 @@ dependencies: "@types/node" "*" -"@types/node-notifier@^0.0.28": - version "0.0.28" - resolved "https://registry.yarnpkg.com/@types/node-notifier/-/node-notifier-0.0.28.tgz#86ba3d3aa8d918352cc3191d88de328b20dc93c1" - dependencies: - "@types/node" "*" - "@types/node@*", "@types/node@^9.4.0": version "9.4.0" resolved "https://registry.npmjs.org/@types/node/-/node-9.4.0.tgz#b85a0bcf1e1cc84eb4901b7e96966aedc6f078d1" @@ -154,16 +140,12 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" -ansi-styles@^3.1.0, ansi-styles@^3.2.0: +ansi-styles@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" dependencies: color-convert "^1.9.0" -ansicolors@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef" - argparse@^1.0.7: version "1.0.9" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" @@ -225,13 +207,6 @@ callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" -cardinal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-1.0.0.tgz#50e21c1b0aa37729f9377def196b5a9cec932ee9" - dependencies: - ansicolors "~0.2.1" - redeyed "~1.0.0" - chai@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" @@ -289,36 +264,12 @@ clean-regexp@^1.0.0: dependencies: escape-string-regexp "^1.0.5" -clean-stack@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-1.3.0.tgz#9e821501ae979986c46b1d66d2d432db2fd4ae31" - cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" dependencies: restore-cursor "^2.0.0" -cli-ux@^3.3.13: - version "3.3.13" - resolved "https://registry.yarnpkg.com/cli-ux/-/cli-ux-3.3.13.tgz#123e0c7a29d1f743447b919500a9055486992df6" - dependencies: - "@anycli/screen" "^0.0.3" - "@heroku/linewrap" "^1.0.0" - ansi-styles "^3.2.0" - cardinal "^1.0.0" - chalk "^2.3.0" - clean-stack "^1.3.0" - extract-stack "^1.0.0" - fs-extra "^5.0.0" - indent-string "^3.2.0" - lodash "^4.17.4" - node-notifier "^5.2.1" - password-prompt "^1.0.4" - semver "^5.5.0" - strip-ansi "^4.0.0" - supports-color "^5.1.0" - cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" @@ -573,10 +524,6 @@ esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" -esprima@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.0.0.tgz#53cf247acda77313e551c3aa2e73342d3fb4f7d9" - esquery@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" @@ -610,10 +557,6 @@ external-editor@^2.0.4: iconv-lite "^0.4.17" tmp "^0.0.33" -extract-stack@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/extract-stack/-/extract-stack-1.0.0.tgz#b97acaf9441eea2332529624b732fc5a1c8165fa" - fancy-test@^0.6.10: version "0.6.10" resolved "https://registry.yarnpkg.com/fancy-test/-/fancy-test-0.6.10.tgz#39001bcb117b7067c851dc58da6236a08a49e267" @@ -726,10 +669,6 @@ growl@1.10.3: version "1.10.3" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" -growly@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - has-ansi@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-0.1.0.tgz#84f265aae8c0e6a88a12d7022894b7568894c62e" @@ -780,10 +719,6 @@ imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" -indent-string@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -999,15 +934,6 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" -node-notifier@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea" - dependencies: - growly "^1.3.0" - semver "^5.4.1" - shellwords "^0.1.1" - which "^1.3.0" - normalize-package-data@^2.3.2: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" @@ -1059,13 +985,6 @@ parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" -password-prompt@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/password-prompt/-/password-prompt-1.0.4.tgz#933bac8db3528fcb27e9fdbc0a6592adcbdb5ed9" - dependencies: - ansi-escapes "^3.0.0" - cross-spawn "^5.1.0" - path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -1150,12 +1069,6 @@ readable-stream@^2.2.2: string_decoder "~1.0.3" util-deprecate "~1.0.1" -redeyed@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-1.0.1.tgz#e96c193b40c0816b00aec842698e61185e55498a" - dependencies: - esprima "~3.0.0" - require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" @@ -1210,7 +1123,7 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: +"semver@2 || 3 || 4 || 5", semver@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" @@ -1228,10 +1141,6 @@ shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" -shellwords@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -1350,12 +1259,6 @@ supports-color@^4.0.0: dependencies: has-flag "^2.0.0" -supports-color@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.1.0.tgz#058a021d1b619f7ddf3980d712ea3590ce7de3d5" - dependencies: - has-flag "^2.0.0" - table@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" @@ -1508,7 +1411,7 @@ validate-npm-package-license@^3.0.1: spdx-correct "~1.0.0" spdx-expression-parse "~1.0.0" -which@^1.2.9, which@^1.3.0: +which@^1.2.9: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" dependencies: