diff --git a/.travis.yml b/.travis.yml index d1959fd..690e9ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,3 +6,4 @@ node_js: script: - yarn test --coverage --coverageReporters=text-lcov | coveralls + - yarn build && bundlewatch --max-size 20kb ./dist/!(*.map) diff --git a/docs/.vuepress/components/CustomHandlers.vue b/docs/.vuepress/components/CustomHandlers.vue new file mode 100644 index 0000000..8fa43e8 --- /dev/null +++ b/docs/.vuepress/components/CustomHandlers.vue @@ -0,0 +1,25 @@ + + + diff --git a/docs/.vuepress/components/TagOnComma.vue b/docs/.vuepress/components/TagOnComma.vue new file mode 100644 index 0000000..59e1d6a --- /dev/null +++ b/docs/.vuepress/components/TagOnComma.vue @@ -0,0 +1,4 @@ + diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 583ba3d..1f2e6a0 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -123,6 +123,13 @@ module.exports = { ['guide/loops', 'Using in Loops'], ], }, + { + title: 'Customizing', + collapsable: false, + children: [ + ['guide/keydown', 'Keydown Events'], + ], + }, { title: 'API', collapsable: false, diff --git a/docs/guide/keydown.md b/docs/guide/keydown.md new file mode 100644 index 0000000..b353960 --- /dev/null +++ b/docs/guide/keydown.md @@ -0,0 +1,73 @@ +### Customizing Keydown Behaviour +--- + +## selectOnKeyCodes + +`selectOnKeyCodes {Array}` is an array of keyCodes that will trigger a typeAheadSelect. Any keyCodes + in this array will prevent the default event action and trigger a typeahead select. By default, + it's just `[13]` for return. For example, maybe you want to tag on a comma keystroke: + + + +<<< @/.vuepress/components/TagOnComma.vue + +## mapKeyDown + +Vue Select provides the `map-keydown` Function prop to allow for customizing the components response to +keydown events while the search input has focus. + +```js +/** + * @param map {Object} Mapped keyCode to handlers { : } + * @param vm {VueSelect} + * @return {Object} + */ +(map, vm) => map, +``` + +By default, the prop is a no–op returning the same object `map` object it receives. This object +maps keyCodes to handlers: `{ : }`. Modifying this object can override default +functionality, or add handlers for different keys that the component doesn't normally listen for. + +Note that any keyCodes you've added to `selectOnKeyCodes` will be passed to `map-keydown` as well, +so `map-keydown` will always take precedence. + +**Default Handlers** + +```js +// delete +8: e => this.maybeDeleteValue() + +// tab +9: e => this.onTab() + +// enter +13: e => { + e.preventDefault(); + return this.typeAheadSelect(); +} + +// esc +27: e => this.onEscape() + +// up +38: e => { + e.preventDefault(); + return this.typeAheadUp(); +} + +// down +40: e => { + e.preventDefault(); + return this.typeAheadDown(); +} +``` + +### Example: Autocomplete Email Addresses + +This is example listens for the `@` key, and autocompletes an email address with `@gmail.com`. + + + +<<< @/.vuepress/components/CustomHandlers.vue + diff --git a/docs/guide/upgrading.md b/docs/guide/upgrading.md index e16128a..db720e2 100644 --- a/docs/guide/upgrading.md +++ b/docs/guide/upgrading.md @@ -69,10 +69,10 @@ has always provided the same parameters and can be used in it's place. ``` -### `onSearch` with null search string +### `@search` with null search string -The `onSearch` callback is now fired anytime the search string changes. In v2.x, the component -would first check if the search string was empty, and only run the callback if it had at least one +The `@search` event is now fired anytime the search string changes. In v2.x, the component +would first check if the search string was empty, and only emit the event if it had at least one character. This was a design mistake, as it should be the consumers decision if a search should be run on an empty string. diff --git a/package.json b/package.json index deefd80..beb7fd1 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "autoprefixer": "^9.4.7", "babel-core": "^7.0.0-bridge.0", "babel-loader": "^8.0.5", + "bundlewatch": "^0.2.5", "chokidar": "^2.1.5", "coveralls": "^3.0.2", "cross-env": "^5.2.0", diff --git a/src/components/Select.vue b/src/components/Select.vue index 9ef97c6..047fcb3 100644 --- a/src/components/Select.vue +++ b/src/components/Select.vue @@ -20,7 +20,7 @@ -
+
[13], + }, + /** * Query Selector used to find the search input * when the 'search' scoped slot is used. @@ -529,6 +538,21 @@ searchInputQuerySelector: { type: String, default: '[type=search]' + }, + + /** + * Used to modify the default keydown events map + * for the search input. Can be used to implement + * custom behaviour for key presses. + */ + mapKeydown: { + type: Function, + /** + * @param map {Object} + * @param vm {VueSelect} + * @return {Object} + */ + default: (map, vm) => map, } }, @@ -536,6 +560,7 @@ return { search: '', open: false, + isComposing: false, pushedTags: [], _value: [] // Internal value managed by Vue Select if no `value` prop is passed } @@ -613,7 +638,8 @@ select(option) { if (!this.isOptionSelected(option)) { if (this.taggable && !this.optionExists(option)) { - option = this.createOption(option) + option = this.createOption(option); + this.$emit('option:created', option); } if (this.multiple) { option = this.selectedValue.concat(option) @@ -695,6 +721,8 @@ this.$el, this.searchEl, this.$refs.toggle, + this.$refs.actions, + this.$refs.selectedOptions, ]; if (typeof this.$refs.openIndicator !== 'undefined') { @@ -902,39 +930,46 @@ }, /** - * Search 'input' KeyBoardEvent handler. + * Search KeyBoardEvent handler. * @param e {KeyboardEvent} * @return {Function} */ onSearchKeyDown (e) { - switch (e.keyCode) { - case 8: - // delete - return this.maybeDeleteValue(); - case 9: - // tab - return this.onTab(); - case 13: - // enter.prevent - e.preventDefault(); - return this.typeAheadSelect(); - case 27: - // esc - return this.onEscape(); - case 38: - // up.prevent + const preventAndSelect = e => { + e.preventDefault(); + return !this.isComposing && this.typeAheadSelect(); + }; + + const defaults = { + // delete + 8: e => this.maybeDeleteValue(), + // tab + 9: e => this.onTab(), + // esc + 27: e => this.onEscape(), + // up.prevent + 38: e => { e.preventDefault(); return this.typeAheadUp(); - case 40: - // down.prevent + }, + // down.prevent + 40: e => { e.preventDefault(); return this.typeAheadDown(); + }, + }; + + this.selectOnKeyCodes.forEach(keyCode => defaults[keyCode] = preventAndSelect); + + const handlers = this.mapKeydown(defaults, this); + + if (typeof handlers[e.keyCode] === 'function') { + return handlers[e.keyCode](e); } } }, computed: { - /** * Determine if the component needs to * track the state of values internally. @@ -1018,6 +1053,8 @@ 'value': this.search, }, events: { + 'compositionstart': () => this.isComposing = true, + 'compositionend': () => this.isComposing = false, 'keydown': this.onSearchKeyDown, 'blur': this.onSearchBlur, 'focus': this.onSearchFocus, diff --git a/src/scss/modules/_search-input.scss b/src/scss/modules/_search-input.scss index 252b858..8616b49 100644 --- a/src/scss/modules/_search-input.scss +++ b/src/scss/modules/_search-input.scss @@ -3,8 +3,16 @@ $line-height: $vs-component-line-height; $font-size: 1em; +/** + * Super weird bug... If this declaration is grouped + * below, the cancel button will still appear in chrome. + * If it's up here on it's own, it'll hide it. + */ +.vs__search::-webkit-search-cancel-button { + display: none; +} + .vs__search::-webkit-search-decoration, -.vs__search::-webkit-search-cancel-button, .vs__search::-webkit-search-results-button, .vs__search::-webkit-search-results-decoration, .vs__search::-ms-clear { diff --git a/tests/unit/Keydown.spec.js b/tests/unit/Keydown.spec.js new file mode 100644 index 0000000..4721719 --- /dev/null +++ b/tests/unit/Keydown.spec.js @@ -0,0 +1,74 @@ +import { mountDefault } from '../helpers'; + +describe('Custom Keydown Handlers', () => { + + it('can use the map-keydown prop to trigger custom behaviour', () => { + const onKeyDown = jest.fn(); + const Select = mountDefault({ + mapKeydown: (defaults, vm) => ({...defaults, 32: onKeyDown}), + }); + + Select.find({ref: 'search'}).trigger('keydown.space'); + + expect(onKeyDown.mock.calls.length).toBe(1); + }); + + it('selectOnKeyCodes should trigger a selection for custom keycodes', () => { + const Select = mountDefault({ + selectOnKeyCodes: [32], + }); + + const spy = jest.spyOn(Select.vm, 'typeAheadSelect'); + + Select.find({ref: 'search'}).trigger('keydown.space'); + + expect(spy).toHaveBeenCalledTimes(1); + }); + + it('even works when combining selectOnKeyCodes with map-keydown', () => { + const onKeyDown = jest.fn(); + const Select = mountDefault({ + mapKeydown: (defaults, vm) => ({...defaults, 32: onKeyDown}), + selectOnKeyCodes: [9], + }); + + const spy = jest.spyOn(Select.vm, 'typeAheadSelect'); + + Select.find({ref: 'search'}).trigger('keydown.space'); + expect(onKeyDown.mock.calls.length).toBe(1); + + Select.find({ref: 'search'}).trigger('keydown.tab'); + expect(spy).toHaveBeenCalledTimes(1); + }); + + describe('CompositionEvent support', () => { + + it('will not select a value with enter if the user is composing', () => { + const Select = mountDefault(); + const spy = jest.spyOn(Select.vm, 'typeAheadSelect'); + + Select.find({ref: 'search'}).trigger('compositionstart'); + Select.find({ref: 'search'}).trigger('keydown.enter'); + expect(spy).toHaveBeenCalledTimes(0); + + Select.find({ref: 'search'}).trigger('compositionend'); + Select.find({ref: 'search'}).trigger('keydown.enter'); + expect(spy).toHaveBeenCalledTimes(1); + }); + + it('will not select a value with tab if the user is composing', () => { + const Select = mountDefault({selectOnTab: true}); + const spy = jest.spyOn(Select.vm, 'typeAheadSelect'); + + Select.find({ref: 'search'}).trigger('compositionstart'); + Select.find({ref: 'search'}).trigger('keydown.tab'); + expect(spy).toHaveBeenCalledTimes(0); + + Select.find({ref: 'search'}).trigger('compositionend'); + Select.find({ref: 'search'}).trigger('keydown.tab'); + expect(spy).toHaveBeenCalledTimes(1); + }); + + }); + +}); diff --git a/tests/unit/Selectable.spec.js b/tests/unit/Selectable.spec.js index b8158eb..11d7663 100644 --- a/tests/unit/Selectable.spec.js +++ b/tests/unit/Selectable.spec.js @@ -4,7 +4,7 @@ describe("Selectable prop", () => { it("should select selectable option if clicked", () => { const Select = selectWithProps({ options: ["one", "two", "three"], - selectable: (option) => option == "one" + selectable: (option) => option === "one" }); Select.vm.$data.open = true; @@ -16,7 +16,7 @@ describe("Selectable prop", () => { it("should not select not selectable option if clicked", () => { const Select = selectWithProps({ options: ["one", "two", "three"], - selectable: (option) => option == "one" + selectable: (option) => option === "one" }); Select.vm.$data.open = true; diff --git a/tests/unit/Tagging.spec.js b/tests/unit/Tagging.spec.js index d7c8de8..f0e2176 100755 --- a/tests/unit/Tagging.spec.js +++ b/tests/unit/Tagging.spec.js @@ -80,6 +80,20 @@ describe("When Tagging Is Enabled", () => { expect(Select.vm.optionList).toEqual(["one", "two", "three"]); }); + it("should pushTags even if the consumer has defined a createOption callback", () => { + const Select = selectWithProps({ + pushTags: true, + taggable: true, + createOption: option => option, + options: ["one", "two"] + }); + + searchSubmit(Select, "three"); + + expect(Select.vm.pushedTags).toEqual(["three"]); + expect(Select.vm.optionList).toEqual(["one", "two", "three"]); + }); + it("should add a freshly created option/tag to the options list when pushTags is true and filterable is false", () => { const Select = selectWithProps({ filterable: false, diff --git a/yarn.lock b/yarn.lock index 9822a2e..e108df5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1403,6 +1403,14 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== +axios@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" + integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ== + dependencies: + follow-redirects "1.5.10" + is-buffer "^2.0.2" + babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" @@ -1791,12 +1799,27 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= +bundlewatch@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/bundlewatch/-/bundlewatch-0.2.5.tgz#c5fd76fb29ca2e324cf3282733fbc7be07863fc0" + integrity sha512-woAzcef9345Y9yC3lxkkKDZfjIbAV7jGt8Je4FL9WlkS6R3n/39v2cIfivkgN2zRDH9l88sRuWxvyvgr9U90Gg== + dependencies: + axios "^0.19.0" + bytes "^3.0.0" + chalk "^2.4.0" + commander "^2.15.1" + glob "^7.1.2" + gzip-size "^4.0.0" + jsonpack "^1.1.5" + lodash.merge "^4.6.1" + read-pkg-up "^3.0.0" + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= -bytes@3.1.0: +bytes@3.1.0, bytes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== @@ -1932,7 +1955,7 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" -chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2181,6 +2204,11 @@ commander@2.9.x: dependencies: graceful-readlink ">= 1.0.0" +commander@^2.15.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" @@ -2683,6 +2711,13 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8: dependencies: ms "2.0.0" +debug@=3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + debug@^3.0.0, debug@^3.2.5, debug@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" @@ -2940,6 +2975,11 @@ dot-prop@^4.1.1: dependencies: is-obj "^1.0.0" +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + duplexify@^3.4.2, duplexify@^3.6.0: version "3.7.1" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" @@ -3402,6 +3442,13 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.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" @@ -3427,6 +3474,13 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + follow-redirects@^1.0.0: version "1.8.1" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.8.1.tgz#24804f9eaab67160b0e840c085885d606371a35b" @@ -3684,6 +3738,14 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= +gzip-size@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-4.1.0.tgz#8ae096257eabe7d69c45be2b67c448124ffb517c" + integrity sha1-iuCWJX6r59acRb4rZ8RIEk/7UXw= + dependencies: + duplexer "^0.1.1" + pify "^3.0.0" + handle-thing@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" @@ -4234,6 +4296,11 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-buffer@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" + integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== + is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" @@ -5031,6 +5098,11 @@ json5@^2.1.0: dependencies: minimist "^1.2.0" +jsonpack@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/jsonpack/-/jsonpack-1.1.5.tgz#d42b0dcfd91ac58ef3110f96d2c599404c3dc27c" + integrity sha1-1CsNz9kaxY7zEQ+W0sWZQEw9wnw= + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -5162,6 +5234,14 @@ loader-utils@^0.2.16: json5 "^0.5.0" object-assign "^4.0.1" +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" @@ -5180,6 +5260,11 @@ lodash.memoize@^4.1.2: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= +lodash.merge@^4.6.1: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -6062,6 +6147,13 @@ p-is-promise@^2.0.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== +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.2.1" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" @@ -6069,6 +6161,13 @@ p-limit@^2.0.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" @@ -6093,6 +6192,11 @@ p-retry@^3.0.1: dependencies: retry "^0.12.0" +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" @@ -6899,6 +7003,14 @@ read-pkg-up@^1.0.1: find-up "^1.0.0" read-pkg "^1.0.0" +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"