From 0e9824cbdac42a5710ae8c64c19f2d16f0d16a61 Mon Sep 17 00:00:00 2001 From: Jeff Dickey <216188+jdxcode@users.noreply.github.com> Date: Sat, 13 Jan 2018 17:41:58 -0800 Subject: [PATCH] feat: added base config object --- .circleci/config.yml | 17 +- .eslintignore | 1 + .gitattributes | 2 + .gitignore | 8 +- .gitmodules | 6 + README.md | 2 + appveyor.yml | 6 +- package.json | 51 ++-- plugins/heroku-cli-status | 1 + plugins/heroku-run | 1 + scripts/circleci | 69 ++++-- src/command.ts | 16 ++ src/config.ts | 288 +++++++++++++++++++++++ src/engine.ts | 21 ++ src/hooks.ts | 19 ++ src/index.ts | 6 +- src/pjson.ts | 83 +++++++ src/plugin.ts | 15 ++ src/topic.ts | 5 + test/config.test.ts | 68 ++++++ test/index.test.ts | 8 - tsconfig.json | 1 + yarn.lock | 484 ++++++++++++++++++-------------------- 23 files changed, 875 insertions(+), 303 deletions(-) create mode 100644 .gitmodules create mode 160000 plugins/heroku-cli-status create mode 160000 plugins/heroku-run create mode 100644 src/command.ts create mode 100644 src/config.ts create mode 100644 src/engine.ts create mode 100644 src/hooks.ts create mode 100644 src/pjson.ts create mode 100644 src/plugin.ts create mode 100644 src/topic.ts create mode 100644 test/config.test.ts delete mode 100644 test/index.test.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index 84ed87d2..c57a4ad2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,12 +9,14 @@ jobs: - checkout - restore_cache: &restore_cache keys: - - v0-yarn-{{ .Environment.CIRCLE_JOB }}-{{checksum ".circleci/config.yml"}}-{{ .Branch }}-{{checksum "yarn.lock"}} - - v0-yarn-{{ .Environment.CIRCLE_JOB }}-{{checksum ".circleci/config.yml"}}-{{ .Branch }}- - - v0-yarn-{{ .Environment.CIRCLE_JOB }}-{{checksum ".circleci/config.yml"}}-master - - run: ./scripts/circleci + - v0-yarn-{{ .Environment.CIRCLE_JOB }}-{{checksum "scripts/circleci"}}-{{checksum ".circleci/config.yml"}}-{{ .Branch }}-{{checksum "yarn.lock"}} + - v0-yarn-{{ .Environment.CIRCLE_JOB }}-{{checksum "scripts/circleci"}}-{{checksum ".circleci/config.yml"}}-{{ .Branch }}- + - v0-yarn-{{ .Environment.CIRCLE_JOB }}-{{checksum "scripts/circleci"}}-{{checksum ".circleci/config.yml"}}-master- + - run: ./scripts/circleci test + - store_test_results: + path: ~/cli/reports - save_cache: &save_cache - key: v0-yarn-{{ .Environment.CIRCLE_JOB }}-{{checksum ".circleci/config.yml"}}-{{ .Branch }}-{{checksum "yarn.lock"}} + key: v0-yarn-{{ .Environment.CIRCLE_JOB }}-{{checksum "scripts/circleci"}}-{{checksum ".circleci/config.yml"}}-{{ .Branch }}-{{checksum "yarn.lock"}} paths: - ~/cli/node_modules - /usr/local/share/.cache/yarn @@ -28,13 +30,12 @@ jobs: steps: - checkout - restore_cache: *restore_cache - - run: yarn - - run: ./node_modules/.bin/dxcli-dev-semantic-release + - run: ./scripts/circleci release - save_cache: *save_cache workflows: version: 2 - test: + "@dxcli/config": jobs: - node-latest - node-8 diff --git a/.eslintignore b/.eslintignore index 502167fa..a33da626 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ /lib +/plugins diff --git a/.gitattributes b/.gitattributes index 176a458f..3beda43c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,3 @@ * text=auto +*.js text eol=lf +*.ts text eol=lf diff --git a/.gitignore b/.gitignore index daf0cee9..7bc5cb1e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ +*-debug.log +*-error.log +/.nyc_output /coverage +/coverage.lcov /lib /node_modules /tmp -/.nyc_output - -*-error.log -*-debug.log diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..655d2928 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "plugins/heroku-run"] + path = plugins/heroku-run + url = https://github.com/heroku/heroku-run +[submodule "plugins/heroku-cli-status"] + path = plugins/heroku-cli-status + url = https://github.com/heroku/heroku-cli-status diff --git a/README.md b/README.md index 14aa9c9a..0706e7ce 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ @dxcli/config ============= +base config object and standard interfaces for dxcli components + [![Version](https://img.shields.io/npm/v/@dxcli/config.svg)](https://npmjs.org/package/@dxcli/config) [![CircleCI](https://circleci.com/gh/dxcli/config/tree/master.svg?style=svg)](https://circleci.com/gh/dxcli/config/tree/master) [![Appveyor CI](https://ci.appveyor.com/api/projects/status/github/dxcli/config?branch=master&svg=true)](https://ci.appveyor.com/project/heroku/config/branch/master) diff --git a/appveyor.yml b/appveyor.yml index a5177d6b..4d7c1c23 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,10 +2,14 @@ environment: nodejs_version: "9" cache: - '%LOCALAPPDATA%\Yarn -> appveyor.yml' - - node_modules -> package.json + - node_modules -> yarn.lock install: - ps: Install-Product node $env:nodejs_version x64 + - git submodule sync + - git submodule update --init --recursive + - git config --global user.email "dxcli@example.com" + - git config --global user.name "dxcli" - yarn test_script: - yarn test diff --git a/package.json b/package.json index 06bf0b64..90887bc9 100644 --- a/package.json +++ b/package.json @@ -1,26 +1,39 @@ { "name": "@dxcli/config", + "description": "base config object and standard interfaces for dxcli components", "version": "0.0.0", "author": "Jeff Dickey @jdxcode", + "bugs": "https://github.com/dxcli/config/issues", "dependencies": { - "cli-ux": "^2.0.21" + "cli-ux": "^2.0.21", + "debug": "^3.1.0", + "fs-extra": "^5.0.0", + "load-json-file": "^4.0.0", + "lodash": "^4.17.4", + "read-pkg-up": "^3.0.0" }, "devDependencies": { - "@dxcli/dev": "^0.0.3", + "@dxcli/dev": "^1.1.3", "@dxcli/dev-nyc-config": "^0.0.3", "@dxcli/dev-semantic-release": "^0.0.3", - "@dxcli/dev-tslint": "^0.0.5", + "@dxcli/dev-test": "^0.1.2", + "@dxcli/dev-tslint": "^0.0.9", + "@heroku-cli/config-edit": "^1.0.4", "@types/ansi-styles": "^2.0.30", "@types/chai": "^4.1.0", + "@types/fs-extra": "^5.0.0", + "@types/load-json-file": "^2.0.7", + "@types/lodash": "^4.14.92", "@types/mocha": "^2.2.46", "@types/node": "^9.3.0", + "@types/read-pkg-up": "^3.0.0", "chai": "^4.1.2", - "del-cli": "^1.1.0", "eslint": "^4.15.0", - "eslint-config-dxcli": "^1.1.2", + "eslint-config-dxcli": "^1.1.4", "husky": "^0.14.3", "mocha": "^4.1.0", "nyc": "^11.4.1", + "rxjs": "^5.5.6", "ts-node": "^4.1.0", "typescript": "^2.6.2" }, @@ -28,16 +41,16 @@ "workflows": { "test": [ "eslint .", - "tsc", - "tslint -p .", - "commitlint --from master", + "tsc -p test --noEmit", + "tslint -p test", + "commitlint --from origin/master", "mocha \"test/**/*.ts\"" ], "lint": [ "eslint .", - "tsc", - "tslint -p .", - "commitlint --from master" + "tsc -p test --noEmit", + "tslint -p test", + "commitlint --from origin/master" ] } }, @@ -47,13 +60,19 @@ "files": [ "/lib" ], + "homepage": "https://github.com/dxcli/config", + "keywords": [ + "dxcli" + ], "license": "MIT", + "main": "lib/index.js", "repository": "dxcli/config", "scripts": { + "commitmsg": "dxcli-dev-commitmsg", "lint": "dxcli-dev lint", - "test": "dxcli-dev test", - "precommit": "dxcli-dev test", - "prepare": "del-cli lib && tsc", - "commitmsg": "dxcli-dev-commitmsg" - } + "precommit": "dxcli-dev lint", + "prepare": "rm -rf lib && tsc", + "test": "dxcli-dev test" + }, + "types": "lib/index.d.ts" } diff --git a/plugins/heroku-cli-status b/plugins/heroku-cli-status new file mode 160000 index 00000000..df4d65fb --- /dev/null +++ b/plugins/heroku-cli-status @@ -0,0 +1 @@ +Subproject commit df4d65fb1615cf2de60cc80c27d5615c07e47a3c diff --git a/plugins/heroku-run b/plugins/heroku-run new file mode 160000 index 00000000..330d81db --- /dev/null +++ b/plugins/heroku-run @@ -0,0 +1 @@ +Subproject commit 330d81db71b31329d86e0b92afc3a19bd551d640 diff --git a/scripts/circleci b/scripts/circleci index d6bfe96f..e2a41495 100755 --- a/scripts/circleci +++ b/scripts/circleci @@ -2,27 +2,64 @@ set -ex +duration() { + set +x + start=$(date +%s) + "$@" + end=$(date +%s) + python -c "print 'Ran $1 in %u:%02u' % ((${end} - ${start})/60, (${end} - ${start})%60)" + set -x +} + PATH=/usr/local/share/.config/yarn/global/node_modules/.bin:$PATH -CLI_ENGINE_UTIL_YARN_ARGS="--frozen-lockfile" +if [[ ! -z "$GIT_EMAIL" ]] & [[ ! -z "$GIT_USERNAME" ]]; then + git config --global push.default simple + git config --global user.email "$GIT_EMAIL" + git config --global user.user "$GIT_USERNAME" +fi + +git submodule sync +git submodule update --init --recursive -if [[ "$CIRCLE_BRANCH" == greenkeeper/* ]]; then - CLI_ENGINE_GREENKEEPER_BRANCH=1 - CLI_ENGINE_UTIL_YARN_ARGS="" - if [[ ! -x "$(command -v greenkeeper-lockfile-update)" ]]; then - yarn global add greenkeeper-lockfile@1 +_test() { + CLI_ENGINE_UTIL_YARN_ARGS="--frozen-lockfile" + + if [[ "$CIRCLE_BRANCH" == greenkeeper/* ]]; then + CLI_ENGINE_GREENKEEPER_BRANCH=1 + CLI_ENGINE_UTIL_YARN_ARGS="" + if [[ ! -x "$(command -v greenkeeper-lockfile-update)" ]]; then + duration yarn global add greenkeeper-lockfile@1 + fi + duration greenkeeper-lockfile-update fi - greenkeeper-lockfile-update -fi -yarn install $CLI_ENGINE_UTIL_YARN_ARGS + duration yarn install $CLI_ENGINE_UTIL_YARN_ARGS -if [[ "$CLI_ENGINE_GREENKEEPER_BRANCH" == 1 ]]; then - greenkeeper-lockfile-upload -fi + if [[ "$CLI_ENGINE_GREENKEEPER_BRANCH" == 1 ]]; then + duration greenkeeper-lockfile-upload + fi + + CWD=$(pwd) + NYC=(./node_modules/.bin/nyc --nycrc-path node_modules/@dxcli/dev-nyc-config/.nycrc) + mkdir -p reports + MOCHA_FILE="$CWD/reports/mocha.xml" \ + DXCLI_MOCHA_OPTS="--reporter mocha-junit-reporter" \ + DXCLI_ESLINT_OPTS="--format junit --output-file $CWD/reports/eslint.xml" \ + DXCLI_TSLINT_OPTS="--format junit > $CWD/reports/tslint.xml" \ + duration "${NYC[@]}" yarn test + + duration "${NYC[@]}" report --reporter=text-lcov > coverage.lcov + + duration curl -s https://codecov.io/bash | bash +} -NYC="./node_modules/.bin/nyc --nycrc-path node_modules/@dxcli/dev-nyc-config/.nycrc" -$NYC yarn test -$NYC report --reporter=text-lcov > coverage.lcov +_release() { + yarn --frozen-lockfile + ./node_modules/.bin/dxcli-dev-semantic-release +} -curl -s https://codecov.io/bash | bash +case "$1" in + release) _release;; + *) _test;; +esac diff --git a/src/command.ts b/src/command.ts new file mode 100644 index 00000000..16147dbf --- /dev/null +++ b/src/command.ts @@ -0,0 +1,16 @@ +import {IConfig} from './config' + +export interface ICachedCommand { + id?: string + hidden: boolean + base: string + aliases: string[] + // help(config: IConfig): string + // helpLine(config: IConfig): [string, string | undefined] + load(): Promise +} + +export interface ICommand extends ICachedCommand { + base: '@cli-engine/command@1.0.0' + run(argv: string[], config: IConfig): Promise +} diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 00000000..a5f38ebb --- /dev/null +++ b/src/config.ts @@ -0,0 +1,288 @@ +import * as fs from 'fs-extra' +import * as readJSON from 'load-json-file' +import * as os from 'os' +import * as path from 'path' +import * as readPkgUp from 'read-pkg-up' + +import {IEngine} from './engine' +import {ICLIPJSON, IPluginPJSON, normalizePJSON} from './pjson' + +const _pjson = require('../package.json') +const _base = `${_pjson.name}@${_pjson.version}` + +export type PlatformTypes = 'darwin' | 'linux' | 'win32' | 'aix' | 'freebsd' | 'openbsd' | 'sunos' +export type ArchTypes = 'arm' | 'arm64' | 'mips' | 'mipsel' | 'ppc' | 'ppc64' | 's390' | 's390x' | 'x32' | 'x64' | 'x86' + +export interface IConfigBase { + arch: string + bin: string + cacheDir: string + configDir: string + dataDir: string + dirname: string + errlog: string + home: string + name: string + pjson: IPluginPJSON | ICLIPJSON + platform: string + shell: string + windows: boolean + commandsDir: string | undefined + userAgent: string + tsconfig: TSConfig | undefined + hooks: {[k: string]: string[]} +} + +export interface IPluginConfig extends IConfigBase { + type: 'plugin' + pjson: IPluginPJSON +} + +export interface ICLIConfig extends IConfigBase { + type: 'cli' + pjson: ICLIPJSON + engine: IEngine + npmRegistry: string +} + +export type IConfig = IPluginConfig | ICLIConfig + +export interface TSConfig { + compilerOptions: { + rootDir?: string + outDir?: string + } +} + +const debug = require('debug')('@dxcli/config') + +export abstract class ConfigBase implements IConfigBase { + static tsNode: any + /** + * registers ts-node for reading typescript source (./src) instead of compiled js files (./lib) + * there are likely issues doing this any the tsconfig.json files are not compatible with others + */ + static registerTSNode() { + if (this.tsNode) return + return this.tsNode = require('ts-node').register() + } + + readonly _base = _base + arch: string + bin: string + cacheDir: string + configDir: string + dataDir: string + dirname: string + errlog: string + home: string + name: string + pjson: any + platform: string + root: string + shell: string + version: string + windows: boolean + userAgent: string + commandsDir: string | undefined + tsconfig: TSConfig | undefined + debug: number + hooks: {[k: string]: string[]} + + constructor() { + this.arch = (os.arch() === 'ia32' ? 'x86' : os.arch() as any) + this.platform = os.platform() as any + this.windows = this.platform === 'win32' + } + + async load({name, root}: {name?: string, root: string}) { + root = await findRootByName(name, root) + const pkg = await readPkgUp({cwd: root}) + this.root = path.dirname(pkg.path) + debug('found root at', this.root) + this.pjson = normalizePJSON(pkg.pkg) + + this.name = this.pjson.name + this.version = this.pjson.version + this.bin = this.pjson.dxcli.bin + this.dirname = this.pjson.dxcli.dirname + this.userAgent = `${this.name}/${this.version} (${this.platform}-${this.arch}) node-${process.version}` + this.shell = this._shell() + this.debug = this._debug() + + this.home = process.env.HOME || (this.windows && this.windowsHome()) || os.homedir() || os.tmpdir() + this.cacheDir = this.scopedEnvVar('CACHE_DIR') || this.macosCacheDir() || this.dir('cache') + this.configDir = this.scopedEnvVar('CONFIG_DIR') || this.dir('config') + this.dataDir = this.scopedEnvVar('DATA_DIR') || this.dir('data') + this.errlog = path.join(this.cacheDir, 'error.log') + + this.tsconfig = await this._tsConfig() + this.commandsDir = await this._libToSrcPath(this.pjson.dxcli.commands) + this.hooks = await this._hooks() + + return this + } + + scopedEnvVar(k: string) { + return process.env[this.scopedEnvVarKey(k)] + } + + scopedEnvVarTrue(k: string): boolean { + let v = process.env[this.scopedEnvVarKey(k)] + return v === '1' || v === 'true' + } + + scopedEnvVarKey(k: string) { + return [this.bin, k] + .map(p => p.replace(/-/g, '_')) + .join('_') + .toUpperCase() + } + + private dir(category: 'cache' | 'data' | 'config'): string { + const base = process.env[`XDG_${category.toUpperCase()}_HOME`] + || (this.windows && process.env.LOCALAPPDATA) + || path.join(this.home, category === 'data' ? '.local/share' : '.' + category) + return path.join(base, this.dirname) + } + + private windowsHome() { return this.windowsHomedriveHome() || this.windowsUserprofileHome() } + private windowsHomedriveHome() { return (process.env.HOMEDRIVE && process.env.HOMEPATH && path.join(process.env.HOMEDRIVE!, process.env.HOMEPATH!)) } + private windowsUserprofileHome() { return process.env.USERPROFILE } + private macosCacheDir(): string | undefined { return this.platform === 'darwin' && path.join(this.home, 'Library', 'Caches', this.dirname) || undefined } + + private async _tsConfig(): Promise { + try { + const tsconfigPath = path.join(this.root, 'tsconfig.json') + const tsconfig = await readJSON(path.join(this.root, 'tsconfig.json')) + if (!tsconfig || !tsconfig.compilerOptions) return + debug('tsconfig.json found at', tsconfigPath) + return tsconfig + } catch (err) { + if (err.code !== 'ENOENT') throw err + } + } + + /** + * convert a path from the compiled ./lib files to the ./src typescript source + * this is for developing typescript plugins/CLIs + * if there is a tsconfig and the original sources exist, it attempts to require ts- + */ + private async _libToSrcPath(orig: string): Promise { + if (!orig) return + orig = path.join(this.root, orig) + if (!this.tsconfig) return orig + let {rootDir, outDir} = this.tsconfig.compilerOptions + if (!rootDir || !outDir) return orig + try { + // rewrite path from ./lib/foo to ./src/foo + const lib = path.join(this.root, outDir) // ./lib + const src = path.join(this.root, rootDir) // ./src + const relative = path.relative(lib, orig) // ./commands + const out = path.join(src, relative) // ./src/commands + debug('using ts files at', out) + ConfigBase.registerTSNode() + // this can be a directory of commands or point to a hook file + // if it's a directory, we check if the path exists. If so, return the path to the directory. + // For hooks, it might point to a module, not a file. Something like "./hooks/myhook" + // That file doesn't exist, and the real file is "./hooks/myhook.ts" + // In that case we attempt to resolve to the filename. If it fails it will revert back to the lib path + if (!await fs.pathExists(out)) return require.resolve(out) + return out + } catch (err) { + debug(err) + return orig + } + } + + private async _hooks(): Promise<{[k: string]: string[]}> { + const promises = Object.entries(this.pjson.dxcli.hooks) + .map(([k, v]) => [k, v.map(this._libToSrcPath(v))] as [string, Promise[]]) + const hooks: {[k: string]: string[]} = {} + for (let [k, v] of promises) { + hooks[k] = await Promise.all(v) + } + return hooks + } + + private _shell(): string { + let shellPath + const {SHELL, COMSPEC} = process.env + if (SHELL) { + shellPath = SHELL.split('/') + } else if (this.windows && COMSPEC) { + shellPath = COMSPEC.split(/\\|\//) + } else { + shellPath = ['unknown'] + } + return shellPath[shellPath.length - 1] + } + + private _debug(): number { + try { + let debug = require('debug')(this.bin).enabled || this.scopedEnvVarTrue('DEBUG') + return debug ? 1 : 0 + } catch { return 0 } + } +} + +export class PluginConfig extends ConfigBase implements IPluginConfig { + static async create({name, root = __dirname}: {name?: string, root?: string}) { + const config = new this() + await config.load({root, name}) + return config + } + + readonly type: 'plugin' = 'plugin' + pjson: IPluginPJSON +} + +export class CLIConfig extends ConfigBase implements ICLIConfig { + static async create({engine, name, root = __dirname}: {engine: IEngine, name?: string, root?: string}) { + const config = new this(engine) + await config.load({name, root}) + return config + } + + readonly type: 'cli' = 'cli' + pjson: ICLIPJSON + engine: IEngine + npmRegistry: string + + constructor(engine: IEngine) { + super() + this.engine = engine + } + + async load({root, name}: {root: string, name?: string}) { + await super.load({root, name}) + this.npmRegistry = this.scopedEnvVar('NPM_REGISTRY') || this.pjson.dxcli.npmRegistry || 'https://registry.yarnpkg.com' + return this + } +} + +export type Config = PluginConfig | CLIConfig + +/** + * find package root + * for packages installed into node_modules this will go up directories until + * it finds a node_modules directory with the plugin installed into it + * + * This is needed because of the deduping npm does + */ +async function findRootByName(name: string | undefined, root: string) { + if (!name) return root + // essentially just "cd .." + function* up(from: string) { + while (path.dirname(from) !== from) { + yield from + from = path.dirname(from) + } + yield from + } + for (let next of up(root)) { + const cur = path.join(next, 'node_modules', name, 'package.json') + if (await fs.pathExists(cur)) return cur + } + return root +} diff --git a/src/engine.ts b/src/engine.ts new file mode 100644 index 00000000..e6c2a5ff --- /dev/null +++ b/src/engine.ts @@ -0,0 +1,21 @@ +import {ICommand} from './command' +import {IPlugin} from './plugin' +import {ITopic} from './topic' + +export interface IEngine extends ICommand { + readonly plugins: IPlugin[] + + readonly topics: ITopic[] + readonly commands: ICommand[] + readonly commandIDs: string[] + readonly rootTopics: ITopic[] + readonly rootCommands: ICommand[] + + findCommand(id: string, must: true): ICommand + findCommand(id: string, must?: boolean): ICommand | undefined + + findTopic(id: string, must: true): ITopic + findTopic(id: string, must?: boolean): ITopic | undefined + + runHook(event: string, opts: T): Promise +} diff --git a/src/hooks.ts b/src/hooks.ts new file mode 100644 index 00000000..3e916977 --- /dev/null +++ b/src/hooks.ts @@ -0,0 +1,19 @@ +import {ICommand} from './command' +import {IConfig} from './config' +import {IPluginPJSON} from './pjson' +import {IPluginModule} from './plugin' + +export interface IHooks { + init: {} + update: {} + 'plugins:parse': { + module: IPluginModule + pjson: IPluginPJSON + } + prerun: { + Command: ICommand + argv: string[] + } +} + +export type Hook = (options: T & {config: IConfig}) => Promise diff --git a/src/index.ts b/src/index.ts index 7e3ceb73..29099ea7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,5 @@ -export const add = (a: number, b: number) => a + b +export * from './command' +export * from './config' +export * from './topic' +export * from './plugin' +export {IPJSON, IPluginPJSON, ICLIPJSON} from './pjson' diff --git a/src/pjson.ts b/src/pjson.ts new file mode 100644 index 00000000..d5142e27 --- /dev/null +++ b/src/pjson.ts @@ -0,0 +1,83 @@ +import * as _ from 'lodash' +import {Package} from 'read-pkg-up' + +export interface IRawPJSONBase extends Package { + name: string + version: string + dxcli?: { + bin?: string + dirname?: string + commands?: string + hooks?: { [name: string]: string | string[] } + plugins?: string[] | string + topics?: { + [k: string]: { + description?: string + subtopics?: IPJSONBase['dxcli']['topics'] + hidden?: boolean + } + } + } +} + +export interface IRawPluginPJSON extends IRawPJSONBase { + dxcli?: IRawPJSONBase['dxcli'] & { + type?: 'plugin' + } +} + +export interface IRawCLIPJSON extends IRawPJSONBase { + dxcli: IRawPJSONBase['dxcli'] & { + type: 'cli' + npmRegistry?: string + } +} + +export interface IPJSONBase extends IRawPJSONBase { + name: string + version: string + dxcli: { + bin: string + dirname: string + commands?: string + hooks: { [name: string]: string[] } + plugins?: string[] | string + topics: { + [k: string]: { + description?: string + subtopics?: IPJSONBase['dxcli']['topics'] + hidden?: boolean + } + } + } +} + +export interface IPluginPJSON extends IPJSONBase { + dxcli: IPJSONBase['dxcli'] & { + type: 'plugin' + } +} + +export interface ICLIPJSON extends IPJSONBase { + dxcli: IPJSONBase['dxcli'] & { + type: 'cli' + npmRegistry?: string + } +} + +export type IPJSON = IPluginPJSON | ICLIPJSON + +export function normalizePJSON(pjson: IRawCLIPJSON): ICLIPJSON +export function normalizePJSON(pjson: IRawPluginPJSON): IPluginPJSON +export function normalizePJSON(input: IRawPluginPJSON | IRawCLIPJSON): any { + const dxcli: IRawPluginPJSON['dxcli'] | IRawCLIPJSON['dxcli'] = {...(input.dxcli! || input['cli-engine'])} + dxcli.hooks = _.mapValues(dxcli.hooks, _.castArray) + dxcli.type = dxcli.type || 'plugin' + dxcli.bin = dxcli.bin || input.name + dxcli.dirname = dxcli.dirname || dxcli.bin + dxcli.topics = dxcli.topics || {} + return { + ...input, + dxcli, + } +} diff --git a/src/plugin.ts b/src/plugin.ts new file mode 100644 index 00000000..e58e32d2 --- /dev/null +++ b/src/plugin.ts @@ -0,0 +1,15 @@ +import {ICommand} from './command' +import {ITopic} from './topic' + +export interface IPluginModule { + commands: ICommand[] + topic?: ITopic + topics: ITopic[] +} + +export interface IPlugin { + name: string + version: string + type: string + root: string +} diff --git a/src/topic.ts b/src/topic.ts new file mode 100644 index 00000000..97e35f72 --- /dev/null +++ b/src/topic.ts @@ -0,0 +1,5 @@ +export interface ITopic { + name: string + description?: string + hidden?: boolean +} diff --git a/test/config.test.ts b/test/config.test.ts new file mode 100644 index 00000000..47d26f60 --- /dev/null +++ b/test/config.test.ts @@ -0,0 +1,68 @@ +import {describe, expect, it} from '@dxcli/dev-test' +import * as os from 'os' +import * as path from 'path' + +import {PluginConfig} from '../src' + +const pluginRoot = (plugin: string) => path.resolve(__dirname, '../plugins', plugin) + +const testPlugin = (plugin: string, description: string, fn: (config: PluginConfig) => void) => { + it(`${plugin}: ${description}`, async () => { + const config = await PluginConfig.create({name: plugin, root: pluginRoot(plugin)}) + fn(config) + }) +} + +describe('PluginConfig', () => { + describe.env().mock(os, 'homedir', () => path.join('/my/home'))('home = /my/home', () => { + describe.mock(os, 'platform', () => 'darwin')('os = darwin', () => { + testPlugin('heroku-cli-status', 'sets dirs', config => { + expect(config).to.include({ + cacheDir: path.join('/my/home/Library/Caches/heroku-cli-status'), + configDir: path.join('/my/home/.config/heroku-cli-status'), + errlog: path.join('/my/home/Library/Caches/heroku-cli-status/error.log'), + dataDir: path.join('/my/home/.local/share/heroku-cli-status'), + commandsDir: path.join(pluginRoot('heroku-cli-status'), 'src/commands'), + home: path.join('/my/home'), + }) + }) + }) + describe.mock(os, 'platform', () => 'linux')('os = linux', () => { + testPlugin('heroku-cli-status', 'sets dirs', config => { + expect(config).to.include({ + cacheDir: path.join('/my/home/.cache/heroku-cli-status'), + configDir: path.join('/my/home/.config/heroku-cli-status'), + errlog: path.join('/my/home/.cache/heroku-cli-status/error.log'), + dataDir: path.join('/my/home/.local/share/heroku-cli-status'), + commandsDir: path.join(pluginRoot('heroku-cli-status'), 'src/commands'), + home: path.join('/my/home'), + }) + }) + }) + describe.env({LOCALAPPDATA: '/my/home/localappdata'}).mock(os, 'platform', () => 'win32')('os = win32', () => { + testPlugin('heroku-cli-status', 'sets dirs', config => { + expect(config).to.include({ + cacheDir: path.join('/my/home/localappdata/heroku-cli-status'), + configDir: path.join('/my/home/localappdata/heroku-cli-status'), + errlog: path.join('/my/home/localappdata/heroku-cli-status/error.log'), + dataDir: path.join('/my/home/localappdata/heroku-cli-status'), + commandsDir: path.join(pluginRoot('heroku-cli-status'), 'src/commands'), + home: path.join('/my/home'), + }) + }) + }) + }) + + testPlugin('heroku-run', 'has properties', config => { + expect(config).to.include({ + commandsDir: undefined + }) + }) + + testPlugin('@heroku-cli/config-edit', 'has properties', config => { + expect(config).to.include({ + name: '@heroku-cli/config-edit', + commandsDir: path.join(__dirname, '../node_modules/@heroku-cli/config-edit/lib/commands'), + }) + }) +}) diff --git a/test/index.test.ts b/test/index.test.ts deleted file mode 100644 index 81835de9..00000000 --- a/test/index.test.ts +++ /dev/null @@ -1,8 +0,0 @@ -import {expect} from 'chai' -import {add} from '../src' - -describe('add', () => { - it('1+2=3', () => { - expect(add(1, 2)).to.equal(3) - }) -}) diff --git a/tsconfig.json b/tsconfig.json index 59a5cb46..5f353497 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "declaration": true, + "experimentalDecorators": true, "forceConsistentCasingInFileNames": true, "importHelpers": true, "module": "commonjs", diff --git a/yarn.lock b/yarn.lock index 00d63e5d..ac7ac2e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,18 @@ # yarn lockfile v1 +"@cli-engine/command@^12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@cli-engine/command/-/command-12.1.0.tgz#86300ad3c7f51b1c539f9c7b998204f52016e0a7" + dependencies: + "@cli-engine/screen" "^0.0.0" + chalk "^2.3.0" + cli-flags "^2.0.7" + +"@cli-engine/config@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@cli-engine/config/-/config-5.1.0.tgz#d8ac7122317bc505dc09e7fd778777602d6b7568" + "@cli-engine/screen@^0.0.0": version "0.0.0" resolved "https://registry.yarnpkg.com/@cli-engine/screen/-/screen-0.0.0.tgz#c2e847c7d4d998490c9097282bf21637d5162116" @@ -130,26 +142,44 @@ "@semantic-release/npm" "^2.6.1" semantic-release "^12.2.0" -"@dxcli/dev-tslint@^0.0.5": - version "0.0.5" - resolved "https://registry.yarnpkg.com/@dxcli/dev-tslint/-/dev-tslint-0.0.5.tgz#4ee334cf67d4928313ada1abed521448ae2b4c12" +"@dxcli/dev-test@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@dxcli/dev-test/-/dev-test-0.1.2.tgz#6971411652a65e9c6da82c7411a84f191e334e56" + dependencies: + "@dxcli/dev-nyc-config" "^0.0.3" + "@types/ansi-styles" "^2.0.30" + "@types/chai" "^4.1.0" + "@types/lodash" "^4.14.92" + "@types/mocha" "^2.2.46" + "@types/strip-ansi" "^3.0.0" + chai "^4.1.2" + lodash "^4.17.4" + mocha-junit-reporter "^1.15.0" + std-mocks "^1.0.1" + strip-ansi "^4.0.0" + ts-node "^4.1.0" + +"@dxcli/dev-tslint@^0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@dxcli/dev-tslint/-/dev-tslint-0.0.9.tgz#552b62b769ede24b30fdc3b8c04e10b1a60f027f" dependencies: tslint "^5.9.1" - tslint-xo "^0.4.0" + tslint-xo "^0.5.0" -"@dxcli/dev@^0.0.3": - version "0.0.3" - resolved "https://registry.yarnpkg.com/@dxcli/dev/-/dev-0.0.3.tgz#aa3891810a964f822d42efebfd8be103d556884d" +"@dxcli/dev@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@dxcli/dev/-/dev-1.1.3.tgz#da1b929372cae0af15f78849483494a74c3c075e" dependencies: cli-ux "^2.0.21" concurrently "^3.5.1" debug "^3.1.0" execa "^0.9.0" get-stream "^3.0.0" + lodash "^4.17.4" read-pkg-up "^3.0.0" supports-color "^5.1.0" -"@heroku-cli/color@^1.0.4": +"@heroku-cli/color@^1.0.4", "@heroku-cli/color@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@heroku-cli/color/-/color-1.1.1.tgz#a2c25239ff1196733a79cabc7a750cd46b96dc30" dependencies: @@ -158,6 +188,29 @@ strip-ansi "^4.0.0" supports-color "^5.1.0" +"@heroku-cli/command@^7.0.13": + version "7.0.13" + resolved "https://registry.yarnpkg.com/@heroku-cli/command/-/command-7.0.13.tgz#d2eafe24e4a0e1857f8ac81e84791e5ca392b6b9" + dependencies: + "@cli-engine/command" "^12.1.0" + "@cli-engine/config" "^5.1.0" + cli-ux "^2.0.21" + heroku-client "3.0.6" + http-call "^4.0.8" + netrc-parser "^3.0.0" + +"@heroku-cli/config-edit@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@heroku-cli/config-edit/-/config-edit-1.0.4.tgz#98aa514fd6af1bcde64973b6dcdfb249a6256243" + dependencies: + "@heroku-cli/color" "^1.1.1" + "@heroku-cli/command" "^7.0.13" + cli-ux "^2.0.21" + edit-string "1.1.5" + shell-quote "1.6.1" + ts-lodash "4.0.9" + tslib "^1.8.1" + "@heroku/linewrap@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@heroku/linewrap/-/linewrap-1.0.0.tgz#a9d4e99f0a3e423a899b775f5f3d6747a1ff15c6" @@ -260,14 +313,42 @@ version "4.1.0" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.0.tgz#d9008fa4c06f6801f93396d121f0227cd4244ac6" +"@types/fs-extra@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.0.0.tgz#d3e225b35eb5c6d3a5a782c28219df365c781413" + dependencies: + "@types/node" "*" + +"@types/load-json-file@^2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@types/load-json-file/-/load-json-file-2.0.7.tgz#c887826f5230b7507d5230994d26315c6776be06" + +"@types/lodash@^4.14.92": + version "4.14.92" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.92.tgz#6e3cb0b71a1e12180a47a42a744e856c3ae99a57" + "@types/mocha@^2.2.46": version "2.2.46" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.46.tgz#b04713f7759d1cf752effdaae7b3969e285ebc16" -"@types/node@^9.3.0": +"@types/node@*", "@types/node@^9.3.0": version "9.3.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-9.3.0.tgz#3a129cda7c4e5df2409702626892cb4b96546dd5" +"@types/normalize-package-data@*": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" + +"@types/read-pkg-up@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/read-pkg-up/-/read-pkg-up-3.0.0.tgz#d8ef96f335f505e1d38c2eda92f097565e7da168" + dependencies: + "@types/normalize-package-data" "*" + +"@types/strip-ansi@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/strip-ansi/-/strip-ansi-3.0.0.tgz#9b63d453a6b54aa849182207711a08be8eea48ae" + "@types/strip-bom@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2" @@ -328,12 +409,6 @@ amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" -ansi-align@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" - dependencies: - string-width "^2.0.0" - ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" @@ -421,6 +496,10 @@ arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" +array-filter@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" @@ -429,6 +508,14 @@ array-ify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" +array-map@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + +array-reduce@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -600,18 +687,6 @@ boom@5.x.x: dependencies: hoek "4.x.x" -boxen@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" - dependencies: - ansi-align "^2.0.0" - camelcase "^4.0.0" - chalk "^2.0.1" - cli-boxes "^1.0.0" - string-width "^2.0.0" - term-size "^1.2.0" - widest-line "^2.0.0" - brace-expansion@^1.1.7: version "1.1.8" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" @@ -708,14 +783,10 @@ camelcase@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" -camelcase@^4.0.0, camelcase@^4.1.0: +camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" -capture-stack-trace@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" - cardinal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-1.0.0.tgz#50e21c1b0aa37729f9377def196b5a9cec932ee9" @@ -777,6 +848,10 @@ chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" +charenc@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + check-error@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" @@ -804,10 +879,6 @@ clean-regexp@^1.0.0: dependencies: escape-string-regexp "^1.0.5" -cli-boxes@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - cli-cursor@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" @@ -820,6 +891,14 @@ cli-cursor@^2.1.0: dependencies: restore-cursor "^2.0.0" +cli-flags@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/cli-flags/-/cli-flags-2.0.7.tgz#215b3f8d911142c3e4833eaf7f2f96ab97fd22cf" + dependencies: + "@cli-engine/screen" "^0.0.0" + "@heroku/linewrap" "^1.0.0" + ts-lodash "^4.0.8" + cli-table@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" @@ -978,21 +1057,14 @@ config-chain@^1.1.11: ini "^1.3.4" proto-list "~1.2.1" -configstore@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.1.tgz#094ee662ab83fad9917678de114faaea8fcdca90" - dependencies: - dot-prop "^4.1.0" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - unique-string "^1.0.0" - write-file-atomic "^2.0.0" - xdg-basedir "^3.0.0" - console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" +content-type@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + conventional-changelog-angular@^1.3.3, conventional-changelog-angular@^1.4.0: version "1.6.0" resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-1.6.0.tgz#0a26a071f2c9fcfcf2b86ba0cfbf6e6301b75bfa" @@ -1063,12 +1135,6 @@ cosmiconfig@^3.0.1, cosmiconfig@^3.1.0: parse-json "^3.0.0" require-from-string "^2.0.1" -create-error-class@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - dependencies: - capture-stack-trace "^1.0.0" - cross-spawn@^4: version "4.0.2" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" @@ -1084,16 +1150,16 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" +crypt@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + cryptiles@3.x.x: version "3.1.2" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" dependencies: boom "5.x.x" -crypto-random-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -1204,14 +1270,6 @@ define-property@^1.0.0: dependencies: is-descriptor "^1.0.0" -del-cli@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/del-cli/-/del-cli-1.1.0.tgz#27557d69a0b7df99dcbaa1e34a09e6ac6591d2c4" - dependencies: - del "^3.0.0" - meow "^3.6.0" - update-notifier "^2.1.0" - del@^2.0.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" @@ -1224,17 +1282,6 @@ del@^2.0.2: pinkie-promise "^2.0.0" rimraf "^2.2.8" -del@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" - dependencies: - globby "^6.1.0" - is-path-cwd "^1.0.0" - is-path-in-cwd "^1.0.0" - p-map "^1.1.1" - pify "^3.0.0" - rimraf "^2.2.8" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1289,12 +1336,6 @@ dot-prop@^3.0.0: dependencies: is-obj "^1.0.0" -dot-prop@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" - dependencies: - is-obj "^1.0.0" - dotenv@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d" @@ -1305,16 +1346,22 @@ duplexer2@~0.1.0: dependencies: readable-stream "^2.0.2" -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" dependencies: jsbn "~0.1.0" +edit-string@1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/edit-string/-/edit-string-1.1.5.tgz#5fa869211ce8af5a3596dcf72d575f3f86f4a4bd" + dependencies: + debug "^3.1.0" + execa "^0.8.0" + tmp "^0.0.33" + ts-lodash "^4.0.9" + tslib "^1.8.1" + env-ci@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/env-ci/-/env-ci-1.2.1.tgz#3973dd365289df494fe6fbacbf208486d79c4207" @@ -1349,9 +1396,9 @@ eslint-ast-utils@^1.0.0: lodash.get "^4.4.2" lodash.zip "^4.2.0" -eslint-config-dxcli@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/eslint-config-dxcli/-/eslint-config-dxcli-1.1.2.tgz#284fe88dd54312217659ec81656e57e2b375ea56" +eslint-config-dxcli@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/eslint-config-dxcli/-/eslint-config-dxcli-1.1.4.tgz#e74a6be724d4de72f116d87f300afb5aacd25fe9" dependencies: eslint-config-xo-space "^0.17.0" eslint-plugin-node "^5.2.1" @@ -1951,16 +1998,6 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - globby@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" @@ -1972,22 +2009,6 @@ globby@^7.1.1: pify "^3.0.0" slash "^1.0.0" -got@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" - dependencies: - create-error-class "^3.0.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - is-redirect "^1.0.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" - lowercase-keys "^1.0.0" - safe-buffer "^5.0.1" - timed-out "^4.0.0" - unzip-response "^2.0.1" - url-parse-lax "^1.0.0" - graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -2081,6 +2102,13 @@ he@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" +heroku-client@3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/heroku-client/-/heroku-client-3.0.6.tgz#bf603716a9d469682d4f7f80489276d82b896305" + dependencies: + is-retry-allowed "^1.0.0" + tunnel-agent "^0.6.0" + hoek@4.x.x: version "4.2.0" resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" @@ -2095,6 +2123,17 @@ hosted-git-info@^2.1.4, hosted-git-info@^2.4.2: version "2.5.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" +http-call@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/http-call/-/http-call-4.0.8.tgz#fd0207764958a3f1238bb3344ff912b32ddfa64a" + dependencies: + content-type "^1.0.4" + debug "^3.1.0" + is-retry-allowed "^1.1.0" + is-stream "^1.1.0" + tslib "^1.8.1" + tunnel-agent "^0.6.0" + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -2132,10 +2171,6 @@ import-from@^2.1.0: dependencies: resolve-from "^3.0.0" -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - import-modules@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/import-modules/-/import-modules-1.1.0.tgz#748db79c5cc42bb9701efab424f894e72600e9dc" @@ -2240,7 +2275,7 @@ is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" -is-buffer@^1.1.5: +is-buffer@^1.1.5, is-buffer@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -2334,17 +2369,6 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" -is-installed-globally@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" - dependencies: - global-dirs "^0.1.0" - is-path-inside "^1.0.0" - -is-npm@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" - is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" @@ -2401,15 +2425,11 @@ is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" -is-redirect@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" - is-resolvable@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.1.tgz#acca1cd36dbe44b974b924321555a70ba03b1cf4" -is-retry-allowed@^1.0.0: +is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" @@ -2419,7 +2439,7 @@ is-ssh@^1.3.0: dependencies: protocols "^1.1.0" -is-stream@^1.0.0, is-stream@^1.1.0: +is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -2573,6 +2593,10 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + jsonparse@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" @@ -2612,12 +2636,6 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" -latest-version@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" - dependencies: - package-json "^4.0.0" - lazy-cache@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" @@ -2641,6 +2659,10 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lex@^1.7.9: + version "1.7.9" + resolved "https://registry.yarnpkg.com/lex/-/lex-1.7.9.tgz#5d5636ccef574348362938b79a47f0eed8ed0d43" + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -2748,7 +2770,7 @@ lodash@4.17.2: version "4.17.2" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.2.tgz#34a3055babe04ce42467b607d700072c7ff6bf42" -lodash@^4.0.0, lodash@^4.17.4, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1: +lodash@^4.0.0, lodash@^4.11.1, lodash@^4.17.4, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -2769,10 +2791,6 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" -lowercase-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" - lru-cache@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" @@ -2780,12 +2798,6 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" -make-dir@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51" - dependencies: - pify "^3.0.0" - make-error@^1.1.1: version "1.3.2" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.2.tgz#8762ffad2444dd8ff1f7c819629fa28e24fea1c4" @@ -2828,13 +2840,21 @@ md5-o-matic@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" +md5@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" + dependencies: + charenc "~0.0.1" + crypt "~0.0.1" + is-buffer "~1.1.1" + mem@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" dependencies: mimic-fn "^1.0.0" -meow@3.7.0, meow@^3.3.0, meow@^3.6.0: +meow@3.7.0, meow@^3.3.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" dependencies: @@ -2938,12 +2958,21 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: +mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" +mocha-junit-reporter@^1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/mocha-junit-reporter/-/mocha-junit-reporter-1.15.0.tgz#309f4b7a20fcda26d0ad69c9b7d0808d772302c2" + dependencies: + debug "^2.2.0" + md5 "^2.1.0" + mkdirp "~0.5.1" + xml "^1.0.0" + mocha@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.1.0.tgz#7d86cfbcf35cb829e2754c32e17355ec05338794" @@ -3003,6 +3032,15 @@ nerf-dart@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/nerf-dart/-/nerf-dart-1.0.0.tgz#e6dab7febf5ad816ea81cf5c629c5a0ebde72c1a" +netrc-parser@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/netrc-parser/-/netrc-parser-3.0.3.tgz#1b3e6cf85e7dc3618dc7daaf639b1fa624392852" + dependencies: + execa "^0.8.0" + fs-extra "^5.0.0" + graceful-fs "^4.1.11" + lex "^1.7.9" + node-emoji@^1.4.1: version "1.8.1" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.8.1.tgz#6eec6bfb07421e2148c75c6bba72421f8530a826" @@ -3228,10 +3266,6 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" -p-map@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" - p-reduce@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" @@ -3240,15 +3274,6 @@ p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" -package-json@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" - dependencies: - got "^6.7.1" - registry-auth-token "^3.0.1" - registry-url "^3.0.3" - semver "^5.1.0" - pad-right@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/pad-right/-/pad-right-0.2.2.tgz#6fbc924045d244f2a2a244503060d3bfc6009774" @@ -3393,10 +3418,6 @@ prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" @@ -3444,7 +3465,7 @@ randomatic@^1.1.3: is-number "^3.0.0" kind-of "^4.0.0" -rc@^1.0.1, rc@^1.1.6: +rc@^1.1.6: version "1.2.3" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.3.tgz#51575a900f8dd68381c710b4712c2154c3e2035b" dependencies: @@ -3534,19 +3555,13 @@ regex-not@^1.0.0: dependencies: extend-shallow "^2.0.1" -registry-auth-token@^3.0.1, registry-auth-token@^3.3.1: +registry-auth-token@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006" dependencies: rc "^1.1.6" safe-buffer "^5.0.1" -registry-url@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" - dependencies: - rc "^1.0.1" - remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -3708,6 +3723,12 @@ rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" +rxjs@^5.5.6: + version "5.5.6" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.6.tgz#e31fb96d6fd2ff1fd84bcea8ae9c02d007179c02" + dependencies: + symbol-observable "1.0.1" + safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, 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" @@ -3737,13 +3758,7 @@ semantic-release@^12.2.0: resolve-from "^4.0.0" semver "^5.4.1" -semver-diff@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" - dependencies: - semver "^5.0.3" - -"semver@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", semver@5.4.1, semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1: +"semver@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", semver@5.4.1, semver@^5.0.1, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" @@ -3789,6 +3804,15 @@ shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" +shell-quote@1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" + shelljs@0.7.6: version "0.7.6" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.6.tgz#379cccfb56b91c8601e4793356eb5382924de9ad" @@ -3977,6 +4001,12 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" +std-mocks@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/std-mocks/-/std-mocks-1.0.1.tgz#d3388876d7beeba3c70fbd8e2bcaf46eb07d79fe" + dependencies: + lodash "^4.11.1" + stream-combiner2@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" @@ -4087,6 +4117,10 @@ supports-color@^5.1.0: dependencies: has-flag "^2.0.0" +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + table@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" @@ -4098,12 +4132,6 @@ table@^4.0.1: slice-ansi "1.0.0" string-width "^2.1.1" -term-size@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" - dependencies: - execa "^0.7.0" - test-exclude@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" @@ -4133,10 +4161,6 @@ through@2, "through@>=2.2.7 <3", through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" -timed-out@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - tmp@^0.0.29: version "0.0.29" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.29.tgz#f25125ff0dd9da3ccb0c2dd371ee1288bb9128c0" @@ -4200,7 +4224,13 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" -ts-lodash@^4.0.8: +ts-lodash@4.0.9: + version "4.0.9" + resolved "https://registry.yarnpkg.com/ts-lodash/-/ts-lodash-4.0.9.tgz#088d7ceefbf36c8c4bcdf28372249015ccafd429" + dependencies: + lodash "^4.17.4" + +ts-lodash@^4.0.8, ts-lodash@^4.0.9: version "4.0.11" resolved "https://registry.yarnpkg.com/ts-lodash/-/ts-lodash-4.0.11.tgz#f668e2ad4b6cb3bcbeceb894cf0a8cde48b3cd85" dependencies: @@ -4255,9 +4285,9 @@ tslint-microsoft-contrib@^5.0.1: dependencies: tsutils "^1.4.0" -tslint-xo@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/tslint-xo/-/tslint-xo-0.4.0.tgz#7cbdfc933ff60d88449c64142e3e060e6432e734" +tslint-xo@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/tslint-xo/-/tslint-xo-0.5.0.tgz#56e591dcd2731de35e7462a0dfa1214731ba9f27" dependencies: tslint-consistent-codestyle "^1.11.0" tslint-eslint-rules "^4.1.1" @@ -4340,12 +4370,6 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^0.4.3" -unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - dependencies: - crypto-random-string "^1.0.0" - universalify@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" @@ -4357,24 +4381,6 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -unzip-response@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" - -update-notifier@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.3.0.tgz#4e8827a6bb915140ab093559d7014e3ebb837451" - dependencies: - boxen "^1.2.1" - chalk "^2.0.1" - configstore "^3.0.0" - import-lazy "^2.1.0" - is-installed-globally "^0.1.0" - is-npm "^1.0.0" - latest-version "^3.0.0" - semver-diff "^2.0.0" - xdg-basedir "^3.0.0" - urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" @@ -4383,12 +4389,6 @@ url-join@^2.0.2: version "2.0.5" resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.5.tgz#5af22f18c052a000a48d7b82c5e9c2e2feeda728" -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - dependencies: - prepend-http "^1.0.1" - url-template@^2.0.8: version "2.0.8" resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" @@ -4452,12 +4452,6 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2" -widest-line@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.0.tgz#0142a4e8a243f8882c0233aa0e0281aa76152273" - dependencies: - string-width "^2.1.1" - window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" @@ -4497,23 +4491,15 @@ write-file-atomic@^1.1.4: imurmurhash "^0.1.4" slide "^1.1.5" -write-file-atomic@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" dependencies: mkdirp "^0.5.1" -xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" +xml@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" xtend@~4.0.1: version "4.0.1"