diff --git a/package.json b/package.json index 7cf0cfcd..73d6213e 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,10 @@ "author": "Jeff Dickey @jdxcode", "bugs": "https://github.com/oclif/command/issues", "dependencies": { - "@oclif/config": "^1", + "@oclif/config": "^1.15.1", "@oclif/errors": "^1.2.2", "@oclif/parser": "^3.8.3", - "@oclif/plugin-help": "^2", + "@oclif/plugin-help": "^3", "debug": "^4.1.1", "semver": "^5.6.0" }, @@ -27,12 +27,12 @@ "fancy-test": "^1.4.3", "globby": "^9.0.0", "mocha": "^6.0.2", - "ts-node": "^8.0.3", - "typescript": "^3.3.3333" + "sinon": "^9.0.1", + "ts-node": "^8.8.2", + "typescript": "^3.8.3" }, "peerDependencies": { - "@oclif/config": "^1", - "@oclif/plugin-help": "^2" + "@oclif/config": "^1" }, "engines": { "node": ">=8.0.0" diff --git a/src/command.ts b/src/command.ts index 303ee881..00f9fd3e 100644 --- a/src/command.ts +++ b/src/command.ts @@ -2,11 +2,12 @@ const pjson = require('../package.json') import * as Config from '@oclif/config' import * as Errors from '@oclif/errors' import * as Parser from '@oclif/parser' -import Help from '@oclif/plugin-help' +import {HelpBase} from '@oclif/plugin-help' import {format, inspect} from 'util' import * as flags from './flags' import {sortBy, uniqBy} from './util' +import {getHelpClass} from '@oclif/plugin-help' /** * swallows stdout epipe errors @@ -186,8 +187,8 @@ export default abstract class Command { } protected _help() { - const HHelp: typeof Help = require('@oclif/plugin-help').default - const help = new HHelp(this.config) + const HelpClass = getHelpClass(this.config) + const help: HelpBase = new HelpClass(this.config) const cmd = Config.Command.toCached(this.ctor as any as Config.Command.Class) if (!cmd.id) cmd.id = '' let topics = this.config.topics diff --git a/src/main.ts b/src/main.ts index eaa8a74c..2db52490 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,8 @@ import * as Config from '@oclif/config' -import Help from '@oclif/plugin-help' +import {HelpBase} from '@oclif/plugin-help' import {Command} from '.' +import {getHelpClass} from '@oclif/plugin-help' export class Main extends Command { static run(argv = process.argv.slice(2), options?: Config.LoadOptions) { @@ -36,8 +37,8 @@ export class Main extends Command { } protected _help() { - const HHelp: typeof Help = require('@oclif/plugin-help').default - const help = new HHelp(this.config) + const HelpClass = getHelpClass(this.config) + const help: HelpBase = new HelpClass(this.config) help.showHelp(this.argv) return this.exit(0) } diff --git a/test/command.test.ts b/test/command.test.ts index e566249d..40062644 100644 --- a/test/command.test.ts +++ b/test/command.test.ts @@ -2,6 +2,10 @@ import * as Config from '@oclif/config' import {expect, fancy} from 'fancy-test' import Base, {flags} from '../src' +import {TestHelpClassConfig} from './helpers/test-help-in-src/src/test-help-plugin' +import * as PluginHelp from '@oclif/plugin-help' + +const originalgetHelpClass = PluginHelp.getHelpClass // const pjson = require('../package.json') @@ -267,6 +271,144 @@ USAGE `) }) + + fancy + .stdout() + .add('config', async () => { + const config: TestHelpClassConfig = await Config.load() + config.pjson.oclif.helpClass = 'help-class-does-not-exist' + return config + }) + .do(async ({config}) => { + class CMD extends Command { + config = config + } + await CMD.run(['-h']) + }) + .catch((error: Error) => expect(error.message).to.contain('Unable to load configured help class "help-class-does-not-exist", failed with message:\n')) + .it('shows useful error message when configured help class cannot be loaded') + + fancy + .stdout() + .stub(PluginHelp, 'getHelpClass', function (config: any) { + return originalgetHelpClass(config, '') + }) + .add('config', async () => { + const config: TestHelpClassConfig = await Config.load() + config.pjson.oclif.helpClass = undefined + return config + }) + .do(async ({config}) => { + class CMD extends Command { + config = config + } + await CMD.run(['-h']) + }) + .catch((error: Error) => expect(error.message).to.contain('Could not load a help class, consider installing the @oclif/plugin-help package, failed with message:\n')) + .it('shows useful error message when no help class has been configured and the default cannot be loaded') + + describe('from a help class', () => { + fancy + .stdout() + .stub(PluginHelp, 'getHelpClass', function (config: Config.IConfig) { + const patchedConfig = { + ...config, + root: `${__dirname}/helpers/test-help-in-lib/`, + } + + return originalgetHelpClass(patchedConfig) + }) + .add('config', async () => { + const config: TestHelpClassConfig = await Config.load() + config.pjson.oclif.helpClass = './lib/test-help-plugin' + return config + }) + .do(async ({config}) => { + class CMD extends Command { + static id = 'test-command-for-help-plugin' + + config = config + } + await CMD.run(['-h']) + }) + .catch(/EEXIT: 0/) + .it('-h via a plugin in lib dir (compiled to js)', ctx => { + expect(ctx.stdout).to.equal('hello from test-help-plugin #showCommandHelp in the lib folder and in compiled javascript\n') + expect(ctx.config.showCommandHelpSpy!.getCalls().length).to.equal(1) + expect(ctx.config.showHelpSpy!.getCalls().length).to.equal(0) + const [Command, Topics] = ctx.config.showCommandHelpSpy!.firstCall.args + expect(Command.id).to.deep.equal('test-command-for-help-plugin') + expect(Topics).to.be.an('array') + }) + + fancy + .stdout() + .stub(PluginHelp, 'getHelpClass', function (config: Config.IConfig) { + const patchedConfig = { + ...config, + root: `${__dirname}/helpers/test-help-in-src/`, + } + + return originalgetHelpClass(patchedConfig) + }) + .add('config', async () => { + const config: TestHelpClassConfig = await Config.load() + config.pjson.oclif.helpClass = './lib/test-help-plugin' + return config + }) + .do(async ({config}) => { + class CMD extends Command { + static id = 'test-command-for-help-plugin' + + config = config + } + await CMD.run(['-h']) + }) + .catch(/EEXIT: 0/) + .it('-h via a plugin in src dir (source in ts)', ctx => { + expect(ctx.stdout).to.equal('hello from test-help-plugin #showCommandHelp\n') + expect(ctx.config.showCommandHelpSpy!.getCalls().length).to.equal(1) + expect(ctx.config.showHelpSpy!.getCalls().length).to.equal(0) + const [Command, Topics] = ctx.config.showCommandHelpSpy!.firstCall.args + expect(Command.id).to.deep.equal('test-command-for-help-plugin') + expect(Topics).to.be.an('array') + }) + + fancy + .stdout() + .stub(PluginHelp, 'getHelpClass', function (config: Config.IConfig) { + const patchedConfig = { + ...config, + root: `${__dirname}/helpers/test-help-in-src/`, + } + + return originalgetHelpClass(patchedConfig) + }) + .add('config', async () => { + const config: TestHelpClassConfig = await Config.load() + config.pjson.oclif.helpClass = './lib/test-help-plugin' + return config + }) + .do(async ({config}) => { + class CMD extends Command { + static id = 'test-command-for-help-plugin' + + config = config + + static flags = {help: flags.help()} + } + return CMD.run(['--help']) + }) + .catch(/EEXIT: 0/) + .it('--help via a plugin in src dir (source in ts)', ctx => { + expect(ctx.stdout).to.equal('hello from test-help-plugin #showCommandHelp\n') + expect(ctx.config.showCommandHelpSpy!.getCalls().length).to.equal(1) + expect(ctx.config.showHelpSpy!.getCalls().length).to.equal(0) + const [Command, Topics] = ctx.config.showCommandHelpSpy!.firstCall.args + expect(Command.id).to.deep.equal('test-command-for-help-plugin') + expect(Topics).to.be.an('array') + }) + }) }) describe('.log()', () => { diff --git a/test/helpers/test-help-in-lib/lib/test-help-plugin.js b/test/helpers/test-help-in-lib/lib/test-help-plugin.js new file mode 100644 index 00000000..77e76fd8 --- /dev/null +++ b/test/helpers/test-help-in-lib/lib/test-help-plugin.js @@ -0,0 +1,20 @@ +/* eslint-disable */ +'use strict'; +Object.defineProperty (exports, '__esModule', {value: true}); +const sinon_1 = require ('sinon'); +class default_1 { + constructor (config, opts) { + this.showCommandHelp = sinon_1.spy (() => { + console.log ('hello from test-help-plugin #showCommandHelp in the lib folder and in compiled javascript'); + }); + this.showHelp = sinon_1.spy (() => { + console.log ('hello showHelp'); + }); + config.showCommandHelpSpy = this.showCommandHelp; + config.showHelpSpy = this.showHelp; + } + command () { + throw new Error ('not needed for testing @oclif/command'); + } +} +exports.default = default_1; diff --git a/test/helpers/test-help-in-src/src/test-help-plugin.ts b/test/helpers/test-help-in-src/src/test-help-plugin.ts new file mode 100644 index 00000000..4456deeb --- /dev/null +++ b/test/helpers/test-help-in-src/src/test-help-plugin.ts @@ -0,0 +1,25 @@ +import {HelpBase} from '@oclif/plugin-help' +import {spy, SinonSpy} from 'sinon' +import {IConfig} from '@oclif/config' + +export type TestHelpClassConfig = IConfig & { showCommandHelpSpy?: SinonSpy; showHelpSpy?: SinonSpy } + +export default class extends HelpBase { + constructor(config: any, opts: any) { + super(config, opts) + config.showCommandHelpSpy = this.showCommandHelp + config.showHelpSpy = this.showHelp + } + + showCommandHelp = spy(() => { + console.log('hello from test-help-plugin #showCommandHelp') + }) + + showHelp = spy(() => { + console.log('hello showHelp') + }) + + getCommandHelpForReadme(): string { + throw new Error('not needed for testing @oclif/command') + } +} diff --git a/test/helpers/test-help-in-src/tsconfig.json b/test/helpers/test-help-in-src/tsconfig.json new file mode 100644 index 00000000..79c7711d --- /dev/null +++ b/test/helpers/test-help-in-src/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib" + } +} diff --git a/test/main.test.ts b/test/main.test.ts index 0f2dafe0..3402b671 100644 --- a/test/main.test.ts +++ b/test/main.test.ts @@ -1,9 +1,13 @@ import {expect, fancy} from 'fancy-test' import {Main} from '../src/main' +import * as PluginHelp from '@oclif/plugin-help' +import * as Config from '@oclif/config' +import {TestHelpClassConfig} from './helpers/test-help-in-src/src/test-help-plugin' const pjson = require('../package.json') const version = `@oclif/command/${pjson.version} ${process.platform}-${process.arch} node-${process.version}` +const originalgetHelpClass = PluginHelp.getHelpClass describe('main', () => { fancy @@ -31,10 +35,71 @@ VERSION USAGE $ @oclif/command [COMMAND] +TOPICS + plugins list installed plugins + COMMANDS help display help for @oclif/command plugins list installed plugins `)) .it('runs -h') + + describe('with an alternative help class', async () => { + const getMainWithHelpClass = async () => { + const config: TestHelpClassConfig = await Config.load() + config.pjson.oclif.helpClass = './lib/test-help-plugin' + + class MainWithHelpClass extends Main { + config = config + } + + return MainWithHelpClass + } + + fancy + .stdout() + .stub(PluginHelp, 'getHelpClass', function (config: Config.IConfig) { + const patchedConfig = { + ...config, + root: `${__dirname}/helpers/test-help-in-src/`, + } + + return originalgetHelpClass(patchedConfig) + }) + .do(async () => (await getMainWithHelpClass()).run(['-h'])) + .catch('EEXIT: 0') + .do(output => expect(output.stdout).to.equal('hello showHelp\n')) + .it('works with -h') + + fancy + .stdout() + .stub(PluginHelp, 'getHelpClass', function (config: Config.IConfig) { + const patchedConfig = { + ...config, + root: `${__dirname}/helpers/test-help-in-src/`, + } + + return originalgetHelpClass(patchedConfig) + }) + .do(async () => (await getMainWithHelpClass()).run(['--help'])) + .catch('EEXIT: 0') + .do(output => expect(output.stdout).to.equal('hello showHelp\n')) + .it('works with --help') + + fancy + .stdout() + .stub(PluginHelp, 'getHelpClass', function (config: Config.IConfig) { + const patchedConfig = { + ...config, + root: `${__dirname}/helpers/test-help-in-src/`, + } + + return originalgetHelpClass(patchedConfig) + }) + .do(async () => (await getMainWithHelpClass()).run(['help'])) + .catch('EEXIT: 0') + .do(output => expect(output.stdout).to.equal('hello showHelp\n')) + .it('works with help') + }) }) diff --git a/yarn.lock b/yarn.lock index bada72d9..9d7392ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -62,7 +62,19 @@ debug "^4.1.1" semver "^5.6.0" -"@oclif/config@^1": +"@oclif/command@^1.5.20": + version "1.5.20" + resolved "https://registry.yarnpkg.com/@oclif/command/-/command-1.5.20.tgz#bb0693586d7d66a457c49b719e394c02ff0169a7" + integrity sha512-lzst5RU/STfoutJJv4TLE/cm1WtW3xy6Aqvqy3r1lPsGdNifgbEq4dCOYyc/ZEuhV/IStQLDFTnAlqTdolkz1Q== + dependencies: + "@oclif/config" "^1" + "@oclif/errors" "^1.2.2" + "@oclif/parser" "^3.8.3" + "@oclif/plugin-help" "^2" + debug "^4.1.1" + semver "^5.6.0" + +"@oclif/config@^1", "@oclif/config@^1.15.1": version "1.15.1" resolved "https://registry.yarnpkg.com/@oclif/config/-/config-1.15.1.tgz#39950c70811ab82d75bb3cdb33679ed0a4c21c57" integrity sha512-GdyHpEZuWlfU8GSaZoiywtfVBsPcfYn1KuSLT1JTfvZGpPG6vShcGr24YZ3HG2jXUFlIuAqDcYlTzOrqOdTPNQ== @@ -107,12 +119,27 @@ tslib "^1.9.3" "@oclif/plugin-help@^2": - version "2.2.3" - resolved "https://registry.yarnpkg.com/@oclif/plugin-help/-/plugin-help-2.2.3.tgz#b993041e92047f0e1762668aab04d6738ac06767" - integrity sha512-bGHUdo5e7DjPJ0vTeRBMIrfqTRDBfyR5w0MP41u0n3r7YG5p14lvMmiCXxi6WDaP2Hw5nqx3PnkAIntCKZZN7g== + version "2.2.1" + resolved "https://registry.yarnpkg.com/@oclif/plugin-help/-/plugin-help-2.2.1.tgz#cb4d23e453b19340b07c48fb299948b7c74366d3" + integrity sha512-psEA3t41MSGBErLk6xCaAq2jKrRtx3Br+kHpd43vZeGEeZ7Gos4wgK0JAaHBbvhvUQskCHg8dzoqv4XEeTWeVQ== dependencies: "@oclif/command" "^1.5.13" chalk "^2.4.1" + indent-string "^3.2.0" + lodash.template "^4.4.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + widest-line "^2.0.1" + wrap-ansi "^4.0.0" + +"@oclif/plugin-help@^3": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@oclif/plugin-help/-/plugin-help-3.0.0.tgz#7d6433d74b0473a43797c6e0468b503470f23b50" + integrity sha512-mrV1O1VXy+ssW0kmIvFYkuEEPYZWKpyqydyHbKa316esAHatsZlrw6cRItf3TuKHTAqeGuXPctPV4mO2e21F9w== + dependencies: + "@oclif/command" "^1.5.20" + "@oclif/config" "^1.15.1" + chalk "^2.4.1" indent-string "^4.0.0" lodash.template "^4.4.0" string-width "^3.0.0" @@ -143,6 +170,42 @@ resolved "https://registry.yarnpkg.com/@oclif/screen/-/screen-1.0.4.tgz#b740f68609dfae8aa71c3a6cab15d816407ba493" integrity sha512-60CHpq+eqnTxLZQ4PGHYNwUX572hgpMHGPtTWMjdTMsAvlm69lZV/4ly6O3sAYkomo4NggGcomrDpBe34rxUqw== +"@sinonjs/commons@^1", "@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.1.tgz#da5fd19a5f71177a53778073978873964f49acf1" + integrity sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" + integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@sinonjs/formatio@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-5.0.1.tgz#f13e713cb3313b1ab965901b01b0828ea6b77089" + integrity sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ== + dependencies: + "@sinonjs/commons" "^1" + "@sinonjs/samsam" "^5.0.2" + +"@sinonjs/samsam@^5.0.2", "@sinonjs/samsam@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-5.0.3.tgz#86f21bdb3d52480faf0892a480c9906aa5a52938" + integrity sha512-QucHkc2uMJ0pFGjJUDP3F9dq5dx8QIaqISl9QgwLOh6P9yv877uONPGXh/OH/0zmM3tW1JjuJltAZV2l7zU+uQ== + dependencies: + "@sinonjs/commons" "^1.6.0" + lodash.get "^4.4.2" + type-detect "^4.0.8" + +"@sinonjs/text-encoding@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" + integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== + "@types/chai@*", "@types/chai@^4.1.7": version "4.1.7" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a" @@ -948,11 +1011,16 @@ detect-file@^1.0.0: resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= -diff@3.5.0, diff@^3.1.0: +diff@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +diff@^4.0.1, diff@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + dir-glob@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" @@ -1625,6 +1693,11 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" @@ -2003,6 +2076,11 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -2078,6 +2156,11 @@ jsonparse@^1.2.0: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= +just-extend@^4.0.2: + version "4.1.0" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.1.0.tgz#7278a4027d889601640ee0ce0e5a00b992467da4" + integrity sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA== + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -2496,6 +2579,17 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +nise@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nise/-/nise-4.0.3.tgz#9f79ff02fa002ed5ffbc538ad58518fa011dc913" + integrity sha512-EGlhjm7/4KvmmE6B/UFsKh7eHykRl9VH+au8dduHLCyWUO/hr7+N+WtTvDUwc9zHuM1IaIJs/0lQ6Ag1jDkQSg== + dependencies: + "@sinonjs/commons" "^1.7.0" + "@sinonjs/fake-timers" "^6.0.0" + "@sinonjs/text-encoding" "^0.7.1" + just-extend "^4.0.2" + path-to-regexp "^1.7.0" + node-environment-flags@1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.4.tgz#0b784a6551426bfc16d3b2208424dcbc2b2ff038" @@ -2754,6 +2848,13 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -3095,6 +3196,19 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +sinon@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-9.0.1.tgz#dbb18f7d8f5835bcf91578089c0a97b2fffdd73b" + integrity sha512-iTTyiQo5T94jrOx7X7QLBZyucUJ2WvL9J13+96HMfm2CGoJYbIPqRfl6wgNcqmzk0DI28jeGx5bUTXizkrqBmg== + dependencies: + "@sinonjs/commons" "^1.7.0" + "@sinonjs/fake-timers" "^6.0.0" + "@sinonjs/formatio" "^5.0.1" + "@sinonjs/samsam" "^5.0.3" + diff "^4.0.2" + nise "^4.0.1" + supports-color "^7.1.0" + slash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" @@ -3364,6 +3478,13 @@ supports-color@^5.0.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-co dependencies: has-flag "^3.0.0" +supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + supports-hyperlinks@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz#71daedf36cc1060ac5100c351bb3da48c29c0ef7" @@ -3465,16 +3586,16 @@ trim-off-newlines@^1.0.0: resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM= -ts-node@^8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.0.3.tgz#aa60b836a24dafd8bf21b54766841a232fdbc641" - integrity sha512-2qayBA4vdtVRuDo11DEFSsD/SFsBXQBRZZhbRGSIkmYmVkWjULn/GGMdG10KVqkaGndljfaTD8dKjWgcejO8YA== +ts-node@^8.8.2: + version "8.8.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.8.2.tgz#0b39e690bee39ea5111513a9d2bcdc0bc121755f" + integrity sha512-duVj6BpSpUpD/oM4MfhO98ozgkp3Gt9qIp3jGxwU2DFvl/3IRaEAvbLa8G60uS7C77457e/m5TMowjedeRxI1Q== dependencies: arg "^4.1.0" - diff "^3.1.0" + diff "^4.0.1" make-error "^1.1.1" source-map-support "^0.5.6" - yn "^3.0.0" + yn "3.1.1" tslib@^1, tslib@^1.8.1: version "1.9.3" @@ -3512,7 +3633,7 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-detect@^4.0.0, type-detect@^4.0.5: +type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== @@ -3522,10 +3643,10 @@ type-fest@^0.5.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== -typescript@^3.3.3333: - version "3.3.3333" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.3333.tgz#171b2c5af66c59e9431199117a3bcadc66fdcfd6" - integrity sha512-JjSKsAfuHBE/fB2oZ8NxtRTk5iGcg6hkYXMnZ3Wc+b2RSqejEqTaem11mHASMnFilHrax3sLK0GDzcJrekZYLw== +typescript@^3.8.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" + integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== uglify-js@^3.1.4: version "3.7.3" @@ -3713,7 +3834,7 @@ yarn@^1.13.0: resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.4.tgz#01c1197ca5b27f21edc8bc472cd4c8ce0e5a470e" integrity sha512-oYM7hi/lIWm9bCoDMEWgffW8aiNZXCWeZ1/tGy0DWrN6vmzjCXIKu2Y21o8DYVBUtiktwKcNoxyGl/2iKLUNGA== -yn@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.0.0.tgz#0073c6b56e92aed652fbdfd62431f2d6b9a7a091" - integrity sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q== +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==