Ver código fonte

Upgrade flow libs to latest version

`flow-bin` and `flow-typed` NPM modules were upgraded.

Flow's new inference engine caught some previously missed type errors,
so some small updates to our declared types was necessary.
Sergiu Miclea 7 anos atrás
pai
commit
8885745dfc

+ 2 - 2
package.json

@@ -47,8 +47,8 @@
     "eslint-plugin-import": "^2.7.0",
     "eslint-plugin-jsx-a11y": "^6.0.2",
     "eslint-plugin-react": "^7.4.0",
-    "flow-bin": "^0.66.0",
-    "flow-typed": "^2.3.0",
+    "flow-bin": "0.78.0",
+    "flow-typed": "2.5.1",
     "jest": "^21.2.1",
     "react-test-renderer": "^16.0.0",
     "sinon": "^4.1.2",

+ 2 - 1
src/components/atoms/SearchButton/test.jsx

@@ -27,7 +27,8 @@ describe('SearchButton Component', () => {
     const getIconId = (w: TestWrapper): string => {
       /* eslint no-underscore-dangle: off */
       const iconSvg = w.find('icon').prop('dangerouslySetInnerHTML').__html
-      return /data-test-id="(.*?)"/g.exec(iconSvg)[1]
+      const iconSvgId = /data-test-id="(.*?)"/g.exec(iconSvg)
+      return iconSvgId ? iconSvgId[1] : ''
     }
     let wrapper = wrap()
     expect(getIconId(wrapper)).toBe('searchButton-searchIcon')

+ 1 - 0
src/components/atoms/StatusIcon/StatusIcon.jsx

@@ -34,6 +34,7 @@ type Props = {
   status: string,
   useBackground?: boolean,
   hollow?: boolean,
+  secondary?: boolean,
 }
 
 const getRunningImageUrl = (props: Props) => {

+ 1 - 1
src/components/molecules/DatetimePicker/test.jsx

@@ -21,7 +21,7 @@ import sinon from 'sinon'
 import TestWrapper from '../../../utils/TestWrapper'
 import DatetimePicker from '.'
 
-const wrap = props => new TestWrapper(shallow(<DatetimePicker {...props} />), 'datetimePicker')
+const wrap = props => new TestWrapper(shallow(<DatetimePicker timezone="local" {...props} />), 'datetimePicker')
 
 describe('DateTimePicker Component', () => {
   it('renders date value in dropdown label', () => {

+ 4 - 2
src/components/molecules/NewItemDropdown/NewItemDropdown.jsx

@@ -124,6 +124,8 @@ export type ItemType = {
   title: string,
   description: string,
   value?: string,
+  disabled?: boolean,
+  requiresAdmin?: boolean,
 }
 type Props = {
   onChange: (item: ItemType) => void,
@@ -198,13 +200,13 @@ class NewItemDropdown extends React.Component<Props, State> {
       value: 'user',
       description: 'Create a new Coriolis user',
       icon: { user: true },
-      disabled: navigationMenu.find(i => i.value === 'users' && (i.disabled || (i.requiresAdmin && !isAdmin))),
+      disabled: Boolean(navigationMenu.find(i => i.value === 'users' && (i.disabled || (i.requiresAdmin && !isAdmin)))),
     }, {
       title: 'Project',
       value: 'project',
       description: 'Create a new Coriolis project',
       icon: { project: true },
-      disabled: navigationMenu.find(i => i.value === 'projects' && (i.disabled || (i.requiresAdmin && !isAdmin))),
+      disabled: Boolean(navigationMenu.find(i => i.value === 'projects' && (i.disabled || (i.requiresAdmin && !isAdmin)))),
     }]
 
     let list = (

+ 1 - 1
src/components/molecules/PropertiesTable/PropertiesTable.jsx

@@ -111,7 +111,7 @@ class PropertiesTable extends React.Component<Props> {
           value: e,
         }
       } else if (e.separator === true) {
-        return e
+        return { separator: true }
       }
       return {
         label: e.name,

+ 2 - 2
src/components/molecules/ScheduleItem/ScheduleItem.jsx

@@ -61,7 +61,7 @@ const Label = styled.div`
   line-height: 35px;
   margin-bottom: -8px;
 `
-const DropdownStyled = styled(Dropdown) `
+const DropdownStyled = styled(Dropdown)`
   font-size: 12px;
 `
 const ItemButton = props => css`
@@ -176,7 +176,7 @@ class ScheduleItem extends React.Component<Props> {
     let isChanged = false
     executionOptions.forEach(o => {
       let scheduleValue = this.props.item[o.name]
-      let optionValue = o.value !== undefined ? o.value : false
+      let optionValue = o.defaultValue !== undefined ? o.defaultValue : false
       if (scheduleValue !== undefined && scheduleValue !== null && scheduleValue !== optionValue) {
         isChanged = true
       }

+ 1 - 1
src/components/molecules/WizardType/test.jsx

@@ -20,7 +20,7 @@ import sinon from 'sinon'
 import TW from '../../../utils/TestWrapper'
 import WizardType from '.'
 
-const wrap = props => new TW(shallow(<WizardType {...props} />), 'wType')
+const wrap = props => new TW(shallow(<WizardType onChange={() => { }} {...props} />), 'wType')
 
 describe('WizardType Component', () => {
   it('renders with the correct type selected', () => {

+ 2 - 2
src/components/organisms/EndpointDetailsContent/EndpointDetailsContent.jsx

@@ -14,7 +14,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 // @flow
 
-import React from 'react'
+import * as React from 'react'
 import { observer } from 'mobx-react'
 import styled from 'styled-components'
 
@@ -106,7 +106,7 @@ class EndpointDetailsContent extends React.Component<Props> {
     )
   }
 
-  renderConnectionInfo(connectionInfo: any) {
+  renderConnectionInfo(connectionInfo: any): React$Node {
     if (!connectionInfo) {
       return null
     }

+ 13 - 11
src/components/organisms/Navigation/Navigation.jsx

@@ -31,7 +31,7 @@ const Wrapper = styled.div`
   height: 100%;
 `
 
-const LogoStyled = styled(Logo) `
+const LogoStyled = styled(Logo)`
   margin: 40px auto 0 30px;
   cursor: pointer;
 `
@@ -59,16 +59,18 @@ class Navigation extends React.Component<{ currentPage: string }> {
     const isAdmin = userStore.loggedUser ? userStore.loggedUser.isAdmin : false
     return (
       <Menu>
-        {navigationMenu.filter(i => i.disabled ? !i.disabled : i.requiresAdmin ? isAdmin : true).map(item => {
-          return (
-            <MenuItem
-              key={item.value}
-              selected={this.props.currentPage === item.value}
-              href={`/#/${item.value}`}
-              data-test-id={`navigation-item-${item.value}`}
-            >{item.label}</MenuItem>
-          )
-        })}
+        {
+          // $FlowIgnore
+          navigationMenu.filter(i => i.disabled ? !i.disabled : i.requiresAdmin ? isAdmin : true).map(item => {
+            return (
+              <MenuItem
+                key={item.value}
+                selected={this.props.currentPage === item.value}
+                href={`/#/${item.value}`}
+                data-test-id={`navigation-item-${item.value}`}
+              >{item.label}</MenuItem>
+            )
+          })}
       </Menu>
     )
   }

+ 1 - 1
src/components/organisms/ReplicaExecutionOptions/test.jsx

@@ -35,7 +35,7 @@ describe('ReplicaExecutionOptions Component', () => {
   it('renders executionOptions with default values', () => {
     let wrapper = wrap()
     executionOptions.forEach(option => {
-      expect(wrapper.find(`option-${option.name}`).prop('value')).toBe(option.value || undefined)
+      expect(wrapper.find(`option-${option.name}`).prop('value')).toBe(option.defaultValue || undefined)
     })
   })
 

+ 1 - 1
src/components/organisms/ReplicaMigrationOptions/test.jsx

@@ -20,7 +20,7 @@ import sinon from 'sinon'
 import TW from '../../../utils/TestWrapper'
 import ReplicaMigrationOptions from '.'
 
-const wrap = props => new TW(shallow(<ReplicaMigrationOptions {...props} />), 'rmOptions')
+const wrap = props => new TW(shallow(<ReplicaMigrationOptions onMigrateClick={() => { }} {...props} />), 'rmOptions')
 
 describe('ReplicaMigrationOptions Component', () => {
   it('dispatches cancel click', () => {

+ 1 - 1
src/components/organisms/Schedule/Schedule.jsx

@@ -205,7 +205,7 @@ class Schedule extends React.Component<Props, State> {
     let isChanged = false
     executionOptions.forEach(o => {
       let scheduleValue = schedule[o.name]
-      let optionValue = o.value !== undefined ? o.value : false
+      let optionValue = o.defaultValue !== undefined ? o.defaultValue : false
       if (scheduleValue !== undefined && scheduleValue !== null && scheduleValue !== optionValue) {
         isChanged = true
       }

+ 1 - 1
src/components/organisms/UserDetailsContent/UserDetailsContent.jsx

@@ -143,7 +143,7 @@ class UserDetailsContent extends React.Component<Props, State> {
     )
   }
 
-  renderUserProjects(projects: { label: string, id: string }[]) {
+  renderUserProjects(projects: { label: string, id: string }[]): React$Node {
     return projects.map((project, i) => (
       <span key={project.id}>
         {project.label ? (

+ 1 - 1
src/components/pages/AssessmentsPage/AssessmentsPage.jsx

@@ -99,7 +99,7 @@ class AssessmentsPage extends React.Component<Props, State> {
     }
   }
 
-  getFilterItems() {
+  getFilterItems(): { label: string, value: string }[] {
     let types = [{ label: 'All projects', value: 'all' }]
     let assessments = azureStore.assessments
     let uniqueProjects = []

+ 11 - 10
src/components/pages/EndpointsPage/EndpointsPage.jsx

@@ -189,16 +189,17 @@ class EndpointsPage extends React.Component<{}, State> {
     }).then(() => {
       return Promise.all(endpoints.map(endpoint => {
         return EndpointSource.add(endpoint, true)
-      }).map(p => p.catch(e => e))).then(results => {
-        let internalServerErrors = results.filter(r => r.status && r.status === 500)
-        if (internalServerErrors.length > 0) {
-          notificationStore.alert(`There was a problem duplicating ${internalServerErrors.length} endpoint${internalServerErrors.length > 1 ? 's' : ''}`, 'error')
-        }
-        let forbiddenErrors = results.filter(r => r.status && r.status === 403)
-        if (forbiddenErrors.length > 0 && forbiddenErrors[0].data && forbiddenErrors[0].data.description) {
-          notificationStore.alert(String(forbiddenErrors[0].data.description), 'error')
-        }
-      })
+      }).map((p: Promise<any>) => p.catch(e => e)))
+        .then((results: (Endpoint | { status: string, data?: { description: string } })[]) => {
+          let internalServerErrors = results.filter(r => r.status && r.status === 500)
+          if (internalServerErrors.length > 0) {
+            notificationStore.alert(`There was a problem duplicating ${internalServerErrors.length} endpoint${internalServerErrors.length > 1 ? 's' : ''}`, 'error')
+          }
+          let forbiddenErrors = results.filter(r => r.status && r.status === 403)
+          if (forbiddenErrors.length > 0 && forbiddenErrors[0].data && forbiddenErrors[0].data.description) {
+            notificationStore.alert(String(forbiddenErrors[0].data.description), 'error')
+          }
+        })
     }).catch(e => {
       if (e.data && e.data.description) {
         notificationStore.alert(e.data.description, 'error')

+ 1 - 0
src/config.js

@@ -70,6 +70,7 @@ export const executionOptions = [
   {
     name: 'shutdown_instances',
     type: 'strict-boolean',
+    defaultValue: false,
   },
 ]
 

+ 1 - 1
src/index.js

@@ -33,8 +33,8 @@ if (root) {
   render(renderApp(), root)
 }
 
+// $FlowIgnore
 if (module.hot) {
-  // $FlowIgnore
   module.hot.accept('./components/App.jsx', () => {
     require('./components/App.jsx')
     if (root) {

+ 0 - 1
src/plugins/endpoint/default/OptionsSchemaPlugin.js

@@ -23,7 +23,6 @@ const migrationImageOsTypes = ['windows', 'linux']
 
 export const defaultFillFieldValues = (field: Field, option: DestinationOption) => {
   if (field.type === 'string') {
-    // $FlowIgnore
     field.enum = [...option.values]
     if (option.config_default) {
       field.default = typeof option.config_default === 'string' ? option.config_default : option.config_default.id

+ 2 - 4
src/sources/ProviderSource.js

@@ -51,10 +51,8 @@ class ProviderSource {
       envString = `?env=${btoa(JSON.stringify(envData))}`
     }
 
-    return Api.get(`${servicesUrl.coriolis}/${Api.projectId}/endpoints/${endpointId}/destination-options${envString}`).then(response => {
-      let options = response.data.destination_options
-      return options
-    })
+    return Api.get(`${servicesUrl.coriolis}/${Api.projectId}/endpoints/${endpointId}/destination-options${envString}`)
+      .then(response => response.data.destination_options)
   }
 }
 

+ 1 - 3
src/sources/ScheduleSource.js

@@ -117,10 +117,8 @@ class ScheduleSource {
       if (scheduleOldData) {
         payload.schedule = { ...scheduleOldData.schedule }
       }
-      // $FlowIssue
       Object.keys(unsavedData.schedule).forEach(prop => {
-        // $FlowIssue
-        if (unsavedData.schedule[prop] !== null && unsavedData.schedule[prop] !== undefined) {
+        if (unsavedData && unsavedData.schedule && unsavedData.schedule[prop] !== null && unsavedData.schedule[prop] !== undefined) {
           payload.schedule[prop] = unsavedData.schedule[prop]
         } else {
           delete payload.schedule[prop]

+ 4 - 3
src/sources/WizardSource.js

@@ -69,8 +69,8 @@ class WizardSource {
     if (!hashExp.test(window.location.hash)) {
       return
     }
-
-    let hash = hashExp.exec(window.location.hash)[1]
+    let hashExpExec = hashExp.exec(window.location.hash)
+    let hash = hashExpExec ? hashExpExec[1] : 'undefined'
     window.history.replaceState({}, null, `${hash}?d=${btoa(JSON.stringify(data))}`)
   }
 
@@ -81,7 +81,8 @@ class WizardSource {
       return null
     }
 
-    return JSON.parse(atob(dataExp.exec(window.location.hash)[1]))
+    let dataExpExec = dataExp.exec(window.location.hash)
+    return JSON.parse(atob(dataExpExec ? dataExpExec[1] : 'undefined'))
   }
 }
 

+ 3 - 2
src/types/Assessment.js

@@ -46,6 +46,7 @@ export type Assessment = {
   projectName: string,
   resourceGroupName: string,
   groupName: string,
+  assessmentName: string,
   location: string,
   properties: {
     azureLocation: string,
@@ -70,7 +71,7 @@ export type MigrationInfo = {
   source: ?Endpoint,
   target: Endpoint,
   selectedInstances: Instance[],
-  destinationEnv: {[string]: mixed},
+  destinationEnv: { [string]: mixed },
   networks: NetworkMap[],
-  vmSizes: {[string]: VmSize},
+  vmSizes: { [string]: VmSize },
 }

+ 1 - 0
src/types/NotificationItem.js

@@ -24,6 +24,7 @@ export type AlertInfo = {
     }
   },
   message: string,
+  title?: string,
   id?: string,
   level?: 'success' | 'error' | 'info',
 }

+ 2 - 0
src/types/Schema.js

@@ -34,11 +34,13 @@ export type SchemaProperties = {
     } | {
       type: string,
       enum?: string[],
+      default?: string,
     } | {
       $ref: string,
     },
   },
   required: string[],
+  type?: string,
 }
 
 export type SchemaDefinitions = {

+ 1 - 0
src/types/User.js

@@ -27,6 +27,7 @@ export type User = {
   project_id?: string,
   domain_id?: string,
   isAdmin?: boolean,
+  password?: string,
 }
 
 export type Credentials = {

+ 2 - 1
src/utils/DomUtils.js

@@ -59,9 +59,10 @@ class DomUtils {
   static getEventPath(event: Event): HTMLElement[] {
     let path = []
     let node = event.target
+    // $FlowIgnore
     while (node !== document.body && node.parentNode) {
       path.push(node)
-      // $FlowIssue
+      // $FlowIgnore
       node = node.parentNode
     }
 

+ 66 - 17
yarn.lock

@@ -22,6 +22,19 @@
   version "3.0.9"
   resolved "https://registry.yarnpkg.com/@hypnosphi/fuse.js/-/fuse.js-3.0.9.tgz#ea99f6121b4a8f065b4c71f85595db2714498807"
 
+"@octokit/rest@^15.2.6":
+  version "15.9.5"
+  resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-15.9.5.tgz#e356d202bd0b517e381f705ad77d98ccb84e0c65"
+  dependencies:
+    before-after-hook "^1.1.0"
+    btoa-lite "^1.0.0"
+    debug "^3.1.0"
+    http-proxy-agent "^2.1.0"
+    https-proxy-agent "^2.2.0"
+    lodash "^4.17.4"
+    node-fetch "^2.1.1"
+    url-template "^2.0.8"
+
 "@storybook/addon-actions@^3.2.15":
   version "3.2.15"
   resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-3.2.15.tgz#a54228d86baeb637adbbbdd11ff0c040d9862952"
@@ -330,6 +343,12 @@ adal-node@^0.1.25:
     xmldom ">= 0.1.x"
     xpath.js "~1.0.5"
 
+agent-base@4, agent-base@^4.1.0:
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9"
+  dependencies:
+    es6-promisify "^5.0.0"
+
 airbnb-js-shims@^1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-1.3.0.tgz#aac46d80057fb0b414f70e06d07e362fd99ee2fa"
@@ -1737,6 +1756,10 @@ bcrypt-pbkdf@^1.0.0:
   dependencies:
     tweetnacl "^0.14.3"
 
+before-after-hook@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.1.0.tgz#83165e15a59460d13702cb8febd6a1807896db5a"
+
 big-integer@^1.6.17:
   version "1.6.28"
   resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.28.tgz#8cef0fda3ccde8759c2c66efcfacc35aea658283"
@@ -1927,6 +1950,10 @@ bser@^2.0.0:
   dependencies:
     node-int64 "^0.4.0"
 
+btoa-lite@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337"
+
 buffer-crc32@~0.2.3:
   version "0.2.13"
   resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
@@ -3113,6 +3140,16 @@ es6-map@^0.1.3:
     es6-symbol "~3.1.1"
     event-emitter "~0.3.5"
 
+es6-promise@^4.0.3:
+  version "4.2.4"
+  resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29"
+
+es6-promisify@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
+  dependencies:
+    es6-promise "^4.0.3"
+
 es6-set@~0.1.5:
   version "0.1.5"
   resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
@@ -3676,18 +3713,18 @@ flatten@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
 
-flow-bin@^0.66.0:
-  version "0.66.0"
-  resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.66.0.tgz#a96dde7015dc3343fd552a7b4963c02be705ca26"
+flow-bin@0.78.0:
+  version "0.78.0"
+  resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.78.0.tgz#df9fe7f9c9a2dfaff39083949fe2d831b41627b7"
 
-flow-typed@^2.3.0:
-  version "2.4.0"
-  resolved "https://registry.yarnpkg.com/flow-typed/-/flow-typed-2.4.0.tgz#3d2f48cf85df29df3bca6745b623726496ff4788"
+flow-typed@2.5.1:
+  version "2.5.1"
+  resolved "https://registry.yarnpkg.com/flow-typed/-/flow-typed-2.5.1.tgz#0ff565cc94d2af8c557744ba364b6f14726a6b9f"
   dependencies:
+    "@octokit/rest" "^15.2.6"
     babel-polyfill "^6.26.0"
     colors "^1.1.2"
     fs-extra "^5.0.0"
-    github "0.2.4"
     glob "^7.1.2"
     got "^7.1.0"
     md5 "^2.1.0"
@@ -3862,12 +3899,6 @@ getpass@^0.1.1:
   dependencies:
     assert-plus "^1.0.0"
 
-github@0.2.4:
-  version "0.2.4"
-  resolved "https://registry.yarnpkg.com/github/-/github-0.2.4.tgz#24fa7f0e13fa11b946af91134c51982a91ce538b"
-  dependencies:
-    mime "^1.2.11"
-
 glamor@^2.20.40:
   version "2.20.40"
   resolved "https://registry.yarnpkg.com/glamor/-/glamor-2.20.40.tgz#f606660357b7cf18dface731ad1a2cfa93817f05"
@@ -4223,6 +4254,13 @@ http-errors@1.6.2, http-errors@~1.6.2:
     setprototypeof "1.0.3"
     statuses ">= 1.3.1 < 2"
 
+http-proxy-agent@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
+  dependencies:
+    agent-base "4"
+    debug "3.1.0"
+
 http-signature@~1.1.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
@@ -4243,6 +4281,13 @@ https-browserify@0.0.1:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82"
 
+https-proxy-agent@^2.2.0:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
+  dependencies:
+    agent-base "^4.1.0"
+    debug "^3.1.0"
+
 hyphenate-style-name@^1.0.1, hyphenate-style-name@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b"
@@ -5508,10 +5553,6 @@ mime@1.4.1, mime@^1.3.4, mime@^1.4.1:
   version "1.4.1"
   resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
 
-mime@^1.2.11:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
-
 mimic-fn@^1.0.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
@@ -5687,6 +5728,10 @@ node-fetch@^1.0.1:
     encoding "^0.1.11"
     is-stream "^1.0.1"
 
+node-fetch@^2.1.1:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.2.0.tgz#4ee79bde909262f9775f731e3656d0db55ced5b5"
+
 node-int64@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
@@ -8146,6 +8191,10 @@ url-parse-lax@^1.0.0:
   dependencies:
     prepend-http "^1.0.1"
 
+url-template@^2.0.8:
+  version "2.0.8"
+  resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21"
+
 url-to-options@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"