From 33130696b6597e9a80cefe47ab8af7eaa95d56ce Mon Sep 17 00:00:00 2001 From: dobromir-hristov Date: Sat, 11 Apr 2020 18:47:05 +0300 Subject: [PATCH 1/9] feat: extend natively --- src/index.ts | 3 ++- tests/features/plugins.spec.ts | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/features/plugins.spec.ts diff --git a/src/index.ts b/src/index.ts index 891f92be2..da2ebe0c3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import { mount } from './mount' import { RouterLinkStub } from './components/RouterLinkStub' +import { VueWrapper } from './vue-wrapper' -export { mount, RouterLinkStub } +export { mount, RouterLinkStub, VueWrapper } diff --git a/tests/features/plugins.spec.ts b/tests/features/plugins.spec.ts new file mode 100644 index 000000000..930c6027a --- /dev/null +++ b/tests/features/plugins.spec.ts @@ -0,0 +1,19 @@ +import { mount, VueWrapper } from '../../src' +import Hello from '../components/Hello.vue' +// add a method to the VueWrapper +declare module '../../src/vue-wrapper' { + interface VueWrapper { + name(): string + } +} + +VueWrapper.prototype.name = function () { + return this.componentVM.$.type.name +} + +describe('Plugin', () => { + it('adds name property', () => { + const wrapper = mount(Hello) + expect(wrapper.name()).toEqual('Hello') + }) +}) From c8f119e2a65e15aadd2adfe1f809ddcf3c9ce3fb Mon Sep 17 00:00:00 2001 From: dobromir-hristov Date: Sat, 11 Apr 2020 19:26:32 +0300 Subject: [PATCH 2/9] feat: extend natively --- src/config.ts | 6 ++++++ src/index.ts | 4 +++- src/vue-wrapper.ts | 8 ++++++++ tests/features/plugins.spec.ts | 15 ++++++++++++++- 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 src/config.ts diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 000000000..4a394cfa4 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,6 @@ +export const config = { + plugins: { + VueWrapper: {} as any, + DOMWrapper: {} + } +} diff --git a/src/index.ts b/src/index.ts index da2ebe0c3..a3fae534f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,4 +2,6 @@ import { mount } from './mount' import { RouterLinkStub } from './components/RouterLinkStub' import { VueWrapper } from './vue-wrapper' -export { mount, RouterLinkStub, VueWrapper } +import { config } from './config' + +export { mount, RouterLinkStub, VueWrapper, config } diff --git a/src/vue-wrapper.ts b/src/vue-wrapper.ts index 11d6249b0..cc6ffb0f5 100644 --- a/src/vue-wrapper.ts +++ b/src/vue-wrapper.ts @@ -1,5 +1,6 @@ import { ComponentPublicInstance, nextTick } from 'vue' import { ShapeFlags } from '@vue/shared' +import { config } from './config' import { DOMWrapper } from './dom-wrapper' import { WrapperAPI } from './types' @@ -21,6 +22,13 @@ export class VueWrapper implements WrapperAPI { this.__setProps = setProps this.componentVM = this.vm.$refs['VTU_COMPONENT'] as ComponentPublicInstance this.__emitted = events + + // plugins hook + Object.entries(config.plugins.VueWrapper).forEach( + ([name, handler]: [string, () => any]) => { + this[name] = handler.bind(this) + } + ) } private get appRootNode() { diff --git a/tests/features/plugins.spec.ts b/tests/features/plugins.spec.ts index 930c6027a..5b9f6cfb4 100644 --- a/tests/features/plugins.spec.ts +++ b/tests/features/plugins.spec.ts @@ -1,9 +1,11 @@ -import { mount, VueWrapper } from '../../src' +import { mount, VueWrapper, config } from '../../src' import Hello from '../components/Hello.vue' // add a method to the VueWrapper declare module '../../src/vue-wrapper' { interface VueWrapper { name(): string + + lowerCaseName(): string[] } } @@ -11,9 +13,20 @@ VueWrapper.prototype.name = function () { return this.componentVM.$.type.name } +config.plugins.VueWrapper.lowerCaseName = function lowerCaseName( + this: VueWrapper +) { + return this.name().toLocaleLowerCase() +} + describe('Plugin', () => { it('adds name property', () => { const wrapper = mount(Hello) expect(wrapper.name()).toEqual('Hello') }) + + it('adds loweCase name property', () => { + const wrapper = mount(Hello) + expect(wrapper.lowerCaseName()).toEqual('hello') + }) }) From cc5427f283c913f4dc80cf4757a4ae718904c62b Mon Sep 17 00:00:00 2001 From: Jessica Sachs Date: Tue, 21 Apr 2020 00:36:34 -0400 Subject: [PATCH 3/9] wip: pluggable class --- .gitignore | 3 +- src/config.ts | 38 ++++++++++++++++++- src/vue-wrapper.ts | 15 +++++--- tests/features/plugins.spec.ts | 68 +++++++++++++++++++++++----------- 4 files changed, 95 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index c03a38b6e..87c63fdf7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ +.idea node_modules yarn-error.log dist -coverage \ No newline at end of file +coverage diff --git a/src/config.ts b/src/config.ts index 4a394cfa4..91d9026bb 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,6 +1,40 @@ +class Pluggable { + installedPlugins: any + constructor() { + this.installedPlugins = [] + } + + install(handler, options = {}) { + if (typeof handler !== 'function') { + console.error('plugin.install must receive a function') + handler = () => ({}) + } + this.installedPlugins.push({ handler, options }) + } + + extend(instance) { + const invokeSetup = (plugin) => plugin.handler(instance) // invoke the setup method passed to install + const bindProperty = ([property, value]: [string, any]) => { + instance[property] = + typeof value === 'function' ? value.bind(instance) : value + } + const addAllPropertiesFromSetup = (setupResult) => { + setupResult = typeof setupResult === 'object' ? setupResult : {} + Object.entries(setupResult).forEach(bindProperty) + } + + this.installedPlugins.map(invokeSetup).forEach(addAllPropertiesFromSetup) + } + + /** For testing */ + reset() { + this.installedPlugins = [] + } +} + export const config = { plugins: { - VueWrapper: {} as any, - DOMWrapper: {} + VueWrapper: new Pluggable(), + DOMWrapper: new Pluggable() } } diff --git a/src/vue-wrapper.ts b/src/vue-wrapper.ts index cc6ffb0f5..f7f8290b2 100644 --- a/src/vue-wrapper.ts +++ b/src/vue-wrapper.ts @@ -24,11 +24,7 @@ export class VueWrapper implements WrapperAPI { this.__emitted = events // plugins hook - Object.entries(config.plugins.VueWrapper).forEach( - ([name, handler]: [string, () => any]) => { - this[name] = handler.bind(this) - } - ) + config.plugins.VueWrapper.extend(this) } private get appRootNode() { @@ -101,6 +97,15 @@ export class VueWrapper implements WrapperAPI { const rootElementWrapper = new DOMWrapper(this.element) return rootElementWrapper.trigger(eventString) } + + extend() { + // plugins hook + Object.entries(config.plugins.VueWrapper).forEach( + ([name, handler]: [string, () => any]) => { + this[name] = handler.bind(this) + } + ) + } } export function createWrapper( diff --git a/tests/features/plugins.spec.ts b/tests/features/plugins.spec.ts index 5b9f6cfb4..0fd8e2172 100644 --- a/tests/features/plugins.spec.ts +++ b/tests/features/plugins.spec.ts @@ -1,32 +1,58 @@ import { mount, VueWrapper, config } from '../../src' -import Hello from '../components/Hello.vue' -// add a method to the VueWrapper + declare module '../../src/vue-wrapper' { interface VueWrapper { - name(): string - - lowerCaseName(): string[] + width(): number + $el: Element } } -VueWrapper.prototype.name = function () { - return this.componentVM.$.type.name -} - -config.plugins.VueWrapper.lowerCaseName = function lowerCaseName( - this: VueWrapper -) { - return this.name().toLocaleLowerCase() -} +const textValue = `I'm the innerHTML` +const mountComponent = () => mount({ template: `

${textValue}

` }) describe('Plugin', () => { - it('adds name property', () => { - const wrapper = mount(Hello) - expect(wrapper.name()).toEqual('Hello') - }) + describe('#install method', () => { + beforeEach(() => { + config.plugins.VueWrapper.reset() + }) + + it('extends wrappers with the return values from the install function', () => { + const width = 230 + const plugin = () => ({ width }) + config.plugins.VueWrapper.install(plugin) + const wrapper = mountComponent() + expect(wrapper).toHaveProperty('width', width) + }) + + it('receives the wrapper inside the plugin setup', () => { + const plugin = (wrapper) => { + return { + $el: wrapper.element // simple aliases + } + } + config.plugins.VueWrapper.install(plugin) + const wrapper = mountComponent() + expect(wrapper.$el.innerHTML).toEqual(textValue) + }) + + describe('error states', () => { + const plugins = [ + () => false, + () => true, + () => [], + true, + false, + 'property', + 120 + ] - it('adds loweCase name property', () => { - const wrapper = mount(Hello) - expect(wrapper.lowerCaseName()).toEqual('hello') + it.each(plugins)( + 'Calling install with %p is handled gracefully', + (plugin) => { + config.plugins.VueWrapper.install(plugin) + expect(() => mountComponent()).not.toThrow() + } + ) + }) }) }) From 922bc0526b65fc6f7996a66ff72645e661b7e12c Mon Sep 17 00:00:00 2001 From: Jessica Sachs Date: Tue, 21 Apr 2020 01:22:17 -0400 Subject: [PATCH 4/9] poc: remove unused extend function --- src/vue-wrapper.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/vue-wrapper.ts b/src/vue-wrapper.ts index f7f8290b2..517a9ab87 100644 --- a/src/vue-wrapper.ts +++ b/src/vue-wrapper.ts @@ -97,15 +97,6 @@ export class VueWrapper implements WrapperAPI { const rootElementWrapper = new DOMWrapper(this.element) return rootElementWrapper.trigger(eventString) } - - extend() { - // plugins hook - Object.entries(config.plugins.VueWrapper).forEach( - ([name, handler]: [string, () => any]) => { - this[name] = handler.bind(this) - } - ) - } } export function createWrapper( From a818edf597811cf558189d7eb70f1d1cf5d85df1 Mon Sep 17 00:00:00 2001 From: Jessica Sachs Date: Tue, 21 Apr 2020 01:26:23 -0400 Subject: [PATCH 5/9] poc: add functional test for plugin.install --- tests/features/plugins.spec.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/features/plugins.spec.ts b/tests/features/plugins.spec.ts index 0fd8e2172..b1071e1bf 100644 --- a/tests/features/plugins.spec.ts +++ b/tests/features/plugins.spec.ts @@ -4,6 +4,7 @@ declare module '../../src/vue-wrapper' { interface VueWrapper { width(): number $el: Element + myMethod(): void } } @@ -35,6 +36,14 @@ describe('Plugin', () => { expect(wrapper.$el.innerHTML).toEqual(textValue) }) + it('supports functions', () => { + const myMethod = jest.fn() + const plugin = () => ({ myMethod }) + config.plugins.VueWrapper.install(plugin) + mountComponent().myMethod() + expect(myMethod).toHaveBeenCalledTimes(1) + }) + describe('error states', () => { const plugins = [ () => false, From 4a95fb151e9eb66f67dbd857847dc5bbaad785c7 Mon Sep 17 00:00:00 2001 From: Lachlan Miller Date: Tue, 21 Apr 2020 22:13:30 +1000 Subject: [PATCH 6/9] fix conflicts --- .github/workflows/ci.yml | 9 +- README.md | 51 +- docs/API.md | 79 ++ package.json | 28 +- rollup.config.js | 14 +- src/config.ts | 13 +- src/constants.ts | 2 + src/dom-wrapper.ts | 44 +- src/emitMixin.ts | 17 +- src/error-wrapper.ts | 22 +- src/index.ts | 1 - src/mount.ts | 141 ++- src/stubs.ts | 88 ++ src/types.ts | 24 + src/utils.ts | 29 + src/utils/find.ts | 61 ++ src/utils/matchName.ts | 14 + src/vue-wrapper.ts | 141 ++- test-dts/mount.d-test.ts | 87 ++ test-dts/wrapper.d-test.ts | 88 ++ tests/config.spec.ts | 96 ++ tests/emit.spec.ts | 25 +- tests/find.spec.ts | 1 + tests/findAllComponents.spec.ts | 28 + tests/findComponent.spec.ts | 94 ++ tests/get.spec.ts | 29 + tests/lifecycle.spec.ts | 47 +- tests/mountingOptions/stubs.global.spec.ts | 241 +++++ tests/props.spec.ts | 25 + tests/setProps.spec.ts | 33 +- tests/vm.spec.ts | 27 + yarn.lock | 1031 ++++++++++++++++++-- 32 files changed, 2402 insertions(+), 228 deletions(-) create mode 100644 src/stubs.ts create mode 100644 src/utils.ts create mode 100644 src/utils/find.ts create mode 100644 src/utils/matchName.ts create mode 100644 test-dts/mount.d-test.ts create mode 100644 test-dts/wrapper.d-test.ts create mode 100644 tests/config.spec.ts create mode 100644 tests/findAllComponents.spec.ts create mode 100644 tests/findComponent.spec.ts create mode 100644 tests/get.spec.ts create mode 100644 tests/mountingOptions/stubs.global.spec.ts create mode 100644 tests/props.spec.ts create mode 100644 tests/vm.spec.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 67319d427..2ad17a8c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,9 +24,10 @@ jobs: uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - - run: npm install - - run: npm run lint - - run: npm run build - - run: npm test + - run: yarn install + - run: yarn lint + - run: yarn test + - run: yarn build env: CI: true + - run: yarn tsd diff --git a/README.md b/README.md index 9e3f1bc5a..d68441e8c 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,15 @@ The next iteration of Vue Test Utils. It targets Vue 3. - yarn: `yarn add @vue/test-utils@next --dev` - npm: `npm install @vue/test-utils@next --save-dev` +## Coming from Vue 2 + Vue Test Utils beta? + +We are working on some documentation to help people migrate. At this point it will you will have better luck trying this out with a brand new Vue 3 app, as opposed to upgrading an existing Vue 2 app. Feedback and bug reports are welcome! + ## Working with `.vue` files There is [`vue-jest`](https://github.com/vuejs/vue-jest) for loading `.vue` files into Jest. The `next` branch contains support for Vue 3. Install it with `yarn add vue-jest@next`. It lacks support for some things, namely JSX. -If you don't want to configure things, you can download a repository with Vue 3, `@vue/test-utils@next`, `vue-jest` and TypeScript configured [here](https://github.com/lmiller1990/vtu-next-demo). +If you don't want to configure things, you can download a repository with Vue 3, `@vue/test-utils@next`, `vue-jest@next` and TypeScript configured [here](https://github.com/lmiller1990/vtu-next-demo). ## Docs @@ -46,23 +50,23 @@ This is table for those coming from VTU beta, comparing the two APIs. A lot of t | option | status | notes | |---------|-------|------| -context | ⚰️ | different from Vue 2, may not make sense anymore. data | ✅ slots | ✅ | has not been tested vigorously. Please try it out. -scopedSlots | ⚰️ | scopedSlots are merged with slots in Vue 3 -stubs | ❌ mocks | ✅ | nested in [`global`](https://vuejs.github.io/vue-test-utils-next-docs/api/#global) -localVue | ⚰️ | may not make sense anymore since we do not mutate the global Vue instance in Vue 3. -attachToDocument | ❌| will rename to `attachTo`. See [here](https://github.com/vuejs/vue-test-utils/pull/1492) -attrs | ❌ | propsData | ✅ | now called `props` -listeners | ⚰️ | no longer exists in Vue 3 -parentComponent | ⚰️ | provide | ✅ | nested in [`global`](https://vuejs.github.io/vue-test-utils-next-docs/api/#global) mixins | ✅ | (new!) nested in [`global`](https://vuejs.github.io/vue-test-utils-next-docs/api/#global) plugins | ✅ | (new!) nested in [`global`](https://vuejs.github.io/vue-test-utils-next-docs/api/#global) component | ✅ | (new!) nested in [`global`](https://vuejs.github.io/vue-test-utils-next-docs/api/#global) directives | ✅ | (new!) nested in [`global`](https://vuejs.github.io/vue-test-utils-next-docs/api/#global) +stubs | ✅ +attachToDocument | ❌| will rename to `attachTo`. See [here](https://github.com/vuejs/vue-test-utils/pull/1492) +attrs | ❌ | +scopedSlots | ⚰️ | scopedSlots are merged with slots in Vue 3 +context | ⚰️ | different from Vue 2, may not make sense anymore. +localVue | ⚰️ | may not make sense anymore since we do not mutate the global Vue instance in Vue 3. +listeners | ⚰️ | no longer exists in Vue 3 +parentComponent | ⚰️ | ### Wrapper API (mount) @@ -71,26 +75,27 @@ directives | ✅ | (new!) nested in [`global`](https://vuejs.github.io/vue-test- |---------|-------|------| attributes | ✅ classes | ✅ -contains | ⚰️| use `find` -destroy | ❌ -emitted | ✅ -emittedByOrder | ⚰️ | use `emitted` exists | ✅ find | ✅ | only `querySelector` syntax is supported. `find(Comp)` under discussion [here](https://github.com/vuejs/vue-test-utils/issues/1498) +emitted | ✅ findAll | ✅ | see above. `.vm` is different to Vue 2. We are exploring options. -get | ❌ +get | ✅ html | ✅ +setValue | ✅ | works for select, checkbox, radio button, input, textarea. Returns `nextTick`. +text | ✅ | +trigger | ✅ | returns `nextTick`. You can do `await wrapper.find('button').trigger('click')` +setProps | ✅ | +props | ✅ +setData | ❌ | has PR +destroy | ✅ | renamed to `unmount` to match Vue 3 lifecycle hook name. +props | ❌ +contains | ⚰️| use `find` +emittedByOrder | ⚰️ | use `emitted` +setSelected | ⚰️ | now part of `setValue` +setChecked | ⚰️| now part of `setValue` is | ⚰️ isEmpty | ⚰️ | use matchers such as [this](https://github.com/testing-library/jest-dom#tobeempty) -isVisible | ❌ | use matchers such as [this](https://github.com/testing-library/jest-dom#tobeempty) +isVisible | ⚰️ | use matchers such as [this](https://github.com/testing-library/jest-dom#tobevisible) isVueInstance | ⚰️ name | ⚰️ | -props | ❌ -setChecked | ⚰️| now part of `setValue` -setData | ❌ | setMethods | ⚰️ | -setProps | ❌ | -setSelected | ⚰️ | now part of `setValue` -setValue | ✅ | works for select, checkbox, radio button, input, textarea. Returns `nextTick`. -text | ✅ | -trigger | ✅ | returns `nextTick`. You can do `await wrapper.find('button').trigger('click')` diff --git a/docs/API.md b/docs/API.md index 6f975316e..7368312cc 100644 --- a/docs/API.md +++ b/docs/API.md @@ -348,6 +348,85 @@ test('findAll', () => { }) ``` +### `findComponent` + +Finds a Vue Component instance and returns a `VueWrapper` if one is found, otherwise returns `ErrorWrapper`. + +**Supported syntax:** + +* **querySelector** - `findComponent('.component')` - Matches standard query selector. +* **Name** - `findComponent({ name: 'myComponent' })` - matches PascalCase, snake-case, camelCase +* **ref** - `findComponent({ ref: 'dropdown' })` - Can be used only on direct ref children of mounted component +* **SFC** - `findComponent(ImportedComponent)` - Pass an imported component directly. + +```vue + + +``` + +```vue + +``` + +```js +test('findComponent', () => { + const wrapper = mount(Component) + + wrapper.findComponent('.foo') //=> found; returns VueWrapper + wrapper.findComponent('[data-test="foo"]') //=> found; returns VueWrapper + wrapper.findComponent({ name: 'Foo' }) //=> found; returns VueWrapper + wrapper.findComponent({ name: 'foo' }) //=> found; returns VueWrapper + wrapper.findComponent({ ref: 'foo' }) //=> found; returns VueWrapper + wrapper.findComponent(Foo) //=> found; returns VueWrapper +}) +``` + +### `findAllComponents` + +Similar to `findComponent` but finds all Vue Component instances that match the query and returns an array of `VueWrapper`. + +**Supported syntax:** + + * **querySelector** - `findAllComponents('.component')` + * **Name** - `findAllComponents({ name: 'myComponent' })` + * **SFC** - `findAllComponents(ImportedComponent)` + +**Note** - `Ref` is not supported here. + + +```vue + +``` + +```js +test('findAllComponents', () => { + const wrapper = mount(Component) + + wrapper.findAllComponents('[data-test="number"]') //=> found; returns array of VueWrapper +}) +``` + ### `trigger` Simulates an event, for example `click`, `submit` or `keyup`. Since events often cause a re-render, `trigger` returs `Vue.nextTick`. If you expect the event to trigger a re-render, you should use `await` when you call `trigger` to ensure that Vue updates the DOM before you make an assertion. diff --git a/package.json b/package.json index 779969fbc..88fa4ba12 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@vue/test-utils", - "version": "2.0.0-alpha.0", + "version": "2.0.0-alpha.1", "license": "MIT", "main": "dist/vue-test-utils.cjs.js", "browser": "dist/vue-test-utils.esm.js", @@ -9,15 +9,22 @@ "module": "dist/vue-test-utils.esm-bundler.js", "files": [ "dist", - "README.md" + "README.md", + "dist/index.d.ts" ], + "dependencies": { + "lodash": "^4.17.15" + }, "devDependencies": { "@babel/core": "^7.9.0", "@babel/preset-env": "^7.8.4", "@babel/types": "^7.8.3", + "@rollup/plugin-node-resolve": "^7.1.3", "@types/estree": "^0.0.42", "@types/jest": "^24.9.1", - "@vue/compiler-sfc": "^3.0.0-alpha.12", + "@types/node": "12.12.35", + "@types/lodash": "^4.14.149", + "@vue/compiler-sfc": "^3.0.0-beta.2", "babel-jest": "^25.2.3", "babel-preset-jest": "^25.2.1", "flush-promises": "^1.0.2", @@ -28,14 +35,15 @@ "rollup": "^1.31.1", "rollup-plugin-typescript2": "^0.26.0", "ts-jest": "^25.0.0", + "tsd": "0.11.0", "typescript": "^3.7.5", - "vue": "^3.0.0-alpha.12", + "vue": "^3.0.0-beta.2", "vue-jest": "vuejs/vue-jest#next", "vuex": "^4.0.0-alpha.1" }, "peerDependencies": { - "@vue/compiler-sfc": "3.0.0-alpha.11", - "vue": "3.0.0-alpha.11" + "@vue/compiler-sfc": "^3.0.0-alpha.11", + "vue": "^3.0.0-alpha.11" }, "author": { "name": "Lachlan Miller", @@ -43,6 +51,7 @@ }, "scripts": { "test": "yarn jest --runInBand tests", + "tsd": "tsd", "build": "yarn rollup -c rollup.config.js", "lint": "prettier -c --parser typescript \"(src|tests)/**/*.ts?(x)\"", "lint:fix": "yarn lint --write" @@ -56,5 +65,12 @@ "*.ts": [ "prettier --parser=typescript --write" ] + }, + "tsd": { + "directory": "test-dts", + "compilerOptions": { + "strict": false, + "lib": ["esnext", "dom"] + } } } diff --git a/rollup.config.js b/rollup.config.js index 6220b86ed..741fc2206 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,4 +1,5 @@ import ts from 'rollup-plugin-typescript2' +import resolve from '@rollup/plugin-node-resolve' import pkg from './package.json' @@ -19,8 +20,15 @@ function createEntry(options) { const config = { input, - external: ['vue'], - plugins: [], + external: [ + 'vue', + 'lodash/mergeWith', + 'lodash/camelCase', + 'lodash/upperFirst', + 'lodash/kebabCase', + 'lodash/flow' + ], + plugins: [resolve()], output: { banner, file: 'dist/vue-test-utils.other.js', @@ -29,7 +37,7 @@ function createEntry(options) { } if (format === 'es') { - config.output.file = isBrowser ? pkg.browser : pkg.module + config.output.file = isBrowser ? pkg.browser : pkg.module } if (format === 'cjs') { config.output.file = pkg.main diff --git a/src/config.ts b/src/config.ts index 91d9026bb..54c0ab8f7 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,3 +1,13 @@ +import { GlobalMountOptions } from './types' + +interface GlobalConfigOptions { + global: GlobalMountOptions + plugins: { + VueWrapper: Pluggable + DOMWrapper: Pluggable + } +} + class Pluggable { installedPlugins: any constructor() { @@ -32,7 +42,8 @@ class Pluggable { } } -export const config = { +export const config: GlobalConfigOptions = { + global: {}, plugins: { VueWrapper: new Pluggable(), DOMWrapper: new Pluggable() diff --git a/src/constants.ts b/src/constants.ts index 2a7337060..a48a34fab 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1 +1,3 @@ export const MOUNT_ELEMENT_ID = 'app' +export const MOUNT_COMPONENT_REF = 'VTU_COMPONENT' +export const MOUNT_PARENT_NAME = 'VTU_ROOT' diff --git a/src/dom-wrapper.ts b/src/dom-wrapper.ts index e17d099ae..683a4e94e 100644 --- a/src/dom-wrapper.ts +++ b/src/dom-wrapper.ts @@ -41,23 +41,53 @@ export class DOMWrapper implements WrapperAPI { return this.element.outerHTML } - find(selector: string): DOMWrapper | ErrorWrapper { - const result = this.element.querySelector(selector) + find( + selector: K + ): DOMWrapper | ErrorWrapper + find( + selector: K + ): DOMWrapper | ErrorWrapper + find(selector: string): DOMWrapper | ErrorWrapper + find(selector: string): DOMWrapper | ErrorWrapper { + const result = this.element.querySelector(selector) if (result) { - return new DOMWrapper(result) + return new DOMWrapper(result) } return new ErrorWrapper({ selector }) } - findAll(selector: string): DOMWrapper[] { - return Array.from(this.element.querySelectorAll(selector)).map( + get( + selector: K + ): DOMWrapper + get( + selector: K + ): DOMWrapper + get(selector: string): DOMWrapper + get(selector: string): DOMWrapper { + const result = this.find(selector) + if (result instanceof ErrorWrapper) { + throw new Error(`Unable to find ${selector} within: ${this.html()}`) + } + + return result + } + + findAll( + selector: K + ): DOMWrapper[] + findAll( + selector: K + ): DOMWrapper[] + findAll(selector: string): DOMWrapper[] + findAll(selector: string): DOMWrapper[] { + return Array.from(this.element.querySelectorAll(selector)).map( (x) => new DOMWrapper(x) ) } private async setChecked(checked: boolean = true) { - // typecast so we get typesafety + // typecast so we get type safety const element = (this.element as unknown) as HTMLInputElement const type = this.attributes().type @@ -69,7 +99,7 @@ export class DOMWrapper implements WrapperAPI { // we do not want to trigger an event if the user // attempting set the same value twice - // this is beacuse in a browser setting checked = true when it is + // this is because in a browser setting checked = true when it is // already true is a no-op; no change event is triggered if (checked === element.checked) { return diff --git a/src/emitMixin.ts b/src/emitMixin.ts index 64f9b51a0..6da5677c8 100644 --- a/src/emitMixin.ts +++ b/src/emitMixin.ts @@ -1,23 +1,18 @@ import { getCurrentInstance } from 'vue' -export const createEmitMixin = () => { - const events: Record = {} - - const emitMixin = { +export const attachEmitListener = () => { + return { beforeCreate() { - const originalEmit = getCurrentInstance().emit + let events: Record = {} + this.__emitted = events + getCurrentInstance().emit = (event: string, ...args: unknown[]) => { events[event] ? (events[event] = [...events[event], [...args]]) : (events[event] = [[...args]]) - return originalEmit.call(getCurrentInstance(), event, ...args) + return [event, ...args] } } } - - return { - events, - emitMixin - } } diff --git a/src/error-wrapper.ts b/src/error-wrapper.ts index 86d72c625..ba7c00db0 100644 --- a/src/error-wrapper.ts +++ b/src/error-wrapper.ts @@ -1,9 +1,11 @@ +import { FindComponentSelector } from './types' + interface Options { - selector: string + selector: FindComponentSelector } export class ErrorWrapper { - selector: string + selector: FindComponentSelector element: null constructor({ selector }: Options) { @@ -14,6 +16,10 @@ export class ErrorWrapper { return Error(`Cannot call ${method} on an empty wrapper.`) } + vm(): Error { + throw this.wrapperError('vm') + } + attributes() { throw this.wrapperError('attributes') } @@ -30,12 +36,16 @@ export class ErrorWrapper { throw this.wrapperError('find') } + get(): never { + throw this.wrapperError('get') + } + findAll(): never { throw this.wrapperError('findAll') } - setChecked() { - throw this.wrapperError('setChecked') + setProps() { + throw this.wrapperError('setProps') } setValue() { @@ -49,4 +59,8 @@ export class ErrorWrapper { trigger() { throw this.wrapperError('trigger') } + + unmount() { + throw this.wrapperError('unmount') + } } diff --git a/src/index.ts b/src/index.ts index a3fae534f..1fbe0d33c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,6 @@ import { mount } from './mount' import { RouterLinkStub } from './components/RouterLinkStub' import { VueWrapper } from './vue-wrapper' - import { config } from './config' export { mount, RouterLinkStub, VueWrapper, config } diff --git a/src/mount.ts b/src/mount.ts index 97b84104f..0f03bcd40 100644 --- a/src/mount.ts +++ b/src/mount.ts @@ -4,40 +4,76 @@ import { VNode, defineComponent, VNodeNormalizedChildren, - ComponentOptions, - Plugin, - Directive, - Component, - reactive + transformVNodeArgs, + reactive, + ComponentPublicInstance, + ComponentOptionsWithObjectProps, + ComponentOptionsWithArrayProps, + ComponentOptionsWithoutProps, + ExtractPropTypes } from 'vue' -import { createWrapper } from './vue-wrapper' -import { createEmitMixin } from './emitMixin' +import { config } from './config' +import { GlobalMountOptions } from './types' +import { mergeGlobalProperties } from './utils' +import { createWrapper, VueWrapper } from './vue-wrapper' +import { attachEmitListener } from './emitMixin' import { createDataMixin } from './dataMixin' -import { MOUNT_ELEMENT_ID } from './constants' +import { + MOUNT_COMPONENT_REF, + MOUNT_ELEMENT_ID, + MOUNT_PARENT_NAME +} from './constants' +import { stubComponents } from './stubs' type Slot = VNode | string | { render: Function } -interface MountingOptions { +interface MountingOptions { data?: () => Record - props?: Record + props?: Props slots?: { default?: Slot [key: string]: Slot } - global?: { - plugins?: Plugin[] - mixins?: ComponentOptions[] - mocks?: Record - provide?: Record - // TODO how to type `defineComponent`? Using `any` for now. - components?: Record - directives?: Record - } - stubs?: Record + global?: GlobalMountOptions } -export function mount(originalComponent: any, options?: MountingOptions) { +// Component declared with defineComponent +export function mount< + TestedComponent extends ComponentPublicInstance, + PublicProps extends TestedComponent['$props'] +>( + originalComponent: new () => TestedComponent, + options?: MountingOptions +): VueWrapper +// Component declared with { props: { ... } } +export function mount< + TestedComponent extends ComponentOptionsWithObjectProps, + PublicProps extends ExtractPropTypes +>( + originalComponent: TestedComponent, + options?: MountingOptions +): VueWrapper +// Component declared with { props: [] } +export function mount< + TestedComponent extends ComponentOptionsWithArrayProps, + PublicProps extends Record +>( + originalComponent: TestedComponent, + options?: MountingOptions +): VueWrapper +// Component declared with no props +export function mount< + TestedComponent extends ComponentOptionsWithoutProps, + PublicProps extends Record +>( + originalComponent: TestedComponent, + options?: MountingOptions +): VueWrapper +export function mount( + originalComponent: any, + options?: MountingOptions +): VueWrapper { const component = { ...originalComponent } // Reset the document.body @@ -63,15 +99,19 @@ export function mount(originalComponent: any, options?: MountingOptions) { // override component data with mounting options data if (options?.data) { const dataMixin = createDataMixin(options.data()) - component.mixins = [...(component.mixins || []), dataMixin] + ;(component as any).mixins = [ + ...((component as any).mixins || []), + dataMixin + ] } // we define props as reactive so that way when we update them with `setProps` // Vue's reactivity system will cause a rerender. - const props = reactive({ ...options?.props, ref: 'VTU_COMPONENT' }) + const props = reactive({ ...options?.props, ref: MOUNT_COMPONENT_REF }) // create the wrapper component const Parent = defineComponent({ + name: MOUNT_PARENT_NAME, render() { return h(component, props, slots) } @@ -82,59 +122,68 @@ export function mount(originalComponent: any, options?: MountingOptions) { props[k] = v } - return app.$nextTick() + return vm.$nextTick() } - // create the vm - const vm = createApp(Parent) + // create the app + const app = createApp(Parent) + + const global = mergeGlobalProperties(config.global, options?.global) // global mocks mixin - if (options?.global?.mocks) { + if (global?.mocks) { const mixin = { beforeCreate() { - for (const [k, v] of Object.entries(options.global?.mocks)) { + for (const [k, v] of Object.entries(global.mocks)) { this[k] = v } } } - vm.mixin(mixin) + app.mixin(mixin) } // use and plugins from mounting options - if (options?.global?.plugins) { - for (const use of options?.global?.plugins) vm.use(use) + if (global?.plugins) { + for (const use of global.plugins) app.use(use) } // use any mixins from mounting options - if (options?.global?.mixins) { - for (const mixin of options?.global?.mixins) vm.mixin(mixin) + if (global?.mixins) { + for (const mixin of global.mixins) app.mixin(mixin) } - if (options?.global?.components) { - for (const key of Object.keys(options?.global?.components)) - vm.component(key, options.global.components[key]) + if (global?.components) { + for (const key of Object.keys(global.components)) + app.component(key, global.components[key]) } - if (options?.global?.directives) { - for (const key of Object.keys(options?.global?.directives)) - vm.directive(key, options.global.directives[key]) + if (global?.directives) { + for (const key of Object.keys(global.directives)) + app.directive(key, global.directives[key]) } // provide any values passed via provides mounting option - if (options?.global?.provide) { - for (const key of Reflect.ownKeys(options.global.provide)) { + if (global?.provide) { + for (const key of Reflect.ownKeys(global.provide)) { // @ts-ignore: https://github.com/microsoft/TypeScript/issues/1863 - vm.provide(key, options.global.provide[key]) + app.provide(key, global.provide[key]) } } // add tracking for emitted events - const { emitMixin, events } = createEmitMixin() - vm.mixin(emitMixin) + app.mixin(attachEmitListener()) + + // stubs + if (options?.global?.stubs) { + stubComponents(options.global.stubs) + } else { + transformVNodeArgs() + } // mount the app! - const app = vm.mount(el) + const vm = app.mount(el) - return createWrapper(app, events, setProps) + const App = vm.$refs[MOUNT_COMPONENT_REF] as ComponentPublicInstance + return createWrapper(app, App, setProps) } diff --git a/src/stubs.ts b/src/stubs.ts new file mode 100644 index 000000000..7b254b87c --- /dev/null +++ b/src/stubs.ts @@ -0,0 +1,88 @@ +import { transformVNodeArgs, h } from 'vue' + +import { pascalCase, kebabCase } from './utils' + +interface IStubOptions { + name?: string +} + +// TODO: figure out how to type this +type VNodeArgs = any[] + +export const createStub = (options: IStubOptions) => { + const tag = options.name ? `${options.name}-stub` : 'anonymous-stub' + const render = () => h(tag) + + return { name: tag, render } +} + +const resolveComponentStubByName = ( + componentName: string, + stubs: Record +) => { + const componentPascalName = pascalCase(componentName) + const componentKebabName = kebabCase(componentName) + + if (Array.isArray(stubs) && stubs.length) { + // ['Foo', 'Bar'] => { Foo: true, Bar: true } + stubs = stubs.reduce((acc, current) => { + acc[current] = true + return acc + }, {}) + } + + for (const [stubKey, value] of Object.entries(stubs)) { + if ( + stubKey === componentPascalName || + stubKey === componentKebabName || + stubKey === componentName + ) { + return value + } + } +} + +const isHTMLElement = (args: VNodeArgs) => + Array.isArray(args) && typeof args[0] === 'string' + +const isCommentOrFragment = (args: VNodeArgs) => typeof args[0] === 'symbol' + +const isParent = (args: VNodeArgs) => + typeof args[0] === 'object' && args[0]['name'] === 'VTU_COMPONENT' + +const isComponent = (args: VNodeArgs) => typeof args[0] === 'object' + +export function stubComponents(stubs: Record) { + transformVNodeArgs((args) => { + // args[0] can either be: + // 1. a HTML tag (div, span...) + // 2. An object of component options, such as { name: 'foo', render: [Function], props: {...} } + // Depending what it is, we do different things. + if (isHTMLElement(args) || isCommentOrFragment(args) || isParent(args)) { + return args + } + + if (isComponent(args)) { + const name = args[0]['name'] + if (!name) { + return args + } + + const stub = resolveComponentStubByName(name, stubs) + + // we return a stub by matching Vue's `h` function + // where the signature is h(Component, props) + // case 1: default stub + if (stub === true) { + return [createStub({ name }), {}] + } + + // case 2: custom implementation + if (typeof stub === 'object') { + return [stubs[name], {}] + } + } + + return args + }) +} diff --git a/src/types.ts b/src/types.ts index d1e8f2cff..917982e97 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,3 +1,5 @@ +import { Component, ComponentOptions, Directive, Plugin } from 'vue' + import { DOMWrapper } from './dom-wrapper' import { ErrorWrapper } from './error-wrapper' @@ -6,9 +8,31 @@ export interface WrapperAPI { classes: (className?: string) => string[] | boolean | ErrorWrapper readonly element: Element exists: () => boolean + get(selector: string): DOMWrapper find(selector: string): DOMWrapper | ErrorWrapper findAll(selector: string): DOMWrapper[] html: () => string text: () => string trigger: (eventString: string) => Promise<(fn?: () => void) => Promise> } + +interface RefSelector { + ref: string +} + +interface NameSelector { + name: string +} + +export type FindComponentSelector = RefSelector | NameSelector | string +export type FindAllComponentsSelector = NameSelector | string + +export type GlobalMountOptions = { + plugins?: Plugin[] + mixins?: ComponentOptions[] + mocks?: Record + provide?: Record + components?: Record + directives?: Record + stubs?: Record +} diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 000000000..1f7723442 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,29 @@ +import camelCase from 'lodash/camelCase' +import upperFirst from 'lodash/upperFirst' +import kebabCase from 'lodash/kebabCase' +import flow from 'lodash/flow' +import mergeWith from 'lodash/mergeWith' +import { GlobalMountOptions } from './types' + +const pascalCase = flow(camelCase, upperFirst) + +export { kebabCase, pascalCase } + +export function mergeGlobalProperties( + configGlobal = {}, + mountGlobal = {} +): GlobalMountOptions { + return mergeWith({}, configGlobal, mountGlobal, (objValue, srcValue, key) => { + switch (key) { + case 'mocks': + case 'provide': + case 'components': + case 'directives': + case 'globalProperties': + return { ...objValue, ...srcValue } + case 'plugins': + case 'mixins': + return [...(objValue || []), ...(srcValue || [])].filter(Boolean) + } + }) +} diff --git a/src/utils/find.ts b/src/utils/find.ts new file mode 100644 index 000000000..2ebf7ada3 --- /dev/null +++ b/src/utils/find.ts @@ -0,0 +1,61 @@ +import { VNode, ComponentPublicInstance } from 'vue' +import { FindAllComponentsSelector } from '../types' +import { matchName } from './matchName' + +/** + * Detect whether a selector matches a VNode + * @param node + * @param selector + * @return {boolean | ((value: any) => boolean)} + */ +function matches(node: VNode, selector: FindAllComponentsSelector): boolean { + // do not return none Vue components + if (!node.component) return false + + if (typeof selector === 'string') { + return node.el?.matches?.(selector) + } + + if (typeof selector === 'object' && typeof node.type === 'object') { + if (selector.name && ('name' in node.type || 'displayName' in node.type)) { + // match normal component definitions or functional components + return matchName(selector.name, node.type.name || node.type.displayName) + } + } + + return false +} + +/** + * Collect all children + * @param nodes + * @param children + */ +function aggregateChildren(nodes, children) { + if (children && Array.isArray(children)) { + ;[...children].reverse().forEach((n: VNode) => { + nodes.unshift(n) + }) + } +} + +function findAllVNodes(vnode: VNode, selector: any): VNode[] { + const matchingNodes = [] + const nodes = [vnode] + while (nodes.length) { + const node = nodes.shift() + aggregateChildren(nodes, node.children) + aggregateChildren(nodes, node.component?.subTree.children) + if (matches(node, selector)) { + matchingNodes.push(node) + } + } + + return matchingNodes +} + +export function find(root: VNode, selector: any): ComponentPublicInstance[] { + return findAllVNodes(root, selector).map( + (vnode: VNode) => vnode.component.proxy + ) +} diff --git a/src/utils/matchName.ts b/src/utils/matchName.ts new file mode 100644 index 000000000..be2a4395c --- /dev/null +++ b/src/utils/matchName.ts @@ -0,0 +1,14 @@ +import { camelize, capitalize } from '@vue/shared' + +export function matchName(target, sourceName) { + const camelized = camelize(target) + const capitalized = capitalize(camelized) + + return ( + sourceName && + (sourceName === target || + sourceName === camelized || + sourceName === capitalized || + capitalize(camelize(sourceName)) === capitalized) + ) +} diff --git a/src/vue-wrapper.ts b/src/vue-wrapper.ts index 517a9ab87..0d95d25e3 100644 --- a/src/vue-wrapper.ts +++ b/src/vue-wrapper.ts @@ -1,52 +1,58 @@ -import { ComponentPublicInstance, nextTick } from 'vue' +import { ComponentPublicInstance, nextTick, App } from 'vue' import { ShapeFlags } from '@vue/shared' import { config } from './config' import { DOMWrapper } from './dom-wrapper' -import { WrapperAPI } from './types' +import { + FindAllComponentsSelector, + FindComponentSelector, + WrapperAPI +} from './types' import { ErrorWrapper } from './error-wrapper' -import { MOUNT_ELEMENT_ID } from './constants' +import { find } from './utils/find' -export class VueWrapper implements WrapperAPI { - private componentVM: ComponentPublicInstance - private __emitted: Record = {} - private __vm: ComponentPublicInstance +export class VueWrapper + implements WrapperAPI { + private componentVM: T + private rootVM: ComponentPublicInstance + private __app: App | null private __setProps: (props: Record) => void constructor( + app: App | null, vm: ComponentPublicInstance, - events: Record, - setProps: (props: Record) => void + setProps?: (props: Record) => void ) { - this.__vm = vm + this.__app = app + this.rootVM = vm.$root + this.componentVM = vm as T this.__setProps = setProps - this.componentVM = this.vm.$refs['VTU_COMPONENT'] as ComponentPublicInstance - this.__emitted = events - // plugins hook config.plugins.VueWrapper.extend(this) } - private get appRootNode() { - return document.getElementById(MOUNT_ELEMENT_ID) as HTMLDivElement - } - private get hasMultipleRoots(): boolean { // if the subtree is an array of children, we have multiple root nodes - return this.componentVM.$.subTree.shapeFlag === ShapeFlags.ARRAY_CHILDREN + return this.vm.$.subTree.shapeFlag === ShapeFlags.ARRAY_CHILDREN } private get parentElement(): Element { - return this.componentVM.$el.parentElement + return this.vm.$el.parentElement } get element(): Element { // if the component has multiple root elements, we use the parent's element - return this.hasMultipleRoots ? this.parentElement : this.componentVM.$el + return this.hasMultipleRoots ? this.parentElement : this.vm.$el + } + + get vm(): T { + return this.componentVM } - get vm(): ComponentPublicInstance { - return this.__vm + props(selector?: string) { + return selector + ? this.componentVM.$props[selector] + : this.componentVM.$props } classes(className?: string) { @@ -61,21 +67,30 @@ export class VueWrapper implements WrapperAPI { return true } - emitted() { - return this.__emitted + emitted(): Record { + // TODO Should we define this? + // @ts-ignore + return this.vm.__emitted } html() { - return this.appRootNode.innerHTML + return this.parentElement.innerHTML } text() { return this.element.textContent?.trim() } - find(selector: string): DOMWrapper | ErrorWrapper { + find( + selector: K + ): DOMWrapper | ErrorWrapper + find( + selector: K + ): DOMWrapper | ErrorWrapper + find(selector: string): DOMWrapper | ErrorWrapper + find(selector: string): DOMWrapper | ErrorWrapper { // force using the parentElement to allow finding the root element - const result = this.parentElement.querySelector(selector) as T + const result = this.parentElement.querySelector(selector) if (result) { return new DOMWrapper(result) } @@ -83,12 +98,52 @@ export class VueWrapper implements WrapperAPI { return new ErrorWrapper({ selector }) } - findAll(selector: string): DOMWrapper[] { - const results = this.appRootNode.querySelectorAll(selector) - return Array.from(results).map((x) => new DOMWrapper(x)) + get( + selector: K + ): DOMWrapper + get( + selector: K + ): DOMWrapper + get(selector: string): DOMWrapper + get(selector: string): DOMWrapper { + const result = this.find(selector) + if (result instanceof ErrorWrapper) { + throw new Error(`Unable to find ${selector} within: ${this.html()}`) + } + + return result + } + + findComponent(selector: FindComponentSelector): VueWrapper | ErrorWrapper { + if (typeof selector === 'object' && 'ref' in selector) { + return createWrapper(null, this.vm.$refs[selector.ref] as T) + } + const result = find(this.vm.$.subTree, selector) + if (!result.length) return new ErrorWrapper({ selector }) + return createWrapper(null, result[0]) + } + + findAllComponents(selector: FindAllComponentsSelector): VueWrapper[] { + return find(this.vm.$.subTree, selector).map((c) => createWrapper(null, c)) } - setProps(props: Record) { + findAll( + selector: K + ): DOMWrapper[] + findAll( + selector: K + ): DOMWrapper[] + findAll(selector: string): DOMWrapper[] + findAll(selector: string): DOMWrapper[] { + const results = this.parentElement.querySelectorAll(selector) + return Array.from(results).map((element) => new DOMWrapper(element)) + } + + setProps(props: Record): Promise { + // if this VM's parent is not the root, error out + if (this.vm.$parent !== this.rootVM) { + throw Error('You can only use setProps on your mounted component') + } this.__setProps(props) return nextTick() } @@ -97,12 +152,26 @@ export class VueWrapper implements WrapperAPI { const rootElementWrapper = new DOMWrapper(this.element) return rootElementWrapper.trigger(eventString) } + + unmount() { + // preventing dispose of child component + if (!this.__app) { + throw new Error( + `wrapper.unmount() can only be called by the root wrapper` + ) + } + + if (this.parentElement) { + this.parentElement.removeChild(this.element) + } + this.__app.unmount(this.element) + } } -export function createWrapper( +export function createWrapper( + app: App, vm: ComponentPublicInstance, - events: Record, - setProps: (props: Record) => void -): VueWrapper { - return new VueWrapper(vm, events, setProps) + setProps?: (props: Record) => void +): VueWrapper { + return new VueWrapper(app, vm, setProps) } diff --git a/test-dts/mount.d-test.ts b/test-dts/mount.d-test.ts new file mode 100644 index 000000000..e5a2daea6 --- /dev/null +++ b/test-dts/mount.d-test.ts @@ -0,0 +1,87 @@ +import { expectError, expectType } from 'tsd' +import { defineComponent } from 'vue' +import { mount } from '../src' + +const AppWithDefine = defineComponent({ + props: { + a: { + type: String, + required: true + } + }, + template: '' +}) + +// accept props +let wrapper = mount(AppWithDefine, { + props: { a: 'Hello' } +}) +// vm is properly typed +expectType(wrapper.vm.a) + +// can receive extra props +mount(AppWithDefine, { + props: { a: 'Hello', b: 2 } +}) + +// wrong prop type should not compile +expectError( + mount(AppWithDefine, { + props: { a: 2 } + }) +) + +const AppWithProps = { + props: { + a: { + type: String, + required: true + } + }, + template: '' +} + +// accept props +wrapper = mount(AppWithProps, { + props: { a: 'Hello' } +}) +// vm is properly typed +expectType(wrapper.vm.a) + +// can receive extra props +mount(AppWithProps, { + props: { a: 'Hello', b: 2 } +}) + +// wrong prop type should not compile +expectError( + mount(AppWithProps, { + props: { a: 2 } + }) +) + +const AppWithArrayProps = { + props: ['a'], + template: '' +} + +// accept props +wrapper = mount(AppWithArrayProps, { + props: { a: 'Hello' } +}) +// vm is properly typed +expectType(wrapper.vm.a) + +// can receive extra props +mount(AppWithArrayProps, { + props: { a: 'Hello', b: 2 } +}) + +const AppWithoutProps = { + template: '' +} + +// can receive extra props +wrapper = mount(AppWithoutProps, { + props: { b: 'Hello' } +}) diff --git a/test-dts/wrapper.d-test.ts b/test-dts/wrapper.d-test.ts new file mode 100644 index 000000000..b71a50b68 --- /dev/null +++ b/test-dts/wrapper.d-test.ts @@ -0,0 +1,88 @@ +import { expectType } from 'tsd' +import { defineComponent } from 'vue' +import { mount } from '../src' + +const AppWithDefine = defineComponent({ + template: '' +}) + +const wrapper = mount(AppWithDefine) +const domWrapper = wrapper.find('#other') + +// find Vue wrapper +// HTML element selector +let inputMaybe = wrapper.find('input') +expectType(inputMaybe.element) + +// SVG element selector +let lineMaybe = wrapper.find('line') +expectType(lineMaybe.element) + +// string selector +let byClassMaybe = wrapper.find('.todo') +expectType(byClassMaybe.element) + +// find DOM wrapper +// HTML element selector +inputMaybe = domWrapper.find('input') +expectType(inputMaybe.element) + +// SVG element selector +lineMaybe = domWrapper.find('line') +expectType(lineMaybe.element) + +// string selector +byClassMaybe = domWrapper.find('.todo') +expectType(byClassMaybe.element) + +// findAll +// HTML element selector +let inputArray = wrapper.findAll('input') +expectType(inputArray[0].element) + +// SVG element selector +let lineArray = wrapper.findAll('line') +expectType(lineArray[0].element) + +// string selector +let byClassArray = wrapper.findAll('.todo') +expectType(byClassArray[0].element) + +// findAll DOM wrapper +// HTML element selector +inputArray = domWrapper.findAll('input') +expectType(inputArray[0].element) + +// SVG element selector +lineArray = domWrapper.findAll('line') +expectType(lineArray[0].element) + +// string selector +byClassArray = domWrapper.findAll('.todo') +expectType(byClassArray[0].element) + +// get +// HTML element selector +let input = wrapper.get('input') +expectType(input.element) + +// SVG element selector +let line = wrapper.get('line') +expectType(line.element) + +// string selector +let byClass = wrapper.get('.todo') +expectType(byClass.element) + +// get DOM wrapper +// HTML element selector +input = domWrapper.get('input') +expectType(input.element) + +// SVG element selector +line = domWrapper.get('line') +expectType(line.element) + +// string selector +byClass = domWrapper.get('.todo') +expectType(byClass.element) diff --git a/tests/config.spec.ts b/tests/config.spec.ts new file mode 100644 index 000000000..c1d1fa417 --- /dev/null +++ b/tests/config.spec.ts @@ -0,0 +1,96 @@ +import { config, mount } from '../src' +import Hello from './components/Hello.vue' + +describe('config', () => { + beforeEach(() => { + config.global = { + components: undefined, + directives: undefined, + mixins: undefined, + plugins: undefined, + mocks: undefined, + provide: undefined + } + }) + + describe('components', () => { + const Component = { + template: '
{{ msg }}
', + props: ['msg'] + } + + it('allows setting components globally', () => { + config.global.components = { Hello } + const wrapper1 = mount(Component, { props: { msg: 'Wrapper1' } }) + const wrapper2 = mount(Component, { props: { msg: 'Wrapper2' } }) + expect(wrapper1.text()).toEqual('Wrapper1 Hello world') + expect(wrapper2.text()).toEqual('Wrapper2 Hello world') + }) + + it('allows overwriting globally set component config on a per mount instance', () => { + config.global.components = { Hello } + const HelloLocal = { template: '
Hello Overwritten
' } + const wrapper1 = mount(Component, { props: { msg: 'Wrapper1' } }) + const wrapper2 = mount(Component, { + props: { msg: 'Wrapper2' }, + global: { components: { Hello: HelloLocal } } + }) + expect(wrapper1.text()).toEqual('Wrapper1 Hello world') + expect(wrapper2.text()).toEqual('Wrapper2 Hello Overwritten') + }) + }) + + describe('directives', () => { + const Directive = { + beforeMount(el: Element) { + el.classList.add('DirectiveAdded') + } + } + const Component = { template: '
msg
' } + + it('allows setting directives globally', () => { + config.global.directives = { Directive } + expect(mount(Component).classes()).toContain('DirectiveAdded') + expect(mount(Component).classes()).toContain('DirectiveAdded') + }) + + it('allows overwriting globally set directives', () => { + config.global.directives = { Directive } + const LocalDirective = { + beforeMount(el: Element) { + el.classList.add('LocallyDirectiveAdded') + } + } + + expect(mount(Component).classes()).toContain('DirectiveAdded') + expect( + mount(Component, { + global: { directives: { Directive: LocalDirective } } + }).classes() + ).toContain('LocallyDirectiveAdded') + }) + }) + + describe('mocks', () => { + it('sets mock everywhere', () => { + config.global.mocks = { + foo: 'bar' + } + const Component = { template: '
{{ foo }}
' } + expect(mount(Component).text()).toEqual('bar') + expect(mount(Component).text()).toEqual('bar') + }) + + it('allows overwriting a global mock', () => { + config.global.mocks = { + foo: 'bar' + } + const Component = { template: '
{{ foo }}
' } + + expect(mount(Component).text()).toEqual('bar') + expect( + mount(Component, { global: { mocks: { foo: 'baz' } } }).text() + ).toEqual('baz') + }) + }) +}) diff --git a/tests/emit.spec.ts b/tests/emit.spec.ts index 91f9e0cf0..555dc85ca 100644 --- a/tests/emit.spec.ts +++ b/tests/emit.spec.ts @@ -22,9 +22,6 @@ describe('emitted', () => { expect(wrapper.emitted().hello[1]).toEqual(['foo', 'bar']) }) - // NOTE: This will fail until alpha 5. - // For now I am testing this by hacking node_modules/vue/dist/vue.esm.js with the following fix: - // https://github.com/vuejs/vue-next/commit/e308ad99e9f5bdfb0910a2d6959e746f558714c5 it('captures events emitted via ctx.emit', () => { const Component = defineComponent({ name: 'ContextEmit', @@ -46,4 +43,26 @@ describe('emitted', () => { wrapper.find('button').trigger('click') expect(wrapper.emitted().hello[1]).toEqual(['foo', 'bar']) }) + + it('captures events emitted via destructured emit', () => { + const Component = defineComponent({ + name: 'ContextEmit', + + setup(props, { emit }) { + return () => + h('div', [ + h('button', { onClick: () => emit('hello', 'foo', 'bar') }) + ]) + } + }) + const wrapper = mount(Component) + expect(wrapper.emitted()).toEqual({}) + expect(wrapper.emitted().hello).toEqual(undefined) + + wrapper.find('button').trigger('click') + expect(wrapper.emitted().hello[0]).toEqual(['foo', 'bar']) + + wrapper.find('button').trigger('click') + expect(wrapper.emitted().hello[1]).toEqual(['foo', 'bar']) + }) }) diff --git a/tests/find.spec.ts b/tests/find.spec.ts index 6caab72a1..a4b51f147 100644 --- a/tests/find.spec.ts +++ b/tests/find.spec.ts @@ -2,6 +2,7 @@ import { defineComponent, h } from 'vue' import { mount } from '../src' import SuspenseComponent from './components/Suspense.vue' +import Hello from './components/Hello.vue' describe('find', () => { it('find using single root node', () => { diff --git a/tests/findAllComponents.spec.ts b/tests/findAllComponents.spec.ts new file mode 100644 index 000000000..b13e65460 --- /dev/null +++ b/tests/findAllComponents.spec.ts @@ -0,0 +1,28 @@ +import { mount } from '../src' +import Hello from './components/Hello.vue' +import { defineComponent } from 'vue' + +const compC = defineComponent({ + name: 'ComponentC', + template: '
C
' +}) +const compB = defineComponent({ + template: '
TextBeforeTextAfter
', + components: { compC } +}) +const compA = defineComponent({ + template: '
', + components: { compB, Hello } +}) + +describe('findAllComponents', () => { + it('finds all deeply nested vue components', () => { + const wrapper = mount(compA) + // find by DOM selector + expect(wrapper.findAllComponents('.C')).toHaveLength(2) + expect(wrapper.findAllComponents({ name: 'Hello' })[0].text()).toBe( + 'Hello world' + ) + expect(wrapper.findAllComponents(Hello)[0].text()).toBe('Hello world') + }) +}) diff --git a/tests/findComponent.spec.ts b/tests/findComponent.spec.ts new file mode 100644 index 000000000..2efe3b774 --- /dev/null +++ b/tests/findComponent.spec.ts @@ -0,0 +1,94 @@ +import { defineComponent } from 'vue' +import { mount } from '../src' +import Hello from './components/Hello.vue' + +const compC = defineComponent({ + name: 'ComponentC', + template: '
C
' +}) + +const compD = defineComponent({ + name: 'ComponentD', + template: '', + components: { compC } +}) + +const compB = defineComponent({ + name: 'component-b', + template: ` +
+ TextBefore + + TextAfter + + +
`, + components: { compC, compD } +}) + +const compA = defineComponent({ + template: ` +
+ + +
+
`, + components: { compB, Hello } +}) + +describe('findComponent', () => { + it('does not find plain dom elements', () => { + const wrapper = mount(compA) + expect(wrapper.findComponent('.domElement').exists()).toBeFalsy() + }) + + it('finds component by ref', () => { + const wrapper = mount(compA) + // find by ref + expect(wrapper.findComponent({ ref: 'b' })).toBeTruthy() + }) + + it('finds component by dom selector', () => { + const wrapper = mount(compA) + // find by DOM selector + expect(wrapper.findComponent('.C').vm).toHaveProperty( + '$options.name', + 'ComponentC' + ) + }) + + it('does allows using complicated DOM selector query', () => { + const wrapper = mount(compA) + expect(wrapper.findComponent('.B > .C').vm).toHaveProperty( + '$options.name', + 'ComponentC' + ) + }) + + it('finds a component when root of mounted component', async () => { + const wrapper = mount(compD) + // make sure it finds the component, not its root + expect(wrapper.findComponent('.c-as-root-on-d').vm).toHaveProperty( + '$options.name', + 'ComponentC' + ) + }) + + it('finds component by name', () => { + const wrapper = mount(compA) + expect(wrapper.findComponent({ name: 'Hello' }).text()).toBe('Hello world') + expect(wrapper.findComponent({ name: 'ComponentB' }).exists()).toBeTruthy() + expect(wrapper.findComponent({ name: 'component-c' }).exists()).toBeTruthy() + }) + + it('finds component by imported SFC file', () => { + const wrapper = mount(compA) + expect(wrapper.findComponent(Hello).text()).toBe('Hello world') + expect(wrapper.findComponent(compC).text()).toBe('C') + }) + + it('throw error if trying to unmount component from find', () => { + const wrapper = mount(compA) + expect(wrapper.findComponent(Hello).unmount).toThrowError() + }) +}) diff --git a/tests/get.spec.ts b/tests/get.spec.ts new file mode 100644 index 000000000..806ffe9bd --- /dev/null +++ b/tests/get.spec.ts @@ -0,0 +1,29 @@ +import { defineComponent, h } from 'vue' + +import { mount } from '../src' + +describe('get', () => { + test('returns the element if it exists', () => { + const Component = defineComponent({ + render() { + return h('div', {}, [h('span', { id: 'my-span' })]) + } + }) + + const wrapper = mount(Component) + expect(wrapper.get('#my-span')).not.toBeNull() + }) + + test('throws if it does not exist', () => { + const Component = defineComponent({ + render() { + return h('div', {}, [h('span', { id: 'my-span' })]) + } + }) + + const wrapper = mount(Component) + expect(() => wrapper.get('#other-span')).toThrowError( + 'Unable to find #other-span within:
' + ) + }) +}) diff --git a/tests/lifecycle.spec.ts b/tests/lifecycle.spec.ts index 97a116850..442493082 100644 --- a/tests/lifecycle.spec.ts +++ b/tests/lifecycle.spec.ts @@ -1,4 +1,13 @@ -import { defineComponent, h, onMounted, nextTick, onBeforeMount } from 'vue' +import { + defineComponent, + h, + onMounted, + nextTick, + onBeforeMount, + onUnmounted, + onBeforeUnmount, + ref +} from 'vue' import { mount } from '../src' @@ -24,4 +33,40 @@ describe('lifecycles', () => { expect(onBeforeMountFn).toHaveBeenCalled() expect(onBeforeMountFn).toHaveBeenCalled() }) + + it('calls onUnmounted', async () => { + const beforeUnmountFn = jest.fn() + const onBeforeUnmountFn = jest.fn() + const onUnmountFn = jest.fn() + const Component = defineComponent({ + beforeUnmount: beforeUnmountFn, + setup() { + onUnmounted(onUnmountFn) + onBeforeUnmount(onBeforeUnmountFn) + + return () => h('div') + } + }) + + const wrapper = mount(Component) + await nextTick() + expect(beforeUnmountFn).not.toHaveBeenCalled() + expect(onBeforeUnmountFn).not.toHaveBeenCalled() + expect(onUnmountFn).not.toHaveBeenCalled() + + const removeChildSpy = jest.spyOn( + wrapper.element.parentElement, + 'removeChild' + ) + + const el = wrapper.element + + wrapper.unmount() + + expect(beforeUnmountFn).toHaveBeenCalled() + expect(onBeforeUnmountFn).toHaveBeenCalled() + expect(onUnmountFn).toHaveBeenCalled() + + expect(removeChildSpy).toHaveBeenCalledWith(el) + }) }) diff --git a/tests/mountingOptions/stubs.global.spec.ts b/tests/mountingOptions/stubs.global.spec.ts new file mode 100644 index 000000000..9896544c7 --- /dev/null +++ b/tests/mountingOptions/stubs.global.spec.ts @@ -0,0 +1,241 @@ +import { h, ComponentOptions } from 'vue' + +import { mount } from '../../src' +import Hello from '../components/Hello.vue' + +describe('mounting options: stubs', () => { + it('handles Array syntax', () => { + const Foo = { + name: 'Foo', + render() { + return h('p') + } + } + const Component: ComponentOptions = { + render() { + return h(() => [h('div'), h(Foo)]) + } + } + + const wrapper = mount(Component, { + global: { + stubs: ['foo'] + } + }) + + expect(wrapper.html()).toBe('
') + }) + it('stubs in a fragment', () => { + const Foo = { + name: 'Foo', + render() { + return h('p') + } + } + const Component: ComponentOptions = { + render() { + return h(() => [h('div'), h(Foo)]) + } + } + + const wrapper = mount(Component, { + global: { + stubs: { + Foo: true + } + } + }) + + expect(wrapper.html()).toBe('
') + }) + + it('prevents lifecycle hooks triggering in a stub', () => { + const onBeforeMount = jest.fn() + const beforeCreate = jest.fn() + const Foo = { + name: 'Foo', + setup() { + onBeforeMount(onBeforeMount) + return () => h('div') + }, + beforeCreate + } + const Comp = { + render() { + return h(Foo) + } + } + + const wrapper = mount(Comp, { + global: { + stubs: { + Foo: true + } + } + }) + + expect(wrapper.html()).toBe('') + expect(onBeforeMount).not.toHaveBeenCalled() + expect(beforeCreate).not.toHaveBeenCalled() + }) + + it('uses a custom stub implementation', () => { + const onBeforeMount = jest.fn() + const FooStub = { + name: 'FooStub', + setup() { + onBeforeMount(onBeforeMount) + return () => h('div', 'foo stub') + } + } + const Foo = { + name: 'Foo', + render() { + return h('div', 'real foo') + } + } + + const Comp = { + render() { + return h(Foo) + } + } + + const wrapper = mount(Comp, { + global: { + stubs: { + Foo: FooStub + } + } + }) + + expect(onBeforeMount).toHaveBeenCalled() + expect(wrapper.html()).toBe('
foo stub
') + }) + + it('uses an sfc as a custom stub', () => { + const created = jest.fn() + const HelloComp = { + name: 'Hello', + created() { + created() + }, + render() { + return h('span', 'real implementation') + } + } + + const Comp = { + render() { + return h(HelloComp) + } + } + + const wrapper = mount(Comp, { + global: { + stubs: { + Hello: Hello + } + } + }) + + expect(created).not.toHaveBeenCalled() + expect(wrapper.html()).toBe( + '
Hello world
' + ) + }) + + it('stubs using inline components', () => { + const Foo = { + name: 'Foo', + render() { + return h('p') + } + } + const Bar = { + name: 'Bar', + render() { + return h('p') + } + } + const Component: ComponentOptions = { + render() { + return h(() => [h(Foo), h(Bar)]) + } + } + + const wrapper = mount(Component, { + global: { + stubs: { + Foo: { + template: '' + }, + Bar: { + render() { + return h('div') + } + } + } + } + }) + + expect(wrapper.html()).toBe('
') + }) + + it('stubs a component with a kabeb-case name', () => { + const FooBar = { + name: 'foo-bar', + render: () => h('span', 'real foobar') + } + const Comp = { + render: () => h(FooBar) + } + const wrapper = mount(Comp, { + global: { + stubs: { + FooBar: true + } + } + }) + + expect(wrapper.html()).toBe('') + }) + + it('stubs a component with a PascalCase name', () => { + const FooBar = { + name: 'FooBar', + render: () => h('span', 'real foobar') + } + const Comp = { + render: () => h(FooBar) + } + const wrapper = mount(Comp, { + global: { + stubs: { + 'foo-bar': true + } + } + }) + + expect(wrapper.html()).toBe('') + }) + + it('stubs a component with registered with strange casing', () => { + const FooBar = { + name: 'fooBar', + render: () => h('span', 'real foobar') + } + const Comp = { + render: () => h(FooBar) + } + const wrapper = mount(Comp, { + global: { + stubs: { + fooBar: true + } + } + }) + + expect(wrapper.html()).toBe('') + }) +}) diff --git a/tests/props.spec.ts b/tests/props.spec.ts new file mode 100644 index 000000000..006eaee7d --- /dev/null +++ b/tests/props.spec.ts @@ -0,0 +1,25 @@ +import { mount } from '../src' +import WithProps from './components/WithProps.vue' +import Hello from './components/Hello.vue' + +describe('props', () => { + it('returns a single prop applied to a component', () => { + const wrapper = mount(WithProps, { props: { msg: 'ABC' } }) + expect(wrapper.props('msg')).toEqual('ABC') + }) + + it('returns all props applied to a component', () => { + const wrapper = mount(WithProps, { props: { msg: 'ABC' } }) + expect(wrapper.props()).toEqual({ msg: 'ABC' }) + }) + + it('returns undefined if props does not exist', () => { + const wrapper = mount(WithProps, { props: { msg: 'ABC' } }) + expect(wrapper.props('foo')).toEqual(undefined) + }) + + it('returns empty object for components without props', () => { + const wrapper = mount(Hello) + expect(wrapper.props()).toEqual({}) + }) +}) diff --git a/tests/setProps.spec.ts b/tests/setProps.spec.ts index c1ffb81fc..cc6241cdf 100644 --- a/tests/setProps.spec.ts +++ b/tests/setProps.spec.ts @@ -10,10 +10,10 @@ describe('setProps', () => { } const wrapper = mount(Foo, { props: { - foo: 'foo' + foo: 'bar' } }) - expect(wrapper.html()).toContain('foo') + expect(wrapper.html()).toContain('bar') await wrapper.setProps({ foo: 'qux' }) expect(wrapper.html()).toContain('qux') @@ -44,7 +44,8 @@ describe('setProps', () => { it('sets component props, and updates DOM when props were not initially passed', async () => { const Foo = { props: ['foo'], - template: `
{{ foo }}
` + template: ` +
{{ foo }}
` } const wrapper = mount(Foo) expect(wrapper.html()).not.toContain('foo') @@ -67,7 +68,8 @@ describe('setProps', () => { this.bar = val } }, - template: `
{{ bar }}
` + template: ` +
{{ bar }}
` } const wrapper = mount(Foo) expect(wrapper.html()).toContain('original-bar') @@ -118,4 +120,27 @@ describe('setProps', () => { expect(wrapper.attributes()).toEqual(nonExistentProp) expect(wrapper.html()).toBe('
foo
') }) + + it('allows using only on mounted component', async () => { + const Foo = { + name: 'Foo', + props: ['foo'], + template: '
{{ foo }}
' + } + const Baz = { + props: ['baz'], + template: '
', + components: { Foo } + } + + const wrapper = mount(Baz, { + props: { + baz: 'baz' + } + }) + const FooResult = wrapper.findComponent({ name: 'Foo' }) + expect(() => FooResult.setProps({ baz: 'bin' })).toThrowError( + 'You can only use setProps on your mounted component' + ) + }) }) diff --git a/tests/vm.spec.ts b/tests/vm.spec.ts new file mode 100644 index 000000000..6f2a3b31d --- /dev/null +++ b/tests/vm.spec.ts @@ -0,0 +1,27 @@ +import { defineComponent, ref } from 'vue' + +import { mount } from '../src' + +describe('vm', () => { + it('returns the component vm', () => { + const Component = defineComponent({ + name: 'VTUComponent', + template: '
{{ msg }}
', + setup() { + const msg = 'hello' + const isEnabled = ref(true) + const toggle = () => (isEnabled.value = !isEnabled.value) + return { msg, isEnabled, toggle } + } + }) + + const wrapper = mount(Component) + + expect(wrapper.vm.msg).toBe('hello') + expect(wrapper.vm.isEnabled).toBe(true) + + wrapper.vm.toggle() + + expect(wrapper.vm.isEnabled).toBe(false) + }) +}) diff --git a/yarn.lock b/yarn.lock index 784402de1..c8ebd7738 100644 --- a/yarn.lock +++ b/yarn.lock @@ -268,10 +268,10 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-validator-identifier@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed" - integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw== +"@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" + integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== "@babel/helper-wrap-function@^7.8.3": version "7.8.3" @@ -830,7 +830,16 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" -"@babel/types@^7.8.6", "@babel/types@^7.9.0": +"@babel/types@^7.8.6": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.5.tgz#89231f82915a8a566a703b3b20133f73da6b9444" + integrity sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg== + dependencies: + "@babel/helper-validator-identifier" "^7.9.5" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@babel/types@^7.9.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.0.tgz#00b064c3df83ad32b2dbf5ff07312b15c7f1efb5" integrity sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng== @@ -1067,6 +1076,39 @@ "@types/yargs" "^15.0.0" chalk "^3.0.0" +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +"@rollup/plugin-node-resolve@^7.1.3": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz#80de384edfbd7bfc9101164910f86078151a3eca" + integrity sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q== + dependencies: + "@rollup/pluginutils" "^3.0.8" + "@types/resolve" "0.0.8" + builtin-modules "^3.1.0" + is-module "^1.0.0" + resolve "^1.14.2" + +"@rollup/pluginutils@^3.0.8": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.0.9.tgz#aa6adca2c45e5a1b950103a999e3cddfe49fd775" + integrity sha512-TLZavlfPAZYI7v33wQh4mTP6zojne14yok3DNSLcjoG/Hirxfkonn6icP5rrNWRn8nZsirJBFFpijVOJzkUHDg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + micromatch "^4.0.2" + "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" @@ -1124,6 +1166,25 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.42.tgz#8d0c1f480339efedb3e46070e22dd63e0430dd11" integrity sha512-K1DPVvnBCPxzD+G51/cxVIoc2X8uUVl1zpJeE6iKcgHMj4+tbat5Xu4TjV7v2QSDbIeAfLi2hIk+u2+s0MlpUQ== +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + +"@types/events@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== + +"@types/glob@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" + integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" @@ -1151,16 +1212,38 @@ dependencies: jest-diff "^24.3.0" +"@types/lodash@^4.14.149": + version "4.14.149" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440" + integrity sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ== + +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + "@types/node@*": version "13.7.4" resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.4.tgz#76c3cb3a12909510f52e5dc04a6298cdf9504ffd" integrity sha512-oVeL12C6gQS/GAExndigSaLxTrKpQPxewx9bOcwfvJiJge4rr7wNaph4J+ns5hrmIV2as5qxqN8YKthn9qh0jw== +"@types/node@12.12.35": + version "12.12.35" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.35.tgz#1e61b226c14380f4384f70cfe49a65c2c553ad2b" + integrity sha512-ASYsaKecA7TUsDrqIGPNk3JeEox0z/0XR/WsJJ8BIX/9+SkMSImQXKWfU/yBrSyc7ZSE/NPqLu36Nur0miCFfQ== + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== +"@types/resolve@0.0.8": + version "0.0.8" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" + integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== + dependencies: + "@types/node" "*" + "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -1185,34 +1268,34 @@ dependencies: "@types/yargs-parser" "*" -"@vue/compiler-core@3.0.0-alpha.12": - version "3.0.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.0.0-alpha.12.tgz#f125bdfd637d6bcc95edb2c55483a242932c5d2e" - integrity sha512-0aDhUP9SS+O1psH2xm08oxQQV+5p5ig/zhSNL8fOreSQabIzfSuNfZqrJ8e2Ffa+zoJkZ0Z0SKJ1+UuzHXm0zA== +"@vue/compiler-core@3.0.0-beta.2": + version "3.0.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.0.0-beta.2.tgz#ac8f14856cd874cb22d89181e8c3bddf810b8261" + integrity sha512-/c3ePWU9T7xwn0J/YRlxCxnxqphNVlcXisnI6aMoK3pjvQFXOMD6tfrHUtepCrQLNdKlhxNjqe3Q625Z64Z0kQ== dependencies: "@babel/parser" "^7.8.6" "@babel/types" "^7.8.6" - "@vue/shared" "3.0.0-alpha.12" + "@vue/shared" "3.0.0-beta.2" estree-walker "^0.8.1" source-map "^0.6.1" -"@vue/compiler-dom@3.0.0-alpha.12": - version "3.0.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.0.0-alpha.12.tgz#3f5b856007d5201c477540299bd89e0989e83543" - integrity sha512-MpdGAFmS8Pc945Kgo0FbAQVObi+aTBGpDCz4f1UwBBR8z/TVgENTd8DXzksOnu82RrW1hV5Lbn3uUW/RuHFJlQ== +"@vue/compiler-dom@3.0.0-beta.2": + version "3.0.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.0.0-beta.2.tgz#344263f4e50258496bfdbd01a9a85a7b842e96de" + integrity sha512-VZwvnsWPoi0/MR5CF5p5VhRGk3AkM9MQYt/pMaXDmbl09kWKVjQZubCRvpzuyjjm1QnV1yrSaqTZWDAIYbKYtw== dependencies: - "@vue/compiler-core" "3.0.0-alpha.12" - "@vue/shared" "3.0.0-alpha.12" + "@vue/compiler-core" "3.0.0-beta.2" + "@vue/shared" "3.0.0-beta.2" -"@vue/compiler-sfc@^3.0.0-alpha.12": - version "3.0.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.0.0-alpha.12.tgz#485db9f732486c9007402683eeac2ed78313a788" - integrity sha512-rshwehh3tvRf5xx4ONYgQOYYjXKeZEwES2ZeSEG2oLRw4vnkHryFB9gLpV6I+E9fhlJ4RHiNRxR1Sj+kbDk71A== +"@vue/compiler-sfc@^3.0.0-beta.2": + version "3.0.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.0.0-beta.2.tgz#610697d29e067165d5e2ccf81bdd238399b6d156" + integrity sha512-v3zQ8fR+Oc8U/WZFmJY641b05ayP1cdngZMn8PUgPecRwjQkdR/k9ikCMZpsrWtoS4am0e3PHyCt/BBZCxA4nA== dependencies: - "@vue/compiler-core" "3.0.0-alpha.12" - "@vue/compiler-dom" "3.0.0-alpha.12" - "@vue/compiler-ssr" "3.0.0-alpha.12" - "@vue/shared" "3.0.0-alpha.12" + "@vue/compiler-core" "3.0.0-beta.2" + "@vue/compiler-dom" "3.0.0-beta.2" + "@vue/compiler-ssr" "3.0.0-beta.2" + "@vue/shared" "3.0.0-beta.2" consolidate "^0.15.1" hash-sum "^2.0.0" lru-cache "^5.1.1" @@ -1221,42 +1304,42 @@ postcss-selector-parser "^6.0.2" source-map "^0.6.1" -"@vue/compiler-ssr@3.0.0-alpha.12": - version "3.0.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.0.0-alpha.12.tgz#533d8aa43595a9df764d2af7227ae4720d777324" - integrity sha512-DNdBuRaE37QECxoCskOD2m2AYaInP9b9eGlZM4atWIOUfBrJkpS9mUxloRDP+cOrk6S7N88VGLbEEOpF4wnbIQ== +"@vue/compiler-ssr@3.0.0-beta.2": + version "3.0.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.0.0-beta.2.tgz#05c965d8f5a6362928959d4f8a7b75b07cf68c45" + integrity sha512-+g0u8Zgns3uR6E3338yCGBz927mOdzzsCFxBKTS6O2WRXhUZ1vcRerigruRRF+LDiWtFm2txsjj70CcMqF4D/w== dependencies: - "@vue/compiler-dom" "3.0.0-alpha.12" - "@vue/shared" "3.0.0-alpha.12" + "@vue/compiler-dom" "3.0.0-beta.2" + "@vue/shared" "3.0.0-beta.2" -"@vue/reactivity@3.0.0-alpha.12": - version "3.0.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.0.0-alpha.12.tgz#35cb74dd08ee8f8929166b54cbaa0c30c959a865" - integrity sha512-9lSysYh00p1lkZehwjUf6r4aZIgp+rRKIWfxlffnnEwH1rloOV0RkYJrix4NTOcxHHqIYYcoGBVJ3AK64pCJoQ== +"@vue/reactivity@3.0.0-beta.2": + version "3.0.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.0.0-beta.2.tgz#216922e264dc447a508f756374c09fb26a7cbe1c" + integrity sha512-vAYHiBmpHfLAJulssTTTlvdHtyyKeOCG3qCu/TxDhu3NFHEfrt4eytR2atR6EbpTb853/QKcoW3k6L6g/znxAw== dependencies: - "@vue/shared" "3.0.0-alpha.12" + "@vue/shared" "3.0.0-beta.2" -"@vue/runtime-core@3.0.0-alpha.12": - version "3.0.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.0.0-alpha.12.tgz#790c4a9743d2999d1886b6da1a193f90aaf5fa9a" - integrity sha512-eVhd4bbVNd25FulwR9B6QD5+TeADlwSUm1ktRA0zvO3Sy+QAABPXXI147R/i18tr2v51tVWsUTIWz5f7H7Uang== +"@vue/runtime-core@3.0.0-beta.2": + version "3.0.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.0.0-beta.2.tgz#0413292d8746c532527dbcdbfcbc56be312f05ad" + integrity sha512-tcxNNV7y+H2046F79iw90OdwyxvMEqJ5iOQTsOvfVf2hBNrCWPG1tAU+kywFBlBY4I26k7XB/Q1ZdHb2q8YLaA== dependencies: - "@vue/reactivity" "3.0.0-alpha.12" - "@vue/shared" "3.0.0-alpha.12" + "@vue/reactivity" "3.0.0-beta.2" + "@vue/shared" "3.0.0-beta.2" -"@vue/runtime-dom@3.0.0-alpha.12": - version "3.0.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.0.0-alpha.12.tgz#70044b72db2ec184b49baaa6e36fc7ac6f7b2fbd" - integrity sha512-G5JHfJfm/NX0hsoI/x3PNYqzv99B4Dryz9WU++WAIwM+VZLyTat0H6Q3jWdVeGm5h9tY/zr6UD7NokGRKuwsUw== +"@vue/runtime-dom@3.0.0-beta.2": + version "3.0.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.0.0-beta.2.tgz#957a59ecfcdf54619e4d40d2e2967587ea58728d" + integrity sha512-swWm7fa3JKEGE0KYVevYqaBTSGxx/bmlwJTbJcnnNgdZZGtWUQsUzXCk6JKRuoYjy+iU0ONcHidEhpwdazH9Aw== dependencies: - "@vue/runtime-core" "3.0.0-alpha.12" - "@vue/shared" "3.0.0-alpha.12" + "@vue/runtime-core" "3.0.0-beta.2" + "@vue/shared" "3.0.0-beta.2" csstype "^2.6.8" -"@vue/shared@3.0.0-alpha.12": - version "3.0.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.0-alpha.12.tgz#36855f95e2855f0099980aebf63edf51e0bad471" - integrity sha512-SVXQd0fJ7Fod7J8WBFDPLp0rNobnixo11E+OevC9cBs5Y0fZklAr+8i5XaJJ/fdPr9qDWFHweXDwIvVzpoZMOA== +"@vue/shared@3.0.0-beta.2": + version "3.0.0-beta.2" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.0-beta.2.tgz#6659413868b0ba0b96260cbf3c9ed99f2d0f90ef" + integrity sha512-ED5oa+ZOcjAJkWEzL0zFZ4QG89L23DrW9LBBGT6YBUhBmOsf9BKii2JIBfdxWYwRkjAhbHffQH0mc6rI2famug== abab@^2.0.0: version "2.0.3" @@ -1277,9 +1360,9 @@ acorn-walk@^6.0.1: integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== acorn@^6.0.1: - version "6.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" - integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== acorn@^7.1.0: version "7.1.0" @@ -1296,6 +1379,18 @@ ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= + dependencies: + string-width "^2.0.0" + +ansi-escapes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" + integrity sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs= + ansi-escapes@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" @@ -1396,11 +1491,33 @@ array-equal@^1.0.0: resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= +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" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-union@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + asn1@~0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" @@ -1549,6 +1666,19 @@ bluebird@^3.1.1: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== + 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.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1620,6 +1750,11 @@ buffer-from@1.x, buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +builtin-modules@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.1.0.tgz#aad97c15131eb76b65b50ef208e7584cd76a7484" + integrity sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw== + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -1635,12 +1770,26 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase@^4.1.0: +camelcase-keys@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" + integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c= + dependencies: + camelcase "^4.1.0" + map-obj "^2.0.0" + quick-lru "^1.0.0" + +camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= @@ -1662,6 +1811,11 @@ capture-exit@^2.0.0: dependencies: rsvp "^4.8.4" +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -1695,6 +1849,11 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -1710,6 +1869,11 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= + cli-cursor@^2.0.0, cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -1813,6 +1977,18 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +configstore@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== + 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" + consolidate@^0.15.1: version "0.15.1" resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7" @@ -1856,6 +2032,22 @@ cosmiconfig@^6.0.0: path-type "^4.0.0" yaml "^1.7.2" +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" + integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= + dependencies: + capture-stack-trace "^1.0.0" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + cross-spawn@^6.0.0: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -1876,6 +2068,11 @@ cross-spawn@^7.0.0: shebang-command "^2.0.0" which "^2.0.1" +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" + integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= + css@^2.1.0: version "2.2.4" resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" @@ -1909,9 +2106,16 @@ cssstyle@^2.0.0: cssom "~0.3.6" csstype@^2.6.8: - version "2.6.9" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098" - integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q== + version "2.6.10" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.10.tgz#e63af50e66d7c266edb6b32909cfd0aabe03928b" + integrity sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w== + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" dashdash@^1.12.0: version "1.14.1" @@ -1948,7 +2152,15 @@ debug@^4.1.0, debug@^4.1.1: dependencies: ms "^2.1.1" -decamelize@^1.2.0: +decamelize-keys@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -1963,6 +2175,11 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -2017,6 +2234,13 @@ diff-sequences@^25.1.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.1.0.tgz#fd29a46f1c913fd66c22645dc75bffbe43051f32" integrity sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw== +dir-glob@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + domexception@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" @@ -2024,6 +2248,18 @@ domexception@^1.0.1: dependencies: webidl-conversions "^4.0.2" +dot-prop@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== + dependencies: + is-obj "^1.0.0" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -2104,6 +2340,17 @@ escodegen@^1.11.1: optionalDependencies: source-map "~0.6.1" +eslint-formatter-pretty@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-formatter-pretty/-/eslint-formatter-pretty-1.3.0.tgz#985d9e41c1f8475f4a090c5dbd2dfcf2821d607e" + integrity sha512-5DY64Y1rYCm7cfFDHEGUn54bvCnK+wSUVF07N8oXeqUJFSd+gnYOTXbzelQ1HurESluY6gnEQPmXOIkB4Wa+gA== + dependencies: + ansi-escapes "^2.0.0" + chalk "^2.1.0" + log-symbols "^2.0.0" + plur "^2.1.2" + string-width "^2.0.0" + esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -2124,6 +2371,11 @@ estree-walker@^0.8.1: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.8.1.tgz#6230ce2ec9a5cb03888afcaf295f97d90aa52b79" integrity sha512-H6cJORkqvrNziu0KX2hqOMAlA2CiuAxHeGJXSIoKA/KLv229Dw806J3II6mKTm5xiDX1At1EXCfsOQPB+tMB+g== +estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -2134,6 +2386,19 @@ exec-sh@^0.3.2: resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + execa@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" @@ -2249,6 +2514,18 @@ fast-deep-equal@^3.1.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== +fast-glob@^2.2.6: + version "2.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" + integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -2307,6 +2584,20 @@ find-cache-dir@^3.2.0: make-dir "^3.0.2" pkg-dir "^4.1.0" +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -2392,6 +2683,11 @@ get-own-enumerable-property-symbols@^3.0.0: resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -2418,6 +2714,19 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" @@ -2430,12 +2739,50 @@ glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= + dependencies: + ini "^1.3.4" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.3: +globby@^9.1.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" + integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^1.0.2" + dir-glob "^2.2.2" + fast-glob "^2.2.6" + glob "^7.1.3" + ignore "^4.0.3" + pify "^4.0.1" + slash "^2.0.0" + +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= + 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.6, graceful-fs@^4.2.0, graceful-fs@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== @@ -2523,6 +2870,11 @@ hash-sum@^2.0.0: resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + html-encoding-sniffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" @@ -2572,6 +2924,11 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +ignore@^4.0.3: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + import-fresh@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" @@ -2580,6 +2937,11 @@ import-fresh@^3.1.0: parent-module "^1.0.0" resolve-from "^4.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" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + import-local@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" @@ -2616,6 +2978,11 @@ inherits@2, inherits@^2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -2628,6 +2995,11 @@ ip-regex@^2.1.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= +irregular-plurals@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.4.0.tgz#2ca9b033651111855412f16be5d77c62a458a766" + integrity sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y= + is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -2657,6 +3029,13 @@ is-callable@^1.1.4, is-callable@^1.1.5: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.0" + is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -2713,6 +3092,11 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -2735,6 +3119,38 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +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" + integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -2747,7 +3163,7 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-obj@^1.0.1: +is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= @@ -2759,6 +3175,18 @@ is-observable@^1.1.0: dependencies: symbol-observable "^1.1.0" +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= + dependencies: + path-is-inside "^1.0.1" + +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -2771,6 +3199,11 @@ is-promise@^2.1.0: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= + is-regex@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" @@ -2783,7 +3216,12 @@ is-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= -is-stream@^1.1.0: +is-retry-allowed@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + +is-stream@^1.0.0, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= @@ -3436,6 +3874,13 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= + dependencies: + package-json "^4.0.0" + leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -3524,6 +3969,32 @@ listr@^0.14.3: p-map "^2.0.0" rxjs "^6.3.3" +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -3553,6 +4024,13 @@ log-symbols@^1.0.2: dependencies: chalk "^1.0.0" +log-symbols@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + log-symbols@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" @@ -3583,6 +4061,27 @@ loose-envify@^1.0.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lru-cache@^4.0.1: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -3590,6 +4089,13 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + make-dir@^3.0.0, make-dir@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" @@ -3614,6 +4120,16 @@ map-cache@^0.2.2: resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= +map-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" + integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= + map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -3621,6 +4137,21 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +meow@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" + integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig== + dependencies: + camelcase-keys "^4.0.0" + decamelize-keys "^1.0.0" + loud-rejection "^1.0.0" + minimist-options "^3.0.1" + normalize-package-data "^2.3.4" + read-pkg-up "^3.0.0" + redent "^2.0.0" + trim-newlines "^2.0.0" + yargs-parser "^10.0.0" + merge-source-map@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" @@ -3633,7 +4164,12 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -micromatch@^3.1.4: +merge2@^1.2.3: + version "1.3.0" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" + integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== + +micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -3689,6 +4225,14 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +minimist-options@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" + integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" @@ -3784,6 +4328,16 @@ node-releases@^1.1.49: dependencies: semver "^6.3.0" +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -3934,6 +4488,20 @@ p-finally@^2.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + p-limit@^2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" @@ -3941,6 +4509,20 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + p-locate@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -3953,11 +4535,26 @@ p-map@^2.0.0: resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -3965,6 +4562,14 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + parse-json@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f" @@ -3985,6 +4590,16 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -3995,6 +4610,11 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-is-inside@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" @@ -4010,6 +4630,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-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -4025,6 +4652,16 @@ picomatch@^2.0.4, picomatch@^2.0.5: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA== +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" @@ -4046,6 +4683,13 @@ please-upgrade-node@^3.2.0: dependencies: semver-compare "^1.0.0" +plur@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" + integrity sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo= + dependencies: + irregular-plurals "^1.0.0" + pn@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" @@ -4079,6 +4723,11 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + prettier@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.2.tgz#1ba8f3eb92231e769b7fcd7cb73ae1b6b74ade08" @@ -4117,6 +4766,11 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.4" +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + psl@^1.1.28: version "1.7.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" @@ -4140,11 +4794,51 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +quick-lru@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" + integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= + +rc@^1.0.1, rc@^1.1.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + react-is@^16.12.0, react-is@^16.8.4: version "16.12.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q== +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" + integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== + dependencies: + find-up "^3.0.0" + read-pkg "^3.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + realpath-native@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" @@ -4157,6 +4851,14 @@ realpath-native@^2.0.0: resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-2.0.0.tgz#7377ac429b6e1fd599dc38d08ed942d0d7beb866" integrity sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q== +redent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= + dependencies: + indent-string "^3.0.0" + strip-indent "^2.0.0" + regenerate-unicode-properties@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" @@ -4201,6 +4903,21 @@ regexpu-core@^4.6.0: unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.1.0" +registry-auth-token@^3.0.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" + integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== + 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" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= + dependencies: + rc "^1.0.1" + regjsgen@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" @@ -4307,13 +5024,20 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@1.15.1, resolve@1.x, resolve@^1.3.2: +resolve@1.15.1, resolve@1.x, resolve@^1.14.2, resolve@^1.3.2: version "1.15.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== dependencies: path-parse "^1.0.6" +resolve@^1.10.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.16.0.tgz#063dc704fa3413e13ac1d0d1756a7cbfe95dd1a7" + integrity sha512-LarL/PIKJvc09k1jaeT4kQb/8/7P+qV4qSnN2K80AES+OHdfZELAKVOBjxsvtToT/uLOfFbvYvKfZmV8cee7nA== + dependencies: + path-parse "^1.0.6" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -4422,21 +5146,28 @@ semver-compare@^1.0.0: resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= + dependencies: + semver "^5.0.3" + semver-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + semver@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@^5.4.1, semver@^5.5, semver@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -4501,6 +5232,11 @@ sisteransi@^1.0.4: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.4.tgz#386713f1ef688c7c0304dc4c0632898941cad2e3" integrity sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig== +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -4580,6 +5316,32 @@ source-map@^0.7.3: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" + integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -4647,7 +5409,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.1.1: +string-width@^2.0.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -4717,6 +5479,11 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + strip-bom@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" @@ -4732,6 +5499,16 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -4776,6 +5553,13 @@ symbol-tree@^3.2.2: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= + dependencies: + execa "^0.7.0" + terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" @@ -4798,6 +5582,11 @@ throat@^5.0.0: resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" @@ -4864,6 +5653,11 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +trim-newlines@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" + integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= + ts-jest@^24.0.0: version "24.3.0" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869" @@ -4896,6 +5690,18 @@ ts-jest@^25.0.0: semver "^5.5" yargs-parser "^16.1.0" +tsd@0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/tsd/-/tsd-0.11.0.tgz#ede8b8e85850845b753fff7eaaf68dbd3673700b" + integrity sha512-klKMNC0KRzUIaLJG8XqkvH/9rKwYX74xpqJBN8spWjYUDojAesd6AfDCT5dray+yhLfTGkem7O3nU6i4KwzNDw== + dependencies: + eslint-formatter-pretty "^1.3.0" + globby "^9.1.0" + meow "^5.0.0" + path-exists "^3.0.0" + read-pkg-up "^4.0.0" + update-notifier "^2.5.0" + tslib@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" @@ -4985,6 +5791,13 @@ uniq@^1.0.1: resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= + dependencies: + crypto-random-string "^1.0.0" + universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" @@ -4998,6 +5811,27 @@ 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" + integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= + +update-notifier@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + 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" + uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" @@ -5010,6 +5844,13 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= +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" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -5039,6 +5880,14 @@ v8-to-istanbul@^4.0.1: convert-source-map "^1.6.0" source-map "^0.7.3" +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -5058,14 +5907,14 @@ vue-jest@vuejs/vue-jest#next: extract-from-css "^0.4.4" ts-jest "^24.0.0" -vue@^3.0.0-alpha.12: - version "3.0.0-alpha.12" - resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-alpha.12.tgz#b8eb8dd47822e8d4479bd2d4155a28f7b2c72689" - integrity sha512-EKMdt7MOSXLo6F6h8UHLI8GzW58qDyyKPLt4NV6GOzyjtSPdlx2j+ZsCe6C9d+NRXSvvf4RtUwpWqOZ/jGmZwg== +vue@^3.0.0-beta.2: + version "3.0.0-beta.2" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-beta.2.tgz#f808b498d10cbebe4007738aa2130bd0802f393d" + integrity sha512-/HYhK9i8PWM0fL38YflFK/vY1ots+JyNI2GZa8VtDqj4jD3+2UZ0CH0kjmw9YTmRtHdsU65CXGkVuA3EMV3mXQ== dependencies: - "@vue/compiler-dom" "3.0.0-alpha.12" - "@vue/runtime-dom" "3.0.0-alpha.12" - "@vue/shared" "3.0.0-alpha.12" + "@vue/compiler-dom" "3.0.0-beta.2" + "@vue/runtime-dom" "3.0.0-beta.2" + "@vue/shared" "3.0.0-beta.2" vuex@^4.0.0-alpha.1: version "4.0.0-alpha.1" @@ -5145,6 +5994,13 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== + dependencies: + string-width "^2.1.1" + word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -5172,6 +6028,15 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +write-file-atomic@^2.0.0: + version "2.4.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" + integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + write-file-atomic@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.1.tgz#558328352e673b5bb192cf86500d60b230667d4b" @@ -5187,6 +6052,11 @@ ws@^7.0.0: resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.1.tgz#03ed52423cd744084b2cf42ed197c8b65a936b8e" integrity sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A== +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= + xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" @@ -5202,6 +6072,11 @@ y18n@^4.0.0: resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" @@ -5214,7 +6089,7 @@ yaml@^1.7.2: dependencies: "@babel/runtime" "^7.8.7" -yargs-parser@10.x: +yargs-parser@10.x, yargs-parser@^10.0.0: version "10.1.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== From a1cdd1726f76e1f0348625b3854f9001b37585d7 Mon Sep 17 00:00:00 2001 From: Lachlan Miller Date: Tue, 21 Apr 2020 22:15:53 +1000 Subject: [PATCH 7/9] ts-ignore stuff --- tests/features/plugins.spec.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/features/plugins.spec.ts b/tests/features/plugins.spec.ts index b1071e1bf..c5ad04438 100644 --- a/tests/features/plugins.spec.ts +++ b/tests/features/plugins.spec.ts @@ -1,6 +1,8 @@ -import { mount, VueWrapper, config } from '../../src' +import { mount, config } from '../../src' +import { WrapperAPI } from '../../src/types' declare module '../../src/vue-wrapper' { + // @ts-ignore interface VueWrapper { width(): number $el: Element @@ -26,13 +28,14 @@ describe('Plugin', () => { }) it('receives the wrapper inside the plugin setup', () => { - const plugin = (wrapper) => { + const plugin = (wrapper: WrapperAPI) => { return { $el: wrapper.element // simple aliases } } config.plugins.VueWrapper.install(plugin) const wrapper = mountComponent() + // @ts-ignore expect(wrapper.$el.innerHTML).toEqual(textValue) }) @@ -40,6 +43,7 @@ describe('Plugin', () => { const myMethod = jest.fn() const plugin = () => ({ myMethod }) config.plugins.VueWrapper.install(plugin) + // @ts-ignore mountComponent().myMethod() expect(myMethod).toHaveBeenCalledTimes(1) }) From ce1c00c9e9e048177164faf5f4bad68dd5e6f112 Mon Sep 17 00:00:00 2001 From: Lachlan Miller Date: Fri, 24 Apr 2020 21:21:26 +1000 Subject: [PATCH 8/9] fix: update types --- tests/features/plugins.spec.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/features/plugins.spec.ts b/tests/features/plugins.spec.ts index c5ad04438..d8fd333b3 100644 --- a/tests/features/plugins.spec.ts +++ b/tests/features/plugins.spec.ts @@ -1,9 +1,10 @@ +import { ComponentPublicInstance } from 'vue' + import { mount, config } from '../../src' import { WrapperAPI } from '../../src/types' declare module '../../src/vue-wrapper' { - // @ts-ignore - interface VueWrapper { + interface VueWrapper { width(): number $el: Element myMethod(): void @@ -35,7 +36,6 @@ describe('Plugin', () => { } config.plugins.VueWrapper.install(plugin) const wrapper = mountComponent() - // @ts-ignore expect(wrapper.$el.innerHTML).toEqual(textValue) }) @@ -43,7 +43,6 @@ describe('Plugin', () => { const myMethod = jest.fn() const plugin = () => ({ myMethod }) config.plugins.VueWrapper.install(plugin) - // @ts-ignore mountComponent().myMethod() expect(myMethod).toHaveBeenCalledTimes(1) }) From 407a7570396646b518476cda19a10d04016b56f9 Mon Sep 17 00:00:00 2001 From: Lachlan Miller Date: Fri, 24 Apr 2020 21:25:55 +1000 Subject: [PATCH 9/9] fix: types --- src/types.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/types.ts b/src/types.ts index 117e4393b..ad1952cd7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -27,19 +27,6 @@ interface NameSelector { name: string } -export type FindComponentSelector = RefSelector | NameSelector | string -export type FindAllComponentsSelector = NameSelector | string - -export type GlobalMountOptions = { - plugins?: Plugin[] - mixins?: ComponentOptions[] - mocks?: Record - provide?: Record - components?: Record - directives?: Record - stubs?: Record -} - interface RefSelector { ref: string }