summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2019-02-04 16:50:23 +0100
committerAndrej Mihajlov <and@mullvad.net>2019-02-04 16:50:23 +0100
commit54142b0fa0b26a33d8e6181a61e03b4b46abda00 (patch)
tree743b3c7bb19ba93730d329441ddeee51de5174b1
parentf97c5621fad66ae9768dad8cc422bc3a61f76ef6 (diff)
parent612952ba1d3a277863d0d35c5285890698939d1d (diff)
downloadmullvadvpn-54142b0fa0b26a33d8e6181a61e03b4b46abda00.tar.xz
mullvadvpn-54142b0fa0b26a33d8e6181a61e03b4b46abda00.zip
Merge branch 'typescript'
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml6
-rw-r--r--README.md1
-rw-r--r--appveyor_gui.yml2
-rw-r--r--gui/.eslintignore2
-rw-r--r--gui/.eslintrc55
-rw-r--r--gui/.flowconfig14
-rw-r--r--gui/flow-libs/electron.js.flow270
-rw-r--r--gui/flow-libs/tests.js.flow13
-rw-r--r--gui/package.json10
-rw-r--r--gui/packages/components/.babelrc12
-rw-r--r--gui/packages/components/package.json22
-rw-r--r--gui/packages/components/src/Accordion.tsx8
-rw-r--r--gui/packages/components/src/HeaderBar.tsx2
-rw-r--r--gui/packages/components/src/ImageView.tsx15
-rw-r--r--gui/packages/components/src/Modal.tsx2
-rw-r--r--gui/packages/components/src/SecuredLabel.tsx2
-rw-r--r--gui/packages/components/test/.eslintrc12
-rw-r--r--gui/packages/components/test/setup.ts8
-rw-r--r--gui/packages/components/tsconfig.json21
-rw-r--r--gui/packages/components/tslint.json12
-rw-r--r--gui/packages/config/package.json5
-rw-r--r--gui/packages/config/tsconfig.json17
-rw-r--r--gui/packages/config/tslint.json13
-rw-r--r--gui/packages/desktop/.babelrc13
-rw-r--r--gui/packages/desktop/assets/css/fonts.css (renamed from gui/packages/desktop/src/assets/css/fonts.css)0
-rw-r--r--gui/packages/desktop/assets/css/global.css (renamed from gui/packages/desktop/src/assets/css/global.css)0
-rw-r--r--gui/packages/desktop/assets/css/reset.css (renamed from gui/packages/desktop/src/assets/css/reset.css)0
-rw-r--r--gui/packages/desktop/assets/css/style.css8
-rwxr-xr-xgui/packages/desktop/assets/fonts/DINPro-Black.otf (renamed from gui/packages/desktop/src/assets/fonts/DINPro-Black.otf)bin88940 -> 88940 bytes
-rwxr-xr-xgui/packages/desktop/assets/fonts/DINPro-Bold.otf (renamed from gui/packages/desktop/src/assets/fonts/DINPro-Bold.otf)bin90228 -> 90228 bytes
-rwxr-xr-xgui/packages/desktop/assets/fonts/OpenSans-ExtraBold.ttf (renamed from gui/packages/desktop/src/assets/fonts/OpenSans-ExtraBold.ttf)bin222584 -> 222584 bytes
-rwxr-xr-xgui/packages/desktop/assets/fonts/OpenSans-Semibold.ttf (renamed from gui/packages/desktop/src/assets/fonts/OpenSans-Semibold.ttf)bin221328 -> 221328 bytes
-rw-r--r--gui/packages/desktop/assets/geo/cities.rbush.json (renamed from gui/packages/desktop/src/assets/geo/cities.rbush.json)0
-rw-r--r--gui/packages/desktop/assets/geo/countries.rbush.json (renamed from gui/packages/desktop/src/assets/geo/countries.rbush.json)0
-rw-r--r--gui/packages/desktop/assets/geo/geometry.json (renamed from gui/packages/desktop/src/assets/geo/geometry.json)0
-rw-r--r--gui/packages/desktop/assets/geo/geometry.rbush.json (renamed from gui/packages/desktop/src/assets/geo/geometry.rbush.json)0
-rw-r--r--gui/packages/desktop/assets/geo/states-provinces-lines.json (renamed from gui/packages/desktop/src/assets/geo/states-provinces-lines.json)0
-rw-r--r--gui/packages/desktop/assets/geo/states-provinces-lines.rbush.json (renamed from gui/packages/desktop/src/assets/geo/states-provinces-lines.rbush.json)0
-rw-r--r--gui/packages/desktop/assets/images/app-header-backdrop.svg (renamed from gui/packages/desktop/src/assets/images/app-header-backdrop.svg)0
-rw-r--r--gui/packages/desktop/assets/images/app-triangle.svg (renamed from gui/packages/desktop/src/assets/images/app-triangle.svg)0
-rw-r--r--gui/packages/desktop/assets/images/icon-alert.svg (renamed from gui/packages/desktop/src/assets/images/icon-alert.svg)0
-rwxr-xr-xgui/packages/desktop/assets/images/icon-arrow.svg (renamed from gui/packages/desktop/src/assets/images/icon-arrow.svg)0
-rw-r--r--gui/packages/desktop/assets/images/icon-back.svg (renamed from gui/packages/desktop/src/assets/images/icon-back.svg)0
-rw-r--r--gui/packages/desktop/assets/images/icon-chevron-down.svg (renamed from gui/packages/desktop/src/assets/images/icon-chevron-down.svg)0
-rw-r--r--gui/packages/desktop/assets/images/icon-chevron-up.svg (renamed from gui/packages/desktop/src/assets/images/icon-chevron-up.svg)0
-rw-r--r--gui/packages/desktop/assets/images/icon-chevron.svg (renamed from gui/packages/desktop/src/assets/images/icon-chevron.svg)0
-rw-r--r--gui/packages/desktop/assets/images/icon-close-sml.svg (renamed from gui/packages/desktop/src/assets/images/icon-close-sml.svg)0
-rw-r--r--gui/packages/desktop/assets/images/icon-close.svg (renamed from gui/packages/desktop/src/assets/images/icon-close.svg)0
-rw-r--r--gui/packages/desktop/assets/images/icon-extLink.svg (renamed from gui/packages/desktop/src/assets/images/icon-extLink.svg)0
-rwxr-xr-xgui/packages/desktop/assets/images/icon-fail.svg (renamed from gui/packages/desktop/src/assets/images/icon-fail.svg)0
-rwxr-xr-xgui/packages/desktop/assets/images/icon-fastest.svg (renamed from gui/packages/desktop/src/assets/images/icon-fastest.svg)0
-rw-r--r--gui/packages/desktop/assets/images/icon-nearest.svg (renamed from gui/packages/desktop/src/assets/images/icon-nearest.svg)0
-rwxr-xr-xgui/packages/desktop/assets/images/icon-settings.svg (renamed from gui/packages/desktop/src/assets/images/icon-settings.svg)0
-rw-r--r--gui/packages/desktop/assets/images/icon-spinner.svg (renamed from gui/packages/desktop/src/assets/images/icon-spinner.svg)0
-rwxr-xr-xgui/packages/desktop/assets/images/icon-success.svg (renamed from gui/packages/desktop/src/assets/images/icon-success.svg)0
-rwxr-xr-xgui/packages/desktop/assets/images/icon-tick.svg (renamed from gui/packages/desktop/src/assets/images/icon-tick.svg)0
-rwxr-xr-xgui/packages/desktop/assets/images/location-marker-secure.svg (renamed from gui/packages/desktop/src/assets/images/location-marker-secure.svg)0
-rwxr-xr-xgui/packages/desktop/assets/images/location-marker-unsecure.svg (renamed from gui/packages/desktop/src/assets/images/location-marker-unsecure.svg)0
-rw-r--r--gui/packages/desktop/assets/images/logo-icon.svg (renamed from gui/packages/desktop/src/assets/images/logo-icon.svg)0
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-1.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-1.png)bin131 -> 131 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-10.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-10.png)bin166 -> 166 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-10@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-10@2x.png)bin212 -> 212 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-10Template.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-10Template.png)bin222 -> 222 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-10Template@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-10Template@2x.png)bin360 -> 360 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-1@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-1@2x.png)bin181 -> 181 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-1Template.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-1Template.png)bin131 -> 131 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-1Template@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-1Template@2x.png)bin181 -> 181 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-2.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-2.png)bin143 -> 143 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-2@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-2@2x.png)bin193 -> 193 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-2Template.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-2Template.png)bin143 -> 143 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-2Template@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-2Template@2x.png)bin193 -> 193 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-3.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-3.png)bin129 -> 129 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-3@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-3@2x.png)bin183 -> 183 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-3Template.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-3Template.png)bin129 -> 129 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-3Template@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-3Template@2x.png)bin183 -> 183 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-4.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-4.png)bin138 -> 138 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-4@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-4@2x.png)bin189 -> 189 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-4Template.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-4Template.png)bin138 -> 138 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-4Template@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-4Template@2x.png)bin189 -> 189 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-5.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-5.png)bin121 -> 121 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-5@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-5@2x.png)bin165 -> 165 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-5Template.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-5Template.png)bin121 -> 121 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-5Template@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-5Template@2x.png)bin165 -> 165 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-6.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-6.png)bin128 -> 128 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-6@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-6@2x.png)bin168 -> 168 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-6Template.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-6Template.png)bin128 -> 128 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-6Template@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-6Template@2x.png)bin168 -> 168 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-7.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-7.png)bin127 -> 127 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-7@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-7@2x.png)bin172 -> 172 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-7Template.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-7Template.png)bin127 -> 127 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-7Template@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-7Template@2x.png)bin172 -> 172 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-8.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-8.png)bin127 -> 127 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-8@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-8@2x.png)bin167 -> 167 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-8Template.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-8Template.png)bin127 -> 127 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-8Template@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-8Template@2x.png)bin167 -> 167 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-9.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-9.png)bin128 -> 128 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-9@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-9@2x.png)bin163 -> 163 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-9Template.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-9Template.png)bin128 -> 128 bytes
-rw-r--r--gui/packages/desktop/assets/images/menubar icons/lock-9Template@2x.png (renamed from gui/packages/desktop/src/assets/images/menubar icons/lock-9Template@2x.png)bin163 -> 163 bytes
-rw-r--r--gui/packages/desktop/init.js2
-rw-r--r--gui/packages/desktop/package.json60
-rw-r--r--gui/packages/desktop/scripts/serve.js22
-rw-r--r--gui/packages/desktop/src/assets/css/style.css8
-rw-r--r--gui/packages/desktop/src/main/autostart.ts (renamed from gui/packages/desktop/src/main/autostart.js)6
-rw-r--r--gui/packages/desktop/src/main/daemon-rpc.ts (renamed from gui/packages/desktop/src/main/daemon-rpc.js)62
-rw-r--r--gui/packages/desktop/src/main/errors.ts (renamed from gui/packages/desktop/src/main/errors.js)2
-rw-r--r--gui/packages/desktop/src/main/gui-settings.ts (renamed from gui/packages/desktop/src/main/gui-settings.js)12
-rw-r--r--gui/packages/desktop/src/main/index.ts (renamed from gui/packages/desktop/src/main/index.js)193
-rw-r--r--gui/packages/desktop/src/main/jsonrpc-client.ts (renamed from gui/packages/desktop/src/main/jsonrpc-client.js)99
-rw-r--r--gui/packages/desktop/src/main/keyframe-animation.ts (renamed from gui/packages/desktop/src/main/keyframe-animation.js)26
-rw-r--r--gui/packages/desktop/src/main/notification-controller.ts (renamed from gui/packages/desktop/src/main/notification-controller.js)30
-rw-r--r--gui/packages/desktop/src/main/proc.ts (renamed from gui/packages/desktop/src/main/proc.js)9
-rw-r--r--gui/packages/desktop/src/main/reconnection-backoff.ts (renamed from gui/packages/desktop/src/main/reconnection-backoff.js)2
-rw-r--r--gui/packages/desktop/src/main/tray-icon-controller.ts (renamed from gui/packages/desktop/src/main/tray-icon-controller.js)16
-rw-r--r--gui/packages/desktop/src/main/window-controller.ts (renamed from gui/packages/desktop/src/main/window-controller.js)10
-rw-r--r--gui/packages/desktop/src/renderer/.eslintrc5
-rw-r--r--gui/packages/desktop/src/renderer/app.tsx (renamed from gui/packages/desktop/src/renderer/app.js)90
-rw-r--r--gui/packages/desktop/src/renderer/components/Account.tsx (renamed from gui/packages/desktop/src/renderer/components/Account.js)38
-rw-r--r--gui/packages/desktop/src/renderer/components/AccountStyles.tsx (renamed from gui/packages/desktop/src/renderer/components/AccountStyles.js)12
-rw-r--r--gui/packages/desktop/src/renderer/components/AdvancedSettings.tsx (renamed from gui/packages/desktop/src/renderer/components/AdvancedSettings.js)82
-rw-r--r--gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.tsx (renamed from gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.js)25
-rw-r--r--gui/packages/desktop/src/renderer/components/AppButton.tsx (renamed from gui/packages/desktop/src/renderer/components/AppButton.js)70
-rw-r--r--gui/packages/desktop/src/renderer/components/AppButtonStyles.tsx (renamed from gui/packages/desktop/src/renderer/components/AppButtonStyles.js)24
-rw-r--r--gui/packages/desktop/src/renderer/components/Cell.tsx (renamed from gui/packages/desktop/src/renderer/components/Cell.js)107
-rw-r--r--gui/packages/desktop/src/renderer/components/ChevronButton.tsx (renamed from gui/packages/desktop/src/renderer/components/ChevronButton.js)11
-rw-r--r--gui/packages/desktop/src/renderer/components/CityRow.tsx (renamed from gui/packages/desktop/src/renderer/components/CityRow.js)40
-rw-r--r--gui/packages/desktop/src/renderer/components/Connect.tsx (renamed from gui/packages/desktop/src/renderer/components/Connect.js)131
-rw-r--r--gui/packages/desktop/src/renderer/components/ConnectStyles.tsx (renamed from gui/packages/desktop/src/renderer/components/ConnectStyles.js)12
-rw-r--r--gui/packages/desktop/src/renderer/components/CountryRow.tsx (renamed from gui/packages/desktop/src/renderer/components/CountryRow.js)44
-rw-r--r--gui/packages/desktop/src/renderer/components/CustomScrollbars.tsx (renamed from gui/packages/desktop/src/renderer/components/CustomScrollbars.js)76
-rw-r--r--gui/packages/desktop/src/renderer/components/Launch.tsx (renamed from gui/packages/desktop/src/renderer/components/Launch.js)8
-rw-r--r--gui/packages/desktop/src/renderer/components/Layout.tsx (renamed from gui/packages/desktop/src/renderer/components/Layout.js)8
-rw-r--r--gui/packages/desktop/src/renderer/components/LayoutStyles.tsx (renamed from gui/packages/desktop/src/renderer/components/LayoutStyles.js)4
-rw-r--r--gui/packages/desktop/src/renderer/components/Login.tsx (renamed from gui/packages/desktop/src/renderer/components/Login.js)120
-rw-r--r--gui/packages/desktop/src/renderer/components/LoginStyles.tsx (renamed from gui/packages/desktop/src/renderer/components/LoginStyles.js)8
-rw-r--r--gui/packages/desktop/src/renderer/components/Map.tsx (renamed from gui/packages/desktop/src/renderer/components/Map.js)71
-rw-r--r--gui/packages/desktop/src/renderer/components/NavigationBar.tsx (renamed from gui/packages/desktop/src/renderer/components/NavigationBar.js)156
-rw-r--r--gui/packages/desktop/src/renderer/components/NotificationArea.tsx (renamed from gui/packages/desktop/src/renderer/components/NotificationArea.js)41
-rw-r--r--gui/packages/desktop/src/renderer/components/NotificationBanner.tsx (renamed from gui/packages/desktop/src/renderer/components/NotificationBanner.js)27
-rw-r--r--gui/packages/desktop/src/renderer/components/PlatformWindow.tsx (renamed from gui/packages/desktop/src/renderer/components/PlatformWindow.js)9
-rw-r--r--gui/packages/desktop/src/renderer/components/Preferences.tsx (renamed from gui/packages/desktop/src/renderer/components/Preferences.js)42
-rw-r--r--gui/packages/desktop/src/renderer/components/PreferencesStyles.tsx (renamed from gui/packages/desktop/src/renderer/components/PreferencesStyles.js)9
-rw-r--r--gui/packages/desktop/src/renderer/components/RelayRow.tsx (renamed from gui/packages/desktop/src/renderer/components/RelayRow.js)15
-rw-r--r--gui/packages/desktop/src/renderer/components/RelayStatusIndicator.tsx (renamed from gui/packages/desktop/src/renderer/components/RelayStatusIndicator.js)9
-rw-r--r--gui/packages/desktop/src/renderer/components/SelectLocation.tsx (renamed from gui/packages/desktop/src/renderer/components/SelectLocation.js)97
-rw-r--r--gui/packages/desktop/src/renderer/components/SelectLocationStyles.tsx (renamed from gui/packages/desktop/src/renderer/components/SelectLocationStyles.js)4
-rw-r--r--gui/packages/desktop/src/renderer/components/Settings.tsx (renamed from gui/packages/desktop/src/renderer/components/Settings.js)87
-rw-r--r--gui/packages/desktop/src/renderer/components/SettingsStyles.tsx (renamed from gui/packages/desktop/src/renderer/components/SettingsStyles.js)13
-rw-r--r--gui/packages/desktop/src/renderer/components/Support.tsx (renamed from gui/packages/desktop/src/renderer/components/Support.js)123
-rw-r--r--gui/packages/desktop/src/renderer/components/SupportStyles.tsx (renamed from gui/packages/desktop/src/renderer/components/SupportStyles.js)9
-rw-r--r--gui/packages/desktop/src/renderer/components/SvgMap.tsx (renamed from gui/packages/desktop/src/renderer/components/SvgMap.js)145
-rw-r--r--gui/packages/desktop/src/renderer/components/Switch.tsx (renamed from gui/packages/desktop/src/renderer/components/Switch.js)32
-rw-r--r--gui/packages/desktop/src/renderer/components/TransitionContainer.tsx (renamed from gui/packages/desktop/src/renderer/components/TransitionContainer.js)91
-rw-r--r--gui/packages/desktop/src/renderer/components/TransitionContainerStyles.js23
-rw-r--r--gui/packages/desktop/src/renderer/components/TunnelControl.tsx (renamed from gui/packages/desktop/src/renderer/components/TunnelControl.js)62
-rw-r--r--gui/packages/desktop/src/renderer/containers/AccountPage.tsx (renamed from gui/packages/desktop/src/renderer/containers/AccountPage.js)8
-rw-r--r--gui/packages/desktop/src/renderer/containers/AdvancedSettingsPage.tsx (renamed from gui/packages/desktop/src/renderer/containers/AdvancedSettingsPage.js)27
-rw-r--r--gui/packages/desktop/src/renderer/containers/ConnectPage.tsx (renamed from gui/packages/desktop/src/renderer/containers/ConnectPage.js)21
-rw-r--r--gui/packages/desktop/src/renderer/containers/LaunchPage.tsx (renamed from gui/packages/desktop/src/renderer/containers/LaunchPage.js)6
-rw-r--r--gui/packages/desktop/src/renderer/containers/LoginPage.tsx (renamed from gui/packages/desktop/src/renderer/containers/LoginPage.js)12
-rw-r--r--gui/packages/desktop/src/renderer/containers/PlatformWindowContainer.js18
-rw-r--r--gui/packages/desktop/src/renderer/containers/PlatformWindowContainer.tsx10
-rw-r--r--gui/packages/desktop/src/renderer/containers/PreferencesPage.tsx (renamed from gui/packages/desktop/src/renderer/containers/PreferencesPage.js)16
-rw-r--r--gui/packages/desktop/src/renderer/containers/SelectLocationPage.tsx (renamed from gui/packages/desktop/src/renderer/containers/SelectLocationPage.js)9
-rw-r--r--gui/packages/desktop/src/renderer/containers/SettingsPage.tsx (renamed from gui/packages/desktop/src/renderer/containers/SettingsPage.js)9
-rw-r--r--gui/packages/desktop/src/renderer/containers/SupportPage.tsx (renamed from gui/packages/desktop/src/renderer/containers/SupportPage.js)12
-rw-r--r--gui/packages/desktop/src/renderer/index.html3
-rw-r--r--gui/packages/desktop/src/renderer/index.ts (renamed from gui/packages/desktop/src/renderer/index.js)4
-rw-r--r--gui/packages/desktop/src/renderer/lib/account-expiry.ts (renamed from gui/packages/desktop/src/renderer/lib/account-expiry.js)6
-rw-r--r--gui/packages/desktop/src/renderer/lib/auth-failure.ts (renamed from gui/packages/desktop/src/renderer/lib/auth-failure.js)7
-rw-r--r--gui/packages/desktop/src/renderer/lib/problem-report.ts (renamed from gui/packages/desktop/src/renderer/lib/problem-report.js)16
-rw-r--r--gui/packages/desktop/src/renderer/lib/relay-settings-builder.ts (renamed from gui/packages/desktop/src/renderer/lib/relay-settings-builder.js)66
-rw-r--r--gui/packages/desktop/src/renderer/lib/transition-rule.ts (renamed from gui/packages/desktop/src/renderer/lib/transition-rule.js)20
-rw-r--r--gui/packages/desktop/src/renderer/redux/account/actions.ts (renamed from gui/packages/desktop/src/renderer/redux/account/actions.js)30
-rw-r--r--gui/packages/desktop/src/renderer/redux/account/reducers.ts (renamed from gui/packages/desktop/src/renderer/redux/account/reducers.js)36
-rw-r--r--gui/packages/desktop/src/renderer/redux/connection/actions.ts (renamed from gui/packages/desktop/src/renderer/redux/connection/actions.js)52
-rw-r--r--gui/packages/desktop/src/renderer/redux/connection/reducers.ts (renamed from gui/packages/desktop/src/renderer/redux/connection/reducers.js)37
-rw-r--r--gui/packages/desktop/src/renderer/redux/settings/actions.ts (renamed from gui/packages/desktop/src/renderer/redux/settings/actions.js)54
-rw-r--r--gui/packages/desktop/src/renderer/redux/settings/reducers.ts (renamed from gui/packages/desktop/src/renderer/redux/settings/reducers.js)90
-rw-r--r--gui/packages/desktop/src/renderer/redux/store.ts (renamed from gui/packages/desktop/src/renderer/redux/store.js)64
-rw-r--r--gui/packages/desktop/src/renderer/redux/support/actions.ts (renamed from gui/packages/desktop/src/renderer/redux/support/actions.js)12
-rw-r--r--gui/packages/desktop/src/renderer/redux/support/reducers.ts (renamed from gui/packages/desktop/src/renderer/redux/support/reducers.js)8
-rw-r--r--gui/packages/desktop/src/renderer/redux/userinterface/actions.ts (renamed from gui/packages/desktop/src/renderer/redux/userinterface/actions.js)10
-rw-r--r--gui/packages/desktop/src/renderer/redux/userinterface/reducers.ts (renamed from gui/packages/desktop/src/renderer/redux/userinterface/reducers.js)8
-rw-r--r--gui/packages/desktop/src/renderer/redux/version/actions.ts (renamed from gui/packages/desktop/src/renderer/redux/version/actions.js)18
-rw-r--r--gui/packages/desktop/src/renderer/redux/version/reducers.ts (renamed from gui/packages/desktop/src/renderer/redux/version/reducers.js)24
-rw-r--r--gui/packages/desktop/src/renderer/routes.tsx (renamed from gui/packages/desktop/src/renderer/routes.js)14
-rw-r--r--gui/packages/desktop/src/renderer/transitions.ts (renamed from gui/packages/desktop/src/renderer/transitions.js)17
-rw-r--r--gui/packages/desktop/src/shared/daemon-rpc-types.js215
-rw-r--r--gui/packages/desktop/src/shared/daemon-rpc-types.ts214
-rw-r--r--gui/packages/desktop/src/shared/gui-settings-state.js7
-rw-r--r--gui/packages/desktop/src/shared/gui-settings-state.ts5
-rw-r--r--gui/packages/desktop/src/shared/ipc-event-channel.ts (renamed from gui/packages/desktop/src/shared/ipc-event-channel.js)122
-rw-r--r--gui/packages/desktop/test/.eslintrc15
-rw-r--r--gui/packages/desktop/test/account-data-cache.spec.ts (renamed from gui/packages/desktop/test/account-data-cache.spec.js)45
-rw-r--r--gui/packages/desktop/test/auth-failure.spec.ts (renamed from gui/packages/desktop/test/auth-failure.spec.js)3
-rw-r--r--gui/packages/desktop/test/components/Account.spec.js83
-rw-r--r--gui/packages/desktop/test/components/Login.spec.js82
-rw-r--r--gui/packages/desktop/test/components/NotificationArea.spec.tsx (renamed from gui/packages/desktop/test/components/NotificationArea.spec.js)2
-rw-r--r--gui/packages/desktop/test/components/Preferences.spec.js32
-rw-r--r--gui/packages/desktop/test/components/Settings.spec.js213
-rw-r--r--gui/packages/desktop/test/components/Support.spec.js131
-rw-r--r--gui/packages/desktop/test/jsonrpc-transport.spec.ts (renamed from gui/packages/desktop/test/jsonrpc-transport.spec.js)5
-rw-r--r--gui/packages/desktop/test/keyframe-animation.spec.ts (renamed from gui/packages/desktop/test/keyframe-animation.spec.js)20
-rw-r--r--gui/packages/desktop/test/relay-settings-builder.spec.ts (renamed from gui/packages/desktop/test/relay-settings-builder.spec.js)4
-rw-r--r--gui/packages/desktop/test/setup/main.ts (renamed from gui/packages/desktop/test/setup/main.js)2
-rw-r--r--gui/packages/desktop/test/setup/renderer.js17
-rw-r--r--gui/packages/desktop/test/setup/renderer.ts12
-rw-r--r--gui/packages/desktop/test/transition-rule.spec.ts (renamed from gui/packages/desktop/test/transition-rule.spec.js)4
-rw-r--r--gui/packages/desktop/tsconfig.json19
-rw-r--r--gui/packages/desktop/tslint.json3
-rw-r--r--gui/packages/mobile/package.json4
-rw-r--r--gui/types/JSONStream/index.d.ts40
-rw-r--r--gui/types/d3-geo-projection/index.d.ts5
-rw-r--r--gui/types/react-simple-maps/index.d.ts187
-rw-r--r--gui/types/validated/index.d.ts42
-rw-r--r--gui/yarn.lock1708
218 files changed, 2483 insertions, 4587 deletions
diff --git a/.gitignore b/.gitignore
index dd2f9c88cd..389f4388ec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,5 @@
/target/
/gui/node_modules
-/gui/flow-typed
/gui/packages/**/node_modules
/gui/packages/**/build
/gui/packages/mobile/android
diff --git a/.travis.yml b/.travis.yml
index 56ab9b74d2..70c98e280b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,11 +17,11 @@ matrix:
install: &nodejs_install_script
- cd gui
- yarn install
- - yarn flow-typed install
before_script: &nodejs_before_script
- export DISPLAY=:99.0; sh -e /etc/init.d/xvfb start
script:
- yarn workspace $WORKSPACE lint
+ - yarn workspace $WORKSPACE build
- yarn workspace $WORKSPACE test
# GUI - desktop
@@ -33,9 +33,9 @@ matrix:
install: *nodejs_install_script
before_script: *nodejs_before_script
script:
- - yarn lint
- - yarn flow
- yarn check-format
+ - yarn workspace $WORKSPACE lint
+ - yarn workspace $WORKSPACE build
- yarn workspace $WORKSPACE test
diff --git a/README.md b/README.md
index bc3a261a59..0a1fdc0e7e 100644
--- a/README.md
+++ b/README.md
@@ -243,7 +243,6 @@ this procedure, the `integration-tests.sh` script can be used to run all integra
## Command line tools for Electron GUI app development
- `$ yarn workspace desktop develop` - develop app with live-reload enabled
-- `$ yarn flow` - type-check the code
- `$ yarn lint` - lint code
- `$ yarn pack:<OS>` - prepare app for distribution for your platform. Where `<OS>` can be
`linux`, `mac` or `win`
diff --git a/appveyor_gui.yml b/appveyor_gui.yml
index f603ab43ab..ea027c0123 100644
--- a/appveyor_gui.yml
+++ b/appveyor_gui.yml
@@ -11,7 +11,7 @@ install:
# This is the "test phase", tweak it as you see fit
test_script:
- - yarn lint
+ - yarn workspace %WORKSPACE% lint
- yarn workspace %WORKSPACE% test
# Stops feature branches from triggering two builds (One for branch and one for PR)
diff --git a/gui/.eslintignore b/gui/.eslintignore
deleted file mode 100644
index dd87e2d73f..0000000000
--- a/gui/.eslintignore
+++ /dev/null
@@ -1,2 +0,0 @@
-node_modules
-build
diff --git a/gui/.eslintrc b/gui/.eslintrc
deleted file mode 100644
index c1b955d2ed..0000000000
--- a/gui/.eslintrc
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- "root": true,
- "extends": [
- "eslint:recommended",
- "plugin:react/recommended",
- "plugin:promise/recommended",
- "plugin:flowtype/recommended",
- "prettier",
- "prettier/flowtype",
- "prettier/react",
- "prettier/standard"
- ],
- "parser": "babel-eslint",
- "parserOptions": {
- "ecmaFeatures": {
- "jsx": true,
- "modules": true
- }
- },
- "plugins": [
- "react",
- "flowtype",
- "promise"
- ],
- "rules": {
- "prefer-const": "warn",
- "no-console": "off",
- "no-loop-func": "warn",
- "no-param-reassign": "warn",
- "func-names": "off",
- "no-unused-expressions": "error",
- "no-unused-vars": [
- "error",
- {
- "args": "all",
- "argsIgnorePattern": "_.*",
- "varsIgnorePattern": "_.*"
- }
- ],
- "block-scoped-var": "error",
- "react/prop-types": "off",
- "flowtype/define-flow-type": "warn"
- },
- "settings": {
- "react": {
- "pragma": "React",
- "version": "16.4",
- "flowVersion": "0.82"
- }
- },
- "env": {
- "es6": true,
- "node": true
- }
-}
diff --git a/gui/.flowconfig b/gui/.flowconfig
deleted file mode 100644
index ee4f9e3cc9..0000000000
--- a/gui/.flowconfig
+++ /dev/null
@@ -1,14 +0,0 @@
-[ignore]
-
-[include]
-
-[libs]
-flow-libs/
-
-[lints]
-
-[options]
-suppress_comment= \\(.\\|\n\\)*\\$FlowFixMe
-munge_underscores=true
-
-[strict]
diff --git a/gui/flow-libs/electron.js.flow b/gui/flow-libs/electron.js.flow
deleted file mode 100644
index d8fdd9e88f..0000000000
--- a/gui/flow-libs/electron.js.flow
+++ /dev/null
@@ -1,270 +0,0 @@
-// @flow
-
-import EventEmitter from 'events';
-
-declare var process: Process & {
- resourcesPath: string;
- type: "browser" | "renderer";
- versions: {
- electron: string;
- chrome: string;
- };
-};
-
-declare module 'electron' {
-
- // common types
-
- declare type Size = {
- width: number;
- height: number;
- }
-
- declare type Rectangle = {
- width: number;
- height: number;
- x: number;
- y: number;
- }
-
- declare type Point = {
- x: number;
- y: number;
- }
-
- // http://electron.atom.io/docs/api/app
-
- declare class App extends EventEmitter {
- getPath(name: string): string;
- setPath(name: string, path: string): void;
- quit(): void;
- }
-
- // http://electron.atom.io/docs/api/shell
- declare type OpenExternalOptions = {
- activate: boolean;
- }
-
- declare class Shell {
- showItemInFolder(fullPath: string): boolean;
- openItem(fullPath: string): boolean;
- openExternal(url: string, options?: OpenExternalOptions, callback?: (error: Error) => void): boolean;
- moveItemToTrash(fullPath: string): boolean;
- beep(): void;
- }
-
- // http://electron.atom.io/docs/api/remote
-
- declare class Remote {
- app: App;
- shell: Shell;
- getCurrentWindow(): BrowserWindow;
- getCurrentWebContents(): WebContents;
- getGlobal(name: string): ?mixed;
- }
-
- // http://electron.atom.io/docs/api/clipboard
-
- declare class Clipboard {
- writeText(text: string, type?: string): void;
- }
-
- // http://electron.atom.io/docs/api/native-image
-
- declare class NativeImage {
- isEmpty(): boolean;
- getSize(): Size;
- }
-
- // http://electron.atom.io/docs/api/tray
-
- declare class Tray extends EventEmitter {
- constructor(image: NativeImage | string): void;
- getBounds(): Rectangle;
- setHighlightMode(mode: 'selection' | 'always' | 'never'): void;
- setImage(image: NativeImage | string): void;
- setPressedImage(image: NativeImage | string): void;
- }
-
- // https://electronjs.org/docs/api/screen
-
- declare type Display = {
- id: number;
- rotation: number;
- scaleFactor: number;
- touchSupport: 'available' | 'unavailable' | 'unknown';
- bounds: Rectangle;
- size: Size;
- workArea: Rectangle;
- workAreaSize: Size;
- }
-
- declare class Screen extends EventEmitter {
- getCursorScreenPoint(): Point;
- getPrimaryDisplay(): Display;
- getAllDisplays(): Array<Display>;
- getDisplayNearestPoint(point: Point): Display;
- getDisplayMatching(rect: Rectangle): Display;
- }
-
- // http://electron.atom.io/docs/api/web-frame
-
- declare class WebFrame extends EventEmitter {
- setVisualZoomLevelLimits(minimumLevel: number, maximumLevel: number): void;
- }
-
- // http://electron.atom.io/docs/api/ipc-renderer
-
- declare type IpcRendererEvent = {
- senderId: number;
- }
-
- declare class IpcRenderer extends EventEmitter {
- send(channel: string, ...args: Array<mixed>): void;
- }
-
- // http://electron.atom.io/docs/api/ipc-main
-
- declare type IpcMainEvent = {
- sender: WebContents;
- returnValue?: any;
- }
-
- declare class IpcMain extends EventEmitter {}
-
- declare class WebContents extends EventEmitter {
- send(channel: string, ...args: Array<mixed>): void;
- }
-
- // http://electron.atom.io/docs/api/browser-window
-
- declare type OpenDevToolsOptions = {
- mode: 'right' | 'bottom' | 'undocked' | 'detach';
- }
-
- declare type WebPreferences = {
- backgroundThrottling?: boolean;
- scrollBounce?: boolean;
- blinkFeatures?: string;
- disableBlinkFeatures?: string;
- }
-
- declare type BrowserWindowConstructorOptions = {
- width?: number;
- height?: number;
- resizable?: boolean;
- maximizable?: boolean;
- fullscreenable?: boolean;
- show?: boolean;
- frame?: boolean;
- transparent?: boolean;
- webPreferences?: WebPreferences;
- }
-
- declare type LoadURLOptions = {
- userAgent?: string;
- }
-
- declare class BrowserWindow extends EventEmitter {
- constructor(options: ?BrowserWindowConstructorOptions): this;
- isVisible(): boolean;
- show(): void;
- hide(): void;
- focus(): void;
- setPosition(x: number, y: number, animate?: boolean): void;
- getBounds(): Rectangle;
- setVisibleOnAllWorkspaces(visible: boolean): void;
- isVisibleOnAllWorkspaces(): boolean;
- inspectElement(x: number, y: number): void;
- isDevToolsOpened(): boolean;isDevToolsOpened(): boolean;
- openDevTools(options?: OpenDevToolsOptions): void;
- closeDevTools(): void;
- loadURL(url: string, options?: LoadURLOptions): void;
- webContents: WebContents;
- }
-
- // http://electron.atom.io/docs/api/menu-item
- declare class MenuItem {}
-
- // http://electron.atom.io/docs/api/menu
-
- declare type MenuItemConstructorOptions = {
- type?: 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio';
- label?: string;
- role?: string;
- click?: (menuItem: MenuItem, browserWindow: BrowserWindow, event: Event) => void;
- }
-
- declare type PopupOptions = {
- x?: number;
- y?: number;
- }
-
- declare class Menu {
- static buildFromTemplate(template: Array<MenuItemConstructorOptions>): Menu;
- static setApplicationMenu(menu: Menu): void;
- popup(browserWindow?: BrowserWindow, options?: PopupOptions): void;
- }
-
- // https://electronjs.org/docs/api/structures/notification-action
- declare type NotificationAction = {
- type: 'button',
- text?: string
- };
-
- // https://electronjs.org/docs/api/notification
- declare type NotificationOptions = {
- title?: string,
- subtitle?: string,
- body: string,
- silent?: boolean,
- icon?: string | NativeImage,
- hasReply?: boolean,
- replyPlaceholder?: string,
- sound?: string,
- actions?: Array<NotificationAction>,
- closeButtonText?: string
- };
-
- declare class Notification extends EventEmitter {
- static isSupported(): boolean;
- constructor(options: NotificationOptions): void;
- show(): void;
- close(): void;
- title: string;
- subtitle: string;
- body: string;
- silent: boolean;
- hasReply: boolean;
- replyPlaceholder: string;
- sound: string;
- actions: Array<NotificationAction>,
- closeButtonText: string;
- }
-
-
- // http://electron.atom.io/docs/api/app
-
- declare class App extends EventEmitter {
- setPath(name: string, path: string): void;
- getPath(name: string): string;
- quit(): void;
- }
-
- // MainInterface
-
- declare var nativeImage: {
- createEmpty(): NativeImage,
- createFromPath(path: string): NativeImage,
- createFromBuffer(buffer: Buffer, scaleFactor?: number): NativeImage,
- createFromDataURL(dataURL: string): NativeImage
- };
- declare var webFrame: WebFrame;
- declare var app: App;
- declare var ipcRenderer: IpcRenderer;
- declare var ipcMain: IpcMain;
- declare var remote: Remote;
- declare var shell: Shell;
- declare var clipboard: Clipboard;
- declare var screen: Screen;
-}
diff --git a/gui/flow-libs/tests.js.flow b/gui/flow-libs/tests.js.flow
deleted file mode 100644
index e497690359..0000000000
--- a/gui/flow-libs/tests.js.flow
+++ /dev/null
@@ -1,13 +0,0 @@
-import chai from 'chai';
-
-// We use electron-mocha which has a child dependency on mocha.
-// However flow-typed does not automatically pull annotations for mocha.
-// These stubs remedy the absence of those.
-declare function describe(string, Function): void;
-declare function it(string, (done: Function) => any): Promise<any> | void;
-declare function afterEach((done: Function) => void): Promise<any> | void;
-declare function beforeEach((done: Function) => void): Promise<any> | void;
-
-declare var expect: $PropertyType<chai, 'expect'>;
-declare var sinon: any;
-declare var spy: any;
diff --git a/gui/package.json b/gui/package.json
index 2a62958615..200e25d076 100644
--- a/gui/package.json
+++ b/gui/package.json
@@ -5,8 +5,6 @@
],
"scripts": {
"postinstall": "node unpatch-yarn.js",
- "flow": "flow",
- "lint": "eslint \"packages/**/*.js\"",
"format": "yarn run private:format --write",
"check-format": "yarn run private:format --list-different",
"private:format": "prettier \"packages/**/*.{js,css,ts,tsx}\"",
@@ -15,14 +13,6 @@
"pack:linux": "yarn workspace desktop pack:linux"
},
"devDependencies": {
- "babel-eslint": "^10.0.1",
- "eslint": "^5.8.0",
- "eslint-config-prettier": "^3.1.0",
- "eslint-plugin-flowtype": "^3.2.0",
- "eslint-plugin-promise": "^4.0.1",
- "eslint-plugin-react": "^7.10.0",
- "flow-bin": "0.82",
- "flow-typed": "^2.5.1",
"prettier": "1.15.3"
}
}
diff --git a/gui/packages/components/.babelrc b/gui/packages/components/.babelrc
deleted file mode 100644
index 3c788e0ea7..0000000000
--- a/gui/packages/components/.babelrc
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "presets": [
- ["env", {
- "targets": { "node": "8.9" },
- "useBuiltIns": true
- }], "react"
- ],
- "plugins": [
- "transform-class-properties",
- "transform-object-rest-spread"
- ]
-}
diff --git a/gui/packages/components/package.json b/gui/packages/components/package.json
index 8f8fb5be43..a085f7fc38 100644
--- a/gui/packages/components/package.json
+++ b/gui/packages/components/package.json
@@ -15,32 +15,34 @@
"private:build:watch": "tsc -w"
},
"devDependencies": {
+ "@mullvad/config": "0.1.0",
"@types/chai": "^4.1.7",
"@types/enzyme": "^3.1.15",
"@types/enzyme-adapter-react-16": "^1.0.3",
"@types/jsdom": "^12.2.0",
"@types/mocha": "^5.2.5",
"@types/node": "^10.12.3",
- "@types/react": "^16.4.18",
+ "@types/react": "16.3.18",
+ "@types/react-dom": "16.0.7",
"chai": "^4.2.0",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.7.0",
"jsdom": "^13.0.0",
"mocha": "^5.2.0",
"npm-run-all": "^4.1.3",
- "react": "^16.4.0",
- "react-dom": "^16.4.0",
- "reactxp": "^1.4.0",
+ "react": "^16.5.0",
+ "react-dom": "^16.5.0",
+ "reactxp": "^1.5.0",
"rimraf": "^2.6.2",
"ts-node": "^7.0.1",
- "tslint": "^5.11.0",
- "tslint-config-prettier": "^1.15.0",
- "typescript": "^3.1.6"
+ "tslint": "^5.12.1",
+ "tslint-config-prettier": "^1.17.0",
+ "typescript": "^3.2.4"
},
"dependencies": {},
"peerDependencies": {
- "react": "^16.4.0",
- "react-dom": "^16.4.0",
- "reactxp": "^1.4.0"
+ "react": "^16.5.0",
+ "react-dom": "^16.5.0",
+ "reactxp": "^1.5.0"
}
}
diff --git a/gui/packages/components/src/Accordion.tsx b/gui/packages/components/src/Accordion.tsx
index 7019c9cb9c..19c9ddee56 100644
--- a/gui/packages/components/src/Accordion.tsx
+++ b/gui/packages/components/src/Accordion.tsx
@@ -66,11 +66,9 @@ export default class Accordion extends Component<IProps, IState> {
public render() {
const { style, children, expanded, animationDuration, ...otherProps } = this.props;
- const containerStyles = [style];
-
- if (this.state.applyAnimatedStyle) {
- containerStyles.push(containerOverflowStyle, this.animatedStyle);
- }
+ const containerStyles = this.state.applyAnimatedStyle
+ ? [style, containerOverflowStyle, this.animatedStyle]
+ : [style];
return (
<Animated.View {...otherProps} style={containerStyles} ref={this.containerRef}>
diff --git a/gui/packages/components/src/HeaderBar.tsx b/gui/packages/components/src/HeaderBar.tsx
index 2e2c7bcf30..7fd1a96f24 100644
--- a/gui/packages/components/src/HeaderBar.tsx
+++ b/gui/packages/components/src/HeaderBar.tsx
@@ -9,7 +9,7 @@ export enum HeaderBarStyle {
success = 'success',
}
-interface IHeaderBarProps {
+export interface IHeaderBarProps {
barStyle: HeaderBarStyle;
style?: Types.ViewStyleRuleSet;
}
diff --git a/gui/packages/components/src/ImageView.tsx b/gui/packages/components/src/ImageView.tsx
index d05c72dba7..1f6a90493a 100644
--- a/gui/packages/components/src/ImageView.tsx
+++ b/gui/packages/components/src/ImageView.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { Component, Styles, Types, View } from 'reactxp';
+import { Component, Types, View } from 'reactxp';
interface IProps {
source: string;
@@ -7,8 +7,9 @@ interface IProps {
height?: number;
tintColor?: string;
tintHoverColor?: string;
- style?: Types.ViewStyleRuleSet | Types.ViewStyleRuleSet[];
disabled?: boolean;
+ onPress?: (event: Types.SyntheticEvent) => void;
+ style?: Types.StyleRuleSetRecursive<Types.ViewStyleRuleSet>;
}
interface IState {
@@ -19,8 +20,8 @@ export default class ImageView extends Component<IProps, IState> {
public state = { hovered: false };
public render() {
- const { source, width, height, style, tintColor, tintHoverColor, ...otherProps } = this.props;
- const url = `../assets/images/${source}.svg`;
+ const { source, width, height, tintColor, tintHoverColor, ...otherProps } = this.props;
+ const url = `../../assets/images/${source}.svg`;
let image;
const activeTintColor = (this.state.hovered && tintHoverColor) || tintColor;
@@ -52,11 +53,7 @@ export default class ImageView extends Component<IProps, IState> {
}
return (
- <View
- {...otherProps}
- onMouseEnter={this.onHoverStart}
- onMouseLeave={this.onHoverEnd}
- style={style}>
+ <View {...otherProps} onMouseEnter={this.onHoverStart} onMouseLeave={this.onHoverEnd}>
{image}
</View>
);
diff --git a/gui/packages/components/src/Modal.tsx b/gui/packages/components/src/Modal.tsx
index 6eb070262b..5742e68f2b 100644
--- a/gui/packages/components/src/Modal.tsx
+++ b/gui/packages/components/src/Modal.tsx
@@ -42,7 +42,7 @@ export class ModalAlert extends React.Component {
}
interface IModalContainerProps {
- children?: Array<React.ReactElement<ModalContent | ModalAlert>>;
+ children?: React.ReactNode;
}
export class ModalContainer extends React.Component<IModalContainerProps> {
diff --git a/gui/packages/components/src/SecuredLabel.tsx b/gui/packages/components/src/SecuredLabel.tsx
index 9bf9ce0cdc..26fc425383 100644
--- a/gui/packages/components/src/SecuredLabel.tsx
+++ b/gui/packages/components/src/SecuredLabel.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { Clipboard, Component, Styles, Text, Types } from 'reactxp';
+import { Component, Styles, Text, Types } from 'reactxp';
export enum SecuredDisplayStyle {
secured,
diff --git a/gui/packages/components/test/.eslintrc b/gui/packages/components/test/.eslintrc
deleted file mode 100644
index fc2ab4d496..0000000000
--- a/gui/packages/components/test/.eslintrc
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "rules": {
- "no-unused-expressions" : "off",
- "react/no-render-return-value": "off"
- },
- "env": {
- "mocha": true
- },
- "globals": {
- "expect": true
- }
-}
diff --git a/gui/packages/components/test/setup.ts b/gui/packages/components/test/setup.ts
index fdcc4e49d8..30495cbc89 100644
--- a/gui/packages/components/test/setup.ts
+++ b/gui/packages/components/test/setup.ts
@@ -1,10 +1,10 @@
import { JSDOM } from 'jsdom';
-import * as Enzyme from 'enzyme';
-import * as Adapter from 'enzyme-adapter-react-16';
-import * as chai from 'chai';
+import Enzyme from 'enzyme';
+import ReactSixteenAdapter from 'enzyme-adapter-react-16';
Enzyme.configure({
- adapter: new Adapter(),
+ adapter: new ReactSixteenAdapter(),
});
+// @ts-ignore
const jsdom = new JSDOM('<!doctype html><html><body></body></html>');
diff --git a/gui/packages/components/tsconfig.json b/gui/packages/components/tsconfig.json
index 59dcc25146..5c5913a568 100644
--- a/gui/packages/components/tsconfig.json
+++ b/gui/packages/components/tsconfig.json
@@ -1,19 +1,16 @@
{
"compilerOptions": {
- "outDir": "./build",
- "target": "es2017",
- "module": "commonjs",
+ "declaration": true,
"jsx": "react",
- "strict": true,
- "skipLibCheck": true,
- "types": ["node"]
+ "outDir": "build",
+ "typeRoots": [
+ "../../types",
+ "node_modules/@types"
+ ]
},
+ "extends": "@mullvad/config/tsconfig.json",
"include": [
- "./src/*.ts",
- "./src/*.tsx"
- ],
- "exclude": [
- "node_modules",
- "test"
+ "src/*.ts",
+ "src/*.tsx"
]
}
diff --git a/gui/packages/components/tslint.json b/gui/packages/components/tslint.json
index 03e14ec96a..6b68bf43d6 100644
--- a/gui/packages/components/tslint.json
+++ b/gui/packages/components/tslint.json
@@ -1,13 +1,3 @@
{
- "defaultSeverity": "error",
- "extends": [
- "tslint:latest",
- "tslint-config-prettier"
- ],
- "jsRules": {},
- "rules": {
- "object-literal-sort-keys": false,
- "max-classes-per-file": false
- },
- "rulesDirectory": []
+ "extends": "@mullvad/config/tslint.json"
}
diff --git a/gui/packages/config/package.json b/gui/packages/config/package.json
new file mode 100644
index 0000000000..b876bce389
--- /dev/null
+++ b/gui/packages/config/package.json
@@ -0,0 +1,5 @@
+{
+ "private": true,
+ "name": "@mullvad/config",
+ "version": "0.1.0"
+}
diff --git a/gui/packages/config/tsconfig.json b/gui/packages/config/tsconfig.json
new file mode 100644
index 0000000000..8406543713
--- /dev/null
+++ b/gui/packages/config/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "compilerOptions": {
+ "alwaysStrict": true,
+ "esModuleInterop": true,
+ "module": "commonjs",
+ "noImplicitReturns": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "target": "es2017"
+ },
+ "exclude": [
+ "node_modules"
+ ]
+}
diff --git a/gui/packages/config/tslint.json b/gui/packages/config/tslint.json
new file mode 100644
index 0000000000..b5f8043a6b
--- /dev/null
+++ b/gui/packages/config/tslint.json
@@ -0,0 +1,13 @@
+{
+ "defaultSeverity": "error",
+ "extends": [
+ "tslint:latest",
+ "tslint-config-prettier"
+ ],
+ "jsRules": {},
+ "rules": {
+ "max-classes-per-file": false,
+ "object-literal-sort-keys": false
+ },
+ "rulesDirectory": []
+}
diff --git a/gui/packages/desktop/.babelrc b/gui/packages/desktop/.babelrc
deleted file mode 100644
index f1766428c3..0000000000
--- a/gui/packages/desktop/.babelrc
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "presets": [
- ["@babel/preset-env", {
- "targets": { "electron": "3.0" }
- }],
- "@babel/preset-react",
- "@babel/preset-typescript",
- "@babel/preset-flow"
- ],
- "plugins": [
- "@babel/plugin-proposal-class-properties"
- ]
-}
diff --git a/gui/packages/desktop/src/assets/css/fonts.css b/gui/packages/desktop/assets/css/fonts.css
index d648cd74f5..d648cd74f5 100644
--- a/gui/packages/desktop/src/assets/css/fonts.css
+++ b/gui/packages/desktop/assets/css/fonts.css
diff --git a/gui/packages/desktop/src/assets/css/global.css b/gui/packages/desktop/assets/css/global.css
index 114f58140d..114f58140d 100644
--- a/gui/packages/desktop/src/assets/css/global.css
+++ b/gui/packages/desktop/assets/css/global.css
diff --git a/gui/packages/desktop/src/assets/css/reset.css b/gui/packages/desktop/assets/css/reset.css
index d971da6765..d971da6765 100644
--- a/gui/packages/desktop/src/assets/css/reset.css
+++ b/gui/packages/desktop/assets/css/reset.css
diff --git a/gui/packages/desktop/assets/css/style.css b/gui/packages/desktop/assets/css/style.css
new file mode 100644
index 0000000000..5074c42090
--- /dev/null
+++ b/gui/packages/desktop/assets/css/style.css
@@ -0,0 +1,8 @@
+/* global */
+@import 'reset.css';
+@import 'fonts.css';
+@import 'global.css';
+
+/* app */
+@import '../../src/renderer/components/CustomScrollbars.css';
+@import '../../src/renderer/components/Switch.css';
diff --git a/gui/packages/desktop/src/assets/fonts/DINPro-Black.otf b/gui/packages/desktop/assets/fonts/DINPro-Black.otf
index 2092a7bbdc..2092a7bbdc 100755
--- a/gui/packages/desktop/src/assets/fonts/DINPro-Black.otf
+++ b/gui/packages/desktop/assets/fonts/DINPro-Black.otf
Binary files differ
diff --git a/gui/packages/desktop/src/assets/fonts/DINPro-Bold.otf b/gui/packages/desktop/assets/fonts/DINPro-Bold.otf
index 7c83953648..7c83953648 100755
--- a/gui/packages/desktop/src/assets/fonts/DINPro-Bold.otf
+++ b/gui/packages/desktop/assets/fonts/DINPro-Bold.otf
Binary files differ
diff --git a/gui/packages/desktop/src/assets/fonts/OpenSans-ExtraBold.ttf b/gui/packages/desktop/assets/fonts/OpenSans-ExtraBold.ttf
index 21f6f84a07..21f6f84a07 100755
--- a/gui/packages/desktop/src/assets/fonts/OpenSans-ExtraBold.ttf
+++ b/gui/packages/desktop/assets/fonts/OpenSans-ExtraBold.ttf
Binary files differ
diff --git a/gui/packages/desktop/src/assets/fonts/OpenSans-Semibold.ttf b/gui/packages/desktop/assets/fonts/OpenSans-Semibold.ttf
index 1a7679e394..1a7679e394 100755
--- a/gui/packages/desktop/src/assets/fonts/OpenSans-Semibold.ttf
+++ b/gui/packages/desktop/assets/fonts/OpenSans-Semibold.ttf
Binary files differ
diff --git a/gui/packages/desktop/src/assets/geo/cities.rbush.json b/gui/packages/desktop/assets/geo/cities.rbush.json
index 6894c1da47..6894c1da47 100644
--- a/gui/packages/desktop/src/assets/geo/cities.rbush.json
+++ b/gui/packages/desktop/assets/geo/cities.rbush.json
diff --git a/gui/packages/desktop/src/assets/geo/countries.rbush.json b/gui/packages/desktop/assets/geo/countries.rbush.json
index c29e26daea..c29e26daea 100644
--- a/gui/packages/desktop/src/assets/geo/countries.rbush.json
+++ b/gui/packages/desktop/assets/geo/countries.rbush.json
diff --git a/gui/packages/desktop/src/assets/geo/geometry.json b/gui/packages/desktop/assets/geo/geometry.json
index 332303ddc0..332303ddc0 100644
--- a/gui/packages/desktop/src/assets/geo/geometry.json
+++ b/gui/packages/desktop/assets/geo/geometry.json
diff --git a/gui/packages/desktop/src/assets/geo/geometry.rbush.json b/gui/packages/desktop/assets/geo/geometry.rbush.json
index b415d5374d..b415d5374d 100644
--- a/gui/packages/desktop/src/assets/geo/geometry.rbush.json
+++ b/gui/packages/desktop/assets/geo/geometry.rbush.json
diff --git a/gui/packages/desktop/src/assets/geo/states-provinces-lines.json b/gui/packages/desktop/assets/geo/states-provinces-lines.json
index 50f70b993f..50f70b993f 100644
--- a/gui/packages/desktop/src/assets/geo/states-provinces-lines.json
+++ b/gui/packages/desktop/assets/geo/states-provinces-lines.json
diff --git a/gui/packages/desktop/src/assets/geo/states-provinces-lines.rbush.json b/gui/packages/desktop/assets/geo/states-provinces-lines.rbush.json
index f2ebe22cfa..f2ebe22cfa 100644
--- a/gui/packages/desktop/src/assets/geo/states-provinces-lines.rbush.json
+++ b/gui/packages/desktop/assets/geo/states-provinces-lines.rbush.json
diff --git a/gui/packages/desktop/src/assets/images/app-header-backdrop.svg b/gui/packages/desktop/assets/images/app-header-backdrop.svg
index 4c811518bf..4c811518bf 100644
--- a/gui/packages/desktop/src/assets/images/app-header-backdrop.svg
+++ b/gui/packages/desktop/assets/images/app-header-backdrop.svg
diff --git a/gui/packages/desktop/src/assets/images/app-triangle.svg b/gui/packages/desktop/assets/images/app-triangle.svg
index e2f7ca044b..e2f7ca044b 100644
--- a/gui/packages/desktop/src/assets/images/app-triangle.svg
+++ b/gui/packages/desktop/assets/images/app-triangle.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-alert.svg b/gui/packages/desktop/assets/images/icon-alert.svg
index c11507a4a5..c11507a4a5 100644
--- a/gui/packages/desktop/src/assets/images/icon-alert.svg
+++ b/gui/packages/desktop/assets/images/icon-alert.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-arrow.svg b/gui/packages/desktop/assets/images/icon-arrow.svg
index 96f1356fbe..96f1356fbe 100755
--- a/gui/packages/desktop/src/assets/images/icon-arrow.svg
+++ b/gui/packages/desktop/assets/images/icon-arrow.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-back.svg b/gui/packages/desktop/assets/images/icon-back.svg
index 5ec98cbee6..5ec98cbee6 100644
--- a/gui/packages/desktop/src/assets/images/icon-back.svg
+++ b/gui/packages/desktop/assets/images/icon-back.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-chevron-down.svg b/gui/packages/desktop/assets/images/icon-chevron-down.svg
index e1e7af1104..e1e7af1104 100644
--- a/gui/packages/desktop/src/assets/images/icon-chevron-down.svg
+++ b/gui/packages/desktop/assets/images/icon-chevron-down.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-chevron-up.svg b/gui/packages/desktop/assets/images/icon-chevron-up.svg
index 84d8b56350..84d8b56350 100644
--- a/gui/packages/desktop/src/assets/images/icon-chevron-up.svg
+++ b/gui/packages/desktop/assets/images/icon-chevron-up.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-chevron.svg b/gui/packages/desktop/assets/images/icon-chevron.svg
index 923532cd28..923532cd28 100644
--- a/gui/packages/desktop/src/assets/images/icon-chevron.svg
+++ b/gui/packages/desktop/assets/images/icon-chevron.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-close-sml.svg b/gui/packages/desktop/assets/images/icon-close-sml.svg
index a379068d03..a379068d03 100644
--- a/gui/packages/desktop/src/assets/images/icon-close-sml.svg
+++ b/gui/packages/desktop/assets/images/icon-close-sml.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-close.svg b/gui/packages/desktop/assets/images/icon-close.svg
index df23259a13..df23259a13 100644
--- a/gui/packages/desktop/src/assets/images/icon-close.svg
+++ b/gui/packages/desktop/assets/images/icon-close.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-extLink.svg b/gui/packages/desktop/assets/images/icon-extLink.svg
index bed3cb37b3..bed3cb37b3 100644
--- a/gui/packages/desktop/src/assets/images/icon-extLink.svg
+++ b/gui/packages/desktop/assets/images/icon-extLink.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-fail.svg b/gui/packages/desktop/assets/images/icon-fail.svg
index 3467374198..3467374198 100755
--- a/gui/packages/desktop/src/assets/images/icon-fail.svg
+++ b/gui/packages/desktop/assets/images/icon-fail.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-fastest.svg b/gui/packages/desktop/assets/images/icon-fastest.svg
index 4c915da6d6..4c915da6d6 100755
--- a/gui/packages/desktop/src/assets/images/icon-fastest.svg
+++ b/gui/packages/desktop/assets/images/icon-fastest.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-nearest.svg b/gui/packages/desktop/assets/images/icon-nearest.svg
index badbf3674d..badbf3674d 100644
--- a/gui/packages/desktop/src/assets/images/icon-nearest.svg
+++ b/gui/packages/desktop/assets/images/icon-nearest.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-settings.svg b/gui/packages/desktop/assets/images/icon-settings.svg
index fbaec4e52c..fbaec4e52c 100755
--- a/gui/packages/desktop/src/assets/images/icon-settings.svg
+++ b/gui/packages/desktop/assets/images/icon-settings.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-spinner.svg b/gui/packages/desktop/assets/images/icon-spinner.svg
index 580d56a349..580d56a349 100644
--- a/gui/packages/desktop/src/assets/images/icon-spinner.svg
+++ b/gui/packages/desktop/assets/images/icon-spinner.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-success.svg b/gui/packages/desktop/assets/images/icon-success.svg
index 5a9e943406..5a9e943406 100755
--- a/gui/packages/desktop/src/assets/images/icon-success.svg
+++ b/gui/packages/desktop/assets/images/icon-success.svg
diff --git a/gui/packages/desktop/src/assets/images/icon-tick.svg b/gui/packages/desktop/assets/images/icon-tick.svg
index 16c701574a..16c701574a 100755
--- a/gui/packages/desktop/src/assets/images/icon-tick.svg
+++ b/gui/packages/desktop/assets/images/icon-tick.svg
diff --git a/gui/packages/desktop/src/assets/images/location-marker-secure.svg b/gui/packages/desktop/assets/images/location-marker-secure.svg
index 087fe5d0d4..087fe5d0d4 100755
--- a/gui/packages/desktop/src/assets/images/location-marker-secure.svg
+++ b/gui/packages/desktop/assets/images/location-marker-secure.svg
diff --git a/gui/packages/desktop/src/assets/images/location-marker-unsecure.svg b/gui/packages/desktop/assets/images/location-marker-unsecure.svg
index 509b8022f2..509b8022f2 100755
--- a/gui/packages/desktop/src/assets/images/location-marker-unsecure.svg
+++ b/gui/packages/desktop/assets/images/location-marker-unsecure.svg
diff --git a/gui/packages/desktop/src/assets/images/logo-icon.svg b/gui/packages/desktop/assets/images/logo-icon.svg
index c00cd67fb5..c00cd67fb5 100644
--- a/gui/packages/desktop/src/assets/images/logo-icon.svg
+++ b/gui/packages/desktop/assets/images/logo-icon.svg
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-1.png b/gui/packages/desktop/assets/images/menubar icons/lock-1.png
index b20bc19515..b20bc19515 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-1.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-1.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-10.png b/gui/packages/desktop/assets/images/menubar icons/lock-10.png
index 530e756c56..530e756c56 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-10.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-10.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-10@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-10@2x.png
index af73aa8c7b..af73aa8c7b 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-10@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-10@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-10Template.png b/gui/packages/desktop/assets/images/menubar icons/lock-10Template.png
index d11893684c..d11893684c 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-10Template.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-10Template.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-10Template@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-10Template@2x.png
index 71a918649c..71a918649c 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-10Template@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-10Template@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-1@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-1@2x.png
index 1c512d12bd..1c512d12bd 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-1@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-1@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-1Template.png b/gui/packages/desktop/assets/images/menubar icons/lock-1Template.png
index b20bc19515..b20bc19515 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-1Template.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-1Template.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-1Template@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-1Template@2x.png
index 1c512d12bd..1c512d12bd 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-1Template@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-1Template@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-2.png b/gui/packages/desktop/assets/images/menubar icons/lock-2.png
index d98d05d951..d98d05d951 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-2.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-2.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-2@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-2@2x.png
index c92dec19ec..c92dec19ec 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-2@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-2@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-2Template.png b/gui/packages/desktop/assets/images/menubar icons/lock-2Template.png
index d98d05d951..d98d05d951 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-2Template.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-2Template.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-2Template@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-2Template@2x.png
index c92dec19ec..c92dec19ec 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-2Template@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-2Template@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-3.png b/gui/packages/desktop/assets/images/menubar icons/lock-3.png
index 871f8402bf..871f8402bf 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-3.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-3.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-3@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-3@2x.png
index d961af45f3..d961af45f3 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-3@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-3@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-3Template.png b/gui/packages/desktop/assets/images/menubar icons/lock-3Template.png
index 871f8402bf..871f8402bf 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-3Template.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-3Template.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-3Template@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-3Template@2x.png
index d961af45f3..d961af45f3 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-3Template@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-3Template@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-4.png b/gui/packages/desktop/assets/images/menubar icons/lock-4.png
index 6fcb60c663..6fcb60c663 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-4.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-4.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-4@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-4@2x.png
index f67b4c0921..f67b4c0921 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-4@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-4@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-4Template.png b/gui/packages/desktop/assets/images/menubar icons/lock-4Template.png
index 6fcb60c663..6fcb60c663 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-4Template.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-4Template.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-4Template@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-4Template@2x.png
index f67b4c0921..f67b4c0921 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-4Template@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-4Template@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-5.png b/gui/packages/desktop/assets/images/menubar icons/lock-5.png
index 43d02ab1e0..43d02ab1e0 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-5.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-5.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-5@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-5@2x.png
index 1f05adf802..1f05adf802 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-5@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-5@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-5Template.png b/gui/packages/desktop/assets/images/menubar icons/lock-5Template.png
index 43d02ab1e0..43d02ab1e0 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-5Template.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-5Template.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-5Template@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-5Template@2x.png
index 1f05adf802..1f05adf802 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-5Template@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-5Template@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-6.png b/gui/packages/desktop/assets/images/menubar icons/lock-6.png
index e282ff8dad..e282ff8dad 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-6.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-6.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-6@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-6@2x.png
index f76ab999f1..f76ab999f1 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-6@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-6@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-6Template.png b/gui/packages/desktop/assets/images/menubar icons/lock-6Template.png
index e282ff8dad..e282ff8dad 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-6Template.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-6Template.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-6Template@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-6Template@2x.png
index f76ab999f1..f76ab999f1 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-6Template@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-6Template@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-7.png b/gui/packages/desktop/assets/images/menubar icons/lock-7.png
index 1299817a53..1299817a53 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-7.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-7.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-7@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-7@2x.png
index f3a1428ad4..f3a1428ad4 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-7@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-7@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-7Template.png b/gui/packages/desktop/assets/images/menubar icons/lock-7Template.png
index 1299817a53..1299817a53 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-7Template.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-7Template.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-7Template@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-7Template@2x.png
index f3a1428ad4..f3a1428ad4 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-7Template@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-7Template@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-8.png b/gui/packages/desktop/assets/images/menubar icons/lock-8.png
index 161e4f5e82..161e4f5e82 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-8.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-8.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-8@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-8@2x.png
index 5b12910e4a..5b12910e4a 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-8@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-8@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-8Template.png b/gui/packages/desktop/assets/images/menubar icons/lock-8Template.png
index 161e4f5e82..161e4f5e82 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-8Template.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-8Template.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-8Template@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-8Template@2x.png
index 5b12910e4a..5b12910e4a 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-8Template@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-8Template@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-9.png b/gui/packages/desktop/assets/images/menubar icons/lock-9.png
index c823aa87a1..c823aa87a1 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-9.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-9.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-9@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-9@2x.png
index e4dc28a192..e4dc28a192 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-9@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-9@2x.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-9Template.png b/gui/packages/desktop/assets/images/menubar icons/lock-9Template.png
index c823aa87a1..c823aa87a1 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-9Template.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-9Template.png
Binary files differ
diff --git a/gui/packages/desktop/src/assets/images/menubar icons/lock-9Template@2x.png b/gui/packages/desktop/assets/images/menubar icons/lock-9Template@2x.png
index e4dc28a192..e4dc28a192 100644
--- a/gui/packages/desktop/src/assets/images/menubar icons/lock-9Template@2x.png
+++ b/gui/packages/desktop/assets/images/menubar icons/lock-9Template@2x.png
Binary files differ
diff --git a/gui/packages/desktop/init.js b/gui/packages/desktop/init.js
index e489d4ef8e..448b1dc4f0 100644
--- a/gui/packages/desktop/init.js
+++ b/gui/packages/desktop/init.js
@@ -1 +1 @@
-require('./build/main');
+require('./build/src/main');
diff --git a/gui/packages/desktop/package.json b/gui/packages/desktop/package.json
index 0253f766d2..f25c1f548b 100644
--- a/gui/packages/desktop/package.json
+++ b/gui/packages/desktop/package.json
@@ -13,6 +13,7 @@
"license": "GPL-3.0",
"dependencies": {
"@mullvad/components": "0.1.0",
+ "@mullvad/config": "0.1.0",
"JSONStream": "^1.3.5",
"connected-react-router": "^5.0.1",
"d3-geo-projection": "^2.4.1",
@@ -22,12 +23,12 @@
"mkdirp": "^0.5.1",
"moment": "^2.20.1",
"rbush": "^2.0.2",
- "react": "^16.4.0",
- "react-dom": "^16.4.0",
+ "react": "^16.5.0",
+ "react-dom": "^16.5.0",
"react-redux": "^5.1.0",
"react-router": "^4.3.1",
"react-simple-maps": "^0.12.1",
- "reactxp": "^1.4.0",
+ "reactxp": "^1.5.0",
"redux": "^4.0.1",
"uuid": "^3.0.1",
"validated": "^2.0.1"
@@ -36,15 +37,21 @@
"nseventmonitor": "https://github.com/mullvad/NSEventMonitor.git#0.0.12"
},
"devDependencies": {
- "@babel/cli": "^7.1.5",
- "@babel/core": "^7.1.5",
- "@babel/node": "^7.0.0",
- "@babel/plugin-proposal-class-properties": "^7.1.0",
- "@babel/preset-env": "^7.1.5",
- "@babel/preset-flow": "^7.0.0",
- "@babel/preset-react": "^7.0.0",
- "@babel/preset-typescript": "^7.1.0",
- "@babel/register": "^7.0.0",
+ "@types/chai": "^4.1.7",
+ "@types/chai-spies": "^1.0.0",
+ "@types/chai-as-promised": "^7.1.0",
+ "@types/d3-geo": "^1.11.0",
+ "@types/enzyme": "^3.1.15",
+ "@types/enzyme-adapter-react-16": "^1.0.3",
+ "@types/node": "^10.12.3",
+ "@types/rbush": "^2.0.2",
+ "@types/react": "16.3.18",
+ "@types/react-dom": "16.0.7",
+ "@types/react-router": "^4.4.3",
+ "@types/react-redux": "^7.0.0",
+ "@types/sinon": "^7.0.5",
+ "@types/mkdirp": "^0.5.2",
+ "@types/uuid": "^3.4.4",
"browser-sync": "^2.26.3",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
@@ -59,23 +66,34 @@
"mock-socket": "^8.0.5",
"npm-run-all": "^4.0.1",
"rimraf": "^2.5.4",
- "sinon": "^7.1.1"
+ "sinon": "^7.1.1",
+ "ts-node": "^7.0.1",
+ "tslint": "^5.12.1",
+ "tslint-config-prettier": "^1.17.0",
+ "typescript": "^3.2.4"
},
"scripts": {
"postinstall": "electron-builder install-app-deps",
- "develop": "cross-env yarn run private:compile --source-maps true && run-p -r private:watch private:serve",
- "test": "electron-mocha --renderer -R spec --require @babel/register --require-main \"test/setup/main.js\" --preload \"test/setup/renderer.js\" \"test/*.spec.js\" \"test/**/*.spec.js\"",
- "pack:mac": "run-s private:clean private:compile private:build:mac private:postbuild:mac",
- "pack:win": "run-s private:clean private:compile private:build:win",
- "pack:linux": "run-s private:clean private:compile private:build:linux",
+ "build": "run-s private:clean private:copy-assets private:compile",
+ "lint": "tslint -t stylish -p . || true",
+ "develop": "cross-env run-s private:copy-assets private:compile:dev && run-p -r private:watch private:serve",
+ "test": "electron-mocha --renderer -R spec --require ts-node/register --require-main ts-node/register --require-main \"test/setup/main.ts\" --preload \"test/setup/renderer.ts\" \"test/*.spec.ts\" \"test/**/*.spec.ts\" \"test/**/*.spec.tsx\" || true",
+ "pack:mac": "run-s build private:build:mac private:postbuild:mac",
+ "pack:win": "run-s build private:build:win",
+ "pack:linux": "run-s build private:build:linux",
"private:build:mac": "yarn run private:build --mac",
"private:postbuild:mac": "rimraf ../../../dist/mac",
"private:build:win": "yarn run private:build --win",
"private:build:linux": "yarn run private:build --linux",
"private:build": "electron-builder",
- "private:watch": "cross-env yarn run private:compile --source-maps true --watch --skip-initial-build",
- "private:serve": "cross-env babel-node scripts/serve.js",
- "private:compile": "babel src/ --copy-files --out-dir build --extensions \".ts,.tsx,.js\"",
+ "private:copy-assets": "run-s private:assets:main private:assets:html private:assets:css",
+ "private:assets:main": "cross-env mkdir -p ./build/assets && cp -R ./assets ./build",
+ "private:assets:html": "cross-env mkdir -p ./build/src/renderer && cp ./src/renderer/index.html ./build/src/renderer",
+ "private:assets:css": "cross-env mkdir -p ./build/src/renderer/components && cp ./src/renderer/components/*.css ./build/src/renderer/components",
+ "private:watch": "cross-env yarn run private:compile:dev --watch --preserveWatchOutput",
+ "private:serve": "cross-env node scripts/serve.js",
+ "private:compile": "tsc",
+ "private:compile:dev": "tsc --sourceMap",
"private:clean": "rimraf build"
}
}
diff --git a/gui/packages/desktop/scripts/serve.js b/gui/packages/desktop/scripts/serve.js
index 3b2e7925b3..effbc93446 100644
--- a/gui/packages/desktop/scripts/serve.js
+++ b/gui/packages/desktop/scripts/serve.js
@@ -1,7 +1,7 @@
-import { spawn } from 'child_process';
-import electron from 'electron';
-import browserSync from 'browser-sync';
-import browserSyncConnectUtils from 'browser-sync/dist/connect-utils';
+const { spawn } = require('child_process');
+const electron = require('electron');
+const browserSync = require('browser-sync');
+const browserSyncConnectUtils = require('browser-sync/dist/connect-utils');
const bsync = browserSync.create();
@@ -58,13 +58,15 @@ bsync.init(
let child = runElectron(browserSyncUrl);
- bsync.watch(['build/main/**/*', 'build/shared/**/*']).on('change', () => {
- child.removeListener('close', onCloseElectron);
- child.kill();
+ bsync
+ .watch(['build/src/config.json', 'build/src/main/**/*', 'build/src/shared/**/*'])
+ .on('change', () => {
+ child.removeListener('close', onCloseElectron);
+ child.kill();
- child = runElectron(browserSyncUrl);
- });
+ child = runElectron(browserSyncUrl);
+ });
- bsync.watch('build/renderer/**/*').on('change', bsync.reload);
+ bsync.watch('build/src/renderer/**/*').on('change', bsync.reload);
},
);
diff --git a/gui/packages/desktop/src/assets/css/style.css b/gui/packages/desktop/src/assets/css/style.css
deleted file mode 100644
index 394e0504b6..0000000000
--- a/gui/packages/desktop/src/assets/css/style.css
+++ /dev/null
@@ -1,8 +0,0 @@
-/* global */
-@import 'reset.css';
-@import 'fonts.css';
-@import 'global.css';
-
-/* app */
-@import '../../renderer/components/CustomScrollbars.css';
-@import '../../renderer/components/Switch.css';
diff --git a/gui/packages/desktop/src/main/autostart.js b/gui/packages/desktop/src/main/autostart.ts
index 6f33cca37b..512a53d4ce 100644
--- a/gui/packages/desktop/src/main/autostart.js
+++ b/gui/packages/desktop/src/main/autostart.ts
@@ -1,7 +1,5 @@
-// @flow
-
-import fs from 'fs';
-import path from 'path';
+import * as fs from 'fs';
+import * as path from 'path';
import { promisify } from 'util';
import { app } from 'electron';
import log from 'electron-log';
diff --git a/gui/packages/desktop/src/main/daemon-rpc.js b/gui/packages/desktop/src/main/daemon-rpc.ts
index b5f19c9356..ff319f90a2 100644
--- a/gui/packages/desktop/src/main/daemon-rpc.js
+++ b/gui/packages/desktop/src/main/daemon-rpc.ts
@@ -1,12 +1,10 @@
-// @flow
-
import JsonRpcClient, {
RemoteError as JsonRpcRemoteError,
TimeOutError as JsonRpcTimeOutError,
SocketTransport,
} from './jsonrpc-client';
import { CommunicationError, InvalidAccountError, NoDaemonError } from './errors';
-import type {
+import {
AccountData,
AccountToken,
AppVersionInfo,
@@ -30,7 +28,7 @@ import {
} from 'validated/schema';
import { validate } from 'validated/object';
-import type { Node as SchemaNode } from 'validated/schema';
+import { Node as SchemaNode } from 'validated/schema';
const LocationSchema = maybe(
partialObject({
@@ -228,9 +226,9 @@ const AppVersionInfoSchema = partialObject({
export class ConnectionObserver {
_openHandler: () => void;
- _closeHandler: (error: ?Error) => void;
+ _closeHandler: (error?: Error) => void;
- constructor(openHandler: () => void, closeHandler: (error: ?Error) => void) {
+ constructor(openHandler: () => void, closeHandler: (error?: Error) => void) {
this._openHandler = openHandler;
this._closeHandler = closeHandler;
}
@@ -239,7 +237,7 @@ export class ConnectionObserver {
this._openHandler();
};
- _onClose = (error: ?Error) => {
+ _onClose = (error?: Error) => {
this._closeHandler(error);
};
}
@@ -272,14 +270,14 @@ const SettingsSchema = partialObject({
});
export class ResponseParseError extends Error {
- _validationError: ?Error;
+ _validationError?: Error;
- constructor(message: string, validationError: ?Error) {
+ constructor(message: string, validationError?: Error) {
super(message);
this._validationError = validationError;
}
- get validationError(): ?Error {
+ get validationError(): Error | undefined {
return this._validationError;
}
}
@@ -335,14 +333,14 @@ export class DaemonRpc {
async getRelayLocations(): Promise<RelayList> {
const response = await this._transport.send('get_relay_locations');
try {
- return camelCaseObjectKeys(validate(RelayListSchema, response));
+ return camelCaseObjectKeys(validate(RelayListSchema, response)) as RelayList;
} catch (error) {
throw new ResponseParseError('Invalid response from get_relay_locations', error);
}
}
- async setAccount(accountToken: ?AccountToken): Promise<void> {
- await this._transport.send('set_account', accountToken);
+ async setAccount(accountToken?: AccountToken): Promise<void> {
+ await this._transport.send('set_account', [accountToken]);
}
async updateRelaySettings(relaySettings: RelaySettingsUpdate): Promise<void> {
@@ -361,7 +359,7 @@ export class DaemonRpc {
await this._transport.send('set_block_when_disconnected', [blockWhenDisconnected]);
}
- async setOpenVpnMssfix(mssfix: ?number): Promise<void> {
+ async setOpenVpnMssfix(mssfix?: number): Promise<void> {
await this._transport.send('set_openvpn_mssfix', [mssfix]);
}
@@ -377,13 +375,10 @@ export class DaemonRpc {
await this._transport.send('disconnect');
}
- async getLocation(): Promise<?Location> {
+ async getLocation(): Promise<Location | undefined> {
const response = await this._transport.send('get_current_location', [], NETWORK_CALL_TIMEOUT);
try {
- const validatedResponse = validate(LocationSchema, response);
- if (validatedResponse) {
- return camelCaseObjectKeys(validatedResponse);
- }
+ return camelCaseObjectKeys(validate(LocationSchema, response)) as Location;
} catch (error) {
throw new ResponseParseError('Invalid response from get_current_location', error);
}
@@ -392,7 +387,9 @@ export class DaemonRpc {
async getState(): Promise<TunnelStateTransition> {
const response = await this._transport.send('get_state');
try {
- return camelCaseObjectKeys(validate(TunnelStateTransitionSchema, response));
+ return camelCaseObjectKeys(
+ validate(TunnelStateTransitionSchema, response),
+ ) as TunnelStateTransition;
} catch (error) {
throw new ResponseParseError('Invalid response from get_state', error);
}
@@ -401,7 +398,7 @@ export class DaemonRpc {
async getSettings(): Promise<Settings> {
const response = await this._transport.send('get_settings');
try {
- return camelCaseObjectKeys(validate(SettingsSchema, response));
+ return camelCaseObjectKeys(validate(SettingsSchema, response)) as Settings;
} catch (error) {
throw new ResponseParseError('Invalid response from get_settings', error);
}
@@ -410,7 +407,9 @@ export class DaemonRpc {
subscribeStateListener(listener: SubscriptionListener<TunnelStateTransition>): Promise<void> {
return this._transport.subscribe('new_state', (payload) => {
try {
- const newState = camelCaseObjectKeys(validate(TunnelStateTransitionSchema, payload));
+ const newState = camelCaseObjectKeys(
+ validate(TunnelStateTransitionSchema, payload),
+ ) as TunnelStateTransition;
listener._onEvent(newState);
} catch (error) {
listener._onError(new ResponseParseError('Invalid payload from new_state', error));
@@ -421,7 +420,7 @@ export class DaemonRpc {
subscribeSettingsListener(listener: SubscriptionListener<Settings>): Promise<void> {
return this._transport.subscribe('settings', (payload) => {
try {
- const newSettings = camelCaseObjectKeys(validate(SettingsSchema, payload));
+ const newSettings = camelCaseObjectKeys(validate(SettingsSchema, payload)) as Settings;
listener._onEvent(newSettings);
} catch (error) {
listener._onError(new ResponseParseError('Invalid payload from settings', error));
@@ -434,7 +433,7 @@ export class DaemonRpc {
try {
return validate(arrayOf(string), response);
} catch (error) {
- throw new ResponseParseError('Invalid response from get_account_history', null);
+ throw new ResponseParseError('Invalid response from get_account_history');
}
}
@@ -447,16 +446,16 @@ export class DaemonRpc {
try {
return validate(string, response);
} catch (error) {
- throw new ResponseParseError('Invalid response from get_current_version', null);
+ throw new ResponseParseError('Invalid response from get_current_version');
}
}
async getVersionInfo(): Promise<AppVersionInfo> {
const response = await this._transport.send('get_version_info', [], NETWORK_CALL_TIMEOUT);
try {
- return camelCaseObjectKeys(validate(AppVersionInfoSchema, response));
+ return camelCaseObjectKeys(validate(AppVersionInfoSchema, response)) as AppVersionInfo;
} catch (error) {
- throw new ResponseParseError('Invalid response from get_version_info', null);
+ throw new ResponseParseError('Invalid response from get_version_info');
}
}
}
@@ -471,15 +470,18 @@ function camelCaseToUnderscore(str: string): string {
.toLowerCase();
}
-function camelCaseObjectKeys(object: Object) {
+function camelCaseObjectKeys(object: { [key: string]: any }) {
return transformObjectKeys(object, underscoreToCamelCase);
}
-function underscoreObjectKeys(object: Object) {
+function underscoreObjectKeys(object: { [key: string]: any }) {
return transformObjectKeys(object, camelCaseToUnderscore);
}
-function transformObjectKeys(object: Object, keyTransformer: (string) => string) {
+function transformObjectKeys(
+ object: { [key: string]: any },
+ keyTransformer: (key: string) => string,
+) {
for (const sourceKey of Object.keys(object)) {
const targetKey = keyTransformer(sourceKey);
const sourceValue = object[sourceKey];
diff --git a/gui/packages/desktop/src/main/errors.js b/gui/packages/desktop/src/main/errors.ts
index 67f87501dd..f13b99e3e9 100644
--- a/gui/packages/desktop/src/main/errors.js
+++ b/gui/packages/desktop/src/main/errors.ts
@@ -1,5 +1,3 @@
-// @flow
-
export class NoCreditError extends Error {
constructor() {
super("Account doesn't have enough credit available for connection");
diff --git a/gui/packages/desktop/src/main/gui-settings.js b/gui/packages/desktop/src/main/gui-settings.ts
index a6a6efd30b..1b68b5e13c 100644
--- a/gui/packages/desktop/src/main/gui-settings.js
+++ b/gui/packages/desktop/src/main/gui-settings.ts
@@ -1,11 +1,9 @@
-// @flow
-
-import fs from 'fs';
-import log from 'electron-log';
-import path from 'path';
+import * as fs from 'fs';
+import * as path from 'path';
import { app } from 'electron';
+import log from 'electron-log';
-import type { GuiSettingsState } from '../shared/gui-settings-state';
+import { GuiSettingsState } from '../shared/gui-settings-state';
export default class GuiSettings {
_state: GuiSettingsState = {
@@ -14,7 +12,7 @@ export default class GuiSettings {
startMinimized: false,
};
- onChange: ?(newState: GuiSettingsState, oldState: GuiSettingsState) => void;
+ onChange?: (newState: GuiSettingsState, oldState: GuiSettingsState) => void;
load() {
try {
diff --git a/gui/packages/desktop/src/main/index.js b/gui/packages/desktop/src/main/index.ts
index 4da61bf3af..70890f0a2a 100644
--- a/gui/packages/desktop/src/main/index.js
+++ b/gui/packages/desktop/src/main/index.ts
@@ -1,11 +1,9 @@
-// @flow
-
-import fs from 'fs';
+import * as fs from 'fs';
import log from 'electron-log';
-import path from 'path';
+import * as path from 'path';
import { execFile } from 'child_process';
import mkdirp from 'mkdirp';
-import uuid from 'uuid';
+import * as uuid from 'uuid';
import { app, screen, BrowserWindow, ipcMain, Tray, Menu, nativeImage } from 'electron';
import { getOpenAtLogin, setOpenAtLogin } from './autostart';
@@ -13,12 +11,12 @@ import NotificationController from './notification-controller';
import WindowController from './window-controller';
import TrayIconController from './tray-icon-controller';
-import type { TrayIconType } from './tray-icon-controller';
+import { TrayIconType } from './tray-icon-controller';
import { IpcMainEventChannel } from '../shared/ipc-event-channel';
import { DaemonRpc, ConnectionObserver, SubscriptionListener } from './daemon-rpc';
-import type {
+import {
AccountToken,
AppVersionInfo,
Location,
@@ -41,32 +39,32 @@ const DAEMON_RPC_PATH =
type AppQuitStage = 'unready' | 'initiated' | 'ready';
export type CurrentAppVersionInfo = {
- gui: string,
- daemon: string,
- isConsistent: boolean,
+ gui: string;
+ daemon: string;
+ isConsistent: boolean;
};
export type AppUpgradeInfo = {
- nextUpgrade: ?string,
- upToDate: boolean,
+ nextUpgrade?: string;
+ upToDate: boolean;
} & AppVersionInfo;
const ApplicationMain = {
_notificationController: new NotificationController(),
- _windowController: (null: ?WindowController),
- _trayIconController: (null: ?TrayIconController),
+ _windowController: undefined as WindowController | undefined,
+ _trayIconController: undefined as TrayIconController | undefined,
_daemonRpc: new DaemonRpc(),
_reconnectBackoff: new ReconnectionBackoff(),
_connectedToDaemon: false,
_logFilePath: '',
- _oldLogFilePath: (null: ?string),
- _quitStage: ('unready': AppQuitStage),
+ _oldLogFilePath: undefined as undefined | string,
+ _quitStage: 'unready' as AppQuitStage,
- _tunnelState: ({ state: 'disconnected' }: TunnelStateTransition),
- _settings: ({
- accountToken: null,
+ _tunnelState: { state: 'disconnected' } as TunnelStateTransition,
+ _settings: {
+ accountToken: undefined,
allowLan: false,
autoConnect: false,
blockWhenDisconnected: false,
@@ -81,38 +79,38 @@ const ApplicationMain = {
enableIpv6: false,
},
openvpn: {
- mssfix: null,
- proxy: null,
+ mssfix: undefined,
+ proxy: undefined,
},
wireguard: {
- mtu: null,
- fwmark: null,
+ mtu: undefined,
+ fwmark: undefined,
},
},
- }: Settings),
+ } as Settings,
_guiSettings: new GuiSettings(),
- _location: (null: ?Location),
- _lastDisconnectedLocation: (null: ?Location),
+ _location: undefined as Location | undefined,
+ _lastDisconnectedLocation: undefined as Location | undefined,
- _relays: ({ countries: [] }: RelayList),
- _relaysInterval: (null: ?IntervalID),
+ _relays: { countries: [] } as RelayList,
+ _relaysInterval: undefined as NodeJS.Timeout | undefined,
- _currentVersion: ({
+ _currentVersion: {
daemon: '',
gui: '',
isConsistent: true,
- }: CurrentAppVersionInfo),
+ } as CurrentAppVersionInfo,
- _upgradeVersion: ({
+ _upgradeVersion: {
currentIsSupported: true,
latest: {
latestStable: '',
latest: '',
},
- nextUpgrade: null,
+ nextUpgrade: undefined,
upToDate: true,
- }: AppUpgradeInfo),
- _latestVersionInterval: (null: ?IntervalID),
+ } as AppUpgradeInfo,
+ _latestVersionInterval: undefined as NodeJS.Timeout | undefined,
run() {
// Since electron's GPU blacklists are broken, GPU acceleration won't work on older distros
@@ -317,7 +315,7 @@ const ApplicationMain = {
if (process.env.NODE_ENV === 'development') {
await this._installDevTools();
- window.openDevTools({ mode: 'detach' });
+ window.webContents.openDevTools({ mode: 'detach' });
}
switch (process.platform) {
@@ -416,7 +414,7 @@ const ApplicationMain = {
}
},
- _onDaemonDisconnected(error: ?Error) {
+ _onDaemonDisconnected(error?: Error) {
// make sure we were connected before to distinguish between a failed attempt to reconnect and
// connection loss.
const wasConnected = this._connectedToDaemon;
@@ -432,7 +430,7 @@ const ApplicationMain = {
if (this._windowController) {
IpcMainEventChannel.daemonDisconnected.notify(
this._windowController.webContents,
- error ? error.message : null,
+ error ? error.message : undefined,
);
}
}
@@ -461,7 +459,7 @@ const ApplicationMain = {
});
},
- _recoverFromBootstrapError(_error: ?Error) {
+ _recoverFromBootstrapError(_error?: Error) {
// Attempt to reconnect to daemon if the program fails to fetch settings, tunnel state or
// subscribe for RPC events.
this._daemonRpc.disconnect();
@@ -550,7 +548,7 @@ const ApplicationMain = {
_stopRelaysPeriodicUpdates() {
if (this._relaysInterval) {
clearInterval(this._relaysInterval);
- this._relaysInterval = null;
+ this._relaysInterval = undefined;
log.debug('Stop relays periodic updates');
}
@@ -577,11 +575,15 @@ const ApplicationMain = {
return version.includes('-');
}
- function nextUpgrade(current: string, latest: string, latestStable: string): ?string {
+ function nextUpgrade(
+ current: string,
+ latest: string,
+ latestStable: string,
+ ): string | undefined {
if (isBeta(current)) {
- return current === latest ? null : latest;
+ return current === latest ? undefined : latest;
} else {
- return current === latestStable ? null : latestStable;
+ return current === latestStable ? undefined : latestStable;
}
}
@@ -651,12 +653,12 @@ const ApplicationMain = {
if (this._latestVersionInterval) {
clearInterval(this._latestVersionInterval);
- this._latestVersionInterval = null;
+ this._latestVersionInterval = undefined;
}
},
- _shouldSuppressNotifications() {
- return this._windowController && this._windowController.isVisible();
+ _shouldSuppressNotifications(): boolean {
+ return this._windowController ? this._windowController.isVisible() : false;
},
async _updateLocation() {
@@ -721,9 +723,6 @@ const ApplicationMain = {
} else {
return 'unsecured';
}
-
- default:
- throw new Error(`Invalid tunnel state: ${(tunnelState.state: empty)}`);
}
},
@@ -766,7 +765,7 @@ const ApplicationMain = {
IpcMainEventChannel.settings.handleBlockWhenDisconnected((blockWhenDisconnected: boolean) =>
this._daemonRpc.setBlockWhenDisconnected(blockWhenDisconnected),
);
- IpcMainEventChannel.settings.handleOpenVpnMssfix((mssfix: ?number) =>
+ IpcMainEventChannel.settings.handleOpenVpnMssfix((mssfix?: number) =>
this._daemonRpc.setOpenVpnMssfix(mssfix),
);
IpcMainEventChannel.settings.handleUpdateRelaySettings((update: RelaySettingsUpdate) =>
@@ -795,7 +794,7 @@ const ApplicationMain = {
IpcMainEventChannel.account.handleSet((token: AccountToken) =>
this._daemonRpc.setAccount(token),
);
- IpcMainEventChannel.account.handleUnset(() => this._daemonRpc.setAccount(null));
+ IpcMainEventChannel.account.handleUnset(() => this._daemonRpc.setAccount());
IpcMainEventChannel.account.handleGetData((token: AccountToken) =>
this._daemonRpc.getAccountData(token),
);
@@ -812,44 +811,53 @@ const ApplicationMain = {
}
});
- ipcMain.on('collect-logs', (event, requestId, toRedact) => {
- const reportPath = path.join(app.getPath('temp'), uuid.v4() + '.log');
- const executable = resolveBin('problem-report');
- const args = ['collect', '--output', reportPath];
- if (toRedact.length > 0) {
- args.push('--redact', ...toRedact, '--');
- }
- args.push(this._logFilePath);
- if (this._oldLogFilePath) {
- args.push(this._oldLogFilePath);
- }
+ ipcMain.on(
+ 'collect-logs',
+ (event: Electron.Event, requestId: string, toRedact: Array<string>) => {
+ const reportPath = path.join(app.getPath('temp'), uuid.v4() + '.log');
+ const executable = resolveBin('problem-report');
+ const args = ['collect', '--output', reportPath];
+ if (toRedact.length > 0) {
+ args.push('--redact', ...toRedact, '--');
+ }
+ args.push(this._logFilePath);
+ if (this._oldLogFilePath) {
+ args.push(this._oldLogFilePath);
+ }
- execFile(executable, args, { windowsHide: true }, (error, stdout, stderr) => {
- if (error) {
- log.error(
- `Failed to collect a problem report: ${error.message}
+ execFile(executable, args, { windowsHide: true }, (error, stdout, stderr) => {
+ if (error) {
+ log.error(
+ `Failed to collect a problem report: ${error.message}
Stdout: ${stdout.toString()}
Stderr: ${stderr.toString()}`,
- );
+ );
- event.sender.send('collect-logs-reply', requestId, {
- success: false,
- error: error.message,
- });
- } else {
- log.debug(`Problem report was written to ${reportPath}`);
+ event.sender.send('collect-logs-reply', requestId, {
+ success: false,
+ error: error.message,
+ });
+ } else {
+ log.debug(`Problem report was written to ${reportPath}`);
- event.sender.send('collect-logs-reply', requestId, {
- success: true,
- reportPath,
- });
- }
- });
- });
+ event.sender.send('collect-logs-reply', requestId, {
+ success: true,
+ reportPath,
+ });
+ }
+ });
+ },
+ );
ipcMain.on(
'send-problem-report',
- (event, requestId, email: string, message: string, savedReport: string) => {
+ (
+ event: Electron.Event,
+ requestId: string,
+ email: string,
+ message: string,
+ savedReport: string,
+ ) => {
const executable = resolveBin('problem-report');
const args = ['send', '--email', email, '--message', message, '--report', savedReport];
@@ -962,7 +970,7 @@ const ApplicationMain = {
},
_setAppMenu() {
- const template = [
+ const template: Electron.MenuItemConstructorOptions[] = [
{
label: 'Mullvad',
submenu: [{ role: 'about' }, { type: 'separator' }, { role: 'quit' }],
@@ -982,7 +990,7 @@ const ApplicationMain = {
},
_addContextMenu(window: BrowserWindow) {
- const menuTemplate = [
+ const menuTemplate: Electron.MenuItemConstructorOptions[] = [
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
@@ -993,30 +1001,33 @@ const ApplicationMain = {
// add inspect element on right click menu
window.webContents.on(
'context-menu',
- (_e: Event, props: { x: number, y: number, isEditable: boolean }) => {
+ (_e: Event, props: { x: number; y: number; isEditable: boolean }) => {
const inspectTemplate = [
{
label: 'Inspect element',
click() {
- window.openDevTools({ mode: 'detach' });
- window.inspectElement(props.x, props.y);
+ window.webContents.openDevTools({ mode: 'detach' });
+ window.webContents.inspectElement(props.x, props.y);
},
},
];
if (props.isEditable) {
- let inputMenu = menuTemplate;
-
// mixin 'inspect element' into standard menu when in development mode
if (process.env.NODE_ENV === 'development') {
- inputMenu = menuTemplate.concat([{ type: 'separator' }], inspectTemplate);
- }
+ const inputMenu: Electron.MenuItemConstructorOptions[] = [
+ { type: 'separator' },
+ ...inspectTemplate,
+ ];
- Menu.buildFromTemplate(inputMenu).popup(window);
+ Menu.buildFromTemplate(inputMenu).popup({ window });
+ } else {
+ Menu.buildFromTemplate(menuTemplate).popup({ window });
+ }
} else if (process.env.NODE_ENV === 'development') {
// display inspect element for all non-editable
// elements when in development mode
- Menu.buildFromTemplate(inspectTemplate).popup(window);
+ Menu.buildFromTemplate(inspectTemplate).popup({ window });
}
},
);
diff --git a/gui/packages/desktop/src/main/jsonrpc-client.js b/gui/packages/desktop/src/main/jsonrpc-client.ts
index 7635b62827..811c151fb5 100644
--- a/gui/packages/desktop/src/main/jsonrpc-client.js
+++ b/gui/packages/desktop/src/main/jsonrpc-client.ts
@@ -1,46 +1,44 @@
-// @flow
-
import assert from 'assert';
import { EventEmitter } from 'events';
import log from 'electron-log';
import jsonrpc from 'jsonrpc-lite';
-import uuid from 'uuid';
-import net from 'net';
+import * as uuid from 'uuid';
+import * as net from 'net';
import JSONStream from 'JSONStream';
export type UnansweredRequest = {
- resolve: (mixed) => void,
- reject: (mixed) => void,
- timerId: TimeoutID,
- message: Object,
+ resolve: (value: any) => void;
+ reject: (value: any) => void;
+ timerId: NodeJS.Timeout;
+ message: Object;
};
export type JsonRpcErrorResponse = {
- type: 'error',
+ type: 'error';
payload: {
- id: string,
+ id: string;
error: {
- code: number,
- message: string,
- },
- },
+ code: number;
+ message: string;
+ };
+ };
};
export type JsonRpcNotification = {
- type: 'notification',
+ type: 'notification';
payload: {
- method: string,
+ method: string;
params: {
- subscription: string,
- result: mixed,
- },
- },
+ subscription: string;
+ result: any;
+ };
+ };
};
export type JsonRpcSuccess = {
- type: 'success',
+ type: 'success';
payload: {
- id: string,
- result: mixed,
- },
+ id: string;
+ result: any;
+ };
};
export type JsonRpcMessage = JsonRpcErrorResponse | JsonRpcNotification | JsonRpcSuccess;
@@ -78,9 +76,9 @@ export class TimeOutError extends Error {
}
export class SubscriptionError extends Error {
- _reply: mixed;
+ _reply: any;
- constructor(message: string, reply: mixed) {
+ constructor(message: string, reply: any) {
const replyString = JSON.stringify(reply);
super(`${message}: ${replyString}`);
@@ -88,7 +86,7 @@ export class SubscriptionError extends Error {
this._reply = reply;
}
- get reply(): mixed {
+ get reply(): any {
return this._reply;
}
}
@@ -127,7 +125,7 @@ const DEFAULT_TIMEOUT_MILLIS = 5000;
export default class JsonRpcClient<T> extends EventEmitter {
_unansweredRequests: Map<string, UnansweredRequest> = new Map();
- _subscriptions: Map<string | number, (mixed) => void> = new Map();
+ _subscriptions: Map<string | number, (value: any) => void> = new Map();
_transport: Transport<T>;
constructor(transport: Transport<T>) {
@@ -161,7 +159,7 @@ export default class JsonRpcClient<T> extends EventEmitter {
this._onMessage(obj);
};
- transport.onClose = (error: ?Error) => {
+ transport.onClose = (error?: Error) => {
// Remove all subscriptions since they are connection based
this._subscriptions.clear();
@@ -184,7 +182,7 @@ export default class JsonRpcClient<T> extends EventEmitter {
}
}
- async subscribe(event: string, listener: (mixed) => void): Promise<*> {
+ async subscribe(event: string, listener: (value: any) => void): Promise<void> {
log.silly(`Adding a listener for ${event}`);
try {
@@ -203,7 +201,7 @@ export default class JsonRpcClient<T> extends EventEmitter {
}
}
- send(action: string, data: mixed, timeout: number = DEFAULT_TIMEOUT_MILLIS): Promise<mixed> {
+ send(action: string, data?: any, timeout: number = DEFAULT_TIMEOUT_MILLIS): Promise<any> {
return new Promise((resolve, reject) => {
const transport = this._transport;
if (!transport) {
@@ -237,7 +235,7 @@ export default class JsonRpcClient<T> extends EventEmitter {
});
}
- _prepareParams(data: mixed): Array<mixed> | Object {
+ _prepareParams(data?: any): Array<any> | Object {
// JSONRPC only accepts arrays and objects as params, but
// this isn't very nice to use, so this method wraps other
// types in an array. The choice of array is based on try-and-error
@@ -253,7 +251,7 @@ export default class JsonRpcClient<T> extends EventEmitter {
}
}
- _onTimeout(requestId) {
+ _onTimeout(requestId: string) {
const request = this._unansweredRequests.get(requestId);
this._unansweredRequests.delete(requestId);
@@ -267,8 +265,10 @@ export default class JsonRpcClient<T> extends EventEmitter {
}
_onMessage(obj: Object) {
- let messages = [];
+ let messages: Array<any> = [];
try {
+ // TODO: Fix the type weirdness.
+ // @ts-ignore
const message = jsonrpc.parseObject(obj);
messages = Array.isArray(message) ? message : [message];
} catch (error) {
@@ -322,19 +322,19 @@ export default class JsonRpcClient<T> extends EventEmitter {
interface Transport<T> {
close(): void;
onOpen: () => void;
- onMessage: (Object) => void;
- onClose: (error: ?Error) => void;
+ onMessage: (data: Object) => void;
+ onClose: (error?: Error) => void;
send(message: string): void;
connect(params: T): void;
}
export class WebsocketTransport implements Transport<string> {
- ws: ?WebSocket;
+ ws?: WebSocket;
onOpen = () => {};
onMessage = (_message: Object) => {};
- onClose = (_error: ?Error) => {};
+ onClose = (_error?: Error) => {};
- constructor(ws: ?WebSocket) {
+ constructor(ws?: WebSocket) {
this.ws = ws;
}
@@ -372,8 +372,11 @@ export class WebsocketTransport implements Transport<string> {
this.ws.onclose = (event) => {
log.info(`The websocket connection closed with code: ${event.code}`);
- const error = event.code === 1000 ? null : new WebSocketError(event.code);
- this.onClose(error);
+ if (event.code === 1000) {
+ this.onClose();
+ } else {
+ this.onClose(new WebSocketError(event.code));
+ }
};
}
}
@@ -382,18 +385,18 @@ export class WebsocketTransport implements Transport<string> {
// domain sockets, and also TCP/UDP sockets
export class SocketTransport implements Transport<{ path: string }> {
onMessage = (_message: Object) => {};
- onClose = (_error: ?Error) => {};
+ onClose = (_error?: Error) => {};
onOpen = () => {};
- _connection: ?net.Socket;
+ _connection?: net.Socket;
_socketReady = false;
_shouldClose = false;
- _lastError: ?Error;
+ _lastError?: Error;
connect(options: { path: string }) {
assert(!this._connection, 'Make sure to close the existing socket');
- const jsonStream = JSONStream.parse()
+ const jsonStream = JSONStream.parse(null)
.on('data', this._onJsonStreamData)
.on('error', this._onJsonStreamError);
@@ -405,7 +408,7 @@ export class SocketTransport implements Transport<{ path: string }> {
this._connection = connection;
this._socketReady = false;
this._shouldClose = false;
- this._lastError = null;
+ this._lastError = undefined;
log.debug('Connect socket');
@@ -424,7 +427,7 @@ export class SocketTransport implements Transport<{ path: string }> {
log.error('Failed to close the socket: ', error);
}
- this._connection = null;
+ this._connection = undefined;
}
send(msg: string) {
@@ -465,7 +468,7 @@ export class SocketTransport implements Transport<{ path: string }> {
}
};
- _onJsonStreamData = (data) => {
+ _onJsonStreamData = (data: Object) => {
this.onMessage(data);
};
diff --git a/gui/packages/desktop/src/main/keyframe-animation.js b/gui/packages/desktop/src/main/keyframe-animation.ts
index 3323670d27..aad9a3d24f 100644
--- a/gui/packages/desktop/src/main/keyframe-animation.js
+++ b/gui/packages/desktop/src/main/keyframe-animation.ts
@@ -1,18 +1,16 @@
-// @flow
-
export type OnFrameFn = (frame: number) => void;
-export type OnFinishFn = (void) => void;
+export type OnFinishFn = () => void;
export type KeyframeAnimationOptions = {
- start?: number,
- end: number,
+ start?: number;
+ end: number;
};
export type KeyframeAnimationRange = [number, number];
export default class KeyframeAnimation {
_speed: number = 200; // ms
- _onFrame: ?OnFrameFn;
- _onFinish: ?OnFinishFn;
+ _onFrame?: OnFrameFn;
+ _onFinish?: OnFinishFn;
_currentFrame: number = 0;
_targetFrame: number = 0;
@@ -20,26 +18,26 @@ export default class KeyframeAnimation {
_isRunning: boolean = false;
_isFinished: boolean = false;
- _timeout = null;
+ _timeout?: NodeJS.Timeout;
- set onFrame(newValue: ?OnFrameFn) {
+ set onFrame(newValue: OnFrameFn | undefined) {
this._onFrame = newValue;
}
- get onFrame(): ?OnFrameFn {
+ get onFrame(): OnFrameFn | undefined {
return this._onFrame;
}
// called when animation finished
- set onFinish(newValue: ?OnFinishFn) {
+ set onFinish(newValue: OnFinishFn | undefined) {
this._onFinish = newValue;
}
- get onFinish(): ?OnFinishFn {
+ get onFinish(): OnFinishFn | undefined {
return this._onFinish;
}
// pace per frame in ms
set speed(newValue: number) {
- this._speed = parseInt(newValue);
+ this._speed = newValue;
}
get speed(): number {
return this._speed;
@@ -79,7 +77,7 @@ export default class KeyframeAnimation {
_unscheduleUpdate() {
if (this._timeout) {
clearTimeout(this._timeout);
- this._timeout = null;
+ this._timeout = undefined;
}
}
diff --git a/gui/packages/desktop/src/main/notification-controller.js b/gui/packages/desktop/src/main/notification-controller.ts
index b316c7f750..2825775e97 100644
--- a/gui/packages/desktop/src/main/notification-controller.js
+++ b/gui/packages/desktop/src/main/notification-controller.ts
@@ -1,15 +1,12 @@
-// @flow
-
import { shell, Notification } from 'electron';
-import log from 'electron-log';
-import config from '../config';
+import config from '../config.json';
-import type { TunnelStateTransition } from '../shared/daemon-rpc-types';
+import { TunnelStateTransition } from '../shared/daemon-rpc-types';
export default class NotificationController {
- _lastTunnelStateNotification: ?Notification;
+ _lastTunnelStateAnnouncement?: { body: string; notification: Notification };
_reconnecting = false;
- _presentedNotifications = {};
+ _presentedNotifications: { [key: string]: boolean } = {};
_pendingNotifications: Array<Notification> = [];
notifyTunnelState(tunnelState: TunnelStateTransition) {
@@ -47,8 +44,6 @@ export default class NotificationController {
return;
}
break;
- default:
- log.error(`Unexpected TunnelStateTransition: ${(tunnelState.state: empty)}`);
}
this._reconnecting = false;
@@ -57,6 +52,7 @@ export default class NotificationController {
notifyInconsistentVersion() {
this._presentNotificationOnce('inconsistent-version', () => {
const notification = new Notification({
+ title: '',
body: 'Inconsistent internal version information, please restart the app',
silent: true,
});
@@ -67,6 +63,7 @@ export default class NotificationController {
notifyUnsupportedVersion(upgradeVersion: string) {
this._presentNotificationOnce('unsupported-version', () => {
const notification = new Notification({
+ title: '',
body: `You are running an unsupported app version. Please upgrade to ${upgradeVersion} now to ensure your security`,
silent: true,
});
@@ -86,23 +83,28 @@ export default class NotificationController {
}
_showTunnelStateNotification(message: string) {
- const lastNotification = this._lastTunnelStateNotification;
- const sameAsLastNotification = lastNotification && lastNotification.body === message;
+ const lastAnnouncement = this._lastTunnelStateAnnouncement;
+ const sameAsLastNotification = lastAnnouncement && lastAnnouncement.body === message;
if (sameAsLastNotification) {
return;
}
const newNotification = new Notification({
+ title: '',
body: message,
silent: true,
});
- if (lastNotification) {
- lastNotification.close();
+ if (lastAnnouncement) {
+ lastAnnouncement.notification.close();
}
- this._lastTunnelStateNotification = newNotification;
+ this._lastTunnelStateAnnouncement = {
+ body: message,
+ notification: newNotification,
+ };
+
this._scheduleNotification(newNotification);
}
diff --git a/gui/packages/desktop/src/main/proc.js b/gui/packages/desktop/src/main/proc.ts
index a939845d5c..5b118c1ec8 100644
--- a/gui/packages/desktop/src/main/proc.js
+++ b/gui/packages/desktop/src/main/proc.ts
@@ -1,19 +1,16 @@
-// @flow
-
import path from 'path';
export function resolveBin(binaryName: string) {
- const basepath = getBasePath();
- return path.resolve(basepath, binaryName + getExtension());
+ return path.resolve(getBasePath(), binaryName + getExtension());
}
-function getBasePath() {
+function getBasePath(): string {
if (process.env.NODE_ENV === 'development') {
return (
process.env.MULLVAD_PATH || path.resolve(path.join(__dirname, '../../../../../target/debug'))
);
} else {
- return process.resourcesPath;
+ return process.resourcesPath!;
}
}
diff --git a/gui/packages/desktop/src/main/reconnection-backoff.js b/gui/packages/desktop/src/main/reconnection-backoff.ts
index d777e86e57..a9a2cd9c75 100644
--- a/gui/packages/desktop/src/main/reconnection-backoff.js
+++ b/gui/packages/desktop/src/main/reconnection-backoff.ts
@@ -1,5 +1,3 @@
-// @flow
-
/*
* Used to calculate the time to wait before reconnecting to the daemon.
* It uses a linear backoff function that goes from 500ms to 3000ms.
diff --git a/gui/packages/desktop/src/main/tray-icon-controller.js b/gui/packages/desktop/src/main/tray-icon-controller.ts
index dbabe6a9a9..1a8c5b28c8 100644
--- a/gui/packages/desktop/src/main/tray-icon-controller.js
+++ b/gui/packages/desktop/src/main/tray-icon-controller.ts
@@ -1,17 +1,15 @@
-// @flow
-
import path from 'path';
import KeyframeAnimation from './keyframe-animation';
import { nativeImage } from 'electron';
-import type { NativeImage, Tray } from 'electron';
+import { NativeImage, Tray } from 'electron';
export type TrayIconType = 'unsecured' | 'securing' | 'secured';
export default class TrayIconController {
- _animation: ?KeyframeAnimation;
+ _animation?: KeyframeAnimation;
_iconType: TrayIconType;
- _iconImages: Array<NativeImage>;
- _monochromaticIconImages: Array<NativeImage>;
+ _iconImages: Array<NativeImage> = [];
+ _monochromaticIconImages: Array<NativeImage> = [];
_useMonochromaticIcon: boolean;
constructor(tray: Tray, initialType: TrayIconType, useMonochromaticIcon: boolean) {
@@ -31,7 +29,7 @@ export default class TrayIconController {
dispose() {
if (this._animation) {
this._animation.stop();
- this._animation = null;
+ this._animation = undefined;
}
}
@@ -61,7 +59,7 @@ export default class TrayIconController {
}
_loadImages() {
- const basePath = path.resolve(path.join(__dirname, '../assets/images/menubar icons'));
+ const basePath = path.resolve(path.join(__dirname, '../../assets/images/menubar icons'));
const frames = Array.from({ length: 10 }, (_, i) => i + 1);
this._iconImages = frames.map((frame) =>
@@ -81,8 +79,6 @@ export default class TrayIconController {
return 9;
case 'secured':
return 8;
- default:
- throw new Error(`Unknown tray icon type: ${(this._iconType: empty)}`);
}
}
diff --git a/gui/packages/desktop/src/main/window-controller.js b/gui/packages/desktop/src/main/window-controller.ts
index 782f5ee770..e740f216ab 100644
--- a/gui/packages/desktop/src/main/window-controller.js
+++ b/gui/packages/desktop/src/main/window-controller.ts
@@ -1,12 +1,10 @@
-// @flow
-
import { screen } from 'electron';
-import type { BrowserWindow, Tray, Display, WebContents } from 'electron';
+import { BrowserWindow, Tray, Display, WebContents } from 'electron';
-type Position = { x: number, y: number };
+type Position = { x: number; y: number };
export type WindowShapeParameters = {
- arrowPosition?: number,
+ arrowPosition?: number;
};
interface WindowPositioning {
@@ -183,7 +181,7 @@ export default class WindowController {
return this._window.isVisible();
}
- send(event: string, ...data: Array<mixed>): void {
+ send(event: string, ...data: any[]): void {
this._window.webContents.send(event, ...data);
}
diff --git a/gui/packages/desktop/src/renderer/.eslintrc b/gui/packages/desktop/src/renderer/.eslintrc
deleted file mode 100644
index e5a34aec6a..0000000000
--- a/gui/packages/desktop/src/renderer/.eslintrc
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "env": {
- "browser": true
- }
-}
diff --git a/gui/packages/desktop/src/renderer/app.js b/gui/packages/desktop/src/renderer/app.tsx
index 280c815ba8..50c4773ca0 100644
--- a/gui/packages/desktop/src/renderer/app.js
+++ b/gui/packages/desktop/src/renderer/app.tsx
@@ -1,5 +1,3 @@
-// @flow
-
import log from 'electron-log';
import { webFrame, ipcRenderer } from 'electron';
import * as React from 'react';
@@ -22,12 +20,12 @@ import settingsActions from './redux/settings/actions';
import versionActions from './redux/version/actions';
import userInterfaceActions from './redux/userinterface/actions';
-import type { WindowShapeParameters } from '../main/window-controller';
-import type { CurrentAppVersionInfo, AppUpgradeInfo } from '../main';
-import type { GuiSettingsState } from '../shared/gui-settings-state';
+import { WindowShapeParameters } from '../main/window-controller';
+import { CurrentAppVersionInfo, AppUpgradeInfo } from '../main';
+import { GuiSettingsState } from '../shared/gui-settings-state';
import { IpcRendererEventChannel } from '../shared/ipc-event-channel';
-import type {
+import {
AccountToken,
AccountData,
ConnectionConfig,
@@ -42,7 +40,7 @@ import type {
export default class AppRenderer {
_memoryHistory = createMemoryHistory();
_reduxStore = configureStore(null, this._memoryHistory);
- _reduxActions: *;
+ _reduxActions: { [key: string]: any };
_accountDataCache = new AccountDataCache(
(accountToken) => {
return IpcRendererEventChannel.account.getData(accountToken);
@@ -59,7 +57,7 @@ export default class AppRenderer {
_connectedToDaemon = false;
_autoConnected = false;
_doingLogin = false;
- _loginTimer: ?TimeoutID;
+ _loginTimer?: NodeJS.Timeout;
constructor() {
const dispatch = this._reduxStore.dispatch;
@@ -78,11 +76,14 @@ export default class AppRenderer {
),
};
- ipcRenderer.on('update-window-shape', (_event, shapeParams: WindowShapeParameters) => {
- if (typeof shapeParams.arrowPosition === 'number') {
- this._reduxActions.userInterface.updateWindowArrowPosition(shapeParams.arrowPosition);
- }
- });
+ ipcRenderer.on(
+ 'update-window-shape',
+ (_event: Electron.Event, shapeParams: WindowShapeParameters) => {
+ if (typeof shapeParams.arrowPosition === 'number') {
+ this._reduxActions.userInterface.updateWindowArrowPosition(shapeParams.arrowPosition);
+ }
+ },
+ );
ipcRenderer.on('window-shown', () => {
if (this._connectedToDaemon) {
@@ -94,8 +95,8 @@ export default class AppRenderer {
this._onDaemonConnected();
});
- IpcRendererEventChannel.daemonDisconnected.listen((errorMessage: ?string) => {
- this._onDaemonDisconnected(errorMessage ? new Error(errorMessage) : null);
+ IpcRendererEventChannel.daemonDisconnected.listen((errorMessage?: string) => {
+ this._onDaemonDisconnected(errorMessage ? new Error(errorMessage) : undefined);
});
IpcRendererEventChannel.tunnel.listen((newState: TunnelStateTransition) => {
@@ -136,6 +137,10 @@ export default class AppRenderer {
// Request the initial state from the main process
const initialState = IpcRendererEventChannel.state.get();
+ this._tunnelState = initialState.tunnelState;
+ this._settings = initialState.settings;
+ this._guiSettings = initialState.guiSettings;
+
this._setTunnelState(initialState.tunnelState);
this._setSettings(initialState.settings);
@@ -200,7 +205,7 @@ export default class AppRenderer {
}
}
- async verifyAccount(accountToken: AccountToken): Promise<AccountVerification> {
+ verifyAccount(accountToken: AccountToken): Promise<AccountVerification> {
return new Promise((resolve, reject) => {
this._accountDataCache.invalidate();
this._accountDataCache.fetch(accountToken, {
@@ -249,8 +254,8 @@ export default class AppRenderer {
_setRelaySettings(relaySettings: RelaySettings) {
const actions = this._reduxActions;
- if (relaySettings.normal) {
- const payload = {};
+ if ('normal' in relaySettings) {
+ const payload: { [key: string]: any } = {};
const normal = relaySettings.normal;
const tunnel = normal.tunnel;
const location = normal.location;
@@ -273,19 +278,19 @@ export default class AppRenderer {
actions.settings.updateRelay({
normal: payload,
});
- } else if (relaySettings.customTunnelEndpoint) {
+ } else if ('customTunnelEndpoint' in relaySettings) {
const customTunnelEndpoint = relaySettings.customTunnelEndpoint;
const host = customTunnelEndpoint.host;
const config: ConnectionConfig = customTunnelEndpoint.config;
let port = 0;
let protocol = 'udp';
- if (config.openvpn) {
+ if ('openvpn' in config) {
port = config.openvpn.endpoint.port;
protocol = config.openvpn.endpoint.protocol;
}
- if (config.wireguard) {
+ if ('wireguard' in config) {
// TODO: handle wireguard
}
@@ -334,15 +339,13 @@ export default class AppRenderer {
actions.settings.updateBlockWhenDisconnected(blockWhenDisconnected);
}
- async setOpenVpnMssfix(mssfix: ?number) {
+ async setOpenVpnMssfix(mssfix?: number) {
const actions = this._reduxActions;
actions.settings.updateOpenVpnMssfix(mssfix);
await IpcRendererEventChannel.settings.setOpenVpnMssfix(mssfix);
}
async setAutoConnect(autoConnect: boolean) {
- this._reduxActions.settings.updateAutoConnect(autoConnect);
-
return IpcRendererEventChannel.guiSettings.setAutoConnect(autoConnect);
}
@@ -382,7 +385,7 @@ export default class AppRenderer {
}
}
- _onDaemonDisconnected(error: ?Error) {
+ _onDaemonDisconnected(error?: Error) {
const wasConnected = this._connectedToDaemon;
this._connectedToDaemon = false;
@@ -443,10 +446,6 @@ export default class AppRenderer {
case 'blocked':
actions.connection.blocked(tunnelState.details);
break;
-
- default:
- log.error(`Unexpected TunnelState: ${(tunnelState.state: empty)}`);
- break;
}
}
@@ -471,7 +470,7 @@ export default class AppRenderer {
}
}
- _handleAccountChange(oldAccount: ?string, newAccount: ?string) {
+ _handleAccountChange(oldAccount?: string, newAccount?: string) {
if (oldAccount && !newAccount) {
this._accountDataCache.invalidate();
@@ -533,25 +532,28 @@ export default class AppRenderer {
}
}
-type AccountVerification = { status: 'verified' } | { status: 'deferred', error: Error };
+type AccountVerification = { status: 'verified' } | { status: 'deferred'; error: Error };
type AccountFetchRetryAction = 'stop' | 'retry';
type AccountFetchWatcher = {
- onFinish: () => void,
- onError: (any) => AccountFetchRetryAction,
+ onFinish: () => void;
+ onError: (error: Error) => AccountFetchRetryAction;
};
// An account data cache that helps to throttle RPC requests to get_account_data and retain the
// cached value for 1 minute.
export class AccountDataCache {
- _currentAccount: ?AccountToken;
- _expiresAt: ?Date;
+ _currentAccount?: AccountToken;
+ _expiresAt?: Date;
_fetchAttempt: number;
- _fetchRetryTimeout: ?TimeoutID;
- _fetch: (AccountToken) => Promise<AccountData>;
- _update: (?AccountData) => void;
+ _fetchRetryTimeout?: NodeJS.Timeout;
+ _fetch: (token: AccountToken) => Promise<AccountData>;
+ _update: (data?: AccountData) => void;
_watchers: Array<AccountFetchWatcher>;
- constructor(fetch: (AccountToken) => Promise<AccountData>, update: (?AccountData) => void) {
+ constructor(
+ fetch: (token: AccountToken) => Promise<AccountData>,
+ update: (data?: AccountData) => void,
+ ) {
this._fetch = fetch;
this._update = update;
this._watchers = [];
@@ -580,12 +582,12 @@ export class AccountDataCache {
invalidate() {
if (this._fetchRetryTimeout) {
clearTimeout(this._fetchRetryTimeout);
- this._fetchRetryTimeout = null;
+ this._fetchRetryTimeout = undefined;
this._fetchAttempt = 0;
}
- this._expiresAt = null;
- this._update(null);
+ this._expiresAt = undefined;
+ this._update();
this._notifyWatchers((watcher) => {
watcher.onError(new Error('Cancelled'));
});
@@ -640,12 +642,12 @@ export class AccountDataCache {
log.warn(`Failed to fetch account data. Retrying in ${delay} ms`);
this._fetchRetryTimeout = setTimeout(() => {
- this._fetchRetryTimeout = null;
+ this._fetchRetryTimeout = undefined;
this._performFetch(accountToken);
}, delay);
}
- _notifyWatchers(notify: (AccountFetchWatcher) => void) {
+ _notifyWatchers(notify: (watcher: AccountFetchWatcher) => void) {
this._watchers.splice(0).forEach(notify);
}
}
diff --git a/gui/packages/desktop/src/renderer/components/Account.js b/gui/packages/desktop/src/renderer/components/Account.tsx
index 90c145c3d7..8ff36aafbe 100644
--- a/gui/packages/desktop/src/renderer/components/Account.js
+++ b/gui/packages/desktop/src/renderer/components/Account.tsx
@@ -1,24 +1,22 @@
-// @flow
-
import moment from 'moment';
import * as React from 'react';
import { Component, Text, View } from 'reactxp';
-import { ClipboardLabel, ImageView, SettingsHeader, HeaderTitle } from '@mullvad/components';
+import { ClipboardLabel, SettingsHeader, HeaderTitle } from '@mullvad/components';
import * as AppButton from './AppButton';
import { Layout, Container } from './Layout';
import { NavigationBar, BackBarItem } from './NavigationBar';
import styles from './AccountStyles';
-import type { AccountToken } from '../../shared/daemon-rpc-types';
+import { AccountToken } from '../../shared/daemon-rpc-types';
type Props = {
- accountToken: AccountToken,
- accountExpiry: ?string,
- expiryLocale: string,
- isOffline: boolean,
- onLogout: () => void,
- onClose: () => void,
- onBuyMore: () => void,
+ accountToken?: AccountToken;
+ accountExpiry?: string;
+ expiryLocale: string;
+ isOffline: boolean;
+ onLogout: () => void;
+ onClose: () => void;
+ onBuyMore: () => void;
};
export default class Account extends Component<Props> {
@@ -28,7 +26,7 @@ export default class Account extends Component<Props> {
<Container>
<View style={styles.account}>
<NavigationBar>
- <BackBarItem action={this.props.onClose} title={'Settings'} />
+ <BackBarItem action={this.props.onClose}>Settings</BackBarItem>
</NavigationBar>
<View style={styles.account__container}>
@@ -42,7 +40,7 @@ export default class Account extends Component<Props> {
<Text style={styles.account__row_label}>Account ID</Text>
<ClipboardLabel
style={styles.account__row_value}
- value={this.props.accountToken}
+ value={this.props.accountToken || ''}
message={'COPIED TO CLIPBOARD!'}
/>
</View>
@@ -51,8 +49,7 @@ export default class Account extends Component<Props> {
<Text style={styles.account__row_label}>Paid until</Text>
<FormattedAccountExpiry
expiry={this.props.accountExpiry}
- locale={this.props.accountExpiryLocale}
- testName="account__expiry"
+ locale={this.props.expiryLocale}
/>
</View>
@@ -60,14 +57,11 @@ export default class Account extends Component<Props> {
<AppButton.GreenButton
style={styles.account__buy_button}
disabled={this.props.isOffline}
- onPress={this.props.onBuyMore}
- text="Buy more credit"
- icon="icon-extLink"
- testName="account__buymore">
+ onPress={this.props.onBuyMore}>
<AppButton.Label>Buy more credit</AppButton.Label>
- <ImageView source="icon-extLink" height={16} width={16} />
+ <AppButton.Icon source="icon-extLink" height={16} width={16} />
</AppButton.GreenButton>
- <AppButton.RedButton onPress={this.props.onLogout} testName="account__logout">
+ <AppButton.RedButton onPress={this.props.onLogout}>
{'Log out'}
</AppButton.RedButton>
</View>
@@ -81,7 +75,7 @@ export default class Account extends Component<Props> {
}
}
-const FormattedAccountExpiry = (props) => {
+const FormattedAccountExpiry = (props: { expiry?: string; locale: string }) => {
if (!props.expiry) {
return <Text style={styles.account__row_value}>{'Currently unavailable'}</Text>;
}
diff --git a/gui/packages/desktop/src/renderer/components/AccountStyles.js b/gui/packages/desktop/src/renderer/components/AccountStyles.tsx
index b271fd362a..bb230ee759 100644
--- a/gui/packages/desktop/src/renderer/components/AccountStyles.js
+++ b/gui/packages/desktop/src/renderer/components/AccountStyles.tsx
@@ -1,7 +1,5 @@
-// @flow
-
import { Styles } from 'reactxp';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
export default {
account: Styles.createViewStyle({
@@ -14,15 +12,11 @@ export default {
paddingBottom: 48,
}),
account__scrollview: Styles.createViewStyle({
- flexGrow: 1,
- flexShrink: 1,
- flexBasis: '100%',
+ flex: 1,
}),
account__content: Styles.createViewStyle({
flexDirection: 'column',
- flexGrow: 1,
- flexShrink: 0,
- flexBasis: 'auto',
+ flex: 1,
}),
account__main: Styles.createViewStyle({
marginBottom: 24,
diff --git a/gui/packages/desktop/src/renderer/components/AdvancedSettings.js b/gui/packages/desktop/src/renderer/components/AdvancedSettings.tsx
index 6be9d38037..99632a35f5 100644
--- a/gui/packages/desktop/src/renderer/components/AdvancedSettings.js
+++ b/gui/packages/desktop/src/renderer/components/AdvancedSettings.tsx
@@ -1,5 +1,3 @@
-// @flow
-
import * as React from 'react';
import { Button, Component, Text, View } from 'reactxp';
import { ImageView, SettingsHeader, HeaderTitle } from '@mullvad/components';
@@ -14,28 +12,28 @@ import {
} from './NavigationBar';
import Switch from './Switch';
import styles from './AdvancedSettingsStyles';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
const MIN_MSSFIX_VALUE = 1000;
const MAX_MSSFIX_VALUE = 1450;
type Props = {
- enableIpv6: boolean,
- blockWhenDisconnected: boolean,
- protocol: string,
- mssfix: ?number,
- port: string | number,
- setEnableIpv6: (boolean) => void,
- setBlockWhenDisconnected: (boolean) => void,
- setOpenVpnMssfix: (?number) => void,
- onUpdate: (protocol: string, port: string | number) => void,
- onClose: () => void,
+ enableIpv6: boolean;
+ blockWhenDisconnected: boolean;
+ protocol: string;
+ mssfix?: number;
+ port: string | number;
+ setEnableIpv6: (value: boolean) => void;
+ setBlockWhenDisconnected: (value: boolean) => void;
+ setOpenVpnMssfix: (value: number | undefined) => void;
+ onUpdate: (protocol: string, port: string | number) => void;
+ onClose: () => void;
};
type State = {
- persistedMssfix: ?number,
- editedMssfix: ?number,
- focusOnMssfix: boolean,
+ persistedMssfix?: number;
+ editedMssfix?: number;
+ focusOnMssfix: boolean;
};
export class AdvancedSettings extends Component<Props, State> {
@@ -84,7 +82,7 @@ export class AdvancedSettings extends Component<Props, State> {
<View style={styles.advanced_settings}>
<NavigationContainer>
<NavigationBar>
- <BackBarItem action={this.props.onClose} title={'Settings'} />
+ <BackBarItem action={this.props.onClose}>Settings</BackBarItem>
<TitleBarItem>Advanced</TitleBarItem>
</NavigationBar>
@@ -137,7 +135,7 @@ export class AdvancedSettings extends Component<Props, State> {
keyboardType={'numeric'}
maxLength={4}
placeholder={'Default'}
- value={mssfixValue === null ? '' : mssfixValue.toString()}
+ value={mssfixValue ? mssfixValue.toString() : ''}
style={mssfixStyle}
onChangeText={this._onMssfixChange}
onFocus={this._onMssfixFocus}
@@ -180,7 +178,7 @@ export class AdvancedSettings extends Component<Props, State> {
const mssfix = mssfixString.replace(/[^0-9]/g, '');
if (mssfix === '') {
- this.setState({ editedMssfix: null });
+ this.setState({ editedMssfix: undefined });
} else {
this.setState({ editedMssfix: parseInt(mssfix, 10) });
}
@@ -202,26 +200,26 @@ export class AdvancedSettings extends Component<Props, State> {
_mssfixIsValid(): boolean {
const mssfix = this.state.editedMssfix;
- return mssfix === null || (mssfix >= MIN_MSSFIX_VALUE && mssfix <= MAX_MSSFIX_VALUE);
+ return mssfix === undefined || (mssfix >= MIN_MSSFIX_VALUE && mssfix <= MAX_MSSFIX_VALUE);
}
}
type SelectorProps<T> = {
- title: string,
- values: Array<T>,
- value: T,
- onSelect: (T) => void,
+ title: string;
+ values: Array<T>;
+ value: T;
+ onSelect: (value: T) => void;
};
-type SelectorState = {
- hoveredButtonIndex: number,
+type SelectorState<T> = {
+ hoveredButtonValue?: T;
};
-class Selector extends Component<SelectorProps<*>, SelectorState> {
- state = { hoveredButtonIndex: -1 };
+class Selector<T> extends Component<SelectorProps<T>, SelectorState<T>> {
+ state = { hoveredButtonValue: undefined };
- handleButtonHover = (value) => {
- this.setState({ hoveredButtonIndex: value });
+ handleButtonHover = (value?: T) => {
+ this.setState({ hoveredButtonValue: value });
};
render() {
@@ -234,7 +232,7 @@ class Selector extends Component<SelectorProps<*>, SelectorState> {
);
}
- _renderCell(value) {
+ _renderCell(value: T) {
const selected = value === this.props.value;
if (selected) {
return this._renderSelectedCell(value);
@@ -243,19 +241,19 @@ class Selector extends Component<SelectorProps<*>, SelectorState> {
}
}
- _renderSelectedCell(value) {
+ _renderSelectedCell(value: T) {
return (
<Button
style={[
styles.advanced_settings__cell,
- value === this.state.hoveredButtonIndex
- ? styles.advanced_settings__cell_selected_hover
- : null,
+ value === this.state.hoveredButtonValue
+ ? [styles.advanced_settings__cell_selected_hover]
+ : undefined,
]}
onPress={() => this.props.onSelect(value)}
onHoverStart={() => this.handleButtonHover(value)}
- onHoverEnd={() => this.handleButtonHover(-1)}
- key={value}>
+ onHoverEnd={() => this.handleButtonHover(undefined)}
+ key={value.toString()}>
<ImageView
style={styles.advanced_settings__cell_icon}
source="icon-tick"
@@ -266,17 +264,19 @@ class Selector extends Component<SelectorProps<*>, SelectorState> {
);
}
- _renderUnselectedCell(value) {
+ _renderUnselectedCell(value: T) {
return (
<Button
style={[
styles.advanced_settings__cell_dimmed,
- value === this.state.hoveredButtonIndex ? styles.advanced_settings__cell_hover : null,
+ value === this.state.hoveredButtonValue
+ ? styles.advanced_settings__cell_hover
+ : undefined,
]}
onPress={() => this.props.onSelect(value)}
onHoverStart={() => this.handleButtonHover(value)}
- onHoverEnd={() => this.handleButtonHover(-1)}
- key={value}>
+ onHoverEnd={() => this.handleButtonHover(undefined)}
+ key={value.toString()}>
<View style={styles.advanced_settings__cell_icon} />
<Text style={styles.advanced_settings__cell_label}>{value}</Text>
</Button>
diff --git a/gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.js b/gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.tsx
index f051e95bf7..b864c72ebf 100644
--- a/gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.js
+++ b/gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.tsx
@@ -1,7 +1,5 @@
-// @flow
-
import { Styles } from 'reactxp';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
export default {
advanced_settings: Styles.createViewStyle({
@@ -12,19 +10,16 @@ export default {
flexDirection: 'column',
flex: 1,
}),
- advanced_settings__scrollview: Styles.createViewStyle({
- flexGrow: 1,
- flexShrink: 1,
- flexBasis: '100%',
- }),
+ // plain CSS style
+ advanced_settings__scrollview: {
+ flex: 1,
+ },
advanced_settings__content: Styles.createViewStyle({
flexDirection: 'column',
- flexGrow: 1,
- flexShrink: 0,
- flexBasis: 'auto',
+ flex: 0,
overflow: 'visible',
}),
- advanced_settings__cell: Styles.createViewStyle({
+ advanced_settings__cell: Styles.createButtonStyle({
cursor: 'default',
backgroundColor: colors.green,
flexDirection: 'row',
@@ -35,10 +30,10 @@ export default {
marginBottom: 1,
justifyContent: 'flex-start',
}),
- advanced_settings__cell_hover: Styles.createViewStyle({
+ advanced_settings__cell_hover: Styles.createButtonStyle({
backgroundColor: colors.blue80,
}),
- advanced_settings__cell_selected_hover: Styles.createViewStyle({
+ advanced_settings__cell_selected_hover: Styles.createButtonStyle({
backgroundColor: colors.green,
}),
advanced_settings__cell_spacer: Styles.createViewStyle({
@@ -50,7 +45,7 @@ export default {
marginRight: 8,
flex: 0,
}),
- advanced_settings__cell_dimmed: Styles.createViewStyle({
+ advanced_settings__cell_dimmed: Styles.createButtonStyle({
cursor: 'default',
paddingTop: 14,
paddingBottom: 14,
diff --git a/gui/packages/desktop/src/renderer/components/AppButton.js b/gui/packages/desktop/src/renderer/components/AppButton.tsx
index 7e34c84803..31fc9bd679 100644
--- a/gui/packages/desktop/src/renderer/components/AppButton.js
+++ b/gui/packages/desktop/src/renderer/components/AppButton.tsx
@@ -1,27 +1,54 @@
-// @flow
-
import * as React from 'react';
-import { Button, Text, Component } from 'reactxp';
+import { Button, Component, Text, Types } from 'reactxp';
import { ImageView } from '@mullvad/components';
import styles from './AppButtonStyles';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
+
+type LabelProps = {
+ children?: React.ReactText;
+};
+
+export class Label extends Component<LabelProps> {
+ render() {
+ return <Text style={styles.label}>{this.props.children}</Text>;
+ }
+}
+
+type IconProps = {
+ source: string;
+ width?: number;
+ height?: number;
+};
-export class Label extends Text {}
+export class Icon extends Component<IconProps> {
+ render() {
+ return (
+ <ImageView
+ source={this.props.source}
+ width={this.props.width}
+ height={this.props.height}
+ tintColor={colors.white}
+ style={styles.icon}
+ />
+ );
+ }
+}
type Props = {
- children?: React.Node,
- style?: Object,
- disabled: boolean,
+ children?: React.ReactNode;
+ style?: Types.ButtonStyleRuleSet;
+ disabled?: boolean;
+ onPress?: () => void;
};
type State = {
- hovered: boolean,
+ hovered: boolean;
};
class BaseButton extends Component<Props, State> {
- state = { hovered: false };
+ state: State = { hovered: false };
- backgroundStyle = () => {
+ backgroundStyle = (): Types.ButtonStyleRuleSet => {
throw new Error('Implement backgroundStyle in subclasses.');
};
onHoverStart = () => (!this.props.disabled ? this.setState({ hovered: true }) : null);
@@ -29,29 +56,16 @@ class BaseButton extends Component<Props, State> {
render() {
const { children, style, ...otherProps } = this.props;
+
return (
<Button
{...otherProps}
style={[styles.common, this.backgroundStyle(), style]}
onHoverStart={this.onHoverStart}
onHoverEnd={this.onHoverEnd}>
- {React.Children.map(children, (node) => {
- if (React.isValidElement(node)) {
- let updatedProps = {};
-
- if (node.type === Label) {
- updatedProps = { style: [styles.label] };
- }
-
- if (node.type === ImageView) {
- updatedProps = { tintColor: colors.white, style: [styles.icon] };
- }
-
- return React.cloneElement(node, updatedProps);
- } else {
- return <Label style={[styles.label]}>{children}</Label>;
- }
- })}
+ {React.Children.map(children, (child) =>
+ typeof child === 'string' ? <Label>{child as string}</Label> : child,
+ )}
</Button>
);
}
diff --git a/gui/packages/desktop/src/renderer/components/AppButtonStyles.js b/gui/packages/desktop/src/renderer/components/AppButtonStyles.tsx
index 9b11375f01..c5cc6dfc6b 100644
--- a/gui/packages/desktop/src/renderer/components/AppButtonStyles.js
+++ b/gui/packages/desktop/src/renderer/components/AppButtonStyles.tsx
@@ -1,37 +1,35 @@
-// @flow
-
import { Styles } from 'reactxp';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
export default {
- red: Styles.createViewStyle({
+ red: Styles.createButtonStyle({
backgroundColor: colors.red,
}),
- redHover: Styles.createViewStyle({
+ redHover: Styles.createButtonStyle({
backgroundColor: colors.red95,
}),
- green: Styles.createViewStyle({
+ green: Styles.createButtonStyle({
backgroundColor: colors.green,
}),
- greenHover: Styles.createViewStyle({
+ greenHover: Styles.createButtonStyle({
backgroundColor: colors.green90,
}),
- blue: Styles.createViewStyle({
+ blue: Styles.createButtonStyle({
backgroundColor: colors.blue80,
}),
- blueHover: Styles.createViewStyle({
+ blueHover: Styles.createButtonStyle({
backgroundColor: colors.blue60,
}),
- transparent: Styles.createViewStyle({
+ transparent: Styles.createButtonStyle({
backgroundColor: colors.white20,
}),
- transparentHover: Styles.createViewStyle({
+ transparentHover: Styles.createButtonStyle({
backgroundColor: colors.white40,
}),
- redTransparent: Styles.createViewStyle({
+ redTransparent: Styles.createButtonStyle({
backgroundColor: colors.red40,
}),
- redTransparentHover: Styles.createViewStyle({
+ redTransparentHover: Styles.createButtonStyle({
backgroundColor: colors.red45,
}),
icon: Styles.createViewStyle({
diff --git a/gui/packages/desktop/src/renderer/components/Cell.js b/gui/packages/desktop/src/renderer/components/Cell.tsx
index 7e6159cf9f..291b891e64 100644
--- a/gui/packages/desktop/src/renderer/components/Cell.js
+++ b/gui/packages/desktop/src/renderer/components/Cell.tsx
@@ -1,12 +1,10 @@
-// @flow
-
import * as React from 'react';
import { Button, Component, Styles, Text, TextInput, Types, View } from 'reactxp';
import { ImageView } from '@mullvad/components';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
const styles = {
- cellButton: Styles.createViewStyle({
+ cellButton: Styles.createButtonStyle({
backgroundColor: colors.blue,
paddingTop: 0,
paddingBottom: 0,
@@ -80,7 +78,7 @@ const styles = {
}),
},
- cellHover: Styles.createViewStyle({
+ cellHover: Styles.createButtonStyle({
backgroundColor: colors.blue80,
}),
icon: Styles.createViewStyle({
@@ -99,10 +97,11 @@ const styles = {
};
type CellButtonProps = {
- children?: React.Node,
- disabled?: boolean,
- cellHoverStyle?: Types.ViewStyle,
- style?: Types.ViewStyle,
+ children?: React.ReactNode;
+ disabled?: boolean;
+ cellHoverStyle?: Types.StyleRuleSetRecursive<Types.ButtonStyleRuleSet>;
+ style?: Types.StyleRuleSetRecursive<Types.ButtonStyleRuleSet>;
+ onPress?: () => void;
};
type State = { hovered: boolean };
@@ -120,7 +119,7 @@ export class CellButton extends Component<CellButtonProps, State> {
const hoverStyle = cellHoverStyle || styles.cellHover;
return (
<Button
- style={[styles.cellButton, style, this.state.hovered && hoverStyle]}
+ style={[styles.cellButton, style, this.state.hovered ? hoverStyle : undefined]}
onHoverStart={this.onHoverStart}
onHoverEnd={this.onHoverEnd}
{...otherProps}>
@@ -130,35 +129,42 @@ export class CellButton extends Component<CellButtonProps, State> {
}
}
-type ContainerProps = { children: React.Node };
+type ContainerProps = { children: React.ReactNode };
export function Container({ children }: ContainerProps) {
return <View style={styles.cellContainer}>{children}</View>;
}
-export type LabelProps = {
- children: React.Node,
- containerStyle?: Types.ViewStyle,
- textStyle?: Types.TextStyle,
- cellHoverContainerStyle?: Types.ViewStyle,
- cellHoverTextStyle?: Types.TextStyle,
+type LabelProps = {
+ containerStyle?: Types.ViewStyleRuleSet;
+ textStyle?: Types.TextStyleRuleSet;
+ cellHoverContainerStyle?: Types.ViewStyleRuleSet;
+ cellHoverTextStyle?: Types.TextStyleRuleSet;
+ onPress?: (event: Types.SyntheticEvent) => void;
+ children?: React.ReactNode;
};
-export function Label({
- children,
- containerStyle,
- textStyle,
- cellHoverContainerStyle,
- cellHoverTextStyle,
- ...otherProps
-}: LabelProps) {
+export function Label(props: LabelProps) {
+ const {
+ children,
+ containerStyle,
+ textStyle,
+ cellHoverContainerStyle,
+ cellHoverTextStyle,
+ ...otherProps
+ } = props;
+
return (
<CellHoverContext.Consumer>
{(hovered) => (
<View
- style={[styles.label.container, containerStyle, hovered && cellHoverContainerStyle]}
+ style={[
+ styles.label.container,
+ containerStyle,
+ hovered ? cellHoverContainerStyle : undefined,
+ ]}
{...otherProps}>
- <Text style={[styles.label.text, textStyle, hovered && cellHoverTextStyle]}>
+ <Text style={[styles.label.text, textStyle, hovered ? cellHoverTextStyle : undefined]}>
{children}
</Text>
</View>
@@ -167,39 +173,47 @@ export function Label({
);
}
-export function InputFrame({ style, children, ...otherProps }: Types.ViewProps) {
- return (
- <View style={[styles.input.frame, style]} {...otherProps}>
- {children}
- </View>
- );
+type InputFrameProps = {
+ children?: React.ReactNode;
+ style?: Types.StyleRuleSetRecursive<Types.ViewStyleRuleSet>;
+};
+
+export function InputFrame(props: InputFrameProps) {
+ const { style, children } = props;
+
+ return <View style={[styles.input.frame, style]}>{children}</View>;
}
-export function Input({ style, ...otherProps }: Types.TextInputProps) {
+export const Input = React.forwardRef(function InputT(
+ props: Types.TextInputProps,
+ ref?: React.Ref<TextInput>,
+) {
+ const { style, ...otherProps } = props;
+
return (
<TextInput
+ ref={ref as any}
maxLength={10}
placeholderTextColor={colors.white60}
autoCorrect={false}
autoFocus={false}
style={[styles.input.text, style]}
- testId="CellInputField"
{...otherProps}
/>
);
-}
+});
-export type SubTextProps = {
- children: React.Node,
- cellHoverStyle?: Types.ViewStyle,
- style?: Types.ViewStyle,
+type SubTextProps = Types.TextProps & {
+ cellHoverStyle?: Types.ViewStyle;
};
-export function SubText({ children, style, cellHoverStyle, ...otherProps }: SubTextProps) {
+export function SubText(props: SubTextProps) {
+ const { children, ref: _, style, cellHoverStyle, ...otherProps } = props;
+
return (
<CellHoverContext.Consumer>
{(hovered) => (
- <Text style={[styles.subtext, style, hovered && cellHoverStyle]} {...otherProps}>
+ <Text style={[styles.subtext, style, hovered ? cellHoverStyle : undefined]} {...otherProps}>
{children}
</Text>
)}
@@ -207,12 +221,9 @@ export function SubText({ children, style, cellHoverStyle, ...otherProps }: SubT
);
}
-export function Icon({
- style,
- tintColor,
- tintHoverColor,
- ...otherProps
-}: React.ElementProps<typeof ImageView>) {
+export function Icon(props: ImageView['props']) {
+ const { children: _children, style, tintColor, tintHoverColor, ...otherProps } = props;
+
return (
<CellHoverContext.Consumer>
{(hovered) => (
diff --git a/gui/packages/desktop/src/renderer/components/ChevronButton.js b/gui/packages/desktop/src/renderer/components/ChevronButton.tsx
index d594c381cb..efb7c03fdd 100644
--- a/gui/packages/desktop/src/renderer/components/ChevronButton.js
+++ b/gui/packages/desktop/src/renderer/components/ChevronButton.tsx
@@ -1,13 +1,12 @@
-// @flow
-
import * as React from 'react';
-import { Component, Styles } from 'reactxp';
+import { Component, Styles, Types } from 'reactxp';
import * as Cell from './Cell';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
type Props = {
- up: boolean,
- onPress: () => void,
+ up: boolean;
+ onPress?: (event: Types.SyntheticEvent) => void;
+ style?: Types.StyleRuleSetRecursive<Types.ViewStyleRuleSet>;
};
const style = Styles.createViewStyle({
diff --git a/gui/packages/desktop/src/renderer/components/CityRow.js b/gui/packages/desktop/src/renderer/components/CityRow.tsx
index f375969dcf..4137762b16 100644
--- a/gui/packages/desktop/src/renderer/components/CityRow.js
+++ b/gui/packages/desktop/src/renderer/components/CityRow.tsx
@@ -1,34 +1,33 @@
-// @flow
-
import * as React from 'react';
-import { Component, Styles, View } from 'reactxp';
+import { Component, Styles, Types, View } from 'reactxp';
import { Accordion } from '@mullvad/components';
import * as Cell from './Cell';
import RelayRow from './RelayRow';
import RelayStatusIndicator from './RelayStatusIndicator';
import ChevronButton from './ChevronButton';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
+
+type RelayRowElement = React.ReactElement<RelayRow['props']>;
type Props = {
- name: string,
- hasActiveRelays: boolean,
- selected: boolean,
- expanded: boolean,
- selected: boolean,
- onSelect?: () => void,
- onExpand?: () => void,
- children?: React.Element<typeof RelayRow>,
+ name: string;
+ hasActiveRelays: boolean;
+ selected: boolean;
+ expanded: boolean;
+ onSelect?: () => void;
+ onExpand?: (value: boolean) => void;
+ children?: RelayRowElement | RelayRowElement[];
};
const styles = {
- base: Styles.createViewStyle({
+ base: Styles.createButtonStyle({
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0,
paddingLeft: 40,
backgroundColor: colors.blue40,
}),
- selected: Styles.createViewStyle({
+ selected: Styles.createButtonStyle({
backgroundColor: colors.green,
}),
};
@@ -38,7 +37,7 @@ export default class CityRow extends Component<Props> {
return !CityRow.compareProps(this.props, nextProps);
}
- static compareProps(oldProps: Props, nextProps: Props) {
+ static compareProps(oldProps: Props, nextProps: Props): boolean {
if (React.Children.count(oldProps.children) !== React.Children.count(nextProps.children)) {
return false;
}
@@ -52,8 +51,8 @@ export default class CityRow extends Component<Props> {
return false;
}
- const currChildren = React.Children.toArray(oldProps.children);
- const nextChildren = React.Children.toArray(nextProps.children);
+ const currChildren = React.Children.toArray(oldProps.children || []) as RelayRowElement[];
+ const nextChildren = React.Children.toArray(nextProps.children || []) as RelayRowElement[];
for (let i = 0; i < currChildren.length; i++) {
const currChild = currChildren[i];
@@ -75,9 +74,8 @@ export default class CityRow extends Component<Props> {
<Cell.CellButton
onPress={this._handlePress}
disabled={!this.props.hasActiveRelays}
- cellHoverStyle={this.props.selected ? styles.selected : null}
- style={[styles.base, this.props.selected ? styles.selected : null]}
- testName="city">
+ cellHoverStyle={this.props.selected ? styles.selected : undefined}
+ style={[styles.base, this.props.selected ? styles.selected : undefined]}>
<RelayStatusIndicator
isActive={this.props.hasActiveRelays}
isSelected={this.props.selected}
@@ -92,7 +90,7 @@ export default class CityRow extends Component<Props> {
);
}
- _toggleCollapse = (event: Event) => {
+ _toggleCollapse = (event: Types.SyntheticEvent) => {
if (this.props.onExpand) {
this.props.onExpand(!this.props.expanded);
}
diff --git a/gui/packages/desktop/src/renderer/components/Connect.js b/gui/packages/desktop/src/renderer/components/Connect.tsx
index e722f9184f..5c4b883e57 100644
--- a/gui/packages/desktop/src/renderer/components/Connect.js
+++ b/gui/packages/desktop/src/renderer/components/Connect.tsx
@@ -1,5 +1,3 @@
-// @flow
-
import * as React from 'react';
import { Component, View } from 'reactxp';
import { SettingsBarButton, Brand, HeaderBarStyle, ImageView } from '@mullvad/components';
@@ -7,29 +5,30 @@ import { Layout, Container, Header } from './Layout';
import NotificationArea from './NotificationArea';
import * as AppButton from './AppButton';
import TunnelControl from './TunnelControl';
-import Map from './Map';
+import Map, { MarkerStyle, ZoomLevel } from './Map';
import styles from './ConnectStyles';
import { NoCreditError, NoInternetError } from '../../main/errors';
-import { parseSocketAddress } from '../../shared/daemon-rpc-types';
+import { TunnelEndpoint, parseSocketAddress } from '../../shared/daemon-rpc-types';
+import { links } from '../../config.json';
-import type { RelayOutAddress, RelayInAddress } from './TunnelControl';
-import type AccountExpiry from '../lib/account-expiry';
-import type { ConnectionReduxState } from '../redux/connection/reducers';
-import type { VersionReduxState } from '../redux/version/reducers';
+import { RelayOutAddress, RelayInAddress } from './TunnelControl';
+import AccountExpiry from '../lib/account-expiry';
+import { ConnectionReduxState } from '../redux/connection/reducers';
+import { VersionReduxState } from '../redux/version/reducers';
type Props = {
- connection: ConnectionReduxState,
- version: VersionReduxState,
- accountExpiry: ?AccountExpiry,
- selectedRelayName: string,
- connectionInfoOpen: boolean,
- blockWhenDisconnected: boolean,
- onSettings: () => void,
- onSelectLocation: () => void,
- onConnect: () => void,
- onDisconnect: () => void,
- onExternalLink: (type: string) => void,
- onToggleConnectionInfo: (boolean) => void,
+ connection: ConnectionReduxState;
+ version: VersionReduxState;
+ accountExpiry?: AccountExpiry;
+ selectedRelayName: string;
+ connectionInfoOpen: boolean;
+ blockWhenDisconnected: boolean;
+ onSettings: () => void;
+ onSelectLocation: () => void;
+ onConnect: () => void;
+ onDisconnect: () => void;
+ onExternalLink: (url: string) => void;
+ onToggleConnectionInfo: (value: boolean) => void;
};
type MarkerOrSpinner = 'marker' | 'spinner';
@@ -69,7 +68,7 @@ export default class Connect extends Component<Props> {
return (
<View style={styles.connect}>
<View style={styles.status_icon}>
- <ImageView source="icon-fail" height={60} width={60} alt="" />
+ <ImageView source="icon-fail" height={60} width={60} />
</View>
<View style={styles.body}>
<View style={styles.error_title}>{title}</View>
@@ -78,9 +77,9 @@ export default class Connect extends Component<Props> {
<View>
<AppButton.GreenButton
disabled={isBlocked}
- onPress={() => this.props.onExternalLink('purchase')}>
+ onPress={() => this.props.onExternalLink(links.purchase)}>
<AppButton.Label>Buy more time</AppButton.Label>
- <ImageView source="icon-extLink" height={16} width={16} />
+ <AppButton.Icon source="icon-extLink" height={16} width={16} />
</AppButton.GreenButton>
</View>
) : null}
@@ -89,9 +88,12 @@ export default class Connect extends Component<Props> {
);
}
- _getMapProps() {
- const { longitude, latitude, status } = this.props.connection;
- const state = status.state;
+ _getMapProps(): Map['props'] {
+ const {
+ longitude,
+ latitude,
+ status: { state },
+ } = this.props.connection;
// when the user location is known
if (typeof longitude === 'number' && typeof latitude === 'number') {
@@ -101,7 +103,7 @@ export default class Connect extends Component<Props> {
showMarker: this._showMarkerOrSpinner() === 'marker',
markerStyle: this._getMarkerStyle(),
// zoom in when connected
- zoomLevel: state === 'connected' ? 'low' : 'medium',
+ zoomLevel: state === 'connected' ? ZoomLevel.low : ZoomLevel.medium,
// a magic offset to align marker with spinner
offset: [0, 123],
};
@@ -109,86 +111,81 @@ export default class Connect extends Component<Props> {
return {
center: [0, 0],
showMarker: false,
- markerStyle: 'unsecure',
+ markerStyle: MarkerStyle.unsecure,
// show the world when user location is not known
- zoomLevel: 'high',
+ zoomLevel: ZoomLevel.high,
// remove the offset since the marker is hidden
offset: [0, 0],
};
}
}
- _getMarkerStyle() {
+ _getMarkerStyle(): MarkerStyle {
const { status } = this.props.connection;
switch (status.state) {
case 'connecting':
case 'connected':
- return 'secure';
+ return MarkerStyle.secure;
case 'blocked':
switch (status.details.reason) {
case 'set_firewall_policy_error':
- return 'unsecure';
+ return MarkerStyle.unsecure;
default:
- return 'secure';
+ return MarkerStyle.secure;
}
case 'disconnected':
- return 'unsecure';
+ return MarkerStyle.unsecure;
case 'disconnecting':
switch (status.details) {
case 'block':
case 'reconnect':
- return 'secure';
+ return MarkerStyle.secure;
case 'nothing':
- return 'unsecure';
+ return MarkerStyle.unsecure;
default:
- throw new Error(`Invalid action after disconnection: ${(status.details: empty)}`);
+ throw new Error(`Invalid action after disconnection: ${status.details}`);
}
- default:
- throw new Error(`Invalid connection status: ${(status.state: empty)}`);
}
}
_showMarkerOrSpinner(): MarkerOrSpinner {
- const state = this.props.connection.status.state;
- const details = this.props.connection.status.details;
+ const status = this.props.connection.status;
- if (state === 'connecting' || (state === 'disconnecting' && details === 'reconnect')) {
- return 'spinner';
- } else {
- return 'marker';
- }
+ return status.state === 'connecting' ||
+ (status.state === 'disconnecting' && status.details === 'reconnect')
+ ? 'spinner'
+ : 'marker';
+ }
+
+ _tunnelEndpointToRelayInAddress(tunnelEndpoint: TunnelEndpoint): RelayInAddress {
+ const socketAddr = parseSocketAddress(tunnelEndpoint.address);
+ return {
+ ip: socketAddr.host,
+ port: socketAddr.port,
+ protocol: tunnelEndpoint.protocol,
+ };
}
renderMap() {
- const tunnelState = this.props.connection.status.state;
- const details = this.props.connection.status.details;
+ const status = this.props.connection.status;
const relayOutAddress: RelayOutAddress = {
ipv4: this.props.connection.ip,
- ipv6: null,
};
- let relayInAddress: ?RelayInAddress = null;
-
- if ((tunnelState === 'connecting' || tunnelState === 'connected') && details) {
- const socketAddr = parseSocketAddress(details.address);
- relayInAddress = {
- ip: socketAddr.host,
- port: socketAddr.port,
- protocol: details.protocol,
- };
- }
+ const relayInAddress: RelayInAddress | undefined =
+ (status.state === 'connecting' || status.state === 'connected') && status.details
+ ? this._tunnelEndpointToRelayInAddress(status.details)
+ : undefined;
return (
<View style={styles.connect}>
- <View style={styles.map}>
- <Map style={{ width: '100%', height: '100%' }} {...this._getMapProps()} />
- </View>
+ <Map style={styles.map} {...this._getMapProps()} />
<View style={styles.container}>
{/* show spinner when connecting */}
{this._showMarkerOrSpinner() === 'spinner' ? (
<View style={styles.status_icon}>
- <ImageView source="icon-spinner" height={60} width={60} alt="" />
+ <ImageView source="icon-spinner" height={60} width={60} />
</View>
) : null}
@@ -245,14 +242,12 @@ export default class Connect extends Component<Props> {
case 'nothing':
return HeaderBarStyle.error;
default:
- throw new Error(`Invalid action after disconnection: ${(status.details: empty)}`);
+ throw new Error(`Invalid action after disconnection: ${status.details}`);
}
- default:
- throw new Error(`Invalid TunnelState: ${(status.state: empty)}`);
}
}
- checkForErrors(): ?Error {
+ checkForErrors(): Error | undefined {
// Offline?
if (!this.props.connection.isOnline) {
return new NoInternetError();
@@ -263,6 +258,6 @@ export default class Connect extends Component<Props> {
return new NoCreditError();
}
- return null;
+ return undefined;
}
}
diff --git a/gui/packages/desktop/src/renderer/components/ConnectStyles.js b/gui/packages/desktop/src/renderer/components/ConnectStyles.tsx
index a114687457..c00d6667bd 100644
--- a/gui/packages/desktop/src/renderer/components/ConnectStyles.js
+++ b/gui/packages/desktop/src/renderer/components/ConnectStyles.tsx
@@ -1,7 +1,5 @@
-// @flow
-
import { Styles } from 'reactxp';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
export default {
connect: Styles.createViewStyle({
@@ -13,9 +11,8 @@ export default {
left: 0,
right: 0,
bottom: 0,
+ // @ts-ignore
zIndex: 0,
- height: '100%',
- width: '100%',
}),
body: Styles.createViewStyle({
paddingTop: 0,
@@ -29,6 +26,7 @@ export default {
flexDirection: 'column',
flex: 1,
position: 'relative' /* need this for z-index to work to cover map */,
+ // @ts-ignore
zIndex: 1,
}),
status_icon: Styles.createViewStyle({
@@ -39,8 +37,10 @@ export default {
marginTop: 94,
}),
notification_area: Styles.createViewStyle({
- width: '100%',
position: 'absolute',
+ left: 0,
+ top: 0,
+ right: 0,
}),
error_title: Styles.createTextStyle({
fontFamily: 'DINPro',
diff --git a/gui/packages/desktop/src/renderer/components/CountryRow.js b/gui/packages/desktop/src/renderer/components/CountryRow.tsx
index c504ad397c..eac0c70c15 100644
--- a/gui/packages/desktop/src/renderer/components/CountryRow.js
+++ b/gui/packages/desktop/src/renderer/components/CountryRow.tsx
@@ -1,22 +1,22 @@
-// @flow
-
import * as React from 'react';
-import { Component, Styles, View } from 'reactxp';
+import { Component, Styles, Types, View } from 'reactxp';
import { Accordion } from '@mullvad/components';
import * as Cell from './Cell';
import CityRow from './CityRow';
import RelayStatusIndicator from './RelayStatusIndicator';
import ChevronButton from './ChevronButton';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
+
+type CityRowElement = React.ReactElement<CityRow['props']>;
type Props = {
- name: string,
- hasActiveRelays: boolean,
- selected: boolean,
- expanded: boolean,
- onSelect?: () => void,
- onExpand?: (boolean) => void,
- children?: React.Element<typeof CityRow>,
+ name: string;
+ hasActiveRelays: boolean;
+ selected: boolean;
+ expanded: boolean;
+ onSelect?: () => void;
+ onExpand?: (value: boolean) => void;
+ children?: CityRowElement | CityRowElement[];
};
const styles = {
@@ -54,8 +54,8 @@ export default class CountryRow extends Component<Props> {
return false;
}
- const currChildren = React.Children.toArray(oldProps.children);
- const nextChildren = React.Children.toArray(nextProps.children);
+ const currChildren = React.Children.toArray(oldProps.children || []) as CityRowElement[];
+ const nextChildren = React.Children.toArray(nextProps.children || []) as CityRowElement[];
for (let i = 0; i < currChildren.length; i++) {
const currChild = currChildren[i];
@@ -70,19 +70,21 @@ export default class CountryRow extends Component<Props> {
}
render() {
- const numChildren = React.Children.count(this.props.children);
- const onlyChild = numChildren === 1 ? this.props.children[0] : undefined;
- const numOnlyChildChildren = onlyChild ? React.Children.count(onlyChild.props.children) : 0;
+ const childrenArray = React.Children.toArray(this.props.children || []) as CityRowElement[];
+ const numChildren = childrenArray.length;
+ const onlyChild = numChildren === 1 ? childrenArray[0] : undefined;
+ const numOnlyChildChildren = onlyChild
+ ? React.Children.count(onlyChild.props.children || [])
+ : 0;
const hasChildren = numChildren > 1 || numOnlyChildChildren > 1;
return (
<View style={styles.container}>
<Cell.CellButton
- cellHoverStyle={this.props.selected ? styles.selected : null}
- style={[styles.base, this.props.selected ? styles.selected : null]}
+ cellHoverStyle={this.props.selected ? styles.selected : undefined}
+ style={[styles.base, this.props.selected ? styles.selected : undefined]}
onPress={this._handlePress}
- disabled={!this.props.hasActiveRelays}
- testName="country">
+ disabled={!this.props.hasActiveRelays}>
<RelayStatusIndicator
isActive={this.props.hasActiveRelays}
isSelected={this.props.selected}
@@ -98,7 +100,7 @@ export default class CountryRow extends Component<Props> {
);
}
- _toggleCollapse = (event: Event) => {
+ _toggleCollapse = (event: Types.SyntheticEvent) => {
if (this.props.onExpand) {
this.props.onExpand(!this.props.expanded);
}
diff --git a/gui/packages/desktop/src/renderer/components/CustomScrollbars.js b/gui/packages/desktop/src/renderer/components/CustomScrollbars.tsx
index c6e5c09afe..3e2ccef42f 100644
--- a/gui/packages/desktop/src/renderer/components/CustomScrollbars.js
+++ b/gui/packages/desktop/src/renderer/components/CustomScrollbars.tsx
@@ -1,38 +1,38 @@
-// @flow
-
import * as React from 'react';
-type ScrollbarUpdateContext = {
- size: boolean,
- position: boolean,
-};
-
const AUTOHIDE_TIMEOUT = 1000;
type Props = {
- autoHide: boolean,
- trackPadding: { x: number, y: number },
- onScroll?: ({ scrollLeft: number, scrollTop: number }) => void,
- children?: React.Node,
+ autoHide: boolean;
+ trackPadding: { x: number; y: number };
+ onScroll?: (value: ScrollEvent) => void;
+ style?: React.CSSProperties;
+ children?: React.ReactNode;
};
type State = {
- canScroll: boolean,
- showScrollIndicators: boolean,
- showTrack: boolean,
- isTrackHovered: boolean,
- isDragging: boolean,
+ canScroll: boolean;
+ showScrollIndicators: boolean;
+ showTrack: boolean;
+ isTrackHovered: boolean;
+ isDragging: boolean;
dragStart: {
- x: number,
- y: number,
- },
- isWide: boolean,
+ x: number;
+ y: number;
+ };
+ isWide: boolean;
};
-type ScrollPosition = 'top' | 'bottom' | 'middle';
+export type ScrollEvent = { scrollLeft: number; scrollTop: number };
+export type ScrollPosition = 'top' | 'bottom' | 'middle';
+
+type ScrollbarUpdateContext = {
+ size: boolean;
+ position: boolean;
+};
export default class CustomScrollbars extends React.Component<Props, State> {
- static defaultProps = {
+ static defaultProps: Props = {
// auto-hide on macOS by default
autoHide: process.platform === 'darwin',
trackPadding: { x: 2, y: 2 },
@@ -48,10 +48,10 @@ export default class CustomScrollbars extends React.Component<Props, State> {
isWide: false,
};
- _scrollableRef = React.createRef();
- _trackRef = React.createRef();
- _thumbRef = React.createRef();
- _autoHideTimer: ?TimeoutID;
+ _scrollableRef = React.createRef<HTMLDivElement>();
+ _trackRef = React.createRef<HTMLDivElement>();
+ _thumbRef = React.createRef<HTMLDivElement>();
+ _autoHideTimer?: NodeJS.Timeout;
scrollTo(x: number, y: number) {
const scrollable = this._scrollableRef.current;
@@ -336,18 +336,18 @@ export default class CustomScrollbars extends React.Component<Props, State> {
_stopAutoHide() {
if (this._autoHideTimer) {
clearTimeout(this._autoHideTimer);
- this._autoHideTimer = null;
+ this._autoHideTimer = undefined;
}
}
- _isPointInsideOfElement(element: HTMLElement, point: { x: number, y: number }) {
+ _isPointInsideOfElement(element: HTMLElement, point: { x: number; y: number }) {
const rect = element.getBoundingClientRect();
return (
point.x >= rect.left && point.x <= rect.right && point.y >= rect.top && point.y <= rect.bottom
);
}
- _getPointRelativeToElement(element: HTMLElement, point: { x: number, y: number }) {
+ _getPointRelativeToElement(element: HTMLElement, point: { x: number; y: number }) {
const rect = element.getBoundingClientRect();
return {
x: point.x - rect.left,
@@ -364,12 +364,13 @@ export default class CustomScrollbars extends React.Component<Props, State> {
let offsetTop = 0;
let node = child;
- while (node && scrollable.contains(node)) {
+ while (scrollable.contains(node)) {
offsetTop += node.offsetTop;
-
- // Flow bug in offsetParent definition:
- // https://github.com/facebook/flow/issues/4407
- node = ((node.offsetParent: any): HTMLElement);
+ if (node.offsetParent) {
+ node = node.offsetParent as HTMLElement;
+ } else {
+ break;
+ }
}
return offsetTop;
@@ -387,9 +388,6 @@ export default class CustomScrollbars extends React.Component<Props, State> {
case 'middle':
return offsetTop - (scrollable.offsetHeight - child.clientHeight) * 0.5;
-
- default:
- throw new Error(`Unknown enum type for ScrollPosition: ${(scrollPosition: empty)}`);
}
}
@@ -433,7 +431,7 @@ export default class CustomScrollbars extends React.Component<Props, State> {
return Math.max(thumbHeight, 8);
}
- _updateScrollbarsHelper(updateFlags: $Shape<ScrollbarUpdateContext>) {
+ _updateScrollbarsHelper(updateFlags: Partial<ScrollbarUpdateContext>) {
const scrollable = this._scrollableRef.current;
const thumb = this._thumbRef.current;
if (scrollable && thumb) {
@@ -444,7 +442,7 @@ export default class CustomScrollbars extends React.Component<Props, State> {
_updateScrollbars(
scrollable: HTMLElement,
thumb: HTMLElement,
- context: $Shape<ScrollbarUpdateContext>,
+ context: Partial<ScrollbarUpdateContext>,
) {
if (context.size) {
const thumbHeight = this._computeThumbHeight(scrollable);
diff --git a/gui/packages/desktop/src/renderer/components/Launch.js b/gui/packages/desktop/src/renderer/components/Launch.tsx
index cbb58b2078..5841113fce 100644
--- a/gui/packages/desktop/src/renderer/components/Launch.js
+++ b/gui/packages/desktop/src/renderer/components/Launch.tsx
@@ -1,10 +1,8 @@
-// @flow
-
import * as React from 'react';
import { Component, Styles, View, Text } from 'reactxp';
import { ImageView, SettingsBarButton } from '@mullvad/components';
import { Layout, Container, Header } from './Layout';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
const styles = {
container: Styles.createViewStyle({
@@ -35,7 +33,7 @@ const styles = {
};
type Props = {
- openSettings: () => void,
+ openSettings: () => void;
};
export default class Launch extends Component<Props> {
@@ -46,7 +44,7 @@ export default class Launch extends Component<Props> {
<SettingsBarButton onPress={this.props.openSettings} />
</Header>
<Container>
- <View style={styles.container} testName="headerbar__container">
+ <View style={styles.container}>
<ImageView height={120} width={120} source="logo-icon" style={styles.logo} />
<Text style={styles.title}>{'MULLVAD VPN'}</Text>
<Text style={styles.subtitle}>{'Connecting to daemon...'}</Text>
diff --git a/gui/packages/desktop/src/renderer/components/Layout.js b/gui/packages/desktop/src/renderer/components/Layout.tsx
index f7c87a9c08..efe3b3ff11 100644
--- a/gui/packages/desktop/src/renderer/components/Layout.js
+++ b/gui/packages/desktop/src/renderer/components/Layout.tsx
@@ -1,11 +1,9 @@
-// @flow
-
import * as React from 'react';
import { View, Component } from 'reactxp';
import { HeaderBar } from '@mullvad/components';
import styles from './LayoutStyles';
-export class Header extends Component<React.ElementProps<typeof HeaderBar>> {
+export class Header extends Component<HeaderBar['props']> {
static defaultProps = HeaderBar.defaultProps;
render() {
@@ -18,7 +16,7 @@ export class Header extends Component<React.ElementProps<typeof HeaderBar>> {
}
type ContainerProps = {
- children: React.Node,
+ children: React.ReactNode;
};
export class Container extends Component<ContainerProps> {
render() {
@@ -27,7 +25,7 @@ export class Container extends Component<ContainerProps> {
}
type LayoutProps = {
- children: Array<React.Node> | React.Node,
+ children: Array<React.ReactNode> | React.ReactNode;
};
export class Layout extends Component<LayoutProps> {
render() {
diff --git a/gui/packages/desktop/src/renderer/components/LayoutStyles.js b/gui/packages/desktop/src/renderer/components/LayoutStyles.tsx
index be893cb7ba..cebe3f2588 100644
--- a/gui/packages/desktop/src/renderer/components/LayoutStyles.js
+++ b/gui/packages/desktop/src/renderer/components/LayoutStyles.tsx
@@ -1,7 +1,5 @@
-// @flow
-
import { Styles } from 'reactxp';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
export default {
layout: Styles.createViewStyle({
diff --git a/gui/packages/desktop/src/renderer/components/Login.js b/gui/packages/desktop/src/renderer/components/Login.tsx
index 70e4a5c7f4..3af814a347 100644
--- a/gui/packages/desktop/src/renderer/components/Login.js
+++ b/gui/packages/desktop/src/renderer/components/Login.tsx
@@ -1,32 +1,30 @@
-// @flow
-
import * as React from 'react';
-import { Component, Text, TextInput, View, Animated, Styles, UserInterface } from 'reactxp';
+import { Component, Text, TextInput, View, Animated, Styles, UserInterface, Types } from 'reactxp';
import { Layout, Container, Header } from './Layout';
import { Accordion, ImageView, SettingsBarButton, Brand } from '@mullvad/components';
import * as Cell from './Cell';
import * as AppButton from './AppButton';
import styles from './LoginStyles';
-import { colors } from '../../config';
+import { colors, links } from '../../config.json';
-import type { LoginState } from '../redux/account/reducers';
-import type { AccountToken } from '../../shared/daemon-rpc-types';
+import { LoginState } from '../redux/account/reducers';
+import { AccountToken } from '../../shared/daemon-rpc-types';
type Props = {
- accountToken: ?AccountToken,
- accountHistory: Array<AccountToken>,
- loginError: ?Error,
- loginState: LoginState,
- openSettings: ?() => void,
- openExternalLink: (type: string) => void,
- login: (accountToken: AccountToken) => void,
- resetLoginError: () => void,
- updateAccountToken: (accountToken: AccountToken) => void,
- removeAccountTokenFromHistory: (accountToken: AccountToken) => Promise<void>,
+ accountToken?: AccountToken;
+ accountHistory: Array<AccountToken>;
+ loginError?: Error;
+ loginState: LoginState;
+ openSettings?: () => void;
+ openExternalLink: (type: string) => void;
+ login: (accountToken: AccountToken) => void;
+ resetLoginError: () => void;
+ updateAccountToken: (accountToken: AccountToken) => void;
+ removeAccountTokenFromHistory: (accountToken: AccountToken) => Promise<void>;
};
type State = {
- isActive: boolean,
+ isActive: boolean;
};
const MIN_ACCOUNT_TOKEN_LENGTH = 10;
@@ -36,19 +34,19 @@ export default class Login extends Component<Props, State> {
isActive: true,
};
- _accountInput: ?TextInput;
+ _accountInput = React.createRef<TextInput>();
_shouldResetLoginError = false;
_showsFooter = true;
_footerAnimatedValue = Animated.createValue(0);
- _footerAnimation: ?Animated.Animation;
- _footerAnimationStyle: Animated.Style;
- _footerRef: ?React.Node;
+ _footerAnimation?: Types.Animated.CompositeAnimation;
+ _footerAnimationStyle: Types.AnimatedViewStyleRuleSet;
+ _footerRef = React.createRef<Animated.View>();
_isLoginButtonActive = false;
_loginButtonAnimatedValue = Animated.createValue(0);
- _loginButtonAnimation: ?Animated.Animation;
- _loginButtonAnimationStyle: Animated.Style;
+ _loginButtonAnimation?: Types.Animated.CompositeAnimation;
+ _loginButtonAnimationStyle: Types.AnimatedViewStyleRuleSet;
constructor(props: Props) {
super(props);
@@ -83,7 +81,7 @@ export default class Login extends Component<Props, State> {
this._shouldResetLoginError = true;
// focus on login field when failed to log in
- const accountInput = this._accountInput;
+ const accountInput = this._accountInput.current;
if (accountInput) {
accountInput.focus();
}
@@ -109,11 +107,8 @@ export default class Login extends Component<Props, State> {
</View>
<Animated.View
- ref={(ref) => {
- this._footerRef = ref;
- }}
- style={[styles.login_footer, this._footerAnimationStyle]}
- testName={'footerVisibility ' + this._shouldShowFooter().toString()}>
+ ref={this._footerRef}
+ style={[styles.login_footer, this._footerAnimationStyle]}>
{this._createFooter()}
</Animated.View>
</Container>
@@ -121,18 +116,23 @@ export default class Login extends Component<Props, State> {
);
}
- _onCreateAccount = () => this.props.openExternalLink('createAccount');
+ _onCreateAccount = () => this.props.openExternalLink(links.createAccount);
_onFocus = () => {
this.setState({ isActive: true });
};
- _onBlur = (e) => {
+ _onBlur = (e: Types.SyntheticEvent) => {
+ // TOOD: relatedTarget is not exposed by ReactXP and may not work on non-web platforms.
+ // Find a workaround.
+ // @ts-ignore
const relatedTarget = e.relatedTarget;
// restore focus if click happened within dropdown
if (relatedTarget) {
- e.target.focus();
+ if (this._accountInput.current) {
+ this._accountInput.current.focus();
+ }
return;
}
@@ -162,13 +162,13 @@ export default class Login extends Component<Props, State> {
}
async _setFooterVisibility(show: boolean) {
- if (this._showsFooter === show) {
+ if (this._showsFooter === show || !this._footerRef.current) {
return;
}
this._showsFooter = show;
- const layout = await UserInterface.measureLayoutRelativeToWindow(this._footerRef);
+ const layout = await UserInterface.measureLayoutRelativeToWindow(this._footerRef.current);
const value = show ? 0 : layout.height;
const animation = Animated.timing(this._footerAnimatedValue, {
@@ -237,14 +237,12 @@ export default class Login extends Component<Props, State> {
const statusIconPath = this._getStatusIconPath();
return (
<View style={styles.status_icon}>
- {statusIconPath ? (
- <ImageView source={statusIconPath} height={48} width={48} alt="" />
- ) : null}
+ {statusIconPath ? <ImageView source={statusIconPath} height={48} width={48} /> : null}
</View>
);
}
- _getStatusIconPath(): ?string {
+ _getStatusIconPath(): string | undefined {
switch (this.props.loginState) {
case 'logging in':
return 'icon-spinner';
@@ -257,7 +255,7 @@ export default class Login extends Component<Props, State> {
}
}
- _accountInputGroupStyles(): Array<Object> {
+ _accountInputGroupStyles(): Types.ViewStyleRuleSet[] {
const classes = [styles.account_input_group];
if (this.state.isActive) {
classes.push(styles.account_input_group__active);
@@ -276,8 +274,10 @@ export default class Login extends Component<Props, State> {
return classes;
}
- _accountInputButtonStyles(): Array<Object> {
- const classes = [styles.input_button];
+ _accountInputButtonStyles() {
+ const classes: Array<
+ Types.StyleRuleSet<Types.AnimatedViewStyle> | Types.StyleRuleSet<Types.ViewStyle>
+ > = [styles.input_button];
if (this.props.loginState === 'logging in' || this.props.loginState === 'ok') {
classes.push(styles.input_button__invisible);
@@ -288,7 +288,7 @@ export default class Login extends Component<Props, State> {
return classes;
}
- _accountInputArrowStyles(): Array<Object> {
+ _accountInputArrowStyles(): Types.ViewStyleRuleSet[] {
const { loginState } = this.props;
const classes = [styles.input_arrow];
@@ -299,9 +299,12 @@ export default class Login extends Component<Props, State> {
return classes;
}
- _shouldActivateLoginButton() {
+ _shouldActivateLoginButton(): boolean {
const { accountToken } = this.props;
- return accountToken && accountToken.length >= MIN_ACCOUNT_TOKEN_LENGTH;
+ if (accountToken && accountToken.length >= MIN_ACCOUNT_TOKEN_LENGTH) {
+ return true;
+ }
+ return false;
}
_shouldEnableAccountInput() {
@@ -324,12 +327,12 @@ export default class Login extends Component<Props, State> {
);
}
- _onSelectAccountFromHistory = (accountToken) => {
+ _onSelectAccountFromHistory = (accountToken: string) => {
this.props.updateAccountToken(accountToken);
this.props.login(accountToken);
};
- _onRemoveAccountFromHistory = (accountToken) => {
+ _onRemoveAccountFromHistory = (accountToken: string) => {
this._removeAccountFromHistory(accountToken);
};
@@ -363,14 +366,9 @@ export default class Login extends Component<Props, State> {
returnKeyType="done"
keyboardType="numeric"
autoFocus={true}
- ref={(ref) => (this._accountInput = ref)}
- testName="AccountInput"
- testId="AccountInput"
+ ref={this._accountInput}
/>
- <Animated.View
- style={this._accountInputButtonStyles()}
- onPress={this._onSubmit}
- testName="account-input-button">
+ <Animated.View style={this._accountInputButtonStyles()} onPress={this._onSubmit}>
<ImageView
style={this._accountInputArrowStyles()}
source="icon-arrow"
@@ -400,7 +398,7 @@ export default class Login extends Component<Props, State> {
<Text style={styles.login_footer__prompt}>{"Don't have an account number?"}</Text>
<AppButton.BlueButton onPress={this._onCreateAccount}>
<AppButton.Label>Create account</AppButton.Label>
- <ImageView source="icon-extLink" height={16} width={16} />
+ <AppButton.Icon source="icon-extLink" height={16} width={16} />
</AppButton.BlueButton>
</View>
);
@@ -408,9 +406,9 @@ export default class Login extends Component<Props, State> {
}
type AccountDropdownProps = {
- items: Array<AccountToken>,
- onSelect: (value: AccountToken) => void,
- onRemove: (value: AccountToken) => void,
+ items: Array<AccountToken>;
+ onSelect: (value: AccountToken) => void;
+ onRemove: (value: AccountToken) => void;
};
class AccountDropdown extends React.Component<AccountDropdownProps> {
@@ -433,10 +431,10 @@ class AccountDropdown extends React.Component<AccountDropdownProps> {
}
type AccountDropdownItemProps = {
- label: string,
- value: AccountToken,
- onRemove: (value: AccountToken) => void,
- onSelect: (value: AccountToken) => void,
+ label: string;
+ value: AccountToken;
+ onRemove: (value: AccountToken) => void;
+ onSelect: (value: AccountToken) => void;
};
class AccountDropdownItem extends React.Component<AccountDropdownItemProps> {
diff --git a/gui/packages/desktop/src/renderer/components/LoginStyles.js b/gui/packages/desktop/src/renderer/components/LoginStyles.tsx
index 1ab3fb835a..53cf650c99 100644
--- a/gui/packages/desktop/src/renderer/components/LoginStyles.js
+++ b/gui/packages/desktop/src/renderer/components/LoginStyles.tsx
@@ -1,7 +1,5 @@
-// @flow
-
import { Styles } from 'reactxp';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
export default {
login_footer: Styles.createViewStyle({
@@ -44,7 +42,6 @@ export default {
}),
account_input_group__error: Styles.createViewStyle({
borderColor: colors.red40,
- color: colors.red,
}),
account_input_backdrop: Styles.createViewStyle({
backgroundColor: colors.white,
@@ -68,7 +65,6 @@ export default {
width: 48,
alignItems: 'center',
justifyContent: 'center',
- color: colors.blue20,
}),
input_arrow__invisible: Styles.createViewStyle({
opacity: 0,
@@ -99,7 +95,7 @@ export default {
paddingLeft: 12,
marginLeft: 0,
}),
- account_dropdown__label_hover: Styles.createViewStyle({
+ account_dropdown__label_hover: Styles.createTextStyle({
color: colors.blue,
}),
account_dropdown__label_container: Styles.createViewStyle({
diff --git a/gui/packages/desktop/src/renderer/components/Map.js b/gui/packages/desktop/src/renderer/components/Map.tsx
index e9aa70803b..5640c00676 100644
--- a/gui/packages/desktop/src/renderer/components/Map.js
+++ b/gui/packages/desktop/src/renderer/components/Map.tsx
@@ -1,28 +1,37 @@
-// @flow
-
import * as React from 'react';
-import { Component, View } from 'reactxp';
+import { Component, Types, View } from 'reactxp';
import SvgMap from './SvgMap';
-export type MapProps = {
- center: [number, number], // longitude, latitude
- offset: [number, number], // offset [x, y] from the center of the map
- zoomLevel: 'high' | 'medium' | 'low',
- showMarker: boolean,
- markerStyle: 'secure' | 'unsecure',
- style: Object,
-};
+export enum ZoomLevel {
+ high,
+ medium,
+ low,
+}
+
+export enum MarkerStyle {
+ secure,
+ unsecure,
+}
+
+interface IProps {
+ center: [number, number]; // longitude, latitude
+ offset: [number, number]; // offset [x, y] from the center of the map
+ zoomLevel: ZoomLevel;
+ showMarker: boolean;
+ markerStyle: MarkerStyle;
+ style?: Types.StyleRuleSetRecursive<Types.ViewStyleRuleSet>;
+}
-type MapState = {
+interface IState {
bounds: {
- width: number,
- height: number,
- },
-};
+ width: number;
+ height: number;
+ };
+}
-export default class Map extends Component<MapProps, MapState> {
- state = {
+export default class Map extends Component<IProps, IState> {
+ state: IState = {
bounds: {
width: 0,
height: 0,
@@ -49,7 +58,7 @@ export default class Map extends Component<MapProps, MapState> {
);
}
- shouldComponentUpdate(nextProps: MapProps, nextState: MapState) {
+ shouldComponentUpdate(nextProps: IProps, nextState: IState) {
const oldProps = this.props;
const oldState = this.state;
return (
@@ -65,7 +74,7 @@ export default class Map extends Component<MapProps, MapState> {
);
}
- _onLayout = (layoutInfo) => {
+ _onLayout = (layoutInfo: Types.ViewOnLayoutEvent) => {
this.setState({
bounds: {
width: layoutInfo.width,
@@ -75,27 +84,23 @@ export default class Map extends Component<MapProps, MapState> {
};
// TODO: Remove zoom level in favor of center + coordinate span
- _zoomLevel(variant: $PropertyType<MapProps, 'zoomLevel'>) {
+ _zoomLevel(variant: ZoomLevel) {
switch (variant) {
- case 'high':
+ case ZoomLevel.high:
return 1;
- case 'medium':
+ case ZoomLevel.medium:
return 20;
- case 'low':
+ case ZoomLevel.low:
return 40;
- default:
- throw new Error(`Invalid enumeration type: ${variant}`);
}
}
- _markerImage(style: $PropertyType<MapProps, 'markerStyle'>) {
+ _markerImage(style: MarkerStyle): string {
switch (style) {
- case 'secure':
- return '../assets/images/location-marker-secure.svg';
- case 'unsecure':
- return '../assets/images/location-marker-unsecure.svg';
- default:
- throw new Error(`Invalid enumeration type: ${style}`);
+ case MarkerStyle.secure:
+ return '../../assets/images/location-marker-secure.svg';
+ case MarkerStyle.unsecure:
+ return '../../assets/images/location-marker-unsecure.svg';
}
}
}
diff --git a/gui/packages/desktop/src/renderer/components/NavigationBar.js b/gui/packages/desktop/src/renderer/components/NavigationBar.tsx
index 64babac2f4..6708e345f7 100644
--- a/gui/packages/desktop/src/renderer/components/NavigationBar.js
+++ b/gui/packages/desktop/src/renderer/components/NavigationBar.tsx
@@ -1,10 +1,8 @@
-// @flow
-
import * as React from 'react';
-import { Animated, Button, Component, Text, View, Styles, UserInterface } from 'reactxp';
+import { Animated, Button, Component, Text, Types, View, Styles, UserInterface } from 'reactxp';
import { ImageView } from '@mullvad/components';
-import CustomScrollbars from './CustomScrollbars';
-import { colors } from '../../config';
+import CustomScrollbars, { ScrollEvent } from './CustomScrollbars';
+import { colors } from '../../config.json';
const styles = {
navigationBar: {
@@ -27,7 +25,7 @@ const styles = {
}),
linux: Styles.createViewStyle({
paddingTop: 12,
- WebkitAppRegion: 'drag',
+ appRegion: 'drag',
}),
},
navigationBarTitle: {
@@ -48,7 +46,7 @@ const styles = {
closeBarItem: {
default: Styles.createViewStyle({
cursor: 'default',
- WebkitAppRegion: 'no-drag',
+ appRegion: 'no-drag',
}),
icon: Styles.createViewStyle({
flex: 0,
@@ -61,7 +59,7 @@ const styles = {
padding: 0,
margin: 0,
cursor: 'default',
- WebkitAppRegion: 'no-drag',
+ appRegion: 'no-drag',
}),
content: Styles.createViewStyle({
flexDirection: 'row',
@@ -81,13 +79,13 @@ const styles = {
};
type NavigationScrollContextValue = {
- scrollTop: number,
- onScroll: ({ scrollLeft: number, scrollTop: number }) => void,
+ scrollTop: number;
+ onScroll: (event: ScrollEvent) => void;
};
-const NavigationScrollContext: React.Context<NavigationScrollContextValue> = React.createContext({
+const NavigationScrollContext = React.createContext<NavigationScrollContextValue>({
scrollTop: 0,
- onScroll: (_scroll) => {},
+ onScroll: (_event: ScrollEvent) => {},
});
export class NavigationContainer extends Component {
@@ -95,9 +93,9 @@ export class NavigationContainer extends Component {
scrollTop: 0,
};
- _onScroll = (scroll) => {
+ _onScroll = (event: ScrollEvent) => {
this.setState({
- scrollTop: scroll.scrollTop,
+ scrollTop: event.scrollTop,
});
};
@@ -111,17 +109,20 @@ export class NavigationContainer extends Component {
}
}
-/* $FlowFixMe: React.forwardRef is not supported yet by Flow.
- See: https://github.com/facebook/flow/issues/6103 */
-export const NavigationScrollbars = React.forwardRef(function NavigationScrollbars(
- props: React.ElementProps<typeof CustomScrollbars>,
- ref,
+type NavigationScrollbarsProps = {
+ onScroll?: (value: ScrollEvent) => void;
+ style?: React.CSSProperties;
+ children?: React.ReactNode;
+};
+export const NavigationScrollbars = React.forwardRef(function NavigationScrollbarsT(
+ props: NavigationScrollbarsProps,
+ ref?: React.Ref<CustomScrollbars>,
) {
return (
<NavigationScrollContext.Consumer>
{(context) => {
- const { children, ...otherProps } = props;
- const wrappedOnScroll = (scroll) => {
+ const { style, children, ...otherProps } = props;
+ const wrappedOnScroll = (scroll: ScrollEvent) => {
context.onScroll(scroll);
if (otherProps.onScroll) {
@@ -130,7 +131,7 @@ export const NavigationScrollbars = React.forwardRef(function NavigationScrollba
};
return (
- <CustomScrollbars {...otherProps} ref={ref} onScroll={wrappedOnScroll}>
+ <CustomScrollbars ref={ref} style={style} onScroll={wrappedOnScroll}>
{children}
</CustomScrollbars>
);
@@ -140,9 +141,9 @@ export const NavigationScrollbars = React.forwardRef(function NavigationScrollba
});
type PrivateTitleBarItemProps = {
- visible: boolean,
- titleAdjustment: number,
- children?: React.Node,
+ visible: boolean;
+ titleAdjustment: number;
+ children?: React.ReactText;
};
class PrivateTitleBarItem extends Component<PrivateTitleBarItemProps> {
@@ -175,14 +176,14 @@ class PrivateTitleBarItem extends Component<PrivateTitleBarItemProps> {
}
type PrivateBarItemAnimationContainerProps = {
- visible: boolean,
- children?: React.Node,
+ visible: boolean;
+ children?: React.ReactNode;
};
class PrivateBarItemAnimationContainer extends Component<PrivateBarItemAnimationContainerProps> {
_opacityValue: Animated.Value;
- _opacityStyle: Styles.AnimatedViewStyle;
- _animation: ?Animated.Animation;
+ _opacityStyle: Types.AnimatedViewStyleRuleSet;
+ _animation?: Types.Animated.CompositeAnimation;
constructor(props: PrivateBarItemAnimationContainerProps) {
super(props);
@@ -229,9 +230,14 @@ class PrivateBarItemAnimationContainer extends Component<PrivateBarItemAnimation
}
}
-/* $FlowFixMe: React.forwardRef is not supported yet by Flow.
- See: https://github.com/facebook/flow/issues/6103 */
-export const NavigationBar = React.forwardRef(function NavigationBar(props, ref) {
+type NavigationBarProps = {
+ children?: React.ReactNode;
+};
+
+export const NavigationBar = React.forwardRef(function NavigationBarT(
+ props: NavigationBarProps,
+ ref?: React.Ref<PrivateNavigationBar>,
+) {
return (
<NavigationScrollContext.Consumer>
{(context) => (
@@ -244,36 +250,39 @@ export const NavigationBar = React.forwardRef(function NavigationBar(props, ref)
});
type PrivateNavigationBarProps = {
- scrollTop: number,
- children?: React.Node,
+ scrollTop: number;
+ children?: React.ReactNode;
};
type PrivateNavigationBarState = {
- titleAdjustment: number,
- showsBarSeparator: boolean,
- showsBarTitle: boolean,
+ titleAdjustment: number;
+ showsBarSeparator: boolean;
+ showsBarTitle: boolean;
};
const PrivateTitleBarItemContext = React.createContext({
titleAdjustment: 0,
visible: false,
- titleRef: React.createRef(),
+ titleRef: React.createRef<PrivateTitleBarItem>(),
});
class PrivateNavigationBar extends Component<PrivateNavigationBarProps, PrivateNavigationBarState> {
- static defaultProps = {
+ static defaultProps: Partial<PrivateNavigationBarProps> = {
scrollTop: 0,
};
- state = {
+ state: PrivateNavigationBarState = {
titleAdjustment: 0,
showsBarSeparator: false,
showsBarTitle: false,
};
- _titleViewRef = React.createRef();
+ _titleViewRef = React.createRef<PrivateTitleBarItem>();
- static getDerivedStateFromProps(props, state) {
+ static getDerivedStateFromProps(
+ props: PrivateNavigationBarProps,
+ state: PrivateNavigationBarState,
+ ) {
// that's where SettingsHeader.HeaderTitle intersects the navigation bar
const showsBarSeparator = props.scrollTop > 11;
@@ -304,8 +313,8 @@ class PrivateNavigationBar extends Component<PrivateNavigationBarProps, PrivateN
<View
style={[
styles.navigationBar.default,
- this.state.showsBarSeparator && styles.navigationBar.separator,
- styles.navigationBar[process.platform],
+ this.state.showsBarSeparator ? styles.navigationBar.separator : undefined,
+ this._getPlatformStyle(),
]}
onLayout={this._onLayout}>
<PrivateTitleBarItemContext.Provider
@@ -320,14 +329,24 @@ class PrivateNavigationBar extends Component<PrivateNavigationBarProps, PrivateN
);
}
- _onLayout = async (containerLayout) => {
+ _getPlatformStyle(): Types.ViewStyleRuleSet | undefined {
+ switch (process.platform) {
+ case 'darwin':
+ return styles.navigationBar.darwin;
+ case 'win32':
+ return styles.navigationBar.win32;
+ case 'linux':
+ return styles.navigationBar.linux;
+ default:
+ return undefined;
+ }
+ }
+
+ _onLayout = async (containerLayout: Types.ViewOnLayoutEvent) => {
const titleView = this._titleViewRef.current;
if (titleView) {
// calculate the title layout frame
- const titleLayout = await UserInterface.measureLayoutRelativeToAncestor(
- this._titleViewRef.current,
- this,
- );
+ const titleLayout = await UserInterface.measureLayoutRelativeToAncestor(titleView, this);
// calculate the remaining space at the right hand side
const trailingSpace = containerLayout.width - (titleLayout.x + titleLayout.width);
@@ -339,37 +358,27 @@ class PrivateNavigationBar extends Component<PrivateNavigationBarProps, PrivateN
};
}
-/* $FlowFixMe: React.forwardRef is not supported yet by Flow.
- See: https://github.com/facebook/flow/issues/6103 */
-export const TitleBarItem = React.forwardRef(function TitleBarItem(props, ref) {
+type TitleBarItemProps = {
+ children?: React.ReactText;
+};
+export function TitleBarItem(props: TitleBarItemProps) {
return (
<PrivateTitleBarItemContext.Consumer>
{(context) => (
<PrivateTitleBarItem
titleAdjustment={context.titleAdjustment}
visible={context.visible}
- ref={(value) => {
- context.titleRef.current = value;
-
- if (ref) {
- if (typeof ref === 'function') {
- ref(value);
- } else if (typeof ref === 'object') {
- ref.current = value;
- }
- }
- }}>
+ ref={context.titleRef}>
{props.children}
</PrivateTitleBarItem>
)}
</PrivateTitleBarItemContext.Consumer>
);
-});
+}
-export class CloseBarItem extends Component {
- props: {
- action: () => void,
- };
+export class CloseBarItem extends Component<{
+ action: () => void;
+}> {
render() {
return (
<Button style={[styles.closeBarItem.default]} onPress={this.props.action}>
@@ -379,17 +388,16 @@ export class CloseBarItem extends Component {
}
}
-export class BackBarItem extends Component {
- props: {
- title: string,
- action: () => void,
- };
+export class BackBarItem extends Component<{
+ children?: React.ReactText;
+ action: () => void;
+}> {
render() {
return (
<Button style={styles.backBarButton.default} onPress={this.props.action}>
<View style={styles.backBarButton.content}>
<ImageView style={styles.backBarButton.icon} source="icon-back" />
- <Text style={styles.backBarButton.label}>{this.props.title}</Text>
+ <Text style={styles.backBarButton.label}>{this.props.children}</Text>
</View>
</Button>
);
diff --git a/gui/packages/desktop/src/renderer/components/NotificationArea.js b/gui/packages/desktop/src/renderer/components/NotificationArea.tsx
index 5e42f04d47..c5fedd97e0 100644
--- a/gui/packages/desktop/src/renderer/components/NotificationArea.js
+++ b/gui/packages/desktop/src/renderer/components/NotificationArea.tsx
@@ -1,5 +1,3 @@
-// @flow
-
import moment from 'moment';
import * as React from 'react';
import { Component, Types } from 'reactxp';
@@ -12,31 +10,32 @@ import {
NotificationSubtitle,
NotificationOpenLinkAction,
} from './NotificationBanner';
+import { links } from '../../config.json';
import { AuthFailure } from '../lib/auth-failure';
import AccountExpiry from '../lib/account-expiry';
-import type { BlockReason, TunnelStateTransition } from '../../shared/daemon-rpc-types';
-import type { VersionReduxState } from '../redux/version/reducers';
+import { BlockReason, TunnelStateTransition } from '../../shared/daemon-rpc-types';
+import { VersionReduxState } from '../redux/version/reducers';
type Props = {
- style?: Types.ViewStyleRuleSet,
- accountExpiry: ?AccountExpiry,
- tunnelState: TunnelStateTransition,
- version: VersionReduxState,
- openExternalLink: (string) => void,
- blockWhenDisconnected: boolean,
+ style?: Types.ViewStyleRuleSet;
+ accountExpiry?: AccountExpiry;
+ tunnelState: TunnelStateTransition;
+ version: VersionReduxState;
+ openExternalLink: (url: string) => void;
+ blockWhenDisconnected: boolean;
};
type NotificationAreaPresentation =
- | { type: 'failure-unsecured', reason: string }
- | { type: 'blocking', reason: string }
+ | { type: 'failure-unsecured'; reason: string }
+ | { type: 'blocking'; reason: string }
| { type: 'inconsistent-version' }
- | { type: 'unsupported-version', upgradeVersion: string }
- | { type: 'update-available', upgradeVersion: string }
- | { type: 'expires-soon', timeLeft: string };
+ | { type: 'unsupported-version'; upgradeVersion: string }
+ | { type: 'update-available'; upgradeVersion: string }
+ | { type: 'expires-soon'; timeLeft: string };
type State = NotificationAreaPresentation & {
- visible: boolean,
+ visible: boolean;
};
function getBlockReasonMessage(blockReason: BlockReason): string {
@@ -58,13 +57,11 @@ function getBlockReasonMessage(blockReason: BlockReason): string {
return 'This device is offline, no tunnels can be established';
case 'tap_adapter_problem':
return "Unable to detect a working TAP adapter on this device. If you've disabled it, enable it again. Otherwise, please reinstall the app";
- default:
- return `Unknown error: ${(blockReason.reason: empty)}`;
}
}
export default class NotificationArea extends Component<Props, State> {
- state = {
+ state: State = {
type: 'blocking',
reason: '',
visible: false,
@@ -209,7 +206,7 @@ export default class NotificationArea extends Component<Props, State> {
<NotificationActions>
<NotificationOpenLinkAction
onPress={() => {
- this.props.openExternalLink('download');
+ this.props.openExternalLink(links.download);
}}
/>
</NotificationActions>
@@ -228,7 +225,7 @@ export default class NotificationArea extends Component<Props, State> {
<NotificationActions>
<NotificationOpenLinkAction
onPress={() => {
- this.props.openExternalLink('download');
+ this.props.openExternalLink(links.download);
}}
/>
</NotificationActions>
@@ -245,7 +242,7 @@ export default class NotificationArea extends Component<Props, State> {
<NotificationActions>
<NotificationOpenLinkAction
onPress={() => {
- this.props.openExternalLink('purchase');
+ this.props.openExternalLink(links.purchase);
}}
/>
</NotificationActions>
diff --git a/gui/packages/desktop/src/renderer/components/NotificationBanner.js b/gui/packages/desktop/src/renderer/components/NotificationBanner.tsx
index 7a784058c1..3b31a1a16a 100644
--- a/gui/packages/desktop/src/renderer/components/NotificationBanner.js
+++ b/gui/packages/desktop/src/renderer/components/NotificationBanner.tsx
@@ -1,9 +1,7 @@
-// @flow
-
import * as React from 'react';
import { Animated, View, Button, Text, Component, UserInterface, Styles, Types } from 'reactxp';
import { ImageView } from '@mullvad/components';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
const styles = {
collapsible: Styles.createViewStyle({
@@ -135,30 +133,29 @@ export class NotificationIndicator extends Component<{ type: 'success' | 'warnin
}
type NotificationBannerProps = {
- children: Array<
- React.Element<typeof NotificationContent> | React.Element<typeof NotificationActions>,
- >,
- visible: boolean,
- animationDuration: number,
+ children: React.ReactNode; // Array<NotificationContent | NotificationActions>,
+ style?: Types.ViewStyleRuleSet;
+ visible: boolean;
+ animationDuration: number;
};
type NotificationBannerState = {
- contentPinnedToBottom: boolean,
+ contentPinnedToBottom: boolean;
};
export class NotificationBanner extends Component<
NotificationBannerProps,
- NotificationBannerState,
+ NotificationBannerState
> {
static defaultProps = {
animationDuration: 350,
};
- _containerRef = React.createRef();
+ _containerRef = React.createRef<Animated.View>();
_contentHeight = 0;
_heightValue = Animated.createValue(0);
- _animationStyle: Types.AnimatedViewStyle;
- _animation: ?Types.Animated.CompositeAnimation = null;
+ _animationStyle: Types.AnimatedViewStyleRuleSet;
+ _animation?: Types.Animated.CompositeAnimation;
_didFinishFirstLayoutPass = false;
state = {
@@ -213,7 +210,7 @@ export class NotificationBanner extends Component<
);
}
- _onLayout = ({ height }) => {
+ _onLayout = ({ height }: Types.ViewOnLayoutEvent) => {
const oldHeight = this._contentHeight;
this._contentHeight = height;
@@ -266,7 +263,7 @@ export class NotificationBanner extends Component<
_stopAnimation() {
if (this._animation) {
this._animation.stop();
- this._animation = null;
+ this._animation = undefined;
}
}
}
diff --git a/gui/packages/desktop/src/renderer/components/PlatformWindow.js b/gui/packages/desktop/src/renderer/components/PlatformWindow.tsx
index f143c3d381..e8d4330ef1 100644
--- a/gui/packages/desktop/src/renderer/components/PlatformWindow.js
+++ b/gui/packages/desktop/src/renderer/components/PlatformWindow.tsx
@@ -1,10 +1,8 @@
-// @flow
-
import * as React from 'react';
import { Component, View, Styles } from 'reactxp';
type Props = {
- arrowPosition?: number,
+ arrowPosition?: number;
};
export default class PlatformWindow extends Component<Props> {
@@ -22,10 +20,11 @@ export default class PlatformWindow extends Component<Props> {
}
const webkitMask = [
- `url(../assets/images/app-triangle.svg) ${arrowPositionCss} 0% no-repeat`,
- `url(../assets/images/app-header-backdrop.svg) no-repeat`,
+ `url(../../assets/images/app-triangle.svg) ${arrowPositionCss} 0% no-repeat`,
+ `url(../../assets/images/app-header-backdrop.svg) no-repeat`,
];
+ // @ts-ignore
style = Styles.createViewStyle({ WebkitMask: webkitMask.join(',') }, false);
}
diff --git a/gui/packages/desktop/src/renderer/components/Preferences.js b/gui/packages/desktop/src/renderer/components/Preferences.tsx
index b5b8405b75..256390b899 100644
--- a/gui/packages/desktop/src/renderer/components/Preferences.js
+++ b/gui/packages/desktop/src/renderer/components/Preferences.tsx
@@ -1,5 +1,3 @@
-// @flow
-
import * as React from 'react';
import { Component, View } from 'reactxp';
import { SettingsHeader, HeaderTitle } from '@mullvad/components';
@@ -16,19 +14,19 @@ import Switch from './Switch';
import styles from './PreferencesStyles';
export type PreferencesProps = {
- autoStart: boolean,
- autoConnect: boolean,
- allowLan: boolean,
- monochromaticIcon: boolean,
- startMinimized: boolean,
- enableMonochromaticIconToggle: boolean,
- enableStartMinimizedToggle: boolean,
- setAutoStart: (boolean) => void,
- setAutoConnect: (boolean) => void,
- setAllowLan: (boolean) => void,
- setStartMinimized: (boolean) => void,
- setMonochromaticIcon: (boolean) => void,
- onClose: () => void,
+ autoStart: boolean;
+ autoConnect: boolean;
+ allowLan: boolean;
+ monochromaticIcon: boolean;
+ startMinimized: boolean;
+ enableMonochromaticIconToggle: boolean;
+ enableStartMinimizedToggle: boolean;
+ setAutoStart: (autoStart: boolean) => void;
+ setAutoConnect: (autoConnect: boolean) => void;
+ setAllowLan: (allowLan: boolean) => void;
+ setStartMinimized: (startMinimized: boolean) => void;
+ setMonochromaticIcon: (monochromaticIcon: boolean) => void;
+ onClose: () => void;
};
export default class Preferences extends Component<PreferencesProps> {
@@ -39,7 +37,7 @@ export default class Preferences extends Component<PreferencesProps> {
<View style={styles.preferences}>
<NavigationContainer>
<NavigationBar>
- <BackBarItem action={this.props.onClose} title={'Settings'} />
+ <BackBarItem action={this.props.onClose}>Settings</BackBarItem>
<TitleBarItem>Preferences</TitleBarItem>
</NavigationBar>
@@ -99,9 +97,9 @@ export default class Preferences extends Component<PreferencesProps> {
}
type MonochromaticIconProps = {
- enable: boolean,
- monochromaticIcon: boolean,
- onChange: (boolean) => void,
+ enable: boolean;
+ monochromaticIcon: boolean;
+ onChange: (value: boolean) => void;
};
class MonochromaticIconToggle extends Component<MonochromaticIconProps> {
@@ -123,9 +121,9 @@ class MonochromaticIconToggle extends Component<MonochromaticIconProps> {
}
type StartMinimizedProps = {
- enable: boolean,
- startMinimized: boolean,
- onChange: (boolean) => void,
+ enable: boolean;
+ startMinimized: boolean;
+ onChange: (value: boolean) => void;
};
class StartMinimizedToggle extends Component<StartMinimizedProps> {
diff --git a/gui/packages/desktop/src/renderer/components/PreferencesStyles.js b/gui/packages/desktop/src/renderer/components/PreferencesStyles.tsx
index e6428d571d..47a37e8b4c 100644
--- a/gui/packages/desktop/src/renderer/components/PreferencesStyles.js
+++ b/gui/packages/desktop/src/renderer/components/PreferencesStyles.tsx
@@ -1,7 +1,5 @@
-// @flow
-
import { Styles } from 'reactxp';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
export default {
preferences: Styles.createViewStyle({
@@ -9,15 +7,12 @@ export default {
flex: 1,
}),
preferences__container: Styles.createViewStyle({
- display: 'flex',
flexDirection: 'column',
flex: 1,
}),
preferences__content: Styles.createViewStyle({
flexDirection: 'column',
- flexGrow: 1,
- flexShrink: 1,
- flexBasis: 'auto',
+ flex: 1,
}),
preferences__separator: Styles.createViewStyle({
height: 1,
diff --git a/gui/packages/desktop/src/renderer/components/RelayRow.js b/gui/packages/desktop/src/renderer/components/RelayRow.tsx
index 04aadf3fd5..1170961458 100644
--- a/gui/packages/desktop/src/renderer/components/RelayRow.js
+++ b/gui/packages/desktop/src/renderer/components/RelayRow.tsx
@@ -1,15 +1,13 @@
-// @flow
-
import * as React from 'react';
import { Component, Styles } from 'reactxp';
import * as Cell from './Cell';
import RelayStatusIndicator from './RelayStatusIndicator';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
type Props = {
- hostname: string,
- selected: boolean,
- onSelect?: () => void,
+ hostname: string;
+ selected: boolean;
+ onSelect?: () => void;
};
const styles = {
@@ -38,9 +36,8 @@ export default class RelayRow extends Component<Props> {
return (
<Cell.CellButton
onPress={this._handlePress}
- cellHoverStyle={this.props.selected ? styles.selected : null}
- style={[styles.base, this.props.selected ? styles.selected : null]}
- testName="relay">
+ cellHoverStyle={this.props.selected ? styles.selected : undefined}
+ style={[styles.base, this.props.selected ? styles.selected : undefined]}>
<RelayStatusIndicator isActive={true} isSelected={this.props.selected} />
<Cell.Label>{this.props.hostname}</Cell.Label>
diff --git a/gui/packages/desktop/src/renderer/components/RelayStatusIndicator.js b/gui/packages/desktop/src/renderer/components/RelayStatusIndicator.tsx
index d6b3fa1469..d256352bf1 100644
--- a/gui/packages/desktop/src/renderer/components/RelayStatusIndicator.js
+++ b/gui/packages/desktop/src/renderer/components/RelayStatusIndicator.tsx
@@ -1,9 +1,7 @@
-// @flow
-
import * as React from 'react';
import { Component, Styles, View } from 'reactxp';
import * as Cell from './Cell';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
const styles = {
relay_status: Styles.createViewStyle({
@@ -20,15 +18,14 @@ const styles = {
backgroundColor: colors.green90,
}),
tick_icon: Styles.createViewStyle({
- color: colors.white,
marginLeft: 0,
marginRight: 0,
}),
};
type Props = {
- isActive: boolean,
- isSelected: boolean,
+ isActive: boolean;
+ isSelected: boolean;
};
export default class RelayStatusIndicator extends Component<Props> {
diff --git a/gui/packages/desktop/src/renderer/components/SelectLocation.js b/gui/packages/desktop/src/renderer/components/SelectLocation.tsx
index 18b3ea9b52..620ef504b0 100644
--- a/gui/packages/desktop/src/renderer/components/SelectLocation.js
+++ b/gui/packages/desktop/src/renderer/components/SelectLocation.tsx
@@ -1,10 +1,9 @@
-// @flow
-
import * as React from 'react';
import ReactDOM from 'react-dom';
import { View, Component } from 'reactxp';
import { SettingsHeader, HeaderTitle, HeaderSubTitle } from '@mullvad/components';
import { Layout, Container } from './Layout';
+import CustomScrollbars from './CustomScrollbars';
import {
NavigationContainer,
NavigationScrollbars,
@@ -18,58 +17,60 @@ import CountryRow from './CountryRow';
import CityRow from './CityRow';
import RelayRow from './RelayRow';
-import type { RelaySettingsRedux, RelayLocationRedux } from '../redux/settings/reducers';
-import type { RelayLocation } from '../../shared/daemon-rpc-types';
+import { RelaySettingsRedux, RelayLocationRedux } from '../redux/settings/reducers';
+import { RelayLocation } from '../../shared/daemon-rpc-types';
type Props = {
- relaySettings: RelaySettingsRedux,
- relayLocations: Array<RelayLocationRedux>,
- onClose: () => void,
- onSelect: (location: RelayLocation) => void,
+ relaySettings: RelaySettingsRedux;
+ relayLocations: RelayLocationRedux[];
+ onClose: () => void;
+ onSelect: (location: RelayLocation) => void;
};
type State = {
- selectedLocation?: RelayLocation,
- expandedItems: Array<RelayLocation>,
+ selectedLocation?: RelayLocation;
+ expandedItems: RelayLocation[];
};
export default class SelectLocation extends Component<Props, State> {
- _selectedCellRef = React.createRef();
- _scrollViewRef = React.createRef();
+ _selectedCellRef = React.createRef<React.ReactNode>();
+ _scrollViewRef = React.createRef<CustomScrollbars>();
- state = {
- selectedLocation: undefined,
+ state: State = {
expandedItems: [],
};
constructor(props: Props) {
super(props);
- if (this.props.relaySettings.normal) {
- const expandedItems = [];
+ if ('normal' in this.props.relaySettings) {
const location = this.props.relaySettings.normal.location;
- if (location.city) {
- expandedItems.push({ country: location.city[0] });
- }
+ if (typeof location === 'object') {
+ const expandedItems: RelayLocation[] = [];
- if (location.hostname) {
- expandedItems.push({ country: location.hostname[0] });
- expandedItems.push({ city: [location.hostname[0], location.hostname[1]] });
- }
+ if ('city' in location) {
+ expandedItems.push({ country: location.city[0] });
+ } else if ('hostname' in location) {
+ expandedItems.push({ country: location.hostname[0] });
+ expandedItems.push({ city: [location.hostname[0], location.hostname[1]] });
+ }
- if (location !== 'any') {
- this.state.selectedLocation = location;
+ this.state = {
+ selectedLocation: location,
+ expandedItems,
+ };
}
-
- this.state.expandedItems = expandedItems;
}
}
componentDidUpdate(oldProps: Props) {
const currentLocation = this.state.selectedLocation;
- let newLocation = (this.props.relaySettings.normal || {}).location;
- let oldLocation = (oldProps.relaySettings.normal || {}).location;
+ let newLocation =
+ 'normal' in this.props.relaySettings ? this.props.relaySettings.normal.location : undefined;
+
+ let oldLocation =
+ 'normal' in oldProps.relaySettings ? oldProps.relaySettings.normal.location : undefined;
if (newLocation === 'any') {
newLocation = undefined;
@@ -92,8 +93,8 @@ export default class SelectLocation extends Component<Props, State> {
const cell = this._selectedCellRef.current;
const scrollView = this._scrollViewRef.current;
if (scrollView && cell) {
- // eslint-disable-next-line react/no-find-dom-node
- const cellDOMNode = ReactDOM.findDOMNode(cell);
+ // TODO: Fix the browser specific code
+ const cellDOMNode = ReactDOM.findDOMNode(cell as Element);
if (cellDOMNode instanceof HTMLElement) {
scrollView.scrollToElement(cellDOMNode, 'middle');
}
@@ -122,7 +123,7 @@ export default class SelectLocation extends Component<Props, State> {
</SettingsHeader>
{this.props.relayLocations.map((relayCountry) => {
- const location = { country: relayCountry.code };
+ const location: RelayLocation = { country: relayCountry.code };
return (
<CountryRow
@@ -134,7 +135,9 @@ export default class SelectLocation extends Component<Props, State> {
onExpand={(expand) => this._handleExpand(location, expand)}
{...this._getCommonCellProps(location)}>
{relayCountry.cities.map((relayCity) => {
- const location = { city: [relayCountry.code, relayCity.code] };
+ const location: RelayLocation = {
+ city: [relayCountry.code, relayCity.code],
+ };
return (
<CityRow
@@ -146,7 +149,7 @@ export default class SelectLocation extends Component<Props, State> {
onExpand={(expand) => this._handleExpand(location, expand)}
{...this._getCommonCellProps(location)}>
{relayCity.relays.map((relay) => {
- const location = {
+ const location: RelayLocation = {
hostname: [relayCountry.code, relayCity.code, relay.hostname],
};
@@ -206,26 +209,34 @@ export default class SelectLocation extends Component<Props, State> {
});
};
- _getCommonCellProps(location: RelayLocation) {
+ _getCommonCellProps<T>(location: RelayLocation): { selected: boolean; ref?: React.RefObject<T> } {
const selected = this._isSelected(location);
- const ref = selected ? this._selectedCellRef : undefined;
+ const ref = selected ? (this._selectedCellRef as React.RefObject<T>) : undefined;
return { ref, selected };
}
}
-function getLocationKey(location: RelayLocation) {
- const components = location.city || location.country || location.hostname || [];
+function getLocationKey(location: RelayLocation): string {
+ const components: string[] = [];
+
+ if ('city' in location) {
+ components.push(...location.city);
+ } else if ('country' in location) {
+ components.push(location.country);
+ } else if ('hostname' in location) {
+ components.push(...location.hostname);
+ }
- return [].concat(components).join('-');
+ return ([] as string[]).concat(components).join('-');
}
function compareLocation(lhs: RelayLocation, rhs: RelayLocation) {
- if (lhs.country && rhs.country) {
+ if ('country' in lhs && 'country' in rhs && lhs.country && rhs.country) {
return lhs.country === rhs.country;
- } else if (lhs.city && rhs.city) {
+ } else if ('city' in lhs && 'city' in rhs && lhs.city && rhs.city) {
return lhs.city[0] === rhs.city[0] && lhs.city[1] === rhs.city[1];
- } else if (lhs.hostname && rhs.hostname) {
+ } else if ('hostname' in lhs && 'hostname' in rhs && lhs.hostname && rhs.hostname) {
return (
lhs.hostname[0] === rhs.hostname[0] &&
lhs.hostname[1] === rhs.hostname[1] &&
@@ -236,7 +247,7 @@ function compareLocation(lhs: RelayLocation, rhs: RelayLocation) {
}
}
-function compareLocationLoose(lhs: ?RelayLocation, rhs: ?RelayLocation) {
+function compareLocationLoose(lhs?: RelayLocation, rhs?: RelayLocation) {
if (lhs && rhs) {
return compareLocation(lhs, rhs);
} else {
diff --git a/gui/packages/desktop/src/renderer/components/SelectLocationStyles.js b/gui/packages/desktop/src/renderer/components/SelectLocationStyles.tsx
index c2db5a7718..0c9ab0d3c5 100644
--- a/gui/packages/desktop/src/renderer/components/SelectLocationStyles.js
+++ b/gui/packages/desktop/src/renderer/components/SelectLocationStyles.tsx
@@ -1,7 +1,5 @@
-// @flow
-
import { Styles } from 'reactxp';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
export default {
select_location: Styles.createViewStyle({
diff --git a/gui/packages/desktop/src/renderer/components/Settings.js b/gui/packages/desktop/src/renderer/components/Settings.tsx
index 0a056c92de..555ad94954 100644
--- a/gui/packages/desktop/src/renderer/components/Settings.js
+++ b/gui/packages/desktop/src/renderer/components/Settings.tsx
@@ -1,5 +1,3 @@
-// @flow
-
import * as React from 'react';
import { Component, Text, View } from 'reactxp';
import { ImageView, SettingsHeader, HeaderTitle } from '@mullvad/components';
@@ -15,28 +13,28 @@ import {
} from './NavigationBar';
import styles from './SettingsStyles';
import AccountExpiry from '../lib/account-expiry';
-import { colors } from '../../config';
+import { colors, links } from '../../config.json';
-import type { LoginState } from '../redux/account/reducers';
+import { LoginState } from '../redux/account/reducers';
-type Props = {
- loginState: LoginState,
- accountExpiry: ?string,
- appVersion: string,
- consistentVersion: boolean,
- upToDateVersion: boolean,
- isOffline: boolean,
- onQuit: () => void,
- onClose: () => void,
- onViewAccount: () => void,
- onViewSupport: () => void,
- onViewPreferences: () => void,
- onViewAdvancedSettings: () => void,
- onExternalLink: (type: string) => void,
-};
+export interface IProps {
+ loginState: LoginState;
+ accountExpiry?: string;
+ appVersion: string;
+ consistentVersion: boolean;
+ upToDateVersion: boolean;
+ isOffline: boolean;
+ onQuit: () => void;
+ onClose: () => void;
+ onViewAccount: () => void;
+ onViewSupport: () => void;
+ onViewPreferences: () => void;
+ onViewAdvancedSettings: () => void;
+ onExternalLink: (url: string) => void;
+}
-export default class Settings extends Component<Props> {
- render() {
+export default class Settings extends Component<IProps> {
+ public render() {
return (
<Layout>
<Container>
@@ -69,7 +67,7 @@ export default class Settings extends Component<Props> {
);
}
- _renderTopButtons() {
+ private _renderTopButtons() {
const isLoggedIn = this.props.loginState === 'ok';
if (!isLoggedIn) {
return null;
@@ -81,38 +79,30 @@ export default class Settings extends Component<Props> {
return (
<View>
- <View testName="settings__account">
+ <View>
{isOutOfTime ? (
- <Cell.CellButton
- onPress={this.props.onViewAccount}
- testName="settings__account_paid_until_button">
+ <Cell.CellButton onPress={this.props.onViewAccount}>
<Cell.Label>Account</Cell.Label>
- <Cell.SubText
- testName="settings__account_paid_until_subtext"
- style={styles.settings__account_paid_until_label__error}>
+ <Cell.SubText style={styles.settings__account_paid_until_label__error}>
{'OUT OF TIME'}
</Cell.SubText>
<Cell.Icon height={12} width={7} source="icon-chevron" />
</Cell.CellButton>
) : (
- <Cell.CellButton
- onPress={this.props.onViewAccount}
- testName="settings__account_paid_until_button">
+ <Cell.CellButton onPress={this.props.onViewAccount}>
<Cell.Label>Account</Cell.Label>
- <Cell.SubText testName="settings__account_paid_until_subtext">
- {formattedExpiry}
- </Cell.SubText>
+ <Cell.SubText>{formattedExpiry}</Cell.SubText>
<Cell.Icon height={12} width={7} source="icon-chevron" />
</Cell.CellButton>
)}
</View>
- <Cell.CellButton onPress={this.props.onViewPreferences} testName="settings__preferences">
+ <Cell.CellButton onPress={this.props.onViewPreferences}>
<Cell.Label>Preferences</Cell.Label>
<Cell.Icon height={12} width={7} source="icon-chevron" />
</Cell.CellButton>
- <Cell.CellButton onPress={this.props.onViewAdvancedSettings} testName="settings__advanced">
+ <Cell.CellButton onPress={this.props.onViewAdvancedSettings}>
<Cell.Label>Advanced</Cell.Label>
<Cell.Icon height={12} width={7} source="icon-chevron" />
</Cell.CellButton>
@@ -121,7 +111,7 @@ export default class Settings extends Component<Props> {
);
}
- _renderMiddleButtons() {
+ private _renderMiddleButtons() {
let icon;
let footer;
if (!this.props.consistentVersion || !this.props.upToDateVersion) {
@@ -147,10 +137,7 @@ export default class Settings extends Component<Props> {
return (
<View>
- <Cell.CellButton
- disabled={this.props.isOffline}
- onPress={this.props.onExternalLink.bind(this, 'download')}
- testName="settings__version">
+ <Cell.CellButton disabled={this.props.isOffline} onPress={this._openDownloadLink}>
{icon}
<Cell.Label>App version</Cell.Label>
<Cell.SubText>{this.props.appVersion}</Cell.SubText>
@@ -161,18 +148,18 @@ export default class Settings extends Component<Props> {
);
}
- _renderBottomButtons() {
+ private _openDownloadLink = () => this.props.onExternalLink(links.download);
+ private _openFaqLink = () => this.props.onExternalLink(links.faq);
+
+ private _renderBottomButtons() {
return (
<View>
- <Cell.CellButton onPress={this.props.onViewSupport} testName="settings__view_support">
+ <Cell.CellButton onPress={this.props.onViewSupport}>
<Cell.Label>Report a problem</Cell.Label>
<Cell.Icon height={12} width={7} source="icon-chevron" />
</Cell.CellButton>
- <Cell.CellButton
- disabled={this.props.isOffline}
- onPress={this.props.onExternalLink.bind(this, 'faq')}
- testName="settings__external_link">
+ <Cell.CellButton disabled={this.props.isOffline} onPress={this._openFaqLink}>
<Cell.Label>{'FAQs & Guides'}</Cell.Label>
<Cell.Icon height={16} width={16} source="icon-extLink" />
</Cell.CellButton>
@@ -183,9 +170,7 @@ export default class Settings extends Component<Props> {
_renderQuitButton() {
return (
<View style={styles.settings__footer}>
- <AppButton.RedButton onPress={this.props.onQuit} testName="settings__quit">
- <AppButton.Label>Quit app</AppButton.Label>
- </AppButton.RedButton>
+ <AppButton.RedButton onPress={this.props.onQuit}>{'Quit app'}</AppButton.RedButton>
</View>
);
}
diff --git a/gui/packages/desktop/src/renderer/components/SettingsStyles.js b/gui/packages/desktop/src/renderer/components/SettingsStyles.tsx
index 56ec6b3752..d70d413c6a 100644
--- a/gui/packages/desktop/src/renderer/components/SettingsStyles.js
+++ b/gui/packages/desktop/src/renderer/components/SettingsStyles.tsx
@@ -1,7 +1,5 @@
-// @flow
-
import { Styles } from 'reactxp';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
export default {
settings: Styles.createViewStyle({
@@ -18,11 +16,10 @@ export default {
justifyContent: 'space-between',
overflow: 'visible',
}),
- settings__scrollview: Styles.createViewStyle({
- flexGrow: 1,
- flexShrink: 1,
- flexBasis: '100%',
- }),
+ // plain CSS style
+ settings__scrollview: {
+ flex: 1,
+ },
settings__cell_spacer: Styles.createViewStyle({
height: 24,
flex: 0,
diff --git a/gui/packages/desktop/src/renderer/components/Support.js b/gui/packages/desktop/src/renderer/components/Support.tsx
index f9f167e68b..cb432839ca 100644
--- a/gui/packages/desktop/src/renderer/components/Support.js
+++ b/gui/packages/desktop/src/renderer/components/Support.tsx
@@ -1,5 +1,3 @@
-// @flow
-
import * as React from 'react';
import { Component, Text, View, TextInput } from 'reactxp';
import {
@@ -16,37 +14,46 @@ import { Layout, Container } from './Layout';
import { NavigationBar, BackBarItem } from './NavigationBar';
import styles from './SupportStyles';
-import type { AccountToken } from '../../shared/daemon-rpc-types';
-import type { SupportReportForm } from '../redux/support/actions';
+import { AccountToken } from '../../shared/daemon-rpc-types';
+import { SupportReportForm } from '../redux/support/actions';
+
+enum SendState {
+ Initial,
+ Confirm,
+ Loading,
+ Success,
+ Failed,
+}
+
type SupportState = {
- email: string,
- message: string,
- savedReport: ?string,
- sendState: 'INITIAL' | 'CONFIRM' | 'LOADING' | 'SUCCESS' | 'FAILED',
+ email: string;
+ message: string;
+ savedReport?: string;
+ sendState: SendState;
};
-export type SupportProps = {
- defaultEmail: string,
- defaultMessage: string,
- accountHistory: Array<AccountToken>,
- isOffline: boolean,
- onClose: () => void,
- viewLog: (path: string) => void,
- saveReportForm: (form: SupportReportForm) => void,
- clearReportForm: () => void,
- collectProblemReport: (accountsToRedact: Array<string>) => Promise<string>,
- sendProblemReport: (email: string, message: string, savedReport: string) => Promise<void>,
+type SupportProps = {
+ defaultEmail: string;
+ defaultMessage: string;
+ accountHistory: Array<AccountToken>;
+ isOffline: boolean;
+ onClose: () => void;
+ viewLog: (path: string) => void;
+ saveReportForm: (form: SupportReportForm) => void;
+ clearReportForm: () => void;
+ collectProblemReport: (accountsToRedact: Array<string>) => Promise<string>;
+ sendProblemReport: (email: string, message: string, savedReport: string) => Promise<void>;
};
export default class Support extends Component<SupportProps, SupportState> {
state = {
email: '',
message: '',
- savedReport: null,
- sendState: 'INITIAL',
+ savedReport: undefined,
+ sendState: SendState.Initial,
};
- _collectLogPromise: ?Promise<string>;
+ _collectLogPromise?: Promise<string>;
constructor(props: SupportProps) {
super(props);
@@ -103,7 +110,7 @@ export default class Support extends Component<SupportProps, SupportState> {
this.setState({ savedReport: reportPath }, () => resolve(reportPath));
});
} catch (error) {
- this._collectLogPromise = null;
+ this._collectLogPromise = undefined;
throw error;
}
@@ -112,9 +119,9 @@ export default class Support extends Component<SupportProps, SupportState> {
onSend = async (): Promise<void> => {
switch (this.state.sendState) {
- case 'INITIAL':
+ case SendState.Initial:
if (this.state.email.length === 0) {
- this.setState({ sendState: 'CONFIRM' });
+ this.setState({ sendState: SendState.Confirm });
} else {
try {
await this._sendReport();
@@ -124,7 +131,7 @@ export default class Support extends Component<SupportProps, SupportState> {
}
return Promise.resolve();
- case 'CONFIRM':
+ case SendState.Confirm:
try {
await this._sendReport();
} catch (error) {
@@ -140,22 +147,22 @@ export default class Support extends Component<SupportProps, SupportState> {
};
onCancelConfirmation = () => {
- this.setState({ sendState: 'INITIAL' });
+ this.setState({ sendState: SendState.Initial });
};
_sendReport(): Promise<void> {
return new Promise((resolve, reject) => {
- this.setState({ sendState: 'LOADING' }, async () => {
+ this.setState({ sendState: SendState.Loading }, async () => {
try {
const { email, message } = this.state;
const reportPath = await this._collectLog();
await this.props.sendProblemReport(email, message, reportPath);
this.props.clearReportForm();
- this.setState({ sendState: 'SUCCESS' }, () => {
+ this.setState({ sendState: SendState.Success }, () => {
resolve();
});
} catch (error) {
- this.setState({ sendState: 'FAILED' }, () => {
+ this.setState({ sendState: SendState.Failed }, () => {
reject(error);
});
}
@@ -168,7 +175,7 @@ export default class Support extends Component<SupportProps, SupportState> {
const header = (
<SettingsHeader>
<HeaderTitle>Report a problem</HeaderTitle>
- {(sendState === 'INITIAL' || sendState === 'CONFIRM') && (
+ {(sendState === SendState.Initial || sendState === SendState.Confirm) && (
<HeaderSubTitle>
{
"To help you more effectively, your app's log file will be attached to this message. Your data will remain secure and private, as it is anonymised before being sent over an encrypted channel."
@@ -187,7 +194,7 @@ export default class Support extends Component<SupportProps, SupportState> {
<ModalContent>
<View style={styles.support}>
<NavigationBar>
- <BackBarItem action={this.props.onClose} title={'Settings'} />
+ <BackBarItem action={this.props.onClose}>Settings</BackBarItem>
</NavigationBar>
<View style={styles.support__container}>
{header}
@@ -195,7 +202,11 @@ export default class Support extends Component<SupportProps, SupportState> {
</View>
</View>
</ModalContent>
- {sendState === 'CONFIRM' && <ModalAlert>{this._renderConfirm()}</ModalAlert>}
+ {sendState === SendState.Confirm ? (
+ <ModalAlert>{this._renderConfirm()}</ModalAlert>
+ ) : (
+ undefined
+ )}
</ModalContainer>
</Container>
</Layout>
@@ -204,14 +215,14 @@ export default class Support extends Component<SupportProps, SupportState> {
_renderContent() {
switch (this.state.sendState) {
- case 'INITIAL':
- case 'CONFIRM':
+ case SendState.Initial:
+ case SendState.Confirm:
return this._renderForm();
- case 'LOADING':
+ case SendState.Loading:
return this._renderLoading();
- case 'SUCCESS':
+ case SendState.Success:
return this._renderSent();
- case 'FAILED':
+ case SendState.Failed:
return this._renderFailed();
default:
return null;
@@ -243,22 +254,15 @@ export default class Support extends Component<SupportProps, SupportState> {
defaultValue={this.state.message}
multiline={true}
onChangeText={this.onChangeDescription}
- testName="support__form_message"
/>
</View>
</View>
<View style={styles.support__footer}>
- <AppButton.BlueButton
- style={styles.view_logs_button}
- onPress={this.onViewLog}
- testName="support__view_logs">
+ <AppButton.BlueButton style={styles.view_logs_button} onPress={this.onViewLog}>
<AppButton.Label>View app logs</AppButton.Label>
- <ImageView source="icon-extLink" height={16} width={16} />
+ <AppButton.Icon source="icon-extLink" height={16} width={16} />
</AppButton.BlueButton>
- <AppButton.GreenButton
- disabled={!this.validate()}
- onPress={this.onSend}
- testName="support__send_logs">
+ <AppButton.GreenButton disabled={!this.validate()} onPress={this.onSend}>
Send
</AppButton.GreenButton>
</View>
@@ -273,7 +277,7 @@ export default class Support extends Component<SupportProps, SupportState> {
<View style={styles.support__form}>
<View style={styles.support__form_row}>
<View style={styles.support__status_icon}>
- <ImageView source="icon-spinner" height={60} width={60} alt="" />
+ <ImageView source="icon-spinner" height={60} width={60} />
</View>
<View style={styles.support__status_security__secure}>{'SECURE CONNECTION'}</View>
<Text style={styles.support__send_status}>{'Sending...'}</Text>
@@ -289,7 +293,7 @@ export default class Support extends Component<SupportProps, SupportState> {
<View style={styles.support__form}>
<View style={styles.support__form_row}>
<View style={styles.support__status_icon}>
- <ImageView source="icon-success" height={60} width={60} alt="" />
+ <ImageView source="icon-success" height={60} width={60} />
</View>
<Text style={styles.support__status_security__secure}>{'SECURE CONNECTION'}</Text>
<Text style={styles.support__send_status}>{'Sent'}</Text>
@@ -313,7 +317,7 @@ export default class Support extends Component<SupportProps, SupportState> {
<View style={styles.support__form}>
<View style={styles.support__form_row}>
<View style={styles.support__status_icon}>
- <ImageView source="icon-fail" height={60} width={60} alt="" />
+ <ImageView source="icon-fail" height={60} width={60} />
</View>
<Text style={styles.support__status_security__secure}>{'SECURE CONNECTION'}</Text>
<Text style={styles.support__send_status}>{'Failed to send'}</Text>
@@ -327,12 +331,10 @@ export default class Support extends Component<SupportProps, SupportState> {
<View style={styles.support__footer}>
<AppButton.BlueButton
style={styles.edit_message_button}
- onPress={() => this.setState({ sendState: 'INITIAL' })}>
+ onPress={() => this.setState({ sendState: SendState.Initial })}>
{'Edit message'}
</AppButton.BlueButton>
- <AppButton.GreenButton onPress={this.onSend} testName="support__send_logs">
- Try again
- </AppButton.GreenButton>
+ <AppButton.GreenButton onPress={this.onSend}>Try again</AppButton.GreenButton>
</View>
</View>
);
@@ -340,8 +342,8 @@ export default class Support extends Component<SupportProps, SupportState> {
}
type ConfirmNoEmailDialogProps = {
- onConfirm: () => void,
- onDismiss: () => void,
+ onConfirm: () => void;
+ onDismiss: () => void;
};
class ConfirmNoEmailDialog extends Component<ConfirmNoEmailDialogProps> {
@@ -353,13 +355,10 @@ class ConfirmNoEmailDialog extends Component<ConfirmNoEmailDialogProps> {
You are about to send the problem report without a way for us to get back to you. If you
want an answer to your report you will have to enter an email address.
</Text>
- <AppButton.GreenButton onPress={this.props.onConfirm} testName="support__send_logs">
+ <AppButton.GreenButton onPress={this.props.onConfirm}>
{'Send anyway'}
</AppButton.GreenButton>
- <AppButton.RedButton
- onPress={this._dismiss}
- style={styles.confirm_no_email_back_button}
- testName="support__back">
+ <AppButton.RedButton onPress={this._dismiss} style={styles.confirm_no_email_back_button}>
{'Back'}
</AppButton.RedButton>
</View>
diff --git a/gui/packages/desktop/src/renderer/components/SupportStyles.js b/gui/packages/desktop/src/renderer/components/SupportStyles.tsx
index c2b4e2dbb7..bcc05b7b50 100644
--- a/gui/packages/desktop/src/renderer/components/SupportStyles.js
+++ b/gui/packages/desktop/src/renderer/components/SupportStyles.tsx
@@ -1,7 +1,5 @@
-// @flow
-
import { Styles } from 'reactxp';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
export default {
support: Styles.createViewStyle({
@@ -9,18 +7,15 @@ export default {
flex: 1,
}),
support__container: Styles.createViewStyle({
- display: 'flex',
flexDirection: 'column',
flex: 1,
}),
support__content: Styles.createViewStyle({
flex: 1,
- display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
}),
support__form: Styles.createViewStyle({
- display: 'flex',
flex: 1,
flexDirection: 'column',
}),
@@ -41,7 +36,6 @@ export default {
}),
support__form_message_scroll_wrap: Styles.createViewStyle({
flex: 1,
- display: 'flex',
borderRadius: 4,
overflow: 'hidden',
}),
@@ -120,7 +114,6 @@ export default {
marginBottom: 4,
}),
confirm_no_email_background: Styles.createViewStyle({
- display: 'flex',
flex: 1,
justifyContent: 'center',
paddingLeft: 14,
diff --git a/gui/packages/desktop/src/renderer/components/SvgMap.js b/gui/packages/desktop/src/renderer/components/SvgMap.tsx
index f663ac3a11..eb07d74677 100644
--- a/gui/packages/desktop/src/renderer/components/SvgMap.js
+++ b/gui/packages/desktop/src/renderer/components/SvgMap.tsx
@@ -1,5 +1,3 @@
-// @flow
-
import * as React from 'react';
import {
ComposableMap,
@@ -9,50 +7,87 @@ import {
Markers,
Marker,
} from 'react-simple-maps';
-
-import { geoTimes } from 'd3-geo-projection';
import rbush from 'rbush';
+import { geoTimes } from 'd3-geo-projection';
+
+import geographyData from '../../../assets/geo/geometry.json';
+import statesProvincesLinesData from '../../../assets/geo/states-provinces-lines.json';
-import geographyData from '../../assets/geo/geometry.json';
-import statesProvincesLinesData from '../../assets/geo/states-provinces-lines.json';
+import countryTreeData from '../../../assets/geo/countries.rbush.json';
+import cityTreeData from '../../../assets/geo/cities.rbush.json';
+import geometryTreeData from '../../../assets/geo/geometry.rbush.json';
+import statesProvincesLinesTreeData from '../../../assets/geo/states-provinces-lines.rbush.json';
-import countryTreeData from '../../assets/geo/countries.rbush.json';
-import cityTreeData from '../../assets/geo/cities.rbush.json';
-import geometryTreeData from '../../assets/geo/geometry.rbush.json';
-import statesProvincesLinesTreeData from '../../assets/geo/states-provinces-lines.rbush.json';
+// Infer the GeoProjection type from the `geoTimes()` return value
+type GeoProjection = ReturnType<typeof geoTimes>;
-const countryTree = rbush().fromJSON(countryTreeData);
-const cityTree = rbush().fromJSON(cityTreeData);
-const geometryTree = rbush().fromJSON(geometryTreeData);
-const provincesStatesLinesTree = rbush().fromJSON(statesProvincesLinesTreeData);
+interface CountryLeaf extends rbush.BBox {
+ id: string;
+ properties: {
+ name: string;
+ };
+ geometry: {
+ type: string;
+ coordinates: [number, number];
+ };
+}
+
+interface CityLeaf extends rbush.BBox {
+ id: string;
+ properties: {
+ scalerank: number;
+ name: string;
+ latitude: number;
+ longitude: number;
+ };
+ geometry: {
+ type: string;
+ coordinates: [number, number];
+ };
+}
+
+interface GeometryLeaf extends rbush.BBox {
+ id: string;
+}
+
+interface ProvinceAndStateLineLeaf extends rbush.BBox {
+ id: string;
+}
+
+const countryTree = rbush<CountryLeaf>().fromJSON(countryTreeData);
+const cityTree = rbush<CityLeaf>().fromJSON(cityTreeData);
+const geometryTree = rbush<GeometryLeaf>().fromJSON(geometryTreeData);
+const provincesStatesLinesTree = rbush<ProvinceAndStateLineLeaf>().fromJSON(
+ statesProvincesLinesTreeData,
+);
type BBox = [number, number, number, number];
-export type SvgMapProps = {
- width: number,
- height: number,
- center: [number, number], // longitude, latitude
- offset: [number, number], // [x, y] in points
- zoomLevel: number,
- showMarker: boolean,
- markerImagePath: string,
+export type Props = {
+ width: number;
+ height: number;
+ center: [number, number]; // longitude, latitude
+ offset: [number, number]; // [x, y] in points
+ zoomLevel: number;
+ showMarker: boolean;
+ markerImagePath: string;
};
-type SvgMapState = {
- zoomCenter: [number, number],
- zoomLevel: number,
- visibleCities: Array<Object>,
- visibleCountries: Array<Object>,
- visibleGeometry: Array<Object>,
- visibleStatesProvincesLines: Array<Object>,
- viewportBbox: BBox,
+type State = {
+ zoomCenter: [number, number];
+ zoomLevel: number;
+ visibleCities: CityLeaf[];
+ visibleCountries: CountryLeaf[];
+ visibleGeometry: GeometryLeaf[];
+ visibleStatesProvincesLines: ProvinceAndStateLineLeaf[];
+ viewportBbox: BBox;
};
const MOVE_SPEED = 2000;
// @TODO: Calculate zoom level based on (center + span) (aka MKCoordinateSpan)
-export default class SvgMap extends React.Component<SvgMapProps, SvgMapState> {
- state = {
+export default class SvgMap extends React.Component<Props, State> {
+ state: State = {
zoomCenter: [0, 0],
zoomLevel: 1,
visibleCities: [],
@@ -66,19 +101,19 @@ export default class SvgMap extends React.Component<SvgMapProps, SvgMapState> {
scale: 160,
};
- constructor(props: SvgMapProps) {
+ constructor(props: Props) {
super(props);
this.state = this._getNextState(null, props);
}
- UNSAFE_componentWillReceiveProps(nextProps: SvgMapProps) {
+ UNSAFE_componentWillReceiveProps(nextProps: Props) {
if (this._shouldInvalidateState(nextProps)) {
this.setState((prevState) => this._getNextState(prevState, nextProps));
}
}
- shouldComponentUpdate(nextProps: SvgMapProps, nextState: SvgMapState) {
+ shouldComponentUpdate(nextProps: Props, nextState: State) {
return (
this.props.width !== nextProps.width ||
this.props.height !== nextProps.height ||
@@ -134,7 +169,7 @@ export default class SvgMap extends React.Component<SvgMapProps, SvgMapState> {
key={`user-location-${this.props.center.join('-')}`}
marker={{ coordinates: this.props.center }}
style={markerStyle}>
- <image x="-30" y="-30" href={this.props.markerImagePath} />
+ <image x="-30" y="-30" xlinkHref={this.props.markerImagePath} />
</Marker>
);
@@ -178,7 +213,7 @@ export default class SvgMap extends React.Component<SvgMapProps, SvgMapState> {
return this.state.visibleGeometry.map(({ id }) => (
<Geography
key={id}
- geography={geographies[id]}
+ geography={geographies[parseInt(id)]}
projection={projection}
style={geographyStyle}
/>
@@ -190,7 +225,7 @@ export default class SvgMap extends React.Component<SvgMapProps, SvgMapState> {
return this.state.visibleStatesProvincesLines.map(({ id }) => (
<Geography
key={id}
- geography={geographies[id]}
+ geography={geographies[parseInt(id)]}
projection={projection}
style={stateProvinceLineStyle}
/>
@@ -203,7 +238,7 @@ export default class SvgMap extends React.Component<SvgMapProps, SvgMapState> {
);
}
- _mergeRsmStyle(style: Object) {
+ _mergeRsmStyle(style: { [key: string]: any }) {
const defaultStyle = style.default || {};
return {
default: defaultStyle,
@@ -216,11 +251,11 @@ export default class SvgMap extends React.Component<SvgMapProps, SvgMapState> {
width: number,
height: number,
config: {
- scale?: number,
- xOffset?: number,
- yOffset?: number,
- rotation?: [number, number, number],
- precision?: number,
+ scale?: number;
+ xOffset?: number;
+ yOffset?: number;
+ rotation?: [number, number, number];
+ precision?: number;
},
) {
const scale = config.scale || 160;
@@ -239,26 +274,26 @@ export default class SvgMap extends React.Component<SvgMapProps, SvgMapState> {
_getZoomCenter(
center: [number, number],
offset: [number, number],
- projection: Function,
+ projection: GeoProjection,
zoom: number,
- ) {
- const pos = projection(center);
- return projection.invert([pos[0] + offset[0] / zoom, pos[1] + offset[1] / zoom]);
+ ): [number, number] {
+ const pos = projection(center)!;
+ return projection.invert!([pos[0] + offset[0] / zoom, pos[1] + offset[1] / zoom])!;
}
_getViewportGeoBoundingBox(
centerCoordinate: [number, number],
width: number,
height: number,
- projection: Function,
+ projection: GeoProjection,
zoom: number,
- ) {
- const center = projection(centerCoordinate);
+ ): BBox {
+ const center = projection(centerCoordinate)!;
const halfWidth = (width * 0.5) / zoom;
const halfHeight = (height * 0.5) / zoom;
- const northWest = projection.invert([center[0] - halfWidth, center[1] - halfHeight]);
- const southEast = projection.invert([center[0] + halfWidth, center[1] + halfHeight]);
+ const northWest = projection.invert!([center[0] - halfWidth, center[1] - halfHeight])!;
+ const southEast = projection.invert!([center[0] + halfWidth, center[1] + halfHeight])!;
// normalize to [minX, minY, maxX, maxY]
return [
@@ -269,7 +304,7 @@ export default class SvgMap extends React.Component<SvgMapProps, SvgMapState> {
];
}
- _shouldInvalidateState(nextProps: SvgMapProps) {
+ _shouldInvalidateState(nextProps: Props) {
const oldProps = this.props;
return (
oldProps.width !== nextProps.width ||
@@ -282,7 +317,7 @@ export default class SvgMap extends React.Component<SvgMapProps, SvgMapState> {
);
}
- _getNextState(prevState: ?SvgMapState, nextProps: SvgMapProps): SvgMapState {
+ _getNextState(prevState: State | null, nextProps: Props): State {
const { width, height, center, offset, zoomLevel } = nextProps;
const projection = this._getProjection(width, height, this._projectionConfig);
diff --git a/gui/packages/desktop/src/renderer/components/Switch.js b/gui/packages/desktop/src/renderer/components/Switch.tsx
index 4abb4a247f..d74efd97a6 100644
--- a/gui/packages/desktop/src/renderer/components/Switch.js
+++ b/gui/packages/desktop/src/renderer/components/Switch.tsx
@@ -1,39 +1,36 @@
-// @flow
-
import * as React from 'react';
const CLICK_TIMEOUT = 1000;
const MOVE_THRESHOLD = 10;
export type SwitchProps = {
- className?: string,
- isOn: boolean,
- onChange: ?(isOn: boolean) => void,
+ className?: string;
+ isOn: boolean;
+ onChange?: (isOn: boolean) => void;
};
type State = {
- ignoreChange: boolean,
- initialPos: { x: number, y: number },
- startTime: ?number,
+ ignoreChange: boolean;
+ initialPos: { x: number; y: number };
+ startTime?: number;
};
export default class Switch extends React.Component<SwitchProps, State> {
static defaultProps: SwitchProps = {
isOn: false,
- onChange: null,
+ onChange: undefined,
};
state = {
ignoreChange: false,
initialPos: { x: 0, y: 0 },
- startTime: (null: ?number),
+ startTime: undefined,
};
isCapturingMouseEvents = false;
- ref: ?HTMLInputElement;
- onRef = (e: ?HTMLInputElement) => (this.ref = e);
+ ref = React.createRef<HTMLInputElement>();
- handleMouseDown = (e: MouseEvent) => {
+ handleMouseDown = (e: React.MouseEvent<HTMLInputElement>) => {
const { clientX: x, clientY: y } = e;
this.startCapturingMouseEvents();
this.setState({
@@ -43,7 +40,7 @@ export default class Switch extends React.Component<SwitchProps, State> {
};
handleMouseMove = (e: MouseEvent) => {
- const inputElement = this.ref;
+ const inputElement = this.ref.current;
const { x: x0 } = this.state.initialPos;
const { clientX: x, clientY: y } = e;
const dx = Math.abs(x0 - x);
@@ -79,9 +76,9 @@ export default class Switch extends React.Component<SwitchProps, State> {
this.stopCapturingMouseEvents();
};
- handleChange = (e: Event) => {
+ handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const startTime = this.state.startTime;
- const eventTarget: Object = e.target;
+ const eventTarget = e.target;
if (typeof startTime !== 'number') {
throw new Error('startTime must be a number.');
@@ -132,14 +129,13 @@ export default class Switch extends React.Component<SwitchProps, State> {
}
render() {
- // eslint-disable-next-line no-unused-vars
const { isOn, onChange, ...otherProps } = this.props;
const className = ('switch ' + (otherProps.className || '')).trim();
return (
<input
{...otherProps}
type="checkbox"
- ref={this.onRef}
+ ref={this.ref}
className={className}
checked={isOn}
onMouseDown={this.handleMouseDown}
diff --git a/gui/packages/desktop/src/renderer/components/TransitionContainer.js b/gui/packages/desktop/src/renderer/components/TransitionContainer.tsx
index 1255c033d3..112b4c8dff 100644
--- a/gui/packages/desktop/src/renderer/components/TransitionContainer.js
+++ b/gui/packages/desktop/src/renderer/components/TransitionContainer.tsx
@@ -1,35 +1,46 @@
-// @flow
-
import * as React from 'react';
import { Styles, Component, Animated, View, Types, UserInterface } from 'reactxp';
-import type { TransitionGroupProps } from '../transitions';
-import getStyles from './TransitionContainerStyles';
+import { TransitionGroupProps } from '../transitions';
-type TransitionContainerProps = {
- children: React.Node,
- ...TransitionGroupProps,
-};
+type Props = {
+ children: React.ReactNode;
+} & TransitionGroupProps;
type State = {
- previousChildren: ?React.Node,
- childrenAnimation: Types.AnimatedViewStyleRuleSet,
- previousChildrenAnimation: Types.AnimatedViewStyleRuleSet,
- animationStyles: Types.AnimatedViewStyleRuleSet,
- dimensions: Types.Dimensions,
+ previousChildren?: React.ReactNode;
+ childrenAnimation?: Types.AnimatedViewStyleRuleSet;
+ previousChildrenAnimation?: Types.AnimatedViewStyleRuleSet;
+ dimensions: Types.Dimensions;
};
-export default class TransitionContainer extends Component<TransitionContainerProps, State> {
- constructor(props: TransitionContainerProps) {
- super(props);
+const dimensions = UserInterface.measureWindow();
+const styles = {
+ animationDefaultStyle: Styles.createViewStyle({
+ // @ts-ignore
+ position: 'absolute',
+ width: dimensions.width,
+ height: dimensions.height,
+ }),
+ allowPointerEventsStyle: Styles.createViewStyle({
+ // @ts-ignore
+ pointerEvents: 'auto',
+ }),
+ transitionContainerStyle: Styles.createViewStyle({
+ width: dimensions.width,
+ height: dimensions.height,
+ }),
+};
- const dimensions = UserInterface.measureWindow();
+export default class TransitionContainer extends Component<Props, State> {
+ constructor(props: Props) {
+ super(props);
this.state = {
- dimensions,
+ dimensions: UserInterface.measureWindow(),
};
}
- UNSAFE_componentWillReceiveProps(nextProps: TransitionContainerProps) {
+ UNSAFE_componentWillReceiveProps(nextProps: Props) {
switch (nextProps.name) {
case 'slide-up':
this.slideUpTransition(nextProps);
@@ -50,25 +61,27 @@ export default class TransitionContainer extends Component<TransitionContainerPr
onFinishedAnimation() {
this.setState({
- childrenAnimation: getStyles().allowPointerEventsStyle,
+ childrenAnimation: styles.allowPointerEventsStyle,
previousChildren: null,
});
}
- slideUpTransition(nextProps: TransitionContainerProps) {
+ slideUpTransition(nextProps: Props) {
const currentTranslationValue = Animated.createValue(this.state.dimensions.height);
this.setState(
{
previousChildren: this.props.children,
childrenAnimation: Styles.createAnimatedViewStyle({
+ // @ts-ignore
pointerEvents: 'none',
zIndex: 1,
transform: [{ translateY: currentTranslationValue }],
}),
previousChildrenAnimation: Styles.createAnimatedViewStyle({
+ // @ts-ignore
pointerEvents: 'none',
zIndex: 0,
- transform: [{ translateY: 0 }],
+ transform: [{ translateY: Animated.createValue(0) }],
}),
},
() => {
@@ -81,17 +94,19 @@ export default class TransitionContainer extends Component<TransitionContainerPr
);
}
- slideDownTransition(nextProps: TransitionContainerProps) {
+ slideDownTransition(nextProps: Props) {
const previousTranslationValue = Animated.createValue(0);
this.setState(
{
previousChildren: this.props.children,
childrenAnimation: Styles.createAnimatedViewStyle({
+ // @ts-ignore
pointerEvents: 'none',
zIndex: 0,
- transform: [{ translateY: 0 }],
+ transform: [{ translateY: Animated.createValue(0) }],
}),
previousChildrenAnimation: Styles.createAnimatedViewStyle({
+ // @ts-ignore
pointerEvents: 'none',
zIndex: 1,
transform: [{ translateY: previousTranslationValue }],
@@ -107,18 +122,20 @@ export default class TransitionContainer extends Component<TransitionContainerPr
);
}
- pushTransition(nextProps: TransitionContainerProps) {
+ pushTransition(nextProps: Props) {
const currentTranslationValue = Animated.createValue(this.state.dimensions.width);
const previousTranslationValue = Animated.createValue(0);
this.setState(
{
previousChildren: this.props.children,
childrenAnimation: Styles.createAnimatedViewStyle({
+ // @ts-ignore
pointerEvents: 'none',
zIndex: 1,
transform: [{ translateX: currentTranslationValue }],
}),
previousChildrenAnimation: Styles.createAnimatedViewStyle({
+ // @ts-ignore
pointerEvents: 'none',
zIndex: 0,
transform: [{ translateX: previousTranslationValue }],
@@ -142,18 +159,20 @@ export default class TransitionContainer extends Component<TransitionContainerPr
);
}
- popTransition(nextProps: TransitionContainerProps) {
+ popTransition(nextProps: Props) {
const currentTranslationValue = Animated.createValue(-this.state.dimensions.width / 2);
const previousTranslationValue = Animated.createValue(0);
this.setState(
{
previousChildren: this.props.children,
childrenAnimation: Styles.createAnimatedViewStyle({
+ // @ts-ignore
pointerEvents: 'none',
zIndex: 0,
transform: [{ translateX: currentTranslationValue }],
}),
previousChildrenAnimation: Styles.createAnimatedViewStyle({
+ // @ts-ignore
pointerEvents: 'none',
zIndex: 1,
transform: [{ translateX: previousTranslationValue }],
@@ -180,22 +199,32 @@ export default class TransitionContainer extends Component<TransitionContainerPr
render() {
const { children } = this.props;
const { previousChildren, childrenAnimation, previousChildrenAnimation } = this.state;
+
return (
- <View style={getStyles().transitionContainerStyle}>
+ <View style={styles.transitionContainerStyle}>
{previousChildren && (
<Animated.View
- key={previousChildren && previousChildren.key}
- style={[getStyles().animationDefaultStyle, previousChildrenAnimation]}>
+ key={getChildKey(previousChildren)}
+ style={[styles.animationDefaultStyle, previousChildrenAnimation]}>
{previousChildren}
</Animated.View>
)}
<Animated.View
- key={children.key}
- style={[getStyles().animationDefaultStyle, childrenAnimation]}>
+ key={getChildKey(children)}
+ style={[styles.animationDefaultStyle, childrenAnimation]}>
{children}
</Animated.View>
</View>
);
}
}
+
+function getChildKey(child?: React.ReactNode): string | number | undefined {
+ return child &&
+ typeof child === 'object' &&
+ 'key' in child &&
+ (typeof child.key === 'string' || typeof child.key === 'number')
+ ? child.key
+ : undefined;
+}
diff --git a/gui/packages/desktop/src/renderer/components/TransitionContainerStyles.js b/gui/packages/desktop/src/renderer/components/TransitionContainerStyles.js
deleted file mode 100644
index ca95cabfee..0000000000
--- a/gui/packages/desktop/src/renderer/components/TransitionContainerStyles.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// @flow
-
-import { Styles, UserInterface } from 'reactxp';
-
-const dimensions = UserInterface.measureWindow();
-const styles = {
- animationDefaultStyle: Styles.createAnimatedViewStyle({
- position: 'absolute',
- width: dimensions.width,
- height: dimensions.height,
- }),
- allowPointerEventsStyle: Styles.createAnimatedViewStyle({
- pointerEvents: 'auto',
- }),
- transitionContainerStyle: Styles.createViewStyle({
- width: dimensions.width,
- height: dimensions.height,
- }),
-};
-
-export default () => {
- return styles;
-};
diff --git a/gui/packages/desktop/src/renderer/components/TunnelControl.js b/gui/packages/desktop/src/renderer/components/TunnelControl.tsx
index fd84f7cc25..8418f64086 100644
--- a/gui/packages/desktop/src/renderer/components/TunnelControl.js
+++ b/gui/packages/desktop/src/renderer/components/TunnelControl.tsx
@@ -1,37 +1,35 @@
-// @flow
-
import * as React from 'react';
import { Component, Text, View, Styles, Types } from 'reactxp';
-import { ConnectionInfo, SecuredLabel, SecuredDisplayStyle, ImageView } from '@mullvad/components';
+import { ConnectionInfo, SecuredLabel, SecuredDisplayStyle } from '@mullvad/components';
import * as AppButton from './AppButton';
-import { colors } from '../../config';
+import { colors } from '../../config.json';
-import type { TunnelStateTransition, RelayProtocol } from '../../shared/daemon-rpc-types';
+import { TunnelStateTransition, RelayProtocol } from '../../shared/daemon-rpc-types';
export type RelayInAddress = {
- ip: string,
- port: number,
- protocol: RelayProtocol,
+ ip: string;
+ port: number;
+ protocol: RelayProtocol;
};
export type RelayOutAddress = {
- ipv4: ?string,
- ipv6: ?string,
+ ipv4?: string;
+ ipv6?: string;
};
type TunnelControlProps = {
- tunnelState: TunnelStateTransition,
- selectedRelayName: string,
- city: ?string,
- country: ?string,
- hostname: ?string,
- defaultConnectionInfoOpen?: boolean,
- relayInAddress: ?RelayInAddress,
- relayOutAddress: ?RelayOutAddress,
- onConnect: () => void,
- onDisconnect: () => void,
- onSelectLocation: () => void,
- onToggleConnectionInfo: (boolean) => void,
+ tunnelState: TunnelStateTransition;
+ selectedRelayName: string;
+ city?: string;
+ country?: string;
+ hostname?: string;
+ defaultConnectionInfoOpen?: boolean;
+ relayInAddress?: RelayInAddress;
+ relayOutAddress?: RelayOutAddress;
+ onConnect: () => void;
+ onDisconnect: () => void;
+ onSelectLocation: () => void;
+ onToggleConnectionInfo: (value: boolean) => void;
};
const styles = {
@@ -79,7 +77,9 @@ const styles = {
export default class TunnelControl extends Component<TunnelControlProps> {
render() {
- const Location = ({ children }) => <View style={styles.status_location}>{children}</View>;
+ const Location = ({ children }: { children?: React.ReactNode }) => (
+ <View style={styles.status_location}>{children}</View>
+ );
const City = () => <Text style={styles.status_location_text}>{this.props.city}</Text>;
const Country = () => <Text style={styles.status_location_text}>{this.props.country}</Text>;
@@ -88,7 +88,7 @@ export default class TunnelControl extends Component<TunnelControlProps> {
<AppButton.TransparentButton
style={styles.switch_location_button}
onPress={this.props.onSelectLocation}>
- <AppButton.Label>{'Switch location'}</AppButton.Label>
+ {'Switch location'}
</AppButton.TransparentButton>
);
};
@@ -98,7 +98,7 @@ export default class TunnelControl extends Component<TunnelControlProps> {
style={styles.switch_location_button}
onPress={this.props.onSelectLocation}>
<AppButton.Label>{this.props.selectedRelayName}</AppButton.Label>
- <ImageView height={12} width={7} source="icon-chevron" />
+ <AppButton.Icon height={12} width={7} source="icon-chevron" />
</AppButton.TransparentButton>
);
@@ -120,10 +120,12 @@ export default class TunnelControl extends Component<TunnelControlProps> {
</AppButton.RedTransparentButton>
);
- const Secured = ({ displayStyle }) => (
+ const Secured = ({ displayStyle }: { displayStyle: SecuredDisplayStyle }) => (
<SecuredLabel style={styles.status_security} displayStyle={displayStyle} />
);
- const Footer = ({ children }) => <View style={styles.footer}>{children}</View>;
+ const Footer = ({ children }: { children: React.ReactNode }) => (
+ <View style={styles.footer}>{children}</View>
+ );
const connectionDetails = (
<ConnectionInfo
@@ -137,7 +139,7 @@ export default class TunnelControl extends Component<TunnelControlProps> {
let state = this.props.tunnelState.state;
- switch (state) {
+ switch (this.props.tunnelState.state) {
case 'blocked':
switch (this.props.tunnelState.details.reason) {
case 'set_firewall_policy_error':
@@ -246,13 +248,13 @@ export default class TunnelControl extends Component<TunnelControlProps> {
);
default:
- throw new Error(`Unknown TunnelState: ${(this.props.tunnelState: empty)}`);
+ throw new Error(`Unknown TunnelState: ${this.props.tunnelState}`);
}
}
}
type ContainerProps = {
- children?: Types.ReactNode,
+ children?: Types.ReactNode;
};
class Wrapper extends Component<ContainerProps> {
diff --git a/gui/packages/desktop/src/renderer/containers/AccountPage.js b/gui/packages/desktop/src/renderer/containers/AccountPage.tsx
index 94cb653d81..c9725147b5 100644
--- a/gui/packages/desktop/src/renderer/containers/AccountPage.js
+++ b/gui/packages/desktop/src/renderer/containers/AccountPage.tsx
@@ -1,14 +1,12 @@
-// @flow
-
import { remote, shell } from 'electron';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { goBack } from 'connected-react-router';
import Account from '../components/Account';
-import { links } from '../../config';
+import { links } from '../../config.json';
-import type { ReduxState, ReduxDispatch } from '../redux/store';
-import type { SharedRouteProps } from '../routes';
+import { ReduxState, ReduxDispatch } from '../redux/store';
+import { SharedRouteProps } from '../routes';
const mapStateToProps = (state: ReduxState) => ({
accountToken: state.account.accountToken,
diff --git a/gui/packages/desktop/src/renderer/containers/AdvancedSettingsPage.js b/gui/packages/desktop/src/renderer/containers/AdvancedSettingsPage.tsx
index 5a3cad6ed5..cc32d6556d 100644
--- a/gui/packages/desktop/src/renderer/containers/AdvancedSettingsPage.js
+++ b/gui/packages/desktop/src/renderer/containers/AdvancedSettingsPage.tsx
@@ -1,15 +1,14 @@
-// @flow
-
import log from 'electron-log';
import { connect } from 'react-redux';
import { goBack } from 'connected-react-router';
import { bindActionCreators } from 'redux';
import { AdvancedSettings } from '../components/AdvancedSettings';
import RelaySettingsBuilder from '../lib/relay-settings-builder';
+import { RelayProtocol } from '../../shared/daemon-rpc-types';
-import type { ReduxState, ReduxDispatch } from '../redux/store';
-import type { RelaySettingsRedux } from '../redux/settings/reducers';
-import type { SharedRouteProps } from '../routes';
+import { ReduxState, ReduxDispatch } from '../redux/store';
+import { RelaySettingsRedux } from '../redux/settings/reducers';
+import { SharedRouteProps } from '../routes';
const mapStateToProps = (state: ReduxState) => {
const protocolAndPort = mapRelaySettingsToProtocolAndPort(state.settings.relaySettings);
@@ -23,13 +22,13 @@ const mapStateToProps = (state: ReduxState) => {
};
const mapRelaySettingsToProtocolAndPort = (relaySettings: RelaySettingsRedux) => {
- if (relaySettings.normal) {
+ if ('normal' in relaySettings) {
const { protocol, port } = relaySettings.normal;
return {
protocol: protocol === 'any' ? 'Automatic' : protocol,
port: port === 'any' ? 'Automatic' : port,
};
- } else if (relaySettings.customTunnelEndpoint) {
+ } else if ('customTunnelEndpoint' in relaySettings) {
const { protocol, port } = relaySettings.customTunnelEndpoint;
return { protocol, port };
} else {
@@ -43,17 +42,17 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: SharedRouteProps) =>
onClose: () => {
history.goBack();
},
- onUpdate: async (protocol, port) => {
+ onUpdate: async (protocol: string, port: string | number) => {
const relayUpdate = RelaySettingsBuilder.normal()
.tunnel.openvpn((openvpn) => {
if (protocol === 'Automatic') {
openvpn.protocol.any();
} else {
- openvpn.protocol.exact(protocol.toLowerCase());
+ openvpn.protocol.exact(protocol.toLowerCase() as RelayProtocol);
}
- if (port === 'Automatic') {
+ if (typeof port === 'string' && port === 'Automatic') {
openvpn.port.any();
- } else {
+ } else if (typeof port === 'number') {
openvpn.port.exact(port);
}
})
@@ -66,7 +65,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: SharedRouteProps) =>
}
},
- setEnableIpv6: async (enableIpv6) => {
+ setEnableIpv6: async (enableIpv6: boolean) => {
try {
await props.app.setEnableIpv6(enableIpv6);
} catch (e) {
@@ -74,7 +73,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: SharedRouteProps) =>
}
},
- setBlockWhenDisconnected: async (blockWhenDisconnected) => {
+ setBlockWhenDisconnected: async (blockWhenDisconnected: boolean) => {
try {
await props.app.setBlockWhenDisconnected(blockWhenDisconnected);
} catch (e) {
@@ -82,7 +81,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: SharedRouteProps) =>
}
},
- setOpenVpnMssfix: async (mssfix) => {
+ setOpenVpnMssfix: async (mssfix?: number) => {
try {
await props.app.setOpenVpnMssfix(mssfix);
} catch (e) {
diff --git a/gui/packages/desktop/src/renderer/containers/ConnectPage.js b/gui/packages/desktop/src/renderer/containers/ConnectPage.tsx
index 57ca284c4b..f20927ab29 100644
--- a/gui/packages/desktop/src/renderer/containers/ConnectPage.js
+++ b/gui/packages/desktop/src/renderer/containers/ConnectPage.tsx
@@ -1,35 +1,32 @@
-// @flow
-
import { shell } from 'electron';
import log from 'electron-log';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { push } from 'connected-react-router';
-import { links } from '../../config';
import Connect from '../components/Connect';
import AccountExpiry from '../lib/account-expiry';
import userInterfaceActions from '../redux/userinterface/actions';
-import type { ReduxState, ReduxDispatch } from '../redux/store';
-import type { SharedRouteProps } from '../routes';
+import { ReduxState, ReduxDispatch } from '../redux/store';
+import { SharedRouteProps } from '../routes';
-import type { RelaySettingsRedux, RelayLocationRedux } from '../redux/settings/reducers';
+import { RelaySettingsRedux, RelayLocationRedux } from '../redux/settings/reducers';
function getRelayName(
relaySettings: RelaySettingsRedux,
relayLocations: Array<RelayLocationRedux>,
): string {
- if (relaySettings.normal) {
+ if ('normal' in relaySettings) {
const location = relaySettings.normal.location;
if (location === 'any') {
return 'Automatic';
- } else if (location.country) {
+ } else if ('country' in location) {
const country = relayLocations.find(({ code }) => code === location.country);
if (country) {
return country.name;
}
- } else if (location.city) {
+ } else if ('city' in location) {
const [countryCode, cityCode] = location.city;
const country = relayLocations.find(({ code }) => code === countryCode);
if (country) {
@@ -38,7 +35,7 @@ function getRelayName(
return city.name;
}
}
- } else if (location.hostname) {
+ } else if ('hostname' in location) {
const [countryCode, cityCode, hostname] = location.hostname;
const country = relayLocations.find(({ code }) => code === countryCode);
if (country) {
@@ -59,7 +56,7 @@ function getRelayName(
const mapStateToProps = (state: ReduxState) => {
return {
- accountExpiry: state.account.expiry ? new AccountExpiry(state.account.expiry) : null,
+ accountExpiry: state.account.expiry ? new AccountExpiry(state.account.expiry) : undefined,
selectedRelayName: getRelayName(state.settings.relaySettings, state.settings.relayLocations),
connection: state.connection,
version: state.version,
@@ -96,7 +93,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: SharedRouteProps) =>
log.error(`Failed to disconnect the tunnel: ${error.message}`);
}
},
- onExternalLink: (type) => shell.openExternal(links[type]),
+ onExternalLink: (url: string) => shell.openExternal(url),
};
};
diff --git a/gui/packages/desktop/src/renderer/containers/LaunchPage.js b/gui/packages/desktop/src/renderer/containers/LaunchPage.tsx
index 3ab740897d..00d42acdb6 100644
--- a/gui/packages/desktop/src/renderer/containers/LaunchPage.js
+++ b/gui/packages/desktop/src/renderer/containers/LaunchPage.tsx
@@ -1,12 +1,10 @@
-// @flow
-
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { push } from 'connected-react-router';
import Launch from '../components/Launch';
-import type { ReduxState, ReduxDispatch } from '../redux/store';
-import type { SharedRouteProps } from '../routes';
+import { ReduxState, ReduxDispatch } from '../redux/store';
+import { SharedRouteProps } from '../routes';
const mapStateToProps = (_state: ReduxState) => ({});
const mapDispatchToProps = (dispatch: ReduxDispatch, _props: SharedRouteProps) => {
diff --git a/gui/packages/desktop/src/renderer/containers/LoginPage.js b/gui/packages/desktop/src/renderer/containers/LoginPage.tsx
index afdd79caa6..b73883c7fc 100644
--- a/gui/packages/desktop/src/renderer/containers/LoginPage.js
+++ b/gui/packages/desktop/src/renderer/containers/LoginPage.tsx
@@ -1,14 +1,12 @@
-// @flow
import { shell } from 'electron';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { push } from 'connected-react-router';
import Login from '../components/Login';
import accountActions from '../redux/account/actions';
-import { links } from '../../config';
-import type { ReduxState, ReduxDispatch } from '../redux/store';
-import type { SharedRouteProps } from '../routes';
+import { ReduxState, ReduxDispatch } from '../redux/store';
+import { SharedRouteProps } from '../routes';
const mapStateToProps = (state: ReduxState) => {
const { accountToken, accountHistory, error, status } = state.account;
@@ -26,15 +24,15 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: SharedRouteProps) =>
openSettings: () => {
history.push('/settings');
},
- login: (account) => {
+ login: (account: string) => {
props.app.login(account);
},
resetLoginError: () => {
resetLoginError();
},
- openExternalLink: (type) => shell.openExternal(links[type]),
+ openExternalLink: (url: string) => shell.openExternal(url),
updateAccountToken: updateAccountToken,
- removeAccountTokenFromHistory: (token) => props.app.removeAccountFromHistory(token),
+ removeAccountTokenFromHistory: (token: string) => props.app.removeAccountFromHistory(token),
};
};
diff --git a/gui/packages/desktop/src/renderer/containers/PlatformWindowContainer.js b/gui/packages/desktop/src/renderer/containers/PlatformWindowContainer.js
deleted file mode 100644
index a8a154572d..0000000000
--- a/gui/packages/desktop/src/renderer/containers/PlatformWindowContainer.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// @flow
-
-import { connect } from 'react-redux';
-import PlatformWindow from '../components/PlatformWindow';
-
-import type { ReduxState, ReduxDispatch } from '../redux/store';
-import type { SharedRouteProps } from '../routes';
-
-const mapStateToProps = (state: ReduxState) => ({
- arrowPosition: state.userInterface.arrowPosition,
-});
-
-const mapDispatchToProps = (_dispatch: ReduxDispatch, _props: SharedRouteProps) => ({});
-
-export default connect(
- mapStateToProps,
- mapDispatchToProps,
-)(PlatformWindow);
diff --git a/gui/packages/desktop/src/renderer/containers/PlatformWindowContainer.tsx b/gui/packages/desktop/src/renderer/containers/PlatformWindowContainer.tsx
new file mode 100644
index 0000000000..844dd74253
--- /dev/null
+++ b/gui/packages/desktop/src/renderer/containers/PlatformWindowContainer.tsx
@@ -0,0 +1,10 @@
+import { connect } from 'react-redux';
+import PlatformWindow from '../components/PlatformWindow';
+
+import { ReduxState } from '../redux/store';
+
+const mapStateToProps = (state: ReduxState) => ({
+ arrowPosition: state.userInterface.arrowPosition,
+});
+
+export default connect(mapStateToProps)(PlatformWindow);
diff --git a/gui/packages/desktop/src/renderer/containers/PreferencesPage.js b/gui/packages/desktop/src/renderer/containers/PreferencesPage.tsx
index 0d18e50bee..9701a2ff0f 100644
--- a/gui/packages/desktop/src/renderer/containers/PreferencesPage.js
+++ b/gui/packages/desktop/src/renderer/containers/PreferencesPage.tsx
@@ -1,13 +1,11 @@
-// @flow
-
import log from 'electron-log';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { goBack } from 'connected-react-router';
import Preferences from '../components/Preferences';
-import type { ReduxState, ReduxDispatch } from '../redux/store';
-import type { SharedRouteProps } from '../routes';
+import { ReduxState, ReduxDispatch } from '../redux/store';
+import { SharedRouteProps } from '../routes';
const mapStateToProps = (state: ReduxState) => ({
autoStart: state.settings.autoStart,
@@ -23,28 +21,28 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: SharedRouteProps) =>
onClose: () => {
history.goBack();
},
- setAutoStart: async (autoStart) => {
+ setAutoStart: async (autoStart: boolean) => {
try {
await props.app.setAutoStart(autoStart);
} catch (error) {
log.error(`Cannot set auto-start: ${error.message}`);
}
},
- setAutoConnect: async (autoConnect) => {
+ setAutoConnect: async (autoConnect: boolean) => {
try {
props.app.setAutoConnect(autoConnect);
} catch (error) {
log.error(`Cannot set auto-connect: ${error.message}`);
}
},
- setAllowLan: (allowLan) => {
+ setAllowLan: (allowLan: boolean) => {
props.app.setAllowLan(allowLan);
},
- setStartMinimized: (startMinimized) => {
+ setStartMinimized: (startMinimized: boolean) => {
props.app.setStartMinimized(startMinimized);
},
enableStartMinimizedToggle: process.platform === 'linux',
- setMonochromaticIcon: (monochromaticIcon) => {
+ setMonochromaticIcon: (monochromaticIcon: boolean) => {
props.app.setMonochromaticIcon(monochromaticIcon);
},
enableMonochromaticIconToggle: process.platform === 'darwin',
diff --git a/gui/packages/desktop/src/renderer/containers/SelectLocationPage.js b/gui/packages/desktop/src/renderer/containers/SelectLocationPage.tsx
index 80f4f64b74..c15feea88a 100644
--- a/gui/packages/desktop/src/renderer/containers/SelectLocationPage.js
+++ b/gui/packages/desktop/src/renderer/containers/SelectLocationPage.tsx
@@ -1,14 +1,13 @@
-// @flow
-
import log from 'electron-log';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { goBack } from 'connected-react-router';
import SelectLocation from '../components/SelectLocation';
import RelaySettingsBuilder from '../lib/relay-settings-builder';
+import { RelayLocation } from '../../shared/daemon-rpc-types';
-import type { ReduxState, ReduxDispatch } from '../redux/store';
-import type { SharedRouteProps } from '../routes';
+import { ReduxState, ReduxDispatch } from '../redux/store';
+import { SharedRouteProps } from '../routes';
const mapStateToProps = (state: ReduxState) => ({
relaySettings: state.settings.relaySettings,
@@ -18,7 +17,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: SharedRouteProps) =>
const history = bindActionCreators({ goBack }, dispatch);
return {
onClose: () => history.goBack(),
- onSelect: async (relayLocation) => {
+ onSelect: async (relayLocation: RelayLocation) => {
// dismiss the view first
history.goBack();
diff --git a/gui/packages/desktop/src/renderer/containers/SettingsPage.js b/gui/packages/desktop/src/renderer/containers/SettingsPage.tsx
index c37b7f5f4c..abe6fa0e93 100644
--- a/gui/packages/desktop/src/renderer/containers/SettingsPage.js
+++ b/gui/packages/desktop/src/renderer/containers/SettingsPage.tsx
@@ -1,14 +1,11 @@
-// @flow
-
import { remote, shell } from 'electron';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { push, goBack } from 'connected-react-router';
import Settings from '../components/Settings';
-import { links } from '../../config';
-import type { ReduxState, ReduxDispatch } from '../redux/store';
-import type { SharedRouteProps } from '../routes';
+import { ReduxState, ReduxDispatch } from '../redux/store';
+import { SharedRouteProps } from '../routes';
const mapStateToProps = (state: ReduxState) => ({
loginState: state.account.status,
@@ -27,7 +24,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, _props: SharedRouteProps) =
onViewSupport: () => history.push('/settings/support'),
onViewPreferences: () => history.push('/settings/preferences'),
onViewAdvancedSettings: () => history.push('/settings/advanced'),
- onExternalLink: (type) => shell.openExternal(links[type]),
+ onExternalLink: (url: string) => shell.openExternal(url),
};
};
diff --git a/gui/packages/desktop/src/renderer/containers/SupportPage.js b/gui/packages/desktop/src/renderer/containers/SupportPage.tsx
index 86d9f976aa..2746734aee 100644
--- a/gui/packages/desktop/src/renderer/containers/SupportPage.js
+++ b/gui/packages/desktop/src/renderer/containers/SupportPage.tsx
@@ -1,5 +1,3 @@
-// @flow
-
import { shell } from 'electron';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
@@ -7,8 +5,8 @@ import { goBack } from 'connected-react-router';
import Support from '../components/Support';
import { collectProblemReport, sendProblemReport } from '../lib/problem-report';
-import type { ReduxState, ReduxDispatch } from '../redux/store';
-import type { SharedRouteProps } from '../routes';
+import { ReduxState, ReduxDispatch } from '../redux/store';
+import { SharedRouteProps } from '../routes';
import supportActions from '../redux/support/actions';
const mapStateToProps = (state: ReduxState) => ({
@@ -23,8 +21,10 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, _props: SharedRouteProps) =
const history = bindActionCreators({ goBack }, dispatch);
return {
- onClose: () => history.goBack(),
- viewLog: (path) => shell.openItem(path),
+ onClose: () => {
+ history.goBack();
+ },
+ viewLog: (path: string) => shell.openItem(path),
saveReportForm,
clearReportForm,
collectProblemReport,
diff --git a/gui/packages/desktop/src/renderer/index.html b/gui/packages/desktop/src/renderer/index.html
index ab6ad159f5..c88955b3a2 100644
--- a/gui/packages/desktop/src/renderer/index.html
+++ b/gui/packages/desktop/src/renderer/index.html
@@ -2,10 +2,11 @@
<html>
<head>
<title>Mullvad VPN</title>
- <link rel="stylesheet" href="../assets/css/style.css" />
+ <link rel="stylesheet" href="../../assets/css/style.css" />
</head>
<body>
<div id="app" class="app-container"></div>
+ <script>var exports = {};</script>
<script src="./index.js"></script>
<script>
if (process.env.BROWSER_SYNC_CLIENT_URL) {
diff --git a/gui/packages/desktop/src/renderer/index.js b/gui/packages/desktop/src/renderer/index.ts
index eea0c96fc9..aada6fd97b 100644
--- a/gui/packages/desktop/src/renderer/index.js
+++ b/gui/packages/desktop/src/renderer/index.ts
@@ -1,6 +1,4 @@
-// @flow
-
-import RX from 'reactxp';
+import * as RX from 'reactxp';
import App from './app';
const app = new App();
diff --git a/gui/packages/desktop/src/renderer/lib/account-expiry.js b/gui/packages/desktop/src/renderer/lib/account-expiry.ts
index af240c2039..4f4f51ce05 100644
--- a/gui/packages/desktop/src/renderer/lib/account-expiry.js
+++ b/gui/packages/desktop/src/renderer/lib/account-expiry.ts
@@ -1,9 +1,7 @@
-// @flow
-
import moment from 'moment';
export default class AccountExpiry {
- _expiry: moment;
+ _expiry: moment.Moment;
constructor(expiry: string) {
this._expiry = moment(expiry);
@@ -13,7 +11,7 @@ export default class AccountExpiry {
return this.willHaveExpiredIn(moment());
}
- willHaveExpiredIn(time: moment): boolean {
+ willHaveExpiredIn(time: moment.Moment): boolean {
return this._expiry.isSameOrBefore(time);
}
diff --git a/gui/packages/desktop/src/renderer/lib/auth-failure.js b/gui/packages/desktop/src/renderer/lib/auth-failure.ts
index d012e3f826..efee82b08c 100644
--- a/gui/packages/desktop/src/renderer/lib/auth-failure.js
+++ b/gui/packages/desktop/src/renderer/lib/auth-failure.ts
@@ -1,5 +1,3 @@
-// @flow
-
import log from 'electron-log';
export type AuthFailureKind =
@@ -21,7 +19,7 @@ export class AuthFailure {
_reasonId: AuthFailureKind;
_message: string;
- constructor(reason: ?string) {
+ constructor(reason?: string) {
if (!reason) {
log.error('Received invalid auth_failed reason: ', reason);
this._reasonId = 'UNKNOWN';
@@ -53,9 +51,6 @@ export class AuthFailure {
return TOO_MANY_CONNECTIONS_MSG;
case 'UNKNOWN':
return this._message;
-
- default:
- throw new Error(`Invalid reason ID: ${(this._reasonId: empty)}`);
}
}
}
diff --git a/gui/packages/desktop/src/renderer/lib/problem-report.js b/gui/packages/desktop/src/renderer/lib/problem-report.ts
index 19d24f3e0f..0afcf30091 100644
--- a/gui/packages/desktop/src/renderer/lib/problem-report.js
+++ b/gui/packages/desktop/src/renderer/lib/problem-report.ts
@@ -1,12 +1,18 @@
-// @flow
-
import { ipcRenderer } from 'electron';
-import uuid from 'uuid';
+import * as uuid from 'uuid';
+
+type ErrorResult = { success: false; error: string };
+type CollectResult = { success: true; reportPath: string } | ErrorResult;
+type SendResult = { success: true } | ErrorResult;
const collectProblemReport = (toRedact: Array<string>): Promise<string> => {
return new Promise((resolve, reject) => {
const requestId = uuid.v4();
- const responseListener = (_event, responseId, result) => {
+ const responseListener = (
+ _event: Electron.Event,
+ responseId: string,
+ result: CollectResult,
+ ) => {
if (responseId === requestId) {
ipcRenderer.removeListener('collect-logs-reply', responseListener);
if (result.success) {
@@ -25,7 +31,7 @@ const collectProblemReport = (toRedact: Array<string>): Promise<string> => {
const sendProblemReport = (email: string, message: string, savedReport: string): Promise<void> => {
return new Promise((resolve, reject) => {
const requestId = uuid.v4();
- const responseListener = (_event, responseId, result) => {
+ const responseListener = (_event: Electron.Event, responseId: string, result: SendResult) => {
if (requestId === responseId) {
ipcRenderer.removeListener('send-problem-report-reply', responseListener);
if (result.success) {
diff --git a/gui/packages/desktop/src/renderer/lib/relay-settings-builder.js b/gui/packages/desktop/src/renderer/lib/relay-settings-builder.ts
index 3397f543df..949b02d35f 100644
--- a/gui/packages/desktop/src/renderer/lib/relay-settings-builder.js
+++ b/gui/packages/desktop/src/renderer/lib/relay-settings-builder.ts
@@ -1,33 +1,35 @@
-// @flow
-
-import type {
+import {
RelayLocation,
RelayProtocol,
RelaySettingsUpdate,
RelaySettingsNormalUpdate,
+ OpenVpnConstraints,
} from '../../shared/daemon-rpc-types';
type LocationBuilder<Self> = {
- country: (country: string) => Self,
- city: (country: string, city: string) => Self,
- any: () => Self,
- fromRaw: (location: 'any' | RelayLocation) => Self,
+ country: (country: string) => Self;
+ city: (country: string, city: string) => Self;
+ hostname: (country: string, city: string, hostname: string) => Self;
+ any: () => Self;
+ fromRaw: (location: 'any' | RelayLocation) => Self;
};
-type OpenVPNConfigurator<Self> = {
- port: {
- exact: (port: number) => Self,
- any: () => Self,
- },
- protocol: {
- exact: (protocol: RelayProtocol) => Self,
- any: () => Self,
- },
-};
+interface ExactOrAny<T, Self> {
+ exact(value: T): Self;
+ any(): Self;
+}
-type TunnelBuilder<Self> = {
- openvpn: (configurator: (OpenVPNConfigurator<*>) => void) => Self,
-};
+interface OpenVPNConfigurator {
+ port: ExactOrAny<number, OpenVPNConfigurator>;
+ protocol: ExactOrAny<RelayProtocol, OpenVPNConfigurator>;
+}
+
+interface TunnelBuilder {
+ openvpn(
+ configurator: (openVpnConfigurator: OpenVPNConfigurator) => void,
+ ): NormalRelaySettingsBuilder;
+ any(): NormalRelaySettingsBuilder;
+}
class NormalRelaySettingsBuilder {
_payload: RelaySettingsNormalUpdate = {};
@@ -59,19 +61,13 @@ class NormalRelaySettingsBuilder {
fromRaw: function(location: 'any' | RelayLocation) {
if (location === 'any') {
return this.any();
- }
-
- if (location.hostname) {
+ } else if ('hostname' in location) {
const [country, city, hostname] = location.hostname;
return this.hostname(country, city, hostname);
- }
-
- if (location.city) {
+ } else if ('city' in location) {
const [country, city] = location.city;
return this.city(country, city);
- }
-
- if (location.country) {
+ } else if ('country' in location) {
return this.country(location.country);
}
@@ -82,8 +78,8 @@ class NormalRelaySettingsBuilder {
};
}
- get tunnel(): TunnelBuilder<NormalRelaySettingsBuilder> {
- const updateOpenvpn = (next) => {
+ get tunnel(): TunnelBuilder {
+ const updateOpenvpn = (next: Partial<OpenVpnConstraints>) => {
const tunnel = this._payload.tunnel;
if (typeof tunnel === 'string' || typeof tunnel === 'undefined') {
this._payload.tunnel = {
@@ -102,10 +98,10 @@ class NormalRelaySettingsBuilder {
};
return {
- openvpn: (configurator) => {
- const openvpnBuilder = {
+ openvpn: (configurator: (configurator: OpenVPNConfigurator) => void) => {
+ const openvpnBuilder: OpenVPNConfigurator = {
get port() {
- const apply = (port) => {
+ const apply = (port: 'any' | { only: number }) => {
updateOpenvpn({ port });
return this;
};
@@ -115,7 +111,7 @@ class NormalRelaySettingsBuilder {
};
},
get protocol() {
- const apply = (protocol) => {
+ const apply = (protocol: 'any' | { only: RelayProtocol }) => {
updateOpenvpn({ protocol });
return this;
};
diff --git a/gui/packages/desktop/src/renderer/lib/transition-rule.js b/gui/packages/desktop/src/renderer/lib/transition-rule.ts
index dfb56b02ce..5e3a9138c4 100644
--- a/gui/packages/desktop/src/renderer/lib/transition-rule.js
+++ b/gui/packages/desktop/src/renderer/lib/transition-rule.ts
@@ -1,32 +1,30 @@
-// @flow
-
export type TransitionDescriptor = {
- name: string,
- duration: number,
+ name: string;
+ duration: number;
};
export type TransitionFork = {
- forward: TransitionDescriptor,
- backward: TransitionDescriptor,
+ forward: TransitionDescriptor;
+ backward: TransitionDescriptor;
};
export type TransitionMatch = {
- direction: 'forward' | 'backward',
- descriptor: TransitionDescriptor,
+ direction: 'forward' | 'backward';
+ descriptor: TransitionDescriptor;
};
export default class TransitionRule {
- _from: ?string;
+ _from: string | null;
_to: string;
_fork: TransitionFork;
- constructor(from: ?string, to: string, fork: TransitionFork) {
+ constructor(from: string | null, to: string, fork: TransitionFork) {
this._from = from;
this._to = to;
this._fork = fork;
}
- match(fromRoute: ?string, toRoute: string): ?TransitionMatch {
+ match(fromRoute: string | null, toRoute: string): TransitionMatch | null {
if ((!this._from || this._from === fromRoute) && this._to === toRoute) {
return {
direction: 'forward',
diff --git a/gui/packages/desktop/src/renderer/redux/account/actions.js b/gui/packages/desktop/src/renderer/redux/account/actions.ts
index 4d7dff03a3..0084b5a9d7 100644
--- a/gui/packages/desktop/src/renderer/redux/account/actions.js
+++ b/gui/packages/desktop/src/renderer/redux/account/actions.ts
@@ -1,42 +1,40 @@
-// @flow
-
-import type { AccountToken } from '../../../shared/daemon-rpc-types';
+import { AccountToken } from '../../../shared/daemon-rpc-types';
type StartLoginAction = {
- type: 'START_LOGIN',
- accountToken: AccountToken,
+ type: 'START_LOGIN';
+ accountToken: AccountToken;
};
type LoggedInAction = {
- type: 'LOGGED_IN',
+ type: 'LOGGED_IN';
};
type LoginFailedAction = {
- type: 'LOGIN_FAILED',
- error: Error,
+ type: 'LOGIN_FAILED';
+ error: Error;
};
type LoggedOutAction = {
- type: 'LOGGED_OUT',
+ type: 'LOGGED_OUT';
};
type ResetLoginErrorAction = {
- type: 'RESET_LOGIN_ERROR',
+ type: 'RESET_LOGIN_ERROR';
};
type UpdateAccountTokenAction = {
- type: 'UPDATE_ACCOUNT_TOKEN',
- token: AccountToken,
+ type: 'UPDATE_ACCOUNT_TOKEN';
+ token: AccountToken;
};
type UpdateAccountHistoryAction = {
- type: 'UPDATE_ACCOUNT_HISTORY',
- accountHistory: Array<AccountToken>,
+ type: 'UPDATE_ACCOUNT_HISTORY';
+ accountHistory: Array<AccountToken>;
};
type UpdateAccountExpiryAction = {
- type: 'UPDATE_ACCOUNT_EXPIRY',
- expiry: string,
+ type: 'UPDATE_ACCOUNT_EXPIRY';
+ expiry: string;
};
export type AccountAction =
diff --git a/gui/packages/desktop/src/renderer/redux/account/reducers.js b/gui/packages/desktop/src/renderer/redux/account/reducers.ts
index 8c560fac02..75f4fcd997 100644
--- a/gui/packages/desktop/src/renderer/redux/account/reducers.js
+++ b/gui/packages/desktop/src/renderer/redux/account/reducers.ts
@@ -1,23 +1,21 @@
-// @flow
-
-import type { ReduxAction } from '../store';
-import type { AccountToken } from '../../../shared/daemon-rpc-types';
+import { ReduxAction } from '../store';
+import { AccountToken } from '../../../shared/daemon-rpc-types';
export type LoginState = 'none' | 'logging in' | 'failed' | 'ok';
export type AccountReduxState = {
- accountToken: ?AccountToken,
- accountHistory: Array<AccountToken>,
- expiry: ?string, // ISO8601
- status: LoginState,
- error: ?Error,
+ accountToken?: AccountToken;
+ accountHistory: Array<AccountToken>;
+ expiry?: string; // ISO8601
+ status: LoginState;
+ error?: Error;
};
const initialState: AccountReduxState = {
- accountToken: null,
+ accountToken: undefined,
accountHistory: [],
- expiry: null,
+ expiry: undefined,
status: 'none',
- error: null,
+ error: undefined,
};
export default function(
@@ -31,7 +29,7 @@ export default function(
...{
status: 'logging in',
accountToken: action.accountToken,
- error: null,
+ error: undefined,
},
};
case 'LOGGED_IN':
@@ -39,7 +37,7 @@ export default function(
...state,
...{
status: 'ok',
- error: null,
+ error: undefined,
},
};
case 'LOGIN_FAILED':
@@ -47,7 +45,7 @@ export default function(
...state,
...{
status: 'failed',
- accountToken: null,
+ accountToken: undefined,
error: action.error,
},
};
@@ -56,9 +54,9 @@ export default function(
...state,
...{
status: 'none',
- accountToken: null,
- expiry: null,
- error: null,
+ accountToken: undefined,
+ expiry: undefined,
+ error: undefined,
},
};
case 'RESET_LOGIN_ERROR':
@@ -66,7 +64,7 @@ export default function(
...state,
...{
status: 'none',
- error: null,
+ error: undefined,
},
};
case 'UPDATE_ACCOUNT_TOKEN':
diff --git a/gui/packages/desktop/src/renderer/redux/connection/actions.js b/gui/packages/desktop/src/renderer/redux/connection/actions.ts
index 68dafd58f5..e700c8918c 100644
--- a/gui/packages/desktop/src/renderer/redux/connection/actions.js
+++ b/gui/packages/desktop/src/renderer/redux/connection/actions.ts
@@ -1,53 +1,47 @@
-// @flow
-
-import type {
- AfterDisconnect,
- BlockReason,
- TunnelEndpoint,
-} from '../../../shared/daemon-rpc-types';
+import { AfterDisconnect, BlockReason, TunnelEndpoint } from '../../../shared/daemon-rpc-types';
type ConnectingAction = {
- type: 'CONNECTING',
- tunnelEndpoint: ?TunnelEndpoint,
+ type: 'CONNECTING';
+ tunnelEndpoint?: TunnelEndpoint;
};
type ConnectedAction = {
- type: 'CONNECTED',
- tunnelEndpoint: TunnelEndpoint,
+ type: 'CONNECTED';
+ tunnelEndpoint: TunnelEndpoint;
};
type DisconnectedAction = {
- type: 'DISCONNECTED',
+ type: 'DISCONNECTED';
};
type DisconnectingAction = {
- type: 'DISCONNECTING',
- afterDisconnect: AfterDisconnect,
+ type: 'DISCONNECTING';
+ afterDisconnect: AfterDisconnect;
};
type BlockedAction = {
- type: 'BLOCKED',
- reason: BlockReason,
+ type: 'BLOCKED';
+ reason: BlockReason;
};
type NewLocationAction = {
- type: 'NEW_LOCATION',
+ type: 'NEW_LOCATION';
newLocation: {
- country: string,
- city: ?string,
- latitude: number,
- longitude: number,
- mullvadExitIp: boolean,
- hostname: ?string,
- },
+ country: string;
+ city?: string;
+ latitude: number;
+ longitude: number;
+ mullvadExitIp: boolean;
+ hostname?: string;
+ };
};
type OnlineAction = {
- type: 'ONLINE',
+ type: 'ONLINE';
};
type OfflineAction = {
- type: 'OFFLINE',
+ type: 'OFFLINE';
};
export type ConnectionAction =
@@ -60,7 +54,7 @@ export type ConnectionAction =
| OnlineAction
| OfflineAction;
-function connecting(tunnelEndpoint: ?TunnelEndpoint): ConnectingAction {
+function connecting(tunnelEndpoint?: TunnelEndpoint): ConnectingAction {
return {
type: 'CONNECTING',
tunnelEndpoint,
@@ -94,10 +88,10 @@ function blocked(reason: BlockReason): BlockedAction {
};
}
-function newLocation(newLoc: $PropertyType<NewLocationAction, 'newLocation'>): NewLocationAction {
+function newLocation(newLocation: NewLocationAction['newLocation']): NewLocationAction {
return {
type: 'NEW_LOCATION',
- newLocation: newLoc,
+ newLocation,
};
}
diff --git a/gui/packages/desktop/src/renderer/redux/connection/reducers.js b/gui/packages/desktop/src/renderer/redux/connection/reducers.ts
index 23afc7f780..4bca04fa7c 100644
--- a/gui/packages/desktop/src/renderer/redux/connection/reducers.js
+++ b/gui/packages/desktop/src/renderer/redux/connection/reducers.ts
@@ -1,28 +1,28 @@
-// @flow
-
-import type { ReduxAction } from '../store';
-import type { TunnelStateTransition, Ip } from '../../../shared/daemon-rpc-types';
+import { ReduxAction } from '../store';
+import { TunnelStateTransition, Ip } from '../../../shared/daemon-rpc-types';
export type ConnectionReduxState = {
- status: TunnelStateTransition,
- isOnline: boolean,
- isBlocked: boolean,
- ip: ?Ip,
- latitude: ?number,
- longitude: ?number,
- country: ?string,
- city: ?string,
+ status: TunnelStateTransition;
+ isOnline: boolean;
+ isBlocked: boolean;
+ ip?: Ip;
+ hostname?: string;
+ latitude?: number;
+ longitude?: number;
+ country?: string;
+ city?: string;
};
const initialState: ConnectionReduxState = {
status: { state: 'disconnected' },
isOnline: true,
isBlocked: false,
- ip: null,
- latitude: null,
- longitude: null,
- country: null,
- city: null,
+ ip: undefined,
+ hostname: undefined,
+ latitude: undefined,
+ longitude: undefined,
+ country: undefined,
+ city: undefined,
};
export default function(
@@ -31,7 +31,8 @@ export default function(
): ConnectionReduxState {
switch (action.type) {
case 'NEW_LOCATION':
- return { ...state, ...action.newLocation };
+ const { hostname, latitude, longitude, city, country } = action.newLocation;
+ return { ...state, hostname, latitude, longitude, city, country };
case 'CONNECTING':
return {
diff --git a/gui/packages/desktop/src/renderer/redux/settings/actions.js b/gui/packages/desktop/src/renderer/redux/settings/actions.ts
index 20b185c8b3..e08f61fce5 100644
--- a/gui/packages/desktop/src/renderer/redux/settings/actions.js
+++ b/gui/packages/desktop/src/renderer/redux/settings/actions.ts
@@ -1,58 +1,50 @@
-// @flow
-
-import type { RelaySettingsRedux, RelayLocationRedux } from './reducers';
-import type { GuiSettingsState } from '../../../shared/gui-settings-state';
+import { RelaySettingsRedux, RelayLocationRedux } from './reducers';
+import { GuiSettingsState } from '../../../shared/gui-settings-state';
export type UpdateGuiSettingsAction = {
- type: 'UPDATE_GUI_SETTINGS',
- guiSettings: GuiSettingsState,
+ type: 'UPDATE_GUI_SETTINGS';
+ guiSettings: GuiSettingsState;
};
export type UpdateRelayAction = {
- type: 'UPDATE_RELAY',
- relay: RelaySettingsRedux,
+ type: 'UPDATE_RELAY';
+ relay: RelaySettingsRedux;
};
export type UpdateRelayLocationsAction = {
- type: 'UPDATE_RELAY_LOCATIONS',
- relayLocations: Array<RelayLocationRedux>,
-};
-
-export type UpdateAutoConnectAction = {
- type: 'UPDATE_AUTO_CONNECT',
- autoConnect: boolean,
+ type: 'UPDATE_RELAY_LOCATIONS';
+ relayLocations: Array<RelayLocationRedux>;
};
export type UpdateAllowLanAction = {
- type: 'UPDATE_ALLOW_LAN',
- allowLan: boolean,
+ type: 'UPDATE_ALLOW_LAN';
+ allowLan: boolean;
};
export type UpdateEnableIpv6Action = {
- type: 'UPDATE_ENABLE_IPV6',
- enableIpv6: boolean,
+ type: 'UPDATE_ENABLE_IPV6';
+ enableIpv6: boolean;
};
export type UpdateBlockWhenDisconnectedAction = {
- type: 'UPDATE_BLOCK_WHEN_DISCONNECTED',
- blockWhenDisconnected: boolean,
+ type: 'UPDATE_BLOCK_WHEN_DISCONNECTED';
+ blockWhenDisconnected: boolean;
};
export type UpdateOpenVpnMssfixAction = {
- type: 'UPDATE_OPENVPN_MSSFIX',
- mssfix: ?number,
+ type: 'UPDATE_OPENVPN_MSSFIX';
+ mssfix?: number;
};
export type UpdateAutoStartAction = {
- type: 'UPDATE_AUTO_START',
- autoStart: boolean,
+ type: 'UPDATE_AUTO_START';
+ autoStart: boolean;
};
export type SettingsAction =
| UpdateGuiSettingsAction
| UpdateRelayAction
| UpdateRelayLocationsAction
- | UpdateAutoConnectAction
| UpdateAllowLanAction
| UpdateEnableIpv6Action
| UpdateBlockWhenDisconnectedAction
@@ -82,13 +74,6 @@ function updateRelayLocations(
};
}
-function updateAutoConnect(autoConnect: boolean): UpdateAutoConnectAction {
- return {
- type: 'UPDATE_AUTO_CONNECT',
- autoConnect,
- };
-}
-
function updateAllowLan(allowLan: boolean): UpdateAllowLanAction {
return {
type: 'UPDATE_ALLOW_LAN',
@@ -112,7 +97,7 @@ function updateBlockWhenDisconnected(
};
}
-function updateOpenVpnMssfix(mssfix: ?number): UpdateOpenVpnMssfixAction {
+function updateOpenVpnMssfix(mssfix?: number): UpdateOpenVpnMssfixAction {
return {
type: 'UPDATE_OPENVPN_MSSFIX',
mssfix,
@@ -130,7 +115,6 @@ export default {
updateGuiSettings,
updateRelay,
updateRelayLocations,
- updateAutoConnect,
updateAllowLan,
updateEnableIpv6,
updateBlockWhenDisconnected,
diff --git a/gui/packages/desktop/src/renderer/redux/settings/reducers.js b/gui/packages/desktop/src/renderer/redux/settings/reducers.ts
index a51fe7fe02..a4e269626a 100644
--- a/gui/packages/desktop/src/renderer/redux/settings/reducers.js
+++ b/gui/packages/desktop/src/renderer/redux/settings/reducers.ts
@@ -1,60 +1,58 @@
-// @flow
-
-import type { ReduxAction } from '../store';
-import type { RelayProtocol, RelayLocation } from '../../../shared/daemon-rpc-types';
-import type { GuiSettingsState } from '../../../shared/gui-settings-state';
+import { ReduxAction } from '../store';
+import { RelayProtocol, RelayLocation } from '../../../shared/daemon-rpc-types';
+import { GuiSettingsState } from '../../../shared/gui-settings-state';
export type RelaySettingsRedux =
- | {|
+ | {
normal: {
- location: 'any' | RelayLocation,
- port: 'any' | number,
- protocol: 'any' | RelayProtocol,
- },
- |}
- | {|
+ location: 'any' | RelayLocation;
+ port: 'any' | number;
+ protocol: 'any' | RelayProtocol;
+ };
+ }
+ | {
customTunnelEndpoint: {
- host: string,
- port: number,
- protocol: RelayProtocol,
- },
- |};
+ host: string;
+ port: number;
+ protocol: RelayProtocol;
+ };
+ };
export type RelayLocationRelayRedux = {
- hostname: string,
- ipv4AddrIn: string,
- ipv4AddrExit: string,
- includeInCountry: boolean,
- weight: number,
+ hostname: string;
+ ipv4AddrIn: string;
+ ipv4AddrExit: string;
+ includeInCountry: boolean;
+ weight: number;
};
export type RelayLocationCityRedux = {
- name: string,
- code: string,
- latitude: number,
- longitude: number,
- hasActiveRelays: boolean,
- relays: Array<RelayLocationRelayRedux>,
+ name: string;
+ code: string;
+ latitude: number;
+ longitude: number;
+ hasActiveRelays: boolean;
+ relays: RelayLocationRelayRedux[];
};
export type RelayLocationRedux = {
- name: string,
- code: string,
- hasActiveRelays: boolean,
- cities: Array<RelayLocationCityRedux>,
+ name: string;
+ code: string;
+ hasActiveRelays: boolean;
+ cities: RelayLocationCityRedux[];
};
export type SettingsReduxState = {
- autoStart: boolean,
- guiSettings: GuiSettingsState,
- relaySettings: RelaySettingsRedux,
- relayLocations: Array<RelayLocationRedux>,
- allowLan: boolean,
- enableIpv6: boolean,
- blockWhenDisconnected: boolean,
+ autoStart: boolean;
+ guiSettings: GuiSettingsState;
+ relaySettings: RelaySettingsRedux;
+ relayLocations: RelayLocationRedux[];
+ allowLan: boolean;
+ enableIpv6: boolean;
+ blockWhenDisconnected: boolean;
openVpn: {
- mssfix: ?number,
- },
+ mssfix?: number;
+ };
};
const initialState: SettingsReduxState = {
@@ -75,9 +73,7 @@ const initialState: SettingsReduxState = {
allowLan: false,
enableIpv6: true,
blockWhenDisconnected: false,
- openVpn: {
- mssfix: null,
- },
+ openVpn: {},
};
export default function(
@@ -109,12 +105,6 @@ export default function(
allowLan: action.allowLan,
};
- case 'UPDATE_AUTO_CONNECT':
- return {
- ...state,
- autoConnect: action.autoConnect,
- };
-
case 'UPDATE_ENABLE_IPV6':
return {
...state,
diff --git a/gui/packages/desktop/src/renderer/redux/store.js b/gui/packages/desktop/src/renderer/redux/store.ts
index f3a2922808..6bd38f45ea 100644
--- a/gui/packages/desktop/src/renderer/redux/store.js
+++ b/gui/packages/desktop/src/renderer/redux/store.ts
@@ -1,6 +1,4 @@
-// @flow
-
-import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
+import { createStore, applyMiddleware, combineReducers, compose, Dispatch, Store } from 'redux';
import { routerMiddleware, connectRouter, push, replace } from 'connected-react-router';
import accountReducer from './account/reducers';
@@ -16,29 +14,28 @@ import versionActions from './version/actions';
import userInterfaceReducer from './userinterface/reducers';
import userInterfaceActions from './userinterface/actions';
-import type { Store, StoreEnhancer } from 'redux';
-import type { History } from 'history';
-import type { AccountReduxState } from './account/reducers';
-import type { ConnectionReduxState } from './connection/reducers';
-import type { SettingsReduxState } from './settings/reducers';
-import type { SupportReduxState } from './support/reducers';
-import type { VersionReduxState } from './version/reducers';
-import type { UserInterfaceReduxState } from './userinterface/reducers';
+import { History } from 'history';
+import { AccountReduxState } from './account/reducers';
+import { ConnectionReduxState } from './connection/reducers';
+import { SettingsReduxState } from './settings/reducers';
+import { SupportReduxState } from './support/reducers';
+import { VersionReduxState } from './version/reducers';
+import { UserInterfaceReduxState } from './userinterface/reducers';
-import type { AccountAction } from './account/actions';
-import type { ConnectionAction } from './connection/actions';
-import type { SettingsAction } from './settings/actions';
-import type { SupportAction } from './support/actions';
-import type { VersionAction } from './version/actions';
-import type { UserInterfaceAction } from './userinterface/actions';
+import { AccountAction } from './account/actions';
+import { ConnectionAction } from './connection/actions';
+import { SettingsAction } from './settings/actions';
+import { SupportAction } from './support/actions';
+import { VersionAction } from './version/actions';
+import { UserInterfaceAction } from './userinterface/actions';
export type ReduxState = {
- account: AccountReduxState,
- connection: ConnectionReduxState,
- settings: SettingsReduxState,
- support: SupportReduxState,
- version: VersionReduxState,
- userInterface: UserInterfaceReduxState,
+ account: AccountReduxState;
+ connection: ConnectionReduxState;
+ settings: SettingsReduxState;
+ support: SupportReduxState;
+ version: VersionReduxState;
+ userInterface: UserInterfaceReduxState;
};
export type ReduxAction =
@@ -48,23 +45,22 @@ export type ReduxAction =
| SupportAction
| VersionAction
| UserInterfaceAction;
-export type ReduxStore = Store<ReduxState, ReduxAction, ReduxDispatch>;
-export type ReduxGetState = () => ReduxState;
-export type ReduxDispatch = (action: ReduxAction) => any;
+export type ReduxStore = Store<ReduxState, ReduxAction>;
+export type ReduxDispatch = Dispatch<ReduxAction>;
export default function configureStore(
- initialState: ?ReduxState,
+ initialState: ReduxState | null,
routerHistory: History,
): ReduxStore {
- const actionCreators: { [string]: Function } = {
+ const actionCreators: { [key: string]: Function } = {
...accountActions,
...connectionActions,
...settingsActions,
...supportActions,
...versionActions,
...userInterfaceActions,
- pushRoute: (route) => push(route),
- replaceRoute: (route) => replace(route),
+ pushRoute: (route: string) => push(route),
+ replaceRoute: (route: string) => replace(route),
};
const reducers = {
@@ -77,17 +73,15 @@ export default function configureStore(
router: connectRouter(routerHistory),
};
- const composeEnhancers = (() => {
- const reduxCompose = window && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
+ const composeEnhancers: typeof compose = (() => {
+ const reduxCompose = window && (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
if (process.env.NODE_ENV === 'development' && reduxCompose) {
return reduxCompose({ actionCreators });
}
return compose;
})();
- const enhancer: StoreEnhancer<ReduxState, ReduxAction, ReduxDispatch> = composeEnhancers(
- applyMiddleware(routerMiddleware(routerHistory)),
- );
+ const enhancer = composeEnhancers(applyMiddleware(routerMiddleware(routerHistory)));
const rootReducer = combineReducers(reducers);
diff --git a/gui/packages/desktop/src/renderer/redux/support/actions.js b/gui/packages/desktop/src/renderer/redux/support/actions.ts
index d81fd19c0d..1ab40a775a 100644
--- a/gui/packages/desktop/src/renderer/redux/support/actions.js
+++ b/gui/packages/desktop/src/renderer/redux/support/actions.ts
@@ -1,17 +1,15 @@
-// @flow
-
export type SupportReportForm = {
- email: string,
- message: string,
+ email: string;
+ message: string;
};
export type KeepReportFormAction = {
- type: 'SAVE_REPORT_FORM',
- form: SupportReportForm,
+ type: 'SAVE_REPORT_FORM';
+ form: SupportReportForm;
};
export type ClearReportFormAction = {
- type: 'CLEAR_REPORT_FORM',
+ type: 'CLEAR_REPORT_FORM';
};
export type SupportAction = KeepReportFormAction | ClearReportFormAction;
diff --git a/gui/packages/desktop/src/renderer/redux/support/reducers.js b/gui/packages/desktop/src/renderer/redux/support/reducers.ts
index f885f22dd5..19bb395782 100644
--- a/gui/packages/desktop/src/renderer/redux/support/reducers.js
+++ b/gui/packages/desktop/src/renderer/redux/support/reducers.ts
@@ -1,10 +1,8 @@
-// @flow
-
-import type { ReduxAction } from '../store';
+import { ReduxAction } from '../store';
export type SupportReduxState = {
- email: string,
- message: string,
+ email: string;
+ message: string;
};
const initialState: SupportReduxState = {
diff --git a/gui/packages/desktop/src/renderer/redux/userinterface/actions.js b/gui/packages/desktop/src/renderer/redux/userinterface/actions.ts
index fdc0b2423c..701639f884 100644
--- a/gui/packages/desktop/src/renderer/redux/userinterface/actions.js
+++ b/gui/packages/desktop/src/renderer/redux/userinterface/actions.ts
@@ -1,13 +1,11 @@
-// @flow
-
export type UpdateWindowArrowPositionAction = {
- type: 'UPDATE_WINDOW_ARROW_POSITION',
- arrowPosition: number,
+ type: 'UPDATE_WINDOW_ARROW_POSITION';
+ arrowPosition: number;
};
export type UpdateConnectionInfoOpenAction = {
- type: 'UPDATE_CONNECTION_INFO_OPEN',
- isOpen: boolean,
+ type: 'UPDATE_CONNECTION_INFO_OPEN';
+ isOpen: boolean;
};
export type UserInterfaceAction = UpdateWindowArrowPositionAction | UpdateConnectionInfoOpenAction;
diff --git a/gui/packages/desktop/src/renderer/redux/userinterface/reducers.js b/gui/packages/desktop/src/renderer/redux/userinterface/reducers.ts
index 68d2e45463..d46ea0a2e2 100644
--- a/gui/packages/desktop/src/renderer/redux/userinterface/reducers.js
+++ b/gui/packages/desktop/src/renderer/redux/userinterface/reducers.ts
@@ -1,10 +1,8 @@
-// @flow
-
-import type { ReduxAction } from '../store';
+import { ReduxAction } from '../store';
export type UserInterfaceReduxState = {
- arrowPosition?: number,
- connectionInfoOpen: boolean,
+ arrowPosition?: number;
+ connectionInfoOpen: boolean;
};
const initialState: UserInterfaceReduxState = {
diff --git a/gui/packages/desktop/src/renderer/redux/version/actions.js b/gui/packages/desktop/src/renderer/redux/version/actions.ts
index 96fd1db9e5..9faadf963e 100644
--- a/gui/packages/desktop/src/renderer/redux/version/actions.js
+++ b/gui/packages/desktop/src/renderer/redux/version/actions.ts
@@ -1,21 +1,19 @@
-// @flow
-
-import type { AppVersionInfo } from '../../../shared/daemon-rpc-types';
+import { AppVersionInfo } from '../../../shared/daemon-rpc-types';
type UpdateLatestActionPayload = {
- upToDate: boolean,
- nextUpgrade: ?string,
+ upToDate: boolean;
+ nextUpgrade?: string;
} & AppVersionInfo;
export type UpdateLatestAction = {
- type: 'UPDATE_LATEST',
- latestInfo: UpdateLatestActionPayload,
+ type: 'UPDATE_LATEST';
+ latestInfo: UpdateLatestActionPayload;
};
export type UpdateVersionAction = {
- type: 'UPDATE_VERSION',
- version: string,
- consistent: boolean,
+ type: 'UPDATE_VERSION';
+ version: string;
+ consistent: boolean;
};
export type VersionAction = UpdateLatestAction | UpdateVersionAction;
diff --git a/gui/packages/desktop/src/renderer/redux/version/reducers.js b/gui/packages/desktop/src/renderer/redux/version/reducers.ts
index a2bc07c3e7..e496b61563 100644
--- a/gui/packages/desktop/src/renderer/redux/version/reducers.js
+++ b/gui/packages/desktop/src/renderer/redux/version/reducers.ts
@@ -1,23 +1,21 @@
-// @flow
-
-import type { ReduxAction } from '../store';
+import { ReduxAction } from '../store';
export type VersionReduxState = {
- current: string,
- currentIsSupported: boolean,
- latest: ?string,
- latestStable: ?string,
- nextUpgrade: ?string,
- upToDate: boolean,
- consistent: boolean,
+ current: string;
+ currentIsSupported: boolean;
+ latest?: string;
+ latestStable?: string;
+ nextUpgrade?: string;
+ upToDate: boolean;
+ consistent: boolean;
};
const initialState: VersionReduxState = {
current: '',
currentIsSupported: true,
- latest: null,
- latestStable: null,
- nextUpgrade: null,
+ latest: undefined,
+ latestStable: undefined,
+ nextUpgrade: undefined,
upToDate: true,
consistent: true,
};
diff --git a/gui/packages/desktop/src/renderer/routes.js b/gui/packages/desktop/src/renderer/routes.tsx
index 54e6cf8295..74c9be5bee 100644
--- a/gui/packages/desktop/src/renderer/routes.js
+++ b/gui/packages/desktop/src/renderer/routes.tsx
@@ -1,5 +1,3 @@
-// @flow
-
import * as React from 'react';
import { Switch, Route } from 'react-router';
import TransitionContainer from './components/TransitionContainer';
@@ -15,19 +13,23 @@ import SupportPage from './containers/SupportPage';
import SelectLocationPage from './containers/SelectLocationPage';
import { getTransitionProps } from './transitions';
-import type App from './app';
+import App from './app';
export type SharedRouteProps = {
- app: App,
+ app: App;
};
+type CustomRouteProps = {
+ component: React.ComponentClass<SharedRouteProps>;
+} & Route['props'];
+
export default function makeRoutes(componentProps: SharedRouteProps) {
// Renders a route extended with shared props
- const CustomRoute = ({ component: ComponentClass, ...routeProps }) => (
+ const CustomRoute = ({ component: ComponentClass, ...routeProps }: CustomRouteProps) => (
<Route {...routeProps} render={() => <ComponentClass {...componentProps} />} />
);
// store previous route
- let sourceRoute: ?string;
+ let sourceRoute: string | null = null;
return (
<Route
diff --git a/gui/packages/desktop/src/renderer/transitions.js b/gui/packages/desktop/src/renderer/transitions.ts
index 56769f6877..71585f9c24 100644
--- a/gui/packages/desktop/src/renderer/transitions.js
+++ b/gui/packages/desktop/src/renderer/transitions.ts
@@ -1,15 +1,13 @@
-// @flow
-
import TransitionRule from './lib/transition-rule';
-import type { TransitionFork, TransitionDescriptor } from './lib/transition-rule';
+import { TransitionFork, TransitionDescriptor } from './lib/transition-rule';
export type TransitionGroupProps = {
- name: string,
- duration: number,
+ name: string;
+ duration: number;
};
type TransitionMap = {
- [name: string]: TransitionFork,
+ [name: string]: TransitionFork;
};
/**
@@ -57,7 +55,10 @@ const transitionRules = [
* @param {string} [fromRoute] - source route
* @param {string} toRoute - target route
*/
-export function getTransitionProps(fromRoute: ?string, toRoute: string): TransitionGroupProps {
+export function getTransitionProps(
+ fromRoute: string | null,
+ toRoute: string,
+): TransitionGroupProps {
// ignore initial transition and transition between the same routes
if (!fromRoute || fromRoute === toRoute) {
return noTransitionProps();
@@ -98,6 +99,6 @@ function noTransitionProps(): TransitionGroupProps {
/**
* Shortcut to create TransitionRule
*/
-function r(from: ?string, to: string, fork: TransitionFork): TransitionRule {
+function r(from: string | null, to: string, fork: TransitionFork): TransitionRule {
return new TransitionRule(from, to, fork);
}
diff --git a/gui/packages/desktop/src/shared/daemon-rpc-types.js b/gui/packages/desktop/src/shared/daemon-rpc-types.js
deleted file mode 100644
index 3d5a03b87e..0000000000
--- a/gui/packages/desktop/src/shared/daemon-rpc-types.js
+++ /dev/null
@@ -1,215 +0,0 @@
-// @flow
-export type AccountData = { expiry: string };
-export type AccountToken = string;
-export type Ip = string;
-export type Location = {
- ip: ?string,
- country: string,
- city: ?string,
- latitude: number,
- longitude: number,
- mullvadExitIp: boolean,
- hostname: ?string,
-};
-
-export type BlockReason =
- | {
- reason:
- | 'ipv6_unavailable'
- | 'set_firewall_policy_error'
- | 'set_dns_error'
- | 'start_tunnel_error'
- | 'no_matching_relay'
- | 'is_offline'
- | 'tap_adapter_problem',
- }
- | { reason: 'auth_failed', details: ?string };
-
-export type AfterDisconnect = 'nothing' | 'block' | 'reconnect';
-
-export type TunnelState = 'connecting' | 'connected' | 'disconnecting' | 'disconnected' | 'blocked';
-
-export type TunnelType = 'wireguard' | 'openvpn';
-
-export type RelayProtocol = 'tcp' | 'udp';
-
-export type TunnelEndpoint = {
- address: string,
- protocol: RelayProtocol,
- tunnel: TunnelType,
-};
-
-export type TunnelStateTransition =
- | { state: 'disconnected' }
- | { state: 'connecting', details: ?TunnelEndpoint }
- | { state: 'connected', details: TunnelEndpoint }
- | { state: 'disconnecting', details: AfterDisconnect }
- | { state: 'blocked', details: BlockReason };
-
-export type RelayLocation =
- | {| hostname: [string, string, string] |}
- | {| city: [string, string] |}
- | {| country: string |};
-
-type OpenVpnConstraints = {
- port: 'any' | { only: number },
- protocol: 'any' | { only: RelayProtocol },
-};
-
-type TunnelConstraints<TOpenVpnConstraints> = {
- openvpn: TOpenVpnConstraints,
-};
-
-type RelaySettingsNormal<TTunnelConstraints> = {
- location:
- | 'any'
- | {
- only: RelayLocation,
- },
- tunnel:
- | 'any'
- | {
- only: TTunnelConstraints,
- },
-};
-
-export type ConnectionConfig =
- | {|
- openvpn: {
- endpoint: {
- ip: string,
- port: number,
- protocol: RelayProtocol,
- },
- username: string,
- },
- |}
- | {|
- wireguard: {
- tunnel: {
- private_key: string,
- addresses: Array<string>,
- },
- peer: {
- public_key: string,
- addresses: Array<string>,
- endpoint: string,
- },
- gateway: string,
- },
- |};
-
-// types describing the structure of RelaySettings
-export type RelaySettingsCustom = {
- host: string,
- config: ConnectionConfig,
-};
-export type RelaySettings =
- | {|
- normal: RelaySettingsNormal<TunnelConstraints<OpenVpnConstraints>>,
- |}
- | {|
- customTunnelEndpoint: RelaySettingsCustom,
- |};
-
-// types describing the partial update of RelaySettings
-export type RelaySettingsNormalUpdate = $Shape<
- RelaySettingsNormal<TunnelConstraints<$Shape<OpenVpnConstraints>>>,
->;
-export type RelaySettingsUpdate =
- | {|
- normal: RelaySettingsNormalUpdate,
- |}
- | {|
- customTunnelEndpoint: RelaySettingsCustom,
- |};
-
-export type RelayList = {
- countries: Array<RelayListCountry>,
-};
-
-export type RelayListCountry = {
- name: string,
- code: string,
- cities: Array<RelayListCity>,
-};
-
-export type RelayListCity = {
- name: string,
- code: string,
- latitude: number,
- longitude: number,
- relays: Array<RelayListHostname>,
-};
-
-export type RelayListHostname = {
- hostname: string,
- ipv4AddrIn: string,
- includeInCountry: boolean,
- weight: number,
-};
-
-export type TunnelOptions = {
- openvpn: {
- mssfix: ?number,
- proxy: ?ProxySettings,
- },
- wireguard: {
- mtu: ?number,
- // Only relevant on Linux
- fwmark: ?number,
- },
- generic: {
- enableIpv6: boolean,
- },
-};
-
-export type ProxySettings = LocalProxySettings | RemoteProxySettings;
-
-export type LocalProxySettings = {
- port: number,
- peer: string,
-};
-
-export type RemoteProxySettings = {
- address: string,
- auth: ?RemoteProxyAuth,
-};
-
-export type RemoteProxyAuth = {
- username: string,
- password: string,
-};
-
-export type AppVersionInfo = {
- currentIsSupported: boolean,
- latest: {
- latestStable: string,
- latest: string,
- },
-};
-
-export type Settings = {
- accountToken: ?AccountToken,
- allowLan: boolean,
- autoConnect: boolean,
- blockWhenDisconnected: boolean,
- relaySettings: RelaySettings,
- tunnelOptions: TunnelOptions,
-};
-
-export type SocketAddress = { host: string, port: number };
-
-export function parseSocketAddress(socketAddrStr: string): SocketAddress {
- const re = new RegExp(/(.+):(\d+)$/);
- const matches = socketAddrStr.match(re);
-
- if (!matches || matches.length < 3) {
- throw new Error(`Failed to parse socket address from address string '${socketAddrStr}'`);
- }
- const socketAddress: SocketAddress = {
- host: matches[1],
- port: Number(matches[2]),
- };
- return socketAddress;
-}
diff --git a/gui/packages/desktop/src/shared/daemon-rpc-types.ts b/gui/packages/desktop/src/shared/daemon-rpc-types.ts
new file mode 100644
index 0000000000..2cfc30f884
--- /dev/null
+++ b/gui/packages/desktop/src/shared/daemon-rpc-types.ts
@@ -0,0 +1,214 @@
+export type AccountData = { expiry: string };
+export type AccountToken = string;
+export type Ip = string;
+export type Location = {
+ ip?: string;
+ country: string;
+ city?: string;
+ latitude: number;
+ longitude: number;
+ mullvadExitIp: boolean;
+ hostname?: string;
+};
+
+export type BlockReason =
+ | {
+ reason:
+ | 'ipv6_unavailable'
+ | 'set_firewall_policy_error'
+ | 'set_dns_error'
+ | 'start_tunnel_error'
+ | 'no_matching_relay'
+ | 'is_offline'
+ | 'tap_adapter_problem';
+ }
+ | { reason: 'auth_failed'; details?: string };
+
+export type AfterDisconnect = 'nothing' | 'block' | 'reconnect';
+
+export type TunnelState = 'connecting' | 'connected' | 'disconnecting' | 'disconnected' | 'blocked';
+
+export type TunnelType = 'wireguard' | 'openvpn';
+
+export type RelayProtocol = 'tcp' | 'udp';
+
+export type TunnelEndpoint = {
+ address: string;
+ protocol: RelayProtocol;
+ tunnel: TunnelType;
+};
+
+export type TunnelStateTransition =
+ | { state: 'disconnected' }
+ | { state: 'connecting'; details?: TunnelEndpoint }
+ | { state: 'connected'; details: TunnelEndpoint }
+ | { state: 'disconnecting'; details: AfterDisconnect }
+ | { state: 'blocked'; details: BlockReason };
+
+export type RelayLocation =
+ | { hostname: [string, string, string] }
+ | { city: [string, string] }
+ | { country: string };
+
+export type OpenVpnConstraints = {
+ port: 'any' | { only: number };
+ protocol: 'any' | { only: RelayProtocol };
+};
+
+type TunnelConstraints<TOpenVpnConstraints> = {
+ openvpn: TOpenVpnConstraints;
+};
+
+type RelaySettingsNormal<TTunnelConstraints> = {
+ location:
+ | 'any'
+ | {
+ only: RelayLocation;
+ };
+ tunnel:
+ | 'any'
+ | {
+ only: TTunnelConstraints;
+ };
+};
+
+export type ConnectionConfig =
+ | {
+ openvpn: {
+ endpoint: {
+ ip: string;
+ port: number;
+ protocol: RelayProtocol;
+ };
+ username: string;
+ };
+ }
+ | {
+ wireguard: {
+ tunnel: {
+ private_key: string;
+ addresses: Array<string>;
+ };
+ peer: {
+ public_key: string;
+ addresses: Array<string>;
+ endpoint: string;
+ };
+ gateway: string;
+ };
+ };
+
+// types describing the structure of RelaySettings
+export type RelaySettingsCustom = {
+ host: string;
+ config: ConnectionConfig;
+};
+export type RelaySettings =
+ | {
+ normal: RelaySettingsNormal<TunnelConstraints<OpenVpnConstraints>>;
+ }
+ | {
+ customTunnelEndpoint: RelaySettingsCustom;
+ };
+
+// types describing the partial update of RelaySettings
+export type RelaySettingsNormalUpdate = Partial<
+ RelaySettingsNormal<TunnelConstraints<Partial<OpenVpnConstraints>>>
+>;
+export type RelaySettingsUpdate =
+ | {
+ normal: RelaySettingsNormalUpdate;
+ }
+ | {
+ customTunnelEndpoint: RelaySettingsCustom;
+ };
+
+export type RelayList = {
+ countries: Array<RelayListCountry>;
+};
+
+export type RelayListCountry = {
+ name: string;
+ code: string;
+ cities: Array<RelayListCity>;
+};
+
+export type RelayListCity = {
+ name: string;
+ code: string;
+ latitude: number;
+ longitude: number;
+ relays: Array<RelayListHostname>;
+};
+
+export type RelayListHostname = {
+ hostname: string;
+ ipv4AddrIn: string;
+ includeInCountry: boolean;
+ weight: number;
+};
+
+export type TunnelOptions = {
+ openvpn: {
+ mssfix?: number;
+ proxy?: ProxySettings;
+ };
+ wireguard: {
+ mtu?: number;
+ // Only relevant on Linux
+ fwmark?: number;
+ };
+ generic: {
+ enableIpv6: boolean;
+ };
+};
+
+export type ProxySettings = LocalProxySettings | RemoteProxySettings;
+
+export type LocalProxySettings = {
+ port: number;
+ peer: string;
+};
+
+export type RemoteProxySettings = {
+ address: string;
+ auth?: RemoteProxyAuth;
+};
+
+export type RemoteProxyAuth = {
+ username: string;
+ password: string;
+};
+
+export type AppVersionInfo = {
+ currentIsSupported: boolean;
+ latest: {
+ latestStable: string;
+ latest: string;
+ };
+};
+
+export type Settings = {
+ accountToken?: AccountToken;
+ allowLan: boolean;
+ autoConnect: boolean;
+ blockWhenDisconnected: boolean;
+ relaySettings: RelaySettings;
+ tunnelOptions: TunnelOptions;
+};
+
+export type SocketAddress = { host: string; port: number };
+
+export function parseSocketAddress(socketAddrStr: string): SocketAddress {
+ const re = new RegExp(/(.+):(\d+)$/);
+ const matches = socketAddrStr.match(re);
+
+ if (!matches || matches.length < 3) {
+ throw new Error(`Failed to parse socket address from address string '${socketAddrStr}'`);
+ }
+ const socketAddress: SocketAddress = {
+ host: matches[1],
+ port: Number(matches[2]),
+ };
+ return socketAddress;
+}
diff --git a/gui/packages/desktop/src/shared/gui-settings-state.js b/gui/packages/desktop/src/shared/gui-settings-state.js
deleted file mode 100644
index 336e019d1d..0000000000
--- a/gui/packages/desktop/src/shared/gui-settings-state.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// @flow
-
-export type GuiSettingsState = {
- autoConnect: boolean,
- monochromaticIcon: boolean,
- startMinimized: boolean,
-};
diff --git a/gui/packages/desktop/src/shared/gui-settings-state.ts b/gui/packages/desktop/src/shared/gui-settings-state.ts
new file mode 100644
index 0000000000..a94176c650
--- /dev/null
+++ b/gui/packages/desktop/src/shared/gui-settings-state.ts
@@ -0,0 +1,5 @@
+export type GuiSettingsState = {
+ autoConnect: boolean;
+ monochromaticIcon: boolean;
+ startMinimized: boolean;
+};
diff --git a/gui/packages/desktop/src/shared/ipc-event-channel.js b/gui/packages/desktop/src/shared/ipc-event-channel.ts
index 5e21c1c4ae..3ddde3fc13 100644
--- a/gui/packages/desktop/src/shared/ipc-event-channel.js
+++ b/gui/packages/desktop/src/shared/ipc-event-channel.ts
@@ -1,13 +1,10 @@
-// @flow
+import { ipcMain, ipcRenderer, WebContents } from 'electron';
+import * as uuid from 'uuid';
-import { ipcMain, ipcRenderer } from 'electron';
-import type { WebContents, IpcMainEvent, IpcRendererEvent } from 'electron';
-import uuid from 'uuid';
+import { GuiSettingsState } from './gui-settings-state';
-import type { GuiSettingsState } from './gui-settings-state';
-
-import type { AppUpgradeInfo, CurrentAppVersionInfo } from '../main/index';
-import type {
+import { AppUpgradeInfo, CurrentAppVersionInfo } from '../main/index';
+import {
AccountToken,
AccountData,
Location,
@@ -18,23 +15,27 @@ import type {
} from './daemon-rpc-types';
export type AppStateSnapshot = {
- isConnected: boolean,
- autoStart: boolean,
- tunnelState: TunnelStateTransition,
- settings: Settings,
- location: ?Location,
- relays: RelayList,
- currentVersion: CurrentAppVersionInfo,
- upgradeVersion: AppUpgradeInfo,
- guiSettings: GuiSettingsState,
+ isConnected: boolean;
+ autoStart: boolean;
+ tunnelState: TunnelStateTransition;
+ settings: Settings;
+ location?: Location;
+ relays: RelayList;
+ currentVersion: CurrentAppVersionInfo;
+ upgradeVersion: AppUpgradeInfo;
+ guiSettings: GuiSettingsState;
};
interface Sender<T> {
- notify(webContents: WebContents, newState: T): void;
+ notify(webContents: WebContents, value: T): void;
+}
+
+interface SenderVoid {
+ notify(webContents: WebContents): void;
}
interface Receiver<T> {
- listen<T>(fn: (T) => void): void;
+ listen(fn: (value: T) => void): void;
}
interface TunnelMethods {
@@ -48,37 +49,37 @@ interface TunnelHandlers {
}
interface SettingsMethods {
- setAllowLan(boolean): Promise<void>;
- setEnableIpv6(boolean): Promise<void>;
- setBlockWhenDisconnected(boolean): Promise<void>;
- setOpenVpnMssfix(?number): Promise<void>;
+ setAllowLan(allowLan: boolean): Promise<void>;
+ setEnableIpv6(enableIpv6: boolean): Promise<void>;
+ setBlockWhenDisconnected(block: boolean): Promise<void>;
+ setOpenVpnMssfix(mssfix?: number): Promise<void>;
updateRelaySettings(update: RelaySettingsUpdate): Promise<void>;
}
interface SettingsHandlers {
- handleAllowLan(fn: (boolean) => Promise<void>): void;
- handleEnableIpv6(fn: (boolean) => Promise<void>): void;
- handleBlockWhenDisconnected(fn: (boolean) => Promise<void>): void;
- handleOpenVpnMssfix(fn: (?number) => Promise<void>): void;
- handleUpdateRelaySettings(fn: (RelaySettingsUpdate) => Promise<void>): void;
+ handleAllowLan(fn: (allowLan: boolean) => Promise<void>): void;
+ handleEnableIpv6(fn: (enableIpv6: boolean) => Promise<void>): void;
+ handleBlockWhenDisconnected(fn: (block: boolean) => Promise<void>): void;
+ handleOpenVpnMssfix(fn: (mssfix?: number) => Promise<void>): void;
+ handleUpdateRelaySettings(fn: (update: RelaySettingsUpdate) => Promise<void>): void;
}
interface GuiSettingsMethods {
- setAutoConnect(boolean): void;
- setStartMinimized(boolean): void;
- setMonochromaticIcon(boolean): void;
+ setAutoConnect(autoConnect: boolean): void;
+ setStartMinimized(startMinimized: boolean): void;
+ setMonochromaticIcon(monochromaticIcon: boolean): void;
}
interface GuiSettingsHandlers {
- handleAutoConnect((boolean) => void): void;
- handleStartMinimized((boolean) => void): void;
- handleMonochromaticIcon((boolean) => void): void;
+ handleAutoConnect(fn: (autoConnect: boolean) => void): void;
+ handleStartMinimized(fn: (startMinimized: boolean) => void): void;
+ handleMonochromaticIcon(fn: (monochromaticIcon: boolean) => void): void;
}
interface AccountHandlers {
- handleSet(fn: (AccountToken) => Promise<void>): void;
+ handleSet(fn: (token: AccountToken) => Promise<void>): void;
handleUnset(fn: () => Promise<void>): void;
- handleGetData(fn: (AccountToken) => Promise<AccountData>): void;
+ handleGetData(fn: (token: AccountToken) => Promise<AccountData>): void;
}
interface AccountMethods {
@@ -98,12 +99,11 @@ interface AccountHistoryMethods {
}
interface AutoStartMethods {
- listen(fn: (boolean) => void): void;
set(autoStart: boolean): Promise<void>;
}
interface AutoStartHandlers {
- handleSet((boolean) => Promise<void>): void;
+ handleSet(fn: (value: boolean) => Promise<void>): void;
}
/// Events names
@@ -161,7 +161,7 @@ export class IpcRendererEventChannel {
listen: listen(DAEMON_CONNECTED),
};
- static daemonDisconnected: Receiver<?string> = {
+ static daemonDisconnected: Receiver<string | undefined> = {
listen: listen(DAEMON_DISCONNECTED),
};
@@ -181,7 +181,7 @@ export class IpcRendererEventChannel {
};
static location: Receiver<Location> = {
- listen: listen(LOCATION_CHANGED),
+ listen: listen<Location>(LOCATION_CHANGED),
};
static relays: Receiver<RelayList> = {
@@ -223,17 +223,17 @@ export class IpcRendererEventChannel {
export class IpcMainEventChannel {
static state = {
handleGet(fn: () => AppStateSnapshot) {
- ipcMain.on(GET_APP_STATE, (event) => {
+ ipcMain.on(GET_APP_STATE, (event: any) => {
event.returnValue = fn();
});
},
};
- static daemonConnected: Sender<void> = {
- notify: sender(DAEMON_CONNECTED),
+ static daemonConnected: SenderVoid = {
+ notify: senderVoid(DAEMON_CONNECTED),
};
- static daemonDisconnected: Sender<?string> = {
+ static daemonDisconnected: Sender<string | undefined> = {
notify: sender(DAEMON_DISCONNECTED),
};
@@ -276,7 +276,7 @@ export class IpcMainEventChannel {
};
static autoStart: Sender<boolean> & AutoStartHandlers = {
- notify: sender(AUTO_START_CHANGED),
+ notify: sender<boolean>(AUTO_START_CHANGED),
handleSet: requestHandler(SET_AUTO_START),
};
@@ -292,37 +292,43 @@ export class IpcMainEventChannel {
};
}
-function listen<T>(event: string): ((T) => void) => void {
- return function(fn: (T) => void) {
- ipcRenderer.on(event, (_, newState: T) => fn(newState));
+function listen<T>(event: string): (fn: (value: T) => void) => void {
+ return function(fn: (value: T) => void) {
+ ipcRenderer.on(event, (_event: any, newState: T) => fn(newState));
};
}
-function set<T>(event: string): (T) => void {
+function set<T>(event: string): (value: T) => void {
return function(newValue: T) {
ipcRenderer.send(event, newValue);
};
}
-function sender<T>(event: string): (WebContents, T) => void {
- return function(webContents: WebContents, newState: T) {
- webContents.send(event, newState);
+function sender<T>(event: string): (webContents: WebContents, value: T) => void {
+ return (webContents: WebContents, value: T) => {
+ webContents.send(event, value);
+ };
+}
+
+function senderVoid(event: string): (webContents: WebContents) => void {
+ return function(webContents: WebContents) {
+ webContents.send(event);
};
}
-function handler<T>(event: string): ((T) => void) => void {
- return function(handlerFn: (T) => void) {
- ipcMain.on(event, (_, newValue: T) => {
+function handler<T>(event: string): (handlerFn: (value: T) => void) => void {
+ return function(handlerFn: (value: T) => void) {
+ ipcMain.on(event, (_: any, newValue: T) => {
handlerFn(newValue);
});
};
}
-type RequestResult<T> = { type: 'success', value: T } | { type: 'error', message: string };
+type RequestResult<T> = { type: 'success'; value: T } | { type: 'error'; message: string };
function requestHandler<T>(event: string): (fn: (...args: Array<any>) => Promise<T>) => void {
return function(fn: (...args: Array<any>) => Promise<T>) {
- ipcMain.on(event, async (ipcEvent: IpcMainEvent, requestId: string, ...args: Array<any>) => {
+ ipcMain.on(event, async (ipcEvent: any, requestId: string, ...args: Array<any>) => {
const sender = ipcEvent.sender;
const responseEvent = `${event}-${requestId}`;
try {
@@ -344,7 +350,7 @@ function requestSender<T>(event: string): (...args: Array<any>) => Promise<T> {
const requestId = uuid.v4();
const responseEvent = `${event}-${requestId}`;
- ipcRenderer.once(responseEvent, (_ipcEvent: IpcRendererEvent, result: RequestResult<T>) => {
+ ipcRenderer.once(responseEvent, (_ipcEvent: any, result: RequestResult<T>) => {
switch (result.type) {
case 'error':
reject(new Error(result.message));
diff --git a/gui/packages/desktop/test/.eslintrc b/gui/packages/desktop/test/.eslintrc
deleted file mode 100644
index 5efd09aff1..0000000000
--- a/gui/packages/desktop/test/.eslintrc
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "rules": {
- "no-unused-expressions" : "off",
- "react/no-render-return-value": "off"
- },
- "env": {
- "browser": true,
- "mocha": true
- },
- "globals": {
- "expect": true,
- "sinon": true,
- "spy": true
- }
-}
diff --git a/gui/packages/desktop/test/account-data-cache.spec.js b/gui/packages/desktop/test/account-data-cache.spec.ts
index 90c6ad2f80..33cb80e556 100644
--- a/gui/packages/desktop/test/account-data-cache.spec.js
+++ b/gui/packages/desktop/test/account-data-cache.spec.ts
@@ -1,7 +1,12 @@
-// @flow
-
import { AccountDataCache } from '../src/renderer/app';
-import type { AccountData } from '../src/shared/daemon-rpc-types';
+import { AccountData } from '../src/shared/daemon-rpc-types';
+import * as sinon from 'sinon';
+import chai from 'chai';
+import spies from 'chai-spies';
+import chaiAsPromised from 'chai-as-promised';
+import { it, describe, beforeEach, afterEach } from 'mocha';
+
+const { expect, spy } = chai;
describe('AccountData cache', () => {
const dummyAccountToken = '9876543210';
@@ -9,7 +14,7 @@ describe('AccountData cache', () => {
expiry: new Date('2038-01-01').toISOString(),
};
- let clock;
+ let clock: sinon.SinonFakeTimers;
beforeEach(() => {
clock = sinon.useFakeTimers({ shouldAdvanceTime: true });
@@ -20,12 +25,15 @@ describe('AccountData cache', () => {
});
it('should notify when fetch succeeds on the first attempt', async () => {
- const cache = new AccountDataCache((_) => Promise.resolve(dummyAccountData), (_) => {});
+ const cache = new AccountDataCache(
+ (_token) => Promise.resolve(dummyAccountData),
+ (_data) => {},
+ );
const watcher = new Promise((resolve, reject) => {
cache.fetch(dummyAccountToken, {
onFinish: () => resolve(),
- onError: (_) => {
+ onError: (_error: Error) => {
reject();
return 'stop';
},
@@ -36,12 +44,15 @@ describe('AccountData cache', () => {
});
it('should notify when fetch fails on the first attempt', async () => {
- const cache = new AccountDataCache((_) => Promise.reject(new Error('Fetch fail')), (_) => {});
+ const cache = new AccountDataCache(
+ (_token) => Promise.reject(new Error('Fetch fail')),
+ (_data) => {},
+ );
const watcher = new Promise((resolve, reject) => {
cache.fetch(dummyAccountToken, {
- onFinish: () => resolve(),
- onError: (_) => {
+ onFinish: (_reason?: any) => resolve(),
+ onError: (_error: Error) => {
reject();
return 'stop';
},
@@ -57,7 +68,7 @@ describe('AccountData cache', () => {
cache.fetch(dummyAccountToken, {
onFinish: spy(),
- onError: (_) => {
+ onError: (_error: Error) => {
reject();
return 'stop';
},
@@ -70,7 +81,7 @@ describe('AccountData cache', () => {
it('should update when fetch succeeds on the second attempt', async () => {
const update = new Promise((resolve, reject) => {
let firstAttempt = true;
- const fetch = (_) => {
+ const fetch = () => {
if (firstAttempt) {
firstAttempt = false;
setTimeout(() => clock.tick(9000), 0);
@@ -84,8 +95,8 @@ describe('AccountData cache', () => {
const cache = new AccountDataCache(fetch, () => resolve());
cache.fetch(dummyAccountToken, {
- onFinish: reject,
- onError: spy((_) => 'retry'),
+ onFinish: () => reject(),
+ onError: spy((_error: Error) => 'retry'),
});
});
@@ -95,7 +106,7 @@ describe('AccountData cache', () => {
it('should not retry if told to stop', async () => {
const update = new Promise((resolve, reject) => {
let firstAttempt = true;
- const fetch = (_) => {
+ const fetch = () => {
if (firstAttempt) {
firstAttempt = false;
setTimeout(() => clock.tick(14000), 0);
@@ -112,7 +123,7 @@ describe('AccountData cache', () => {
cache.fetch(dummyAccountToken, {
onFinish: spy(),
- onError: spy((_) => 'stop'),
+ onError: spy((_error: Error) => 'stop'),
});
});
@@ -125,13 +136,13 @@ describe('AccountData cache', () => {
const update = new Promise((resolve, reject) => {
let firstAttempt = true;
- const fetch = (_) => {
+ const fetch = () => {
if (firstAttempt) {
firstAttempt = false;
cache.fetch('1231231231', {
onFinish: secondSuccess,
- onError: (_) => {
+ onError: () => {
reject();
return 'stop';
},
diff --git a/gui/packages/desktop/test/auth-failure.spec.js b/gui/packages/desktop/test/auth-failure.spec.ts
index 86bb97b13c..4d1ad75b25 100644
--- a/gui/packages/desktop/test/auth-failure.spec.js
+++ b/gui/packages/desktop/test/auth-failure.spec.ts
@@ -1,4 +1,7 @@
+import { expect } from 'chai';
+import { it, describe } from 'mocha';
import { AuthFailure } from '../src/renderer/lib/auth-failure';
+
describe('auth_failed parsing', () => {
it('invalid line parsing works', () => {
const auth_msg = new AuthFailure('invalid auth_failed message');
diff --git a/gui/packages/desktop/test/components/Account.spec.js b/gui/packages/desktop/test/components/Account.spec.js
deleted file mode 100644
index 4868b6bab6..0000000000
--- a/gui/packages/desktop/test/components/Account.spec.js
+++ /dev/null
@@ -1,83 +0,0 @@
-// @flow
-
-import * as React from 'react';
-import { shallow } from 'enzyme';
-import Account from '../../src/renderer/components/Account';
-import { BackBarItem } from '../../src/renderer/components/NavigationBar';
-
-type AccountProps = React.ElementProps<typeof Account>;
-
-describe('components/Account', () => {
- const makeProps = (mergeProps: $Shape<AccountProps>): AccountProps => {
- const defaultProps: AccountProps = {
- accountToken: '1234',
- accountExpiry: new Date('2038-01-01').toISOString(),
- expiryLocale: 'en-US',
- isOffline: false,
- updateAccountExpiry: () => Promise.resolve(),
- onClose: () => {},
- onLogout: () => {},
- onBuyMore: () => {},
- };
- return {
- ...defaultProps,
- ...mergeProps,
- };
- };
-
- it('should call close callback', (done) => {
- const props = makeProps({
- onClose: () => done(),
- });
- const component = render(props)
- .find(BackBarItem)
- .dive();
- component.simulate('press');
- });
-
- it('should call logout callback', (done) => {
- const props = makeProps({
- onLogout: () => done(),
- });
- const component = getComponent(render(props), 'account__logout');
- component.simulate('press');
- });
-
- it('should call "buy more" callback', (done) => {
- const props = makeProps({
- onBuyMore: () => done(),
- });
- const component = getComponent(render(props), 'account__buymore');
- component.simulate('press');
- });
-
- it('should display "out of time" message when account expired', () => {
- const props = makeProps({
- accountExpiry: new Date('2001-01-01').toISOString(),
- });
- const component = getComponent(render(props), 'account__expiry');
- expect(component.dive().html()).to.contain('OUT OF TIME');
- });
-
- it('should not display "out of time" message when account is active', () => {
- const props = makeProps({});
- const component = getComponent(render(props), 'account__expiry');
- expect(component.dive().html()).to.not.contain('OUT OF TIME');
- });
-
- it('should not display "unavailable" message when account expiry is missing', () => {
- const props = makeProps({
- accountExpiry: null,
- });
- const component = getComponent(render(props), 'account__expiry');
- expect(component.dive().html()).to.contain('Currently unavailable');
- });
-});
-
-function render(props) {
- return shallow(<Account {...props} />);
-}
-
-function getComponent(container, testName) {
- return container.findWhere((n) => n.prop('testName') === testName);
-}
diff --git a/gui/packages/desktop/test/components/Login.spec.js b/gui/packages/desktop/test/components/Login.spec.js
deleted file mode 100644
index b2ab36fdc2..0000000000
--- a/gui/packages/desktop/test/components/Login.spec.js
+++ /dev/null
@@ -1,82 +0,0 @@
-// @flow
-
-import * as React from 'react';
-import { shallow } from 'enzyme';
-import Login from '../../src/renderer/components/Login';
-
-describe('components/Login', () => {
- it('does not show the footer when logging in', () => {
- const component = shallow(
- <Login
- {...{
- ...defaultProps,
- loginState: 'logging in',
- }}
- />,
- );
- const visibleFooters = getComponent(component, 'footerVisibility true');
- const invisibleFooters = getComponent(component, 'footerVisibility false');
- expect(visibleFooters.length).to.equal(0);
- expect(invisibleFooters.length).to.equal(1);
- });
-
- it('shows the footer and account input when not logged in', () => {
- const component = shallow(<Login {...defaultProps} />);
- const visibleFooters = getComponent(component, 'footerVisibility true');
- const invisibleFooters = getComponent(component, 'footerVisibility false');
- expect(visibleFooters.length).to.equal(1);
- expect(invisibleFooters.length).to.equal(0);
- expect(getComponent(component, 'AccountInput').length).to.be.above(0);
- });
-
- it('does not show the footer but shows the account input when logged in', () => {
- const component = shallow(
- <Login
- {...{
- ...defaultProps,
- loginState: 'ok',
- }}
- />,
- );
- const visibleFooters = getComponent(component, 'footerVisibility true');
- const invisibleFooters = getComponent(component, 'footerVisibility false');
- expect(visibleFooters.length).to.equal(0);
- expect(invisibleFooters.length).to.equal(1);
- expect(getComponent(component, 'AccountInput').length).to.equal(1);
- });
-
- it('logs in with the entered account number when clicking the login icon', (done) => {
- const component = shallow(<Login {...defaultProps} />);
- component.setProps({
- accountToken: '1234567890',
- login: (accountToken) => {
- try {
- expect(accountToken).to.equal('1234567890');
- done();
- } catch (e) {
- done(e);
- }
- },
- });
-
- const accountInputButton = getComponent(component, 'account-input-button');
- accountInputButton.simulate('press');
- });
-});
-
-const defaultProps = {
- accountToken: null,
- accountHistory: [],
- loginError: null,
- loginState: 'none',
- openSettings: () => {},
- openExternalLink: (_type) => {},
- login: (_accountToken) => {},
- resetLoginError: () => {},
- updateAccountToken: (_accountToken) => {},
- removeAccountTokenFromHistory: (_accountToken) => Promise.resolve(),
-};
-
-function getComponent(container, testName) {
- return container.findWhere((n) => n.prop('testName') === testName);
-}
diff --git a/gui/packages/desktop/test/components/NotificationArea.spec.js b/gui/packages/desktop/test/components/NotificationArea.spec.tsx
index f661aa9f12..c23a739535 100644
--- a/gui/packages/desktop/test/components/NotificationArea.spec.js
+++ b/gui/packages/desktop/test/components/NotificationArea.spec.tsx
@@ -1,5 +1,3 @@
-// @flow
-
import moment from 'moment';
import * as React from 'react';
import { shallow } from 'enzyme';
diff --git a/gui/packages/desktop/test/components/Preferences.spec.js b/gui/packages/desktop/test/components/Preferences.spec.js
deleted file mode 100644
index 1906236c35..0000000000
--- a/gui/packages/desktop/test/components/Preferences.spec.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// @flow
-
-import * as React from 'react';
-import { shallow } from 'enzyme';
-import Preferences from '../../src/renderer/components/Preferences';
-import { BackBarItem } from '../../src/renderer/components/NavigationBar';
-
-describe('components/Preferences', () => {
- it('Should call close handler', (done) => {
- const props = makeProps({ onClose: done });
- const component = shallow(<Preferences {...props} />);
- const button = component.find(BackBarItem).dive();
- expect(button).to.have.length(1);
- button.simulate('press');
- });
-});
-
-function makeProps(props) {
- return {
- onClose: () => {},
- setAutoConnect: () => {},
- setAutoStart: (_autoStart) => Promise.resolve(),
- getAutoStart: () => false,
- setAllowLan: () => {},
- getStartMinimized: () => Promise.resolve(false),
- setStartMinimized: () => {},
- allowAutoConnect: false,
- allowLan: false,
- enableStartMinimizedToggle: false,
- ...props,
- };
-}
diff --git a/gui/packages/desktop/test/components/Settings.spec.js b/gui/packages/desktop/test/components/Settings.spec.js
deleted file mode 100644
index aa9709e2de..0000000000
--- a/gui/packages/desktop/test/components/Settings.spec.js
+++ /dev/null
@@ -1,213 +0,0 @@
-// @flow
-
-import * as React from 'react';
-import { shallow } from 'enzyme';
-import Settings from '../../src/renderer/components/Settings';
-import { CloseBarItem } from '../../src/renderer/components/NavigationBar';
-
-type SettingsProps = React.ElementProps<typeof Settings>;
-
-describe('components/Settings', () => {
- const defaultProps: SettingsProps = {
- loginState: 'none',
- accountExpiry: null,
- appVersion: '',
- onQuit: () => {},
- onClose: () => {},
- onViewAccount: () => {},
- onViewSupport: () => {},
- onViewAdvancedSettings: () => {},
- onViewPreferences: () => {},
- onExternalLink: (_type) => {},
- updateAccountExpiry: () => Promise.resolve(),
- };
-
- it('should show quit button when logged out', () => {
- const props = {
- ...defaultProps,
- loginState: 'none',
- accountExpiry: null,
- };
- const component = getComponent(shallow(<Settings {...props} />), 'settings__quit');
- expect(component).to.have.length(1);
- });
-
- it('should show quit button when logged in', () => {
- const props = {
- ...defaultProps,
- loginState: 'ok',
- accountExpiry: new Date('2038-01-01').toISOString(),
- };
- const component = getComponent(shallow(<Settings {...props} />), 'settings__quit');
- expect(component).to.have.length(1);
- });
-
- it('should show external links when logged out', () => {
- const props = {
- ...defaultProps,
- loginState: 'none',
- accountExpiry: null,
- };
- const component = getComponent(shallow(<Settings {...props} />), 'settings__external_link');
- expect(component.length).to.be.above(0);
- });
-
- it('should show external links when logged in', () => {
- const props = {
- ...defaultProps,
- loginState: 'ok',
- accountExpiry: new Date('2038-01-01').toISOString(),
- };
- const component = getComponent(shallow(<Settings {...props} />), 'settings__external_link');
- expect(component.length).to.be.above(0);
- });
-
- it('should show account section when logged in', () => {
- const props = {
- ...defaultProps,
- loginState: 'ok',
- accountExpiry: new Date('2038-01-01').toISOString(),
- };
- const component = getComponent(shallow(<Settings {...props} />), 'settings__account');
- expect(component).to.have.length(1);
- });
-
- it('should hide account section when logged out', () => {
- const props = {
- ...defaultProps,
- loginState: 'none',
- accountExpiry: null,
- };
- const elements = getComponent(shallow(<Settings {...props} />), 'settings__account');
- expect(elements).to.have.length(0);
- });
-
- it('should hide account link when not logged in', () => {
- const props = {
- ...defaultProps,
- loginState: 'none',
- accountExpiry: null,
- };
- const elements = getComponent(shallow(<Settings {...props} />), 'settings__view_account');
- expect(elements).to.have.length(0);
- });
-
- it('should show out-of-time message for unpaid account', () => {
- const props = {
- ...defaultProps,
- loginState: 'ok',
- accountExpiry: new Date('2001-01-01').toISOString(),
- };
- const component = getComponent(
- shallow(<Settings {...props} />),
- 'settings__account_paid_until_subtext',
- );
- expect(component.children().text()).to.equal('OUT OF TIME');
- });
-
- it('should hide out-of-time message for paid account', () => {
- const props = {
- ...defaultProps,
- loginState: 'ok',
- accountExpiry: new Date('2038-01-01').toISOString(),
- };
- const component = getComponent(
- shallow(<Settings {...props} />),
- 'settings__account_paid_until_subtext',
- );
- expect(component.children().text()).not.to.equal('OUT OF TIME');
- });
-
- it('should call close callback', (done) => {
- const props = {
- ...defaultProps,
- loginState: 'none',
- accountExpiry: null,
- onClose: () => done(),
- };
- const component = shallow(<Settings {...props} />)
- .find(CloseBarItem)
- .dive();
- component.simulate('press');
- });
-
- it('should call quit callback', (done) => {
- const props = {
- ...defaultProps,
- loginState: 'none',
- accountExpiry: null,
- onQuit: () => done(),
- };
- const component = getComponent(shallow(<Settings {...props} />), 'settings__quit');
- component.simulate('press');
- });
-
- it('should call account callback', (done) => {
- const props = {
- ...defaultProps,
- loginState: 'ok',
- accountExpiry: new Date('2038-01-01').toISOString(),
- onViewAccount: () => done(),
- };
- const component = getComponent(
- shallow(<Settings {...props} />),
- 'settings__account_paid_until_button',
- );
- component.simulate('press');
- });
-
- it('should call advanced settings callback', (done) => {
- const props = {
- ...defaultProps,
- loginState: 'ok',
- accountExpiry: new Date('2038-01-01').toISOString(),
- onViewAdvancedSettings: () => done(),
- };
- const component = getComponent(shallow(<Settings {...props} />), 'settings__advanced');
- component.simulate('press');
- });
-
- it('should call preferences callback', (done) => {
- const props = {
- ...defaultProps,
- loginState: 'ok',
- accountExpiry: new Date('2038-01-01').toISOString(),
- onViewPreferences: () => done(),
- };
- const component = getComponent(shallow(<Settings {...props} />), 'settings__preferences');
- component.simulate('press');
- });
-
- it('should call support callback', (done) => {
- const props = {
- ...defaultProps,
- loginState: 'ok',
- accountExpiry: new Date('2038-01-01').toISOString(),
- onViewSupport: () => done(),
- };
- const component = getComponent(shallow(<Settings {...props} />), 'settings__view_support');
- component.simulate('press');
- });
-
- it('should call external links callback', () => {
- const collectedExternalLinkTypes: Array<string> = [];
- const props = {
- ...defaultProps,
- loginState: 'none',
- accountExpiry: null,
- onExternalLink: (type) => {
- collectedExternalLinkTypes.push(type);
- },
- };
- const container = getComponent(shallow(<Settings {...props} />), 'settings__external_link');
- container
- .find({ testName: 'settings__external_link' })
- .forEach((element) => element.simulate('press'));
-
- expect(collectedExternalLinkTypes).to.include.ordered.members(['faq']);
- });
-});
-
-function getComponent(container, testName) {
- return container.findWhere((n) => n.prop('testName') === testName);
-}
diff --git a/gui/packages/desktop/test/components/Support.spec.js b/gui/packages/desktop/test/components/Support.spec.js
deleted file mode 100644
index c51c585f62..0000000000
--- a/gui/packages/desktop/test/components/Support.spec.js
+++ /dev/null
@@ -1,131 +0,0 @@
-// @flow
-
-import * as React from 'react';
-import { shallow } from 'enzyme';
-import Support from '../../src/renderer/components/Support';
-import type { SupportProps } from '../../src/renderer/components/Support';
-import { BackBarItem } from '../../src/renderer/components/NavigationBar';
-
-describe('components/Support', () => {
- it('should call close callback', () => {
- const props = makeProps({ onClose: spy() });
- const component = shallow(<Support {...props} />);
-
- const closeButton = component.find(BackBarItem).dive();
- closeButton.simulate('press');
-
- expect(props.onClose).to.have.been.called.once;
- });
-
- it('should call view logs callback', async () => {
- const props = makeProps({ viewLog: spy() });
- const component = shallow(<Support {...props} />);
- const viewButton = component.find({ testName: 'support__view_logs' });
-
- await click(viewButton);
- expect(props.viewLog).to.have.been.called.once;
- });
-
- it('should call send callback when description filled in', async () => {
- const props = makeProps({
- defaultEmail: 'foo',
- defaultMessage: 'abc',
- sendProblemReport: spy((_report) => Promise.resolve()),
- });
- const component = shallow(<Support {...props} />);
- const sendButton = component.find({ testName: 'support__send_logs' });
-
- expect(sendButton.prop('disabled')).to.be.false;
- await click(sendButton);
- expect(props.sendProblemReport).to.have.been.called.once;
- });
-
- it('should not call send callback when description is empty', () => {
- const props = makeProps({ defaultMessage: '' });
- const component = shallow(<Support {...props} />);
- const sendButton = component.find({ testName: 'support__send_logs' });
-
- expect(sendButton.prop('disabled')).to.be.true;
- });
-
- it('should not collect report twice', async () => {
- const props = makeProps({
- collectProblemReport: spy(() => Promise.resolve('/path/to/problem/report')),
- });
- const component = shallow(<Support {...props} />);
- const viewButton = component.find({ testName: 'support__view_logs' });
-
- await Promise.all([click(viewButton), click(viewButton)]);
- expect(props.collectProblemReport).to.have.been.called.once;
- });
-
- it('should collect report on submission', async () => {
- const props = makeProps({
- defaultMessage: '',
- defaultEmail: 'foo',
- collectProblemReport: spy(() => Promise.resolve('/path/to/problem/report')),
- sendProblemReport: spy(() => Promise.resolve()),
- });
- const component = shallow(<Support {...props} />);
- const sendButton = component.find({ testName: 'support__send_logs' });
-
- await click(sendButton);
- expect(props.collectProblemReport).to.have.been.called.once;
- expect(props.sendProblemReport).to.have.been.called.once;
- });
-
- it('should save the report form on change', () => {
- const props = makeProps({
- defaultEmail: 'email@domain',
- defaultMessage: 'test message',
- sendProblemReport: () => Promise.reject(new Error('Simulation')),
- saveReportForm: spy(),
- });
- const component = shallow(<Support {...props} />);
- const input = component.find({ testName: 'support__form_message' });
- input.simulate('changeText', 'new message');
- expect(props.saveReportForm).to.have.been.called.once;
- });
-
- it('should clear the report form upon successful submission', async () => {
- const props = makeProps({
- defaultEmail: 'email@domain',
- defaultMessage: 'test message',
- sendProblemReport: () => Promise.resolve(),
- clearReportForm: spy(),
- });
- const component = shallow(<Support {...props} />);
- const sendButton = component.find({ testName: 'support__send_logs' });
-
- await click(sendButton);
- expect(props.clearReportForm).to.have.been.called.once;
- });
-
- it('should not allow sending when off-line', () => {
- const props = makeProps({ isOffline: true });
- const component = shallow(<Support {...props} />);
- const sendButton = component.find({ testName: 'support__send_logs' });
-
- expect(sendButton.prop('disabled')).to.be.true;
- });
-});
-
-function makeProps(mergeProps: $Shape<SupportProps> = {}): SupportProps {
- const defaultProps: SupportProps = {
- defaultEmail: '',
- defaultMessage: '',
- accountHistory: [],
- isOffline: false,
- onClose: () => {},
- viewLog: (_path) => {},
- collectProblemReport: () => Promise.resolve('/path/to/problem/report'),
- sendProblemReport: (_report) => Promise.resolve(),
- saveReportForm: (_form) => {},
- clearReportForm: () => {},
- };
- return { ...defaultProps, ...mergeProps };
-}
-
-function click(component) {
- return component.prop('onPress')();
-}
diff --git a/gui/packages/desktop/test/jsonrpc-transport.spec.js b/gui/packages/desktop/test/jsonrpc-transport.spec.ts
index 42d6de7c23..7e4e56c80a 100644
--- a/gui/packages/desktop/test/jsonrpc-transport.spec.js
+++ b/gui/packages/desktop/test/jsonrpc-transport.spec.ts
@@ -1,4 +1,5 @@
-// @flow
+import { expect } from 'chai';
+import { it, describe, beforeEach, afterEach } from 'mocha';
import jsonrpc from 'jsonrpc-lite';
import { Server } from 'mock-socket';
import JsonRpcClient, { WebsocketTransport, TimeOutError } from '../src/main/jsonrpc-client';
@@ -77,7 +78,7 @@ describe('JSON RPC transport', () => {
await transport.connect(WEBSOCKET_URL);
const eventPromiseHelper = (() => {
- let borrowedResolve: ?(mixed) => void;
+ let borrowedResolve: (param: any) => void | undefined = undefined;
const promise = new Promise((resolve) => (borrowedResolve = resolve));
/* Flow does not understand that the body of Promise runs immediately.
see https://github.com/facebook/flow/issues/6711 */
diff --git a/gui/packages/desktop/test/keyframe-animation.spec.js b/gui/packages/desktop/test/keyframe-animation.spec.ts
index b893c98572..05efa6ad76 100644
--- a/gui/packages/desktop/test/keyframe-animation.spec.js
+++ b/gui/packages/desktop/test/keyframe-animation.spec.ts
@@ -1,5 +1,5 @@
-// @flow
-
+import { expect } from 'chai';
+import { it, describe } from 'mocha';
import KeyframeAnimation from '../src/main/keyframe-animation';
describe('lib/keyframe-animation', function() {
@@ -12,7 +12,7 @@ describe('lib/keyframe-animation', function() {
};
it('should play sequence', (done) => {
- const seq = [];
+ const seq: number[] = [];
const animation = newAnimation();
animation.onFrame = (frame) => {
seq.push(frame);
@@ -27,7 +27,7 @@ describe('lib/keyframe-animation', function() {
});
it('should play one frame', (done) => {
- const seq = [];
+ const seq: number[] = [];
const animation = newAnimation();
animation.onFrame = (frame) => {
seq.push(frame);
@@ -42,7 +42,7 @@ describe('lib/keyframe-animation', function() {
});
it('should play sequence with custom frames', (done) => {
- const seq = [];
+ const seq: number[] = [];
const animation = newAnimation();
animation.onFrame = (frame) => {
seq.push(frame);
@@ -57,7 +57,7 @@ describe('lib/keyframe-animation', function() {
});
it('should play sequence with custom frames in reverse', (done) => {
- const seq = [];
+ const seq: number[] = [];
const animation = newAnimation();
animation.onFrame = (frame) => {
seq.push(frame);
@@ -72,7 +72,7 @@ describe('lib/keyframe-animation', function() {
});
it('should begin from current state starting below range', (done) => {
- const seq = [];
+ const seq: number[] = [];
const animation = newAnimation();
animation.onFrame = (frame) => {
seq.push(frame);
@@ -88,7 +88,7 @@ describe('lib/keyframe-animation', function() {
});
it('should begin from current state starting above range', (done) => {
- const seq = [];
+ const seq: number[] = [];
const animation = newAnimation();
animation.onFrame = (frame) => {
seq.push(frame);
@@ -104,7 +104,7 @@ describe('lib/keyframe-animation', function() {
});
it('should begin from current state starting above range reverse', (done) => {
- const seq = [];
+ const seq: number[] = [];
const animation = newAnimation();
animation.onFrame = (frame) => {
seq.push(frame);
@@ -120,7 +120,7 @@ describe('lib/keyframe-animation', function() {
});
it('should play sequence in reverse', (done) => {
- const seq = [];
+ const seq: number[] = [];
const animation = newAnimation();
animation.onFrame = (frame) => {
seq.push(frame);
diff --git a/gui/packages/desktop/test/relay-settings-builder.spec.js b/gui/packages/desktop/test/relay-settings-builder.spec.ts
index 0782476fe8..fd7f4c1cf4 100644
--- a/gui/packages/desktop/test/relay-settings-builder.spec.js
+++ b/gui/packages/desktop/test/relay-settings-builder.spec.ts
@@ -1,5 +1,5 @@
-// @flow
-
+import { expect } from 'chai';
+import { it, describe } from 'mocha';
import RelaySettingsBuilder from '../src/renderer/lib/relay-settings-builder';
describe('Relay settings builder', () => {
diff --git a/gui/packages/desktop/test/setup/main.js b/gui/packages/desktop/test/setup/main.ts
index dd458a30b6..9b6ecc5ef7 100644
--- a/gui/packages/desktop/test/setup/main.js
+++ b/gui/packages/desktop/test/setup/main.ts
@@ -1,4 +1,4 @@
-const log = require('electron-log');
+import log from 'electron-log';
log.transports.console.level = false;
log.transports.file.level = false;
diff --git a/gui/packages/desktop/test/setup/renderer.js b/gui/packages/desktop/test/setup/renderer.js
deleted file mode 100644
index c008567930..0000000000
--- a/gui/packages/desktop/test/setup/renderer.js
+++ /dev/null
@@ -1,17 +0,0 @@
-const Enzyme = require('enzyme');
-const Adapter = require('enzyme-adapter-react-16');
-const chai = require('chai');
-const spies = require('chai-spies');
-const chaiAsPromised = require('chai-as-promised');
-const sinon = require('sinon');
-
-chai.use(spies);
-chai.use(chaiAsPromised);
-
-Enzyme.configure({
- adapter: new Adapter(),
-});
-
-global.expect = chai.expect;
-global.sinon = sinon;
-global.spy = chai.spy;
diff --git a/gui/packages/desktop/test/setup/renderer.ts b/gui/packages/desktop/test/setup/renderer.ts
new file mode 100644
index 0000000000..05c236a2da
--- /dev/null
+++ b/gui/packages/desktop/test/setup/renderer.ts
@@ -0,0 +1,12 @@
+import Enzyme from 'enzyme';
+import ReactSixteenAdapter from 'enzyme-adapter-react-16';
+import chai from 'chai';
+import spies from 'chai-spies';
+import chaiAsPromised from 'chai-as-promised';
+
+chai.use(spies);
+chai.use(chaiAsPromised);
+
+Enzyme.configure({
+ adapter: new ReactSixteenAdapter(),
+});
diff --git a/gui/packages/desktop/test/transition-rule.spec.js b/gui/packages/desktop/test/transition-rule.spec.ts
index b6b2da4be4..6896370d21 100644
--- a/gui/packages/desktop/test/transition-rule.spec.js
+++ b/gui/packages/desktop/test/transition-rule.spec.ts
@@ -1,5 +1,5 @@
-// @flow
-
+import { expect } from 'chai';
+import { it, describe } from 'mocha';
import TransitionRule from '../src/renderer/lib/transition-rule';
describe('TransitionRule', () => {
diff --git a/gui/packages/desktop/tsconfig.json b/gui/packages/desktop/tsconfig.json
new file mode 100644
index 0000000000..77924cbbe2
--- /dev/null
+++ b/gui/packages/desktop/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compilerOptions": {
+ "jsx": "react",
+ "outDir": "build",
+ "rootDirs": [
+ "src",
+ "assets"
+ ],
+ "typeRoots": [
+ "../../types",
+ "node_modules/@types"
+ ]
+ },
+ "extends": "@mullvad/config/tsconfig.json",
+ "include": [
+ "src/**/*.ts",
+ "src/**/*.tsx"
+ ]
+}
diff --git a/gui/packages/desktop/tslint.json b/gui/packages/desktop/tslint.json
new file mode 100644
index 0000000000..6b68bf43d6
--- /dev/null
+++ b/gui/packages/desktop/tslint.json
@@ -0,0 +1,3 @@
+{
+ "extends": "@mullvad/config/tslint.json"
+}
diff --git a/gui/packages/mobile/package.json b/gui/packages/mobile/package.json
index b13bf2ec86..c864c567e9 100644
--- a/gui/packages/mobile/package.json
+++ b/gui/packages/mobile/package.json
@@ -12,9 +12,9 @@
"license": "GPL-3.0",
"dependencies": {
"@mullvad/components": "0.1.0",
- "react": "^16.4.0",
+ "react": "^16.5.0",
"react-native": "^0.56",
- "reactxp": "^1.4.0"
+ "reactxp": "^1.5.0"
},
"devDependencies": {
"@babel/cli": "^7.1.5",
diff --git a/gui/types/JSONStream/index.d.ts b/gui/types/JSONStream/index.d.ts
new file mode 100644
index 0000000000..094c53ed6a
--- /dev/null
+++ b/gui/types/JSONStream/index.d.ts
@@ -0,0 +1,40 @@
+// Type definitions for JSONStream v0.8.0
+// Project: https://github.com/dominictarr/JSONStream
+// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+/// <reference types="node" />
+
+
+declare module "JSONStream" {
+ export interface Options {
+ recurse: boolean;
+ }
+
+ export declare function parse(pattern: any): NodeJS.ReadWriteStream;
+ export declare function parse(patterns: any[]): NodeJS.ReadWriteStream;
+
+
+ /**
+ * Create a writable stream.
+ * you may pass in custom open, close, and seperator strings. But, by default,
+ * JSONStream.stringify() will create an array,
+ * (with default options open='[\n', sep='\n,\n', close='\n]\n')
+ */
+ export declare function stringify(): NodeJS.ReadWriteStream;
+
+ /** If you call JSONStream.stringify(false) the elements will only be seperated by a newline. */
+ export declare function stringify(newlineOnly: NewlineOnlyIndicator): NodeJS.ReadWriteStream;
+ type NewlineOnlyIndicator = false
+
+ /**
+ * Create a writable stream.
+ * you may pass in custom open, close, and seperator strings. But, by default,
+ * JSONStream.stringify() will create an array,
+ * (with default options open='[\n', sep='\n,\n', close='\n]\n')
+ */
+ export declare function stringify(open: string, sep: string, close: string): NodeJS.ReadWriteStream;
+
+ export declare function stringifyObject(): NodeJS.ReadWriteStream;
+ export declare function stringifyObject(open: string, sep: string, close: string): NodeJS.ReadWriteStream;
+}
diff --git a/gui/types/d3-geo-projection/index.d.ts b/gui/types/d3-geo-projection/index.d.ts
new file mode 100644
index 0000000000..0f6de59ba2
--- /dev/null
+++ b/gui/types/d3-geo-projection/index.d.ts
@@ -0,0 +1,5 @@
+declare module 'd3-geo-projection' {
+ import { GeoProjection } from 'd3-geo';
+
+ export function geoTimes(): GeoProjection;
+}
diff --git a/gui/types/react-simple-maps/index.d.ts b/gui/types/react-simple-maps/index.d.ts
new file mode 100644
index 0000000000..1f7b3a9b4a
--- /dev/null
+++ b/gui/types/react-simple-maps/index.d.ts
@@ -0,0 +1,187 @@
+//
+// TODO: Remove these typings once the following PR is merged and add "@types/react-simple-maps".
+// https://github.com/DefinitelyTyped/DefinitelyTyped/pull/32632
+//
+
+declare module 'react-simple-maps' {
+ // Type definitions for react-simple-maps 0.12
+ // Project: https://github.com/zcreativelabs/react-simple-maps#readme
+ // Definitions by: Novikov Mihail <https://github.com/thepocp>
+ // Andrej Mihajlov <https://github.com/pronebird>
+ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+ // TypeScript Version: 2.8
+
+ import * as React from 'react';
+ import { GeoProjection } from 'd3-geo';
+
+ export type Point = [number, number];
+
+ export interface MarkerType {
+ coordinates: Point;
+ }
+
+ export interface Line {
+ coordinates: {
+ start: Point;
+ end: Point;
+ };
+ }
+
+ export interface ProjectionConfig {
+ scale: number;
+ xOffset: number;
+ yOffset: number;
+ rotation: [number, number, number];
+ precision: number;
+ }
+
+ export type ProjectionFunction = (
+ width: number,
+ height: number,
+ config: ProjectionConfig,
+ ) => GeoProjection;
+
+ export interface ComposableMapProps {
+ width?: number;
+ height?: number;
+ projection?: string | ProjectionFunction;
+ projectionConfig?: Partial<ProjectionConfig>;
+ style?: React.CSSProperties;
+ defs?: SVGDefsElement;
+ className?: string;
+ showCenter?: boolean;
+ preserveAspectRatio?: string;
+ viewBox?: string;
+ }
+
+ export interface ZoomableGlobeProps {
+ center?: Point;
+ zoom?: number;
+ disablePanning?: boolean;
+ style?: React.CSSProperties;
+ width?: number;
+ height?: number;
+ onMoveStart?: (currentCenter: Point) => void;
+ onMoveEnd?: (newCenter: Point) => void;
+ sensitivity?: number;
+ }
+
+ export interface ZoomableGroupProps {
+ center?: Point;
+ zoom?: number;
+ disablePanning?: boolean;
+ style?: React.CSSProperties;
+ width?: number;
+ height?: number;
+ onMoveStart?: (currentCenter: Point) => void;
+ onMoveEnd?: (newCenter: Point) => void;
+ backdrop?: {
+ x: Point;
+ y: Point;
+ };
+ }
+
+ export interface GeographiesProps {
+ disableOptimization?: boolean;
+ geography?: string | { [key: string]: any } | string[];
+ children?: (geographies: object[], projection: GeoProjection) => void;
+ }
+
+ export interface GeographyProps {
+ cacheId?: number | string | null;
+ precision?: number;
+ round?: boolean;
+ geography?: object;
+ projection?: GeoProjection;
+ tabable?: boolean;
+ style?: {
+ default?: React.CSSProperties;
+ hover?: React.CSSProperties;
+ pressed?: React.CSSProperties;
+ };
+ onClick?: (geography: object, evt: React.MouseEvent<SVGPathElement>) => void;
+ onMouseEnter?: (geography: object, evt: React.MouseEvent<SVGPathElement>) => void;
+ onMouseMove?: (geography: object, evt: React.MouseEvent<SVGPathElement>) => void;
+ onMouseLeave?: (geography: object, evt: React.MouseEvent<SVGPathElement>) => void;
+ onMouseDown?: (geography: object, evt: React.MouseEvent<SVGPathElement>) => void;
+ onMouseUp?: (geography: object, evt: React.MouseEvent<SVGPathElement>) => void;
+ onFocus?: (geography: object, evt: React.FocusEvent<SVGPathElement>) => void;
+ onBlur?: (geography: object, evt: React.FocusEvent<SVGPathElement>) => void;
+ }
+
+ export interface MarkerProps {
+ marker?: MarkerType;
+ tabable?: boolean;
+ style?: {
+ default?: React.CSSProperties;
+ hover?: React.CSSProperties;
+ pressed?: React.CSSProperties;
+ };
+ preserveMarkerAspect?: boolean;
+ onClick?: (marker: MarkerType, evt: React.MouseEvent<SVGGElement>) => void;
+ onMouseEnter?: (marker: MarkerType, evt: React.MouseEvent<SVGGElement>) => void;
+ onMouseMove?: (marker: MarkerType, evt: React.MouseEvent<SVGGElement>) => void;
+ onMouseLeave?: (marker: MarkerType, evt: React.MouseEvent<SVGGElement>) => void;
+ onMouseDown?: (marker: MarkerType, evt: React.MouseEvent<SVGGElement>) => void;
+ onMouseUp?: (marker: MarkerType, evt: React.MouseEvent<SVGGElement>) => void;
+ onFocus?: (marker: MarkerType, evt: React.FocusEvent<SVGGElement>) => void;
+ onBlur?: (marker: MarkerType, evt: React.FocusEvent<SVGGElement>) => void;
+ }
+
+ export interface AnnotationProps {
+ subject?: Point;
+ dx?: number;
+ dy?: number;
+ zoom?: number;
+ stroke?: string;
+ strokeWidth?: number;
+ style?: React.CSSProperties;
+ markerEnd?: string;
+ curve?: number;
+ }
+
+ export interface GraticuleProps {
+ step?: Point;
+ round?: boolean;
+ precision?: number;
+ outline?: boolean;
+ stroke?: string;
+ fill?: string;
+ style?: React.CSSProperties;
+ disableOptimization?: boolean;
+ Globe?: boolean;
+ }
+
+ export interface LineProps {
+ line?: Line;
+ tabable?: boolean;
+ style?: {
+ default?: React.CSSProperties;
+ hover?: React.CSSProperties;
+ pressed?: React.CSSProperties;
+ };
+ preserveMarkerAspect?: boolean;
+ buildPath?: (start: Point, end: Point, line: Line) => string;
+ onClick?: (line: Line, evt: React.MouseEvent<SVGPathElement>) => void;
+ onMouseEnter?: (line: Line, evt: React.MouseEvent<SVGPathElement>) => void;
+ onMouseMove?: (line: Line, evt: React.MouseEvent<SVGPathElement>) => void;
+ onMouseLeave?: (line: Line, evt: React.MouseEvent<SVGPathElement>) => void;
+ onMouseDown?: (line: Line, evt: React.MouseEvent<SVGPathElement>) => void;
+ onMouseUp?: (line: Line, evt: React.MouseEvent<SVGPathElement>) => void;
+ onFocus?: (line: Line, evt: React.FocusEvent<SVGPathElement>) => void;
+ onBlur?: (line: Line, evt: React.FocusEvent<SVGPathElement>) => void;
+ }
+
+ export class ComposableMap extends React.Component<ComposableMapProps> {}
+ export class ZoomableGroup extends React.Component<ZoomableGroupProps> {}
+ export class ZoomableGlobe extends React.Component<ZoomableGlobeProps> {}
+ export class Geographies extends React.Component<GeographiesProps> {}
+ export class Geography extends React.Component<GeographyProps> {}
+ export class Markers extends React.Component {}
+ export class Marker extends React.Component<MarkerProps> {}
+ export class Annotations extends React.Component {}
+ export class Annotation extends React.Component<AnnotationProps> {}
+ export class Graticule extends React.Component<GraticuleProps> {}
+ export class Lines extends React.Component {}
+ export class Line extends React.Component<LineProps> {}
+}
diff --git a/gui/types/validated/index.d.ts b/gui/types/validated/index.d.ts
new file mode 100644
index 0000000000..a70536df8c
--- /dev/null
+++ b/gui/types/validated/index.d.ts
@@ -0,0 +1,42 @@
+// TypeScript typings for validated
+// https://github.com/andreypopp/validated
+
+declare module 'validated/schema' {
+ export interface Context {}
+ export interface ValidateResult<T> {
+ context: Context;
+ value: T;
+ }
+
+ export class Node<T> {
+ validate(context: Context): ValidateResult<T>;
+ }
+
+ type NodeDict<T> = { [name: string]: Node<T> };
+
+ export function object<T, S extends NodeDict<T>>(values: S, defaults?: Object): Node<S>;
+ export function partialObject<T, S extends NodeDict<T>>(values: S, defaults?: Object): Node<S>;
+ export function maybe<T>(valueNode: Node<T>): Node<T>;
+ export const string: Node<string>;
+ export const number: Node<number>;
+ export const boolean: Node<boolean>;
+
+ export function enumeration<T>(...values: Array<T>): Node<T>;
+ export function arrayOf<T>(node: Node<T>): Node<T>;
+ export function oneOf<A, B, C, D, E, F, G, H>(
+ a: Node<A>,
+ b?: Node<B>,
+ c?: Node<C>,
+ d?: Node<D>,
+ e?: Node<E>,
+ f?: Node<F>,
+ g?: Node<G>,
+ h?: Node<H>,
+ ): Node<A | B | C | D | E | F | G | H>;
+}
+
+declare module 'validated/object' {
+ export function validate<T>(object: Node<T>, value: any): T {
+ return object.validate(new Context()).value;
+ }
+}
diff --git a/gui/yarn.lock b/gui/yarn.lock
index 20dd7a3fea..f76827f616 100644
--- a/gui/yarn.lock
+++ b/gui/yarn.lock
@@ -95,17 +95,6 @@
source-map "^0.5.0"
trim-right "^1.0.1"
-"@babel/generator@^7.1.3":
- version "7.1.3"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.3.tgz#2103ec9c42d9bdad9190a6ad5ff2d456fd7b8673"
- integrity sha512-ZoCZGcfIJFJuZBqxcY9OjC1KW2lWK64qrX1o4UYL3yshVhwKFYgzpWZ0vvtGMNJdTlvkw0W+HR1VnYN8q3QPFQ==
- dependencies:
- "@babel/types" "^7.1.3"
- jsesc "^2.5.1"
- lodash "^4.17.10"
- source-map "^0.5.0"
- trim-right "^1.0.1"
-
"@babel/generator@^7.1.5":
version "7.1.5"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.5.tgz#615f064d13d95f8f9157c7261f68eddf32ec15b3"
@@ -124,13 +113,6 @@
dependencies:
"@babel/types" "7.0.0-beta.47"
-"@babel/helper-annotate-as-pure@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32"
- integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==
- dependencies:
- "@babel/types" "^7.0.0"
-
"@babel/helper-builder-binary-assignment-operator-visitor@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0-beta.47.tgz#d5917c29ee3d68abc2c72f604bc043f6e056e907"
@@ -139,14 +121,6 @@
"@babel/helper-explode-assignable-expression" "7.0.0-beta.47"
"@babel/types" "7.0.0-beta.47"
-"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f"
- integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==
- dependencies:
- "@babel/helper-explode-assignable-expression" "^7.1.0"
- "@babel/types" "^7.0.0"
-
"@babel/helper-builder-react-jsx@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0-beta.47.tgz#e39bbce315743044c0d64b31f82f20600f761729"
@@ -155,14 +129,6 @@
"@babel/types" "7.0.0-beta.47"
esutils "^2.0.0"
-"@babel/helper-builder-react-jsx@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0.tgz#fa154cb53eb918cf2a9a7ce928e29eb649c5acdb"
- integrity sha512-ebJ2JM6NAKW0fQEqN8hOLxK84RbRz9OkUhGS/Xd5u56ejMfVbayJ4+LykERZCOUM6faa6Fp3SZNX3fcT16MKHw==
- dependencies:
- "@babel/types" "^7.0.0"
- esutils "^2.0.0"
-
"@babel/helper-call-delegate@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0-beta.47.tgz#96b7804397075f722a4030d3876f51ec19d8829b"
@@ -172,15 +138,6 @@
"@babel/traverse" "7.0.0-beta.47"
"@babel/types" "7.0.0-beta.47"
-"@babel/helper-call-delegate@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz#6a957f105f37755e8645343d3038a22e1449cc4a"
- integrity sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ==
- dependencies:
- "@babel/helper-hoist-variables" "^7.0.0"
- "@babel/traverse" "^7.1.0"
- "@babel/types" "^7.0.0"
-
"@babel/helper-define-map@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.0.0-beta.47.tgz#43a9def87c5166dc29630d51b3da9cc4320c131c"
@@ -190,15 +147,6 @@
"@babel/types" "7.0.0-beta.47"
lodash "^4.17.5"
-"@babel/helper-define-map@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz#3b74caec329b3c80c116290887c0dd9ae468c20c"
- integrity sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg==
- dependencies:
- "@babel/helper-function-name" "^7.1.0"
- "@babel/types" "^7.0.0"
- lodash "^4.17.10"
-
"@babel/helper-explode-assignable-expression@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0-beta.47.tgz#56b688e282a698f4d1cf135453a11ae8af870a19"
@@ -207,14 +155,6 @@
"@babel/traverse" "7.0.0-beta.47"
"@babel/types" "7.0.0-beta.47"
-"@babel/helper-explode-assignable-expression@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6"
- integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==
- dependencies:
- "@babel/traverse" "^7.1.0"
- "@babel/types" "^7.0.0"
-
"@babel/helper-function-name@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.47.tgz#8057d63e951e85c57c02cdfe55ad7608d73ffb7d"
@@ -254,13 +194,6 @@
dependencies:
"@babel/types" "7.0.0-beta.47"
-"@babel/helper-hoist-variables@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz#46adc4c5e758645ae7a45deb92bab0918c23bb88"
- integrity sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==
- dependencies:
- "@babel/types" "^7.0.0"
-
"@babel/helper-member-expression-to-functions@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0-beta.47.tgz#35bfcf1d16dce481ef3dec66d5a1ae6a7d80bb45"
@@ -268,13 +201,6 @@
dependencies:
"@babel/types" "7.0.0-beta.47"
-"@babel/helper-member-expression-to-functions@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f"
- integrity sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==
- dependencies:
- "@babel/types" "^7.0.0"
-
"@babel/helper-module-imports@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.47.tgz#5af072029ffcfbece6ffbaf5d9984c75580f3f04"
@@ -283,13 +209,6 @@
"@babel/types" "7.0.0-beta.47"
lodash "^4.17.5"
-"@babel/helper-module-imports@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d"
- integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==
- dependencies:
- "@babel/types" "^7.0.0"
-
"@babel/helper-module-transforms@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0-beta.47.tgz#7eff91fc96873bd7b8d816698f1a69bbc01f3c38"
@@ -302,18 +221,6 @@
"@babel/types" "7.0.0-beta.47"
lodash "^4.17.5"
-"@babel/helper-module-transforms@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.1.0.tgz#470d4f9676d9fad50b324cdcce5fbabbc3da5787"
- integrity sha512-0JZRd2yhawo79Rcm4w0LwSMILFmFXjugG3yqf+P/UsKsRS1mJCmMwwlHDlMg7Avr9LrvSpp4ZSULO9r8jpCzcw==
- dependencies:
- "@babel/helper-module-imports" "^7.0.0"
- "@babel/helper-simple-access" "^7.1.0"
- "@babel/helper-split-export-declaration" "^7.0.0"
- "@babel/template" "^7.1.0"
- "@babel/types" "^7.0.0"
- lodash "^4.17.10"
-
"@babel/helper-optimise-call-expression@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-beta.47.tgz#085d864d0613c5813c1b7c71b61bea36f195929e"
@@ -321,23 +228,11 @@
dependencies:
"@babel/types" "7.0.0-beta.47"
-"@babel/helper-optimise-call-expression@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5"
- integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==
- dependencies:
- "@babel/types" "^7.0.0"
-
"@babel/helper-plugin-utils@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-beta.47.tgz#4f564117ec39f96cf60fafcde35c9ddce0e008fd"
integrity sha512-GR67o8boOKVJRKM5Nhk7oVEHpxYy8R00lwu0F82WxxBH+iiT26DqW1e/4w/mo7Bdn1A6l0pNaOlNk1PdM2Hgag==
-"@babel/helper-plugin-utils@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250"
- integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==
-
"@babel/helper-regex@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0-beta.47.tgz#b8e3b53132c4edbb04804242c02ffe4d60316971"
@@ -345,13 +240,6 @@
dependencies:
lodash "^4.17.5"
-"@babel/helper-regex@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0.tgz#2c1718923b57f9bbe64705ffe5640ac64d9bdb27"
- integrity sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==
- dependencies:
- lodash "^4.17.10"
-
"@babel/helper-remap-async-to-generator@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.47.tgz#444dc362f61470bd61a745ebb364431d9ca186c2"
@@ -363,17 +251,6 @@
"@babel/traverse" "7.0.0-beta.47"
"@babel/types" "7.0.0-beta.47"
-"@babel/helper-remap-async-to-generator@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f"
- integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.0.0"
- "@babel/helper-wrap-function" "^7.1.0"
- "@babel/template" "^7.1.0"
- "@babel/traverse" "^7.1.0"
- "@babel/types" "^7.0.0"
-
"@babel/helper-replace-supers@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-beta.47.tgz#310b206a302868a792b659455ceba27db686cbb7"
@@ -384,16 +261,6 @@
"@babel/traverse" "7.0.0-beta.47"
"@babel/types" "7.0.0-beta.47"
-"@babel/helper-replace-supers@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.1.0.tgz#5fc31de522ec0ef0899dc9b3e7cf6a5dd655f362"
- integrity sha512-BvcDWYZRWVuDeXTYZWxekQNO5D4kO55aArwZOTFXw6rlLQA8ZaDicJR1sO47h+HrnCiDFiww0fSPV0d713KBGQ==
- dependencies:
- "@babel/helper-member-expression-to-functions" "^7.0.0"
- "@babel/helper-optimise-call-expression" "^7.0.0"
- "@babel/traverse" "^7.1.0"
- "@babel/types" "^7.0.0"
-
"@babel/helper-simple-access@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.47.tgz#234d754acbda9251a10db697ef50181eab125042"
@@ -403,14 +270,6 @@
"@babel/types" "7.0.0-beta.47"
lodash "^4.17.5"
-"@babel/helper-simple-access@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c"
- integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==
- dependencies:
- "@babel/template" "^7.1.0"
- "@babel/types" "^7.0.0"
-
"@babel/helper-split-export-declaration@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.47.tgz#e11277855472d8d83baf22f2d0186c4a2059b09a"
@@ -435,16 +294,6 @@
"@babel/traverse" "7.0.0-beta.47"
"@babel/types" "7.0.0-beta.47"
-"@babel/helper-wrap-function@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.1.0.tgz#8cf54e9190706067f016af8f75cb3df829cc8c66"
- integrity sha512-R6HU3dete+rwsdAfrOzTlE9Mcpk4RjU3aX3gi9grtmugQY0u79X7eogUvfXA5sI81Mfq1cn6AgxihfN33STjJA==
- dependencies:
- "@babel/helper-function-name" "^7.1.0"
- "@babel/template" "^7.1.0"
- "@babel/traverse" "^7.1.0"
- "@babel/types" "^7.0.0"
-
"@babel/helpers@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.0.0-beta.47.tgz#f9b42ed2e4d5f75ec0fb2e792c173e451e8d40fd"
@@ -481,29 +330,16 @@
esutils "^2.0.2"
js-tokens "^4.0.0"
-"@babel/node@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.0.0.tgz#20e55bb0e015700a0f6ff281c712de7619ad56f4"
- integrity sha512-mKbN8Bb1TzH9YnKMWMhBRX+o5MVJHtUSalNcsiGa4FRgVfY7ozqkbttuIDWqeXxZ3rwI9ZqmCUr9XsPV2VYlSw==
- dependencies:
- "@babel/polyfill" "^7.0.0"
- "@babel/register" "^7.0.0"
- commander "^2.8.1"
- fs-readdir-recursive "^1.0.0"
- lodash "^4.17.10"
- output-file-sync "^2.0.0"
- v8flags "^3.1.1"
+"@babel/parser@^7.1.2":
+ version "7.1.3"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.3.tgz#2c92469bac2b7fbff810b67fca07bd138b48af77"
+ integrity sha512-gqmspPZOMW3MIRb9HlrnbZHXI1/KHTOroBwN1NcLL6pWxzqzEKGvRTq0W/PxS45OtQGbaFikSQpkS5zbnsQm2w==
-"@babel/parser@^7.0.0", "@babel/parser@^7.1.5":
+"@babel/parser@^7.1.5":
version "7.1.5"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.5.tgz#20b7d5e7e1811ba996f8a868962ea7dd2bfcd2fc"
integrity sha512-WXKf5K5HT6X0kKiCOezJZFljsfxKV1FpU8Tf1A7ZpGvyd/Q4hlrJm2EwoH2onaUq3O4tLDp+4gk0hHPsMyxmOg==
-"@babel/parser@^7.1.2", "@babel/parser@^7.1.3":
- version "7.1.3"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.3.tgz#2c92469bac2b7fbff810b67fca07bd138b48af77"
- integrity sha512-gqmspPZOMW3MIRb9HlrnbZHXI1/KHTOroBwN1NcLL6pWxzqzEKGvRTq0W/PxS45OtQGbaFikSQpkS5zbnsQm2w==
-
"@babel/plugin-external-helpers@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-external-helpers/-/plugin-external-helpers-7.0.0-beta.47.tgz#b348b80da9b5fa3acebbe21979aa3839f6f7b875"
@@ -511,15 +347,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-proposal-async-generator-functions@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.1.0.tgz#41c1a702e10081456e23a7b74d891922dd1bb6ce"
- integrity sha512-Fq803F3Jcxo20MXUSDdmZZXrPe6BWyGcWBPPNB/M7WaUYESKDeKMOGIxEzQOjGSmW/NWb6UaPZrtTB2ekhB/ew==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-remap-async-to-generator" "^7.1.0"
- "@babel/plugin-syntax-async-generators" "^7.0.0"
-
"@babel/plugin-proposal-class-properties@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-beta.47.tgz#08c1a1dfc92d0f5c37b39096c6fb883e1ca4b0f5"
@@ -530,26 +357,6 @@
"@babel/helper-replace-supers" "7.0.0-beta.47"
"@babel/plugin-syntax-class-properties" "7.0.0-beta.47"
-"@babel/plugin-proposal-class-properties@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.1.0.tgz#9af01856b1241db60ec8838d84691aa0bd1e8df4"
- integrity sha512-/PCJWN+CKt5v1xcGn4vnuu13QDoV+P7NcICP44BoonAJoPSGwVkgrXihFIQGiEjjPlUDBIw1cM7wYFLARS2/hw==
- dependencies:
- "@babel/helper-function-name" "^7.1.0"
- "@babel/helper-member-expression-to-functions" "^7.0.0"
- "@babel/helper-optimise-call-expression" "^7.0.0"
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-replace-supers" "^7.1.0"
- "@babel/plugin-syntax-class-properties" "^7.0.0"
-
-"@babel/plugin-proposal-json-strings@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0.tgz#3b4d7b5cf51e1f2e70f52351d28d44fc2970d01e"
- integrity sha512-kfVdUkIAGJIVmHmtS/40i/fg/AGnw/rsZBCaapY5yjeO5RA9m165Xbw9KMOu2nqXP5dTFjEjHdfNdoVcHv133Q==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-syntax-json-strings" "^7.0.0"
-
"@babel/plugin-proposal-object-rest-spread@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.47.tgz#e1529fddc88e948868ee1d0edaa27ebd9502322d"
@@ -558,22 +365,6 @@
"@babel/helper-plugin-utils" "7.0.0-beta.47"
"@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.47"
-"@babel/plugin-proposal-object-rest-spread@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz#9a17b547f64d0676b6c9cecd4edf74a82ab85e7e"
- integrity sha512-14fhfoPcNu7itSen7Py1iGN0gEm87hX/B+8nZPqkdmANyyYWYMY2pjA3r8WXbWVKMzfnSNS0xY8GVS0IjXi/iw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-syntax-object-rest-spread" "^7.0.0"
-
-"@babel/plugin-proposal-optional-catch-binding@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz#b610d928fe551ff7117d42c8bb410eec312a6425"
- integrity sha512-JPqAvLG1s13B/AuoBjdBYvn38RqW6n1TzrQO839/sIpqLpbnXKacsAgpZHzLD83Sm8SDXMkkrAvEnJ25+0yIpw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-syntax-optional-catch-binding" "^7.0.0"
-
"@babel/plugin-proposal-optional-chaining@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.0.0-beta.47.tgz#099e5720121f91eb36544575f98d44cd57865ea5"
@@ -582,22 +373,6 @@
"@babel/helper-plugin-utils" "7.0.0-beta.47"
"@babel/plugin-syntax-optional-chaining" "7.0.0-beta.47"
-"@babel/plugin-proposal-unicode-property-regex@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0.tgz#498b39cd72536cd7c4b26177d030226eba08cd33"
- integrity sha512-tM3icA6GhC3ch2SkmSxv7J/hCWKISzwycub6eGsDrFDgukD4dZ/I+x81XgW0YslS6mzNuQ1Cbzh5osjIMgepPQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-regex" "^7.0.0"
- regexpu-core "^4.2.0"
-
-"@babel/plugin-syntax-async-generators@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0.tgz#bf0891dcdbf59558359d0c626fdc9490e20bc13c"
- integrity sha512-im7ged00ddGKAjcZgewXmp1vxSZQQywuQXe2B1A7kajjZmDeY/ekMPmWr9zJgveSaQH0k7BcGrojQhcK06l0zA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-syntax-class-properties@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-beta.47.tgz#de52bed12fd472c848e1562f57dd4a202fe27f11"
@@ -605,13 +380,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-syntax-class-properties@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0.tgz#e051af5d300cbfbcec4a7476e37a803489881634"
- integrity sha512-cR12g0Qzn4sgkjrbrzWy2GE7m9vMl/sFkqZ3gIpAQdrvPDnLM8180i+ANDFIXfjHo9aqp0ccJlQ0QNZcFUbf9w==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-syntax-dynamic-import@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.0.0-beta.47.tgz#ee964915014a687701ee8e15c289e31a7c899e60"
@@ -626,20 +394,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-syntax-flow@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0.tgz#70638aeaad9ee426bc532e51523cff8ff02f6f17"
- integrity sha512-zGcuZWiWWDa5qTZ6iAnpG0fnX/GOu49pGR5PFvkQ9GmKNaSphXQnlNXh/LG20sqWtNrx/eB6krzfEzcwvUyeFA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-syntax-json-strings@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.0.0.tgz#0d259a68090e15b383ce3710e01d5b23f3770cbd"
- integrity sha512-UlSfNydC+XLj4bw7ijpldc1uZ/HB84vw+U6BTuqMdIEmz/LDe63w/GHtpQMdXWdqQZFeAI9PjnHe/vDhwirhKA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-syntax-jsx@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0-beta.47.tgz#f3849d94288695d724bd205b4f6c3c99e4ec24a4"
@@ -647,13 +401,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-syntax-jsx@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0.tgz#034d5e2b4e14ccaea2e4c137af7e4afb39375ffd"
- integrity sha512-PdmL2AoPsCLWxhIr3kG2+F9v4WH06Q3z+NoGVpQgnUNGcagXHq5sB3OXxkSahKq9TLdNMN/AJzFYSOo8UKDMHg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-syntax-nullish-coalescing-operator@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.0.0-beta.47.tgz#24043fa9b2cdd980d4ff18b9d451569565725ebf"
@@ -668,20 +415,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-syntax-object-rest-spread@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz#37d8fbcaf216bd658ea1aebbeb8b75e88ebc549b"
- integrity sha512-5A0n4p6bIiVe5OvQPxBnesezsgFJdHhSs3uFSvaPdMqtsovajLZ+G2vZyvNe10EzJBWWo3AcHGKhAFUxqwp2dw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-syntax-optional-catch-binding@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz#886f72008b3a8b185977f7cb70713b45e51ee475"
- integrity sha512-Wc+HVvwjcq5qBg1w5RG9o9RVzmCaAg/Vp0erHCKpAYV8La6I94o4GQAmFYNmkzoMO6gzoOSulpKeSSz6mPEoZw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-syntax-optional-chaining@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.0.0-beta.47.tgz#f1febe859d9dde26f2b2e1f20cf679925d1fab23"
@@ -689,13 +422,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-syntax-typescript@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.0.0.tgz#90f4fe0a741ae9c0dcdc3017717c05a0cbbd5158"
- integrity sha512-5fxmdqiAQVQTIS+KSvYeZuTt91wKtBTYi6JlIkvbQ6hmO+9fZE81ezxmMiFMIsxE7CdRSgzn7nQ1BChcvK9OpA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-transform-arrow-functions@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0-beta.47.tgz#d6eecda4c652b909e3088f0983ebaf8ec292984b"
@@ -703,13 +429,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-transform-arrow-functions@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz#a6c14875848c68a3b4b3163a486535ef25c7e749"
- integrity sha512-2EZDBl1WIO/q4DIkIp4s86sdp4ZifL51MoIviLY/gG/mLSuOIEg7J8o6mhbxOTvUJkaN50n+8u41FVsr5KLy/w==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-transform-async-to-generator@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.0.0-beta.47.tgz#5723816ea1e91fa313a84e6ee9cc12ff31d46610"
@@ -719,22 +438,6 @@
"@babel/helper-plugin-utils" "7.0.0-beta.47"
"@babel/helper-remap-async-to-generator" "7.0.0-beta.47"
-"@babel/plugin-transform-async-to-generator@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.1.0.tgz#109e036496c51dd65857e16acab3bafdf3c57811"
- integrity sha512-rNmcmoQ78IrvNCIt/R9U+cixUHeYAzgusTFgIAv+wQb9HJU4szhpDD6e5GCACmj/JP5KxuCwM96bX3L9v4ZN/g==
- dependencies:
- "@babel/helper-module-imports" "^7.0.0"
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-remap-async-to-generator" "^7.1.0"
-
-"@babel/plugin-transform-block-scoped-functions@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0.tgz#482b3f75103927e37288b3b67b65f848e2aa0d07"
- integrity sha512-AOBiyUp7vYTqz2Jibe1UaAWL0Hl9JUXEgjFvvvcSc9MVDItv46ViXFw2F7SVt1B5k+KWjl44eeXOAk3UDEaJjQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-transform-block-scoping@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0-beta.47.tgz#b737cc58a81bea57efd5bda0baef9a43a25859ad"
@@ -743,14 +446,6 @@
"@babel/helper-plugin-utils" "7.0.0-beta.47"
lodash "^4.17.5"
-"@babel/plugin-transform-block-scoping@^7.1.5":
- version "7.1.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.1.5.tgz#3e8e0bc9a5104519923302a24f748f72f2f61f37"
- integrity sha512-jlYcDrz+5ayWC7mxgpn1Wj8zj0mmjCT2w0mPIMSwO926eXBRxpEgoN/uQVRBfjtr8ayjcmS+xk2G1jaP8JjMJQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- lodash "^4.17.10"
-
"@babel/plugin-transform-classes@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0-beta.47.tgz#7aff9cbe7b26fd94d7a9f97fa90135ef20c93fb6"
@@ -765,20 +460,6 @@
"@babel/helper-split-export-declaration" "7.0.0-beta.47"
globals "^11.1.0"
-"@babel/plugin-transform-classes@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.1.0.tgz#ab3f8a564361800cbc8ab1ca6f21108038432249"
- integrity sha512-rNaqoD+4OCBZjM7VaskladgqnZ1LO6o2UxuWSDzljzW21pN1KXkB7BstAVweZdxQkHAujps5QMNOTWesBciKFg==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.0.0"
- "@babel/helper-define-map" "^7.1.0"
- "@babel/helper-function-name" "^7.1.0"
- "@babel/helper-optimise-call-expression" "^7.0.0"
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-replace-supers" "^7.1.0"
- "@babel/helper-split-export-declaration" "^7.0.0"
- globals "^11.1.0"
-
"@babel/plugin-transform-computed-properties@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0-beta.47.tgz#56ef2a021769a2b65e90a3e12fd10b791da9f3e0"
@@ -786,13 +467,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-transform-computed-properties@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz#2fbb8900cd3e8258f2a2ede909b90e7556185e31"
- integrity sha512-ubouZdChNAv4AAWAgU7QKbB93NU5sHwInEWfp+/OzJKA02E6Woh9RVoX4sZrbRwtybky/d7baTUqwFx+HgbvMA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-transform-destructuring@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0-beta.47.tgz#452b607775fd1c4d10621997837189efc0a6d428"
@@ -800,29 +474,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-transform-destructuring@^7.0.0":
- version "7.1.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.1.3.tgz#e69ff50ca01fac6cb72863c544e516c2b193012f"
- integrity sha512-Mb9M4DGIOspH1ExHOUnn2UUXFOyVTiX84fXCd+6B5iWrQg/QMeeRmSwpZ9lnjYLSXtZwiw80ytVMr3zue0ucYw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-dotall-regex@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0.tgz#73a24da69bc3c370251f43a3d048198546115e58"
- integrity sha512-00THs8eJxOJUFVx1w8i1MBF4XH4PsAjKjQ1eqN/uCH3YKwP21GCKfrn6YZFZswbOk9+0cw1zGQPHVc1KBlSxig==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-regex" "^7.0.0"
- regexpu-core "^4.1.3"
-
-"@babel/plugin-transform-duplicate-keys@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0.tgz#a0601e580991e7cace080e4cf919cfd58da74e86"
- integrity sha512-w2vfPkMqRkdxx+C71ATLJG30PpwtTpW7DDdLqYt2acXU7YjztzeWW2Jk1T6hKqCLYCcEA5UQM/+xTAm+QCSnuQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-transform-exponentiation-operator@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0-beta.47.tgz#930e1abf5db9f4db5b63dbf97f3581ad0be1e907"
@@ -831,14 +482,6 @@
"@babel/helper-builder-binary-assignment-operator-visitor" "7.0.0-beta.47"
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-transform-exponentiation-operator@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.1.0.tgz#9c34c2ee7fd77e02779cfa37e403a2e1003ccc73"
- integrity sha512-uZt9kD1Pp/JubkukOGQml9tqAeI8NkE98oZnHZ2qHRElmeKCodbTZgOEUtujSCSLhHSBWbzNiFSDIMC4/RBTLQ==
- dependencies:
- "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0"
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-transform-flow-strip-types@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.0.0-beta.47.tgz#fa45811094c10d70c84efdd0eac62ebd2a634bf7"
@@ -847,14 +490,6 @@
"@babel/helper-plugin-utils" "7.0.0-beta.47"
"@babel/plugin-syntax-flow" "7.0.0-beta.47"
-"@babel/plugin-transform-flow-strip-types@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.0.0.tgz#c40ced34c2783985d90d9f9ac77a13e6fb396a01"
- integrity sha512-WhXUNb4It5a19RsgKKbQPrjmy4yWOY1KynpEbNw7bnd1QTcrT/EIl3MJvnGgpgvrKyKbqX7nUNOJfkpLOnoDKA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-syntax-flow" "^7.0.0"
-
"@babel/plugin-transform-for-of@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0-beta.47.tgz#527d5dc24e4a4ad0fc1d0a3990d29968cb984e76"
@@ -862,13 +497,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-transform-for-of@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz#f2ba4eadb83bd17dc3c7e9b30f4707365e1c3e39"
- integrity sha512-TlxKecN20X2tt2UEr2LNE6aqA0oPeMT1Y3cgz8k4Dn1j5ObT8M3nl9aA37LLklx0PBZKETC9ZAf9n/6SujTuXA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-transform-function-name@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0-beta.47.tgz#fb443c81cc77f3206a863b730b35c8c553ce5041"
@@ -877,14 +505,6 @@
"@babel/helper-function-name" "7.0.0-beta.47"
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-transform-function-name@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.1.0.tgz#29c5550d5c46208e7f730516d41eeddd4affadbb"
- integrity sha512-VxOa1TMlFMtqPW2IDYZQaHsFrq/dDoIjgN098NowhexhZcz3UGlvPgZXuE1jEvNygyWyxRacqDpCZt+par1FNg==
- dependencies:
- "@babel/helper-function-name" "^7.1.0"
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-transform-literals@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0-beta.47.tgz#448fad196f062163684a38f10f14e83315892e9c"
@@ -892,21 +512,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-transform-literals@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz#2aec1d29cdd24c407359c930cdd89e914ee8ff86"
- integrity sha512-1NTDBWkeNXgpUcyoVFxbr9hS57EpZYXpje92zv0SUzjdu3enaRwF/l3cmyRnXLtIdyJASyiS6PtybK+CgKf7jA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-modules-amd@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.1.0.tgz#f9e0a7072c12e296079b5a59f408ff5b97bf86a8"
- integrity sha512-wt8P+xQ85rrnGNr2x1iV3DW32W8zrB6ctuBkYBbf5/ZzJY99Ob4MFgsZDFgczNU76iy9PWsy4EuxOliDjdKw6A==
- dependencies:
- "@babel/helper-module-transforms" "^7.1.0"
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-transform-modules-commonjs@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0-beta.47.tgz#dfe5c6d867aa9614e55f7616736073edb3aab887"
@@ -916,38 +521,6 @@
"@babel/helper-plugin-utils" "7.0.0-beta.47"
"@babel/helper-simple-access" "7.0.0-beta.47"
-"@babel/plugin-transform-modules-commonjs@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.1.0.tgz#0a9d86451cbbfb29bd15186306897c67f6f9a05c"
- integrity sha512-wtNwtMjn1XGwM0AXPspQgvmE6msSJP15CX2RVfpTSTNPLhKhaOjaIfBaVfj4iUZ/VrFSodcFedwtPg/NxwQlPA==
- dependencies:
- "@babel/helper-module-transforms" "^7.1.0"
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-simple-access" "^7.1.0"
-
-"@babel/plugin-transform-modules-systemjs@^7.0.0":
- version "7.1.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.1.3.tgz#2119a3e3db612fd74a19d88652efbfe9613a5db0"
- integrity sha512-PvTxgjxQAq4pvVUZF3mD5gEtVDuId8NtWkJsZLEJZMZAW3TvgQl1pmydLLN1bM8huHFVVU43lf0uvjQj9FRkKw==
- dependencies:
- "@babel/helper-hoist-variables" "^7.0.0"
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-modules-umd@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.1.0.tgz#a29a7d85d6f28c3561c33964442257cc6a21f2a8"
- integrity sha512-enrRtn5TfRhMmbRwm7F8qOj0qEYByqUvTttPEGimcBH4CJHphjyK1Vg7sdU7JjeEmgSpM890IT/efS2nMHwYig==
- dependencies:
- "@babel/helper-module-transforms" "^7.1.0"
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-new-target@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz#ae8fbd89517fa7892d20e6564e641e8770c3aa4a"
- integrity sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-transform-object-assign@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.0.0-beta.47.tgz#aaf0e4593c1e9b1ceb48fc8770736a029b17ed64"
@@ -955,14 +528,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-transform-object-super@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.1.0.tgz#b1ae194a054b826d8d4ba7ca91486d4ada0f91bb"
- integrity sha512-/O02Je1CRTSk2SSJaq0xjwQ8hG4zhZGNjE8psTsSNPXyLRCODv7/PBozqT5AmQMzp7MI3ndvMhGdqp9c96tTEw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-replace-supers" "^7.1.0"
-
"@babel/plugin-transform-parameters@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0-beta.47.tgz#46a4236040a6552a5f165fb3ddd60368954b0ddd"
@@ -972,15 +537,6 @@
"@babel/helper-get-function-arity" "7.0.0-beta.47"
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-transform-parameters@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.1.0.tgz#44f492f9d618c9124026e62301c296bf606a7aed"
- integrity sha512-vHV7oxkEJ8IHxTfRr3hNGzV446GAb+0hgbA7o/0Jd76s+YzccdWuTU296FOCOl/xweU4t/Ya4g41yWz80RFCRw==
- dependencies:
- "@babel/helper-call-delegate" "^7.1.0"
- "@babel/helper-get-function-arity" "^7.0.0"
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-transform-react-display-name@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.0.0-beta.47.tgz#7a45c1703b8b33f252148ecf1b50dd54809de952"
@@ -988,21 +544,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-transform-react-display-name@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.0.0.tgz#93759e6c023782e52c2da3b75eca60d4f10533ee"
- integrity sha512-BX8xKuQTO0HzINxT6j/GiCwoJB0AOMs0HmLbEnAvcte8U8rSkNa/eSCAY+l1OA4JnCVq2jw2p6U8QQryy2fTPg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-react-jsx-self@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.0.0.tgz#a84bb70fea302d915ea81d9809e628266bb0bc11"
- integrity sha512-pymy+AK12WO4safW1HmBpwagUQRl9cevNX+82AIAtU1pIdugqcH+nuYP03Ja6B+N4gliAaKWAegIBL/ymALPHA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-syntax-jsx" "^7.0.0"
-
"@babel/plugin-transform-react-jsx-source@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.0.0-beta.47.tgz#da8c01704b896409eae168a15045216e72d278dc"
@@ -1011,14 +552,6 @@
"@babel/helper-plugin-utils" "7.0.0-beta.47"
"@babel/plugin-syntax-jsx" "7.0.0-beta.47"
-"@babel/plugin-transform-react-jsx-source@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.0.0.tgz#28e00584f9598c0dd279f6280eee213fa0121c3c"
- integrity sha512-OSeEpFJEH5dw/TtxTg4nijl4nHBbhqbKL94Xo/Y17WKIf2qJWeIk/QeXACF19lG1vMezkxqruwnTjVizaW7u7w==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-syntax-jsx" "^7.0.0"
-
"@babel/plugin-transform-react-jsx@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.0.0-beta.47.tgz#98c99a69be748d966c0aea08b5ca942ba3fc9ed1"
@@ -1028,15 +561,6 @@
"@babel/helper-plugin-utils" "7.0.0-beta.47"
"@babel/plugin-syntax-jsx" "7.0.0-beta.47"
-"@babel/plugin-transform-react-jsx@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.0.0.tgz#524379e4eca5363cd10c4446ba163f093da75f3e"
- integrity sha512-0TMP21hXsSUjIQJmu/r7RiVxeFrXRcMUigbKu0BLegJK9PkYodHstaszcig7zxXfaBji2LYUdtqIkHs+hgYkJQ==
- dependencies:
- "@babel/helper-builder-react-jsx" "^7.0.0"
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-syntax-jsx" "^7.0.0"
-
"@babel/plugin-transform-regenerator@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0-beta.47.tgz#86500e1c404055fb98fc82b73b09bd053cacb516"
@@ -1044,13 +568,6 @@
dependencies:
regenerator-transform "^0.12.3"
-"@babel/plugin-transform-regenerator@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz#5b41686b4ed40bef874d7ed6a84bdd849c13e0c1"
- integrity sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw==
- dependencies:
- regenerator-transform "^0.13.3"
-
"@babel/plugin-transform-shorthand-properties@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0-beta.47.tgz#00be44c4fad8fe2c00ed18ea15ea3c88dd519dbb"
@@ -1058,13 +575,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-transform-shorthand-properties@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz#85f8af592dcc07647541a0350e8c95c7bf419d15"
- integrity sha512-g/99LI4vm5iOf5r1Gdxq5Xmu91zvjhEG5+yZDJW268AZELAu4J1EiFLnkSG3yuUsZyOipVOVUKoGPYwfsTymhw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-transform-spread@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0-beta.47.tgz#3feadb02292ed1e9b75090d651b9df88a7ab5c50"
@@ -1072,13 +582,6 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-transform-spread@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz#93583ce48dd8c85e53f3a46056c856e4af30b49b"
- integrity sha512-L702YFy2EvirrR4shTj0g2xQp7aNwZoWNCkNu2mcoU0uyzMl0XRwDSwzB/xp6DSUFiBmEXuyAyEN16LsgVqGGQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
"@babel/plugin-transform-sticky-regex@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0-beta.47.tgz#c0aa347d76b5dc87d3b37ac016ada3f950605131"
@@ -1087,14 +590,6 @@
"@babel/helper-plugin-utils" "7.0.0-beta.47"
"@babel/helper-regex" "7.0.0-beta.47"
-"@babel/plugin-transform-sticky-regex@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz#30a9d64ac2ab46eec087b8530535becd90e73366"
- integrity sha512-LFUToxiyS/WD+XEWpkx/XJBrUXKewSZpzX68s+yEOtIbdnsRjpryDw9U06gYc6klYEij/+KQVRnD3nz3AoKmjw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-regex" "^7.0.0"
-
"@babel/plugin-transform-template-literals@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0-beta.47.tgz#5f7b5badf64c4c5da79026aeab03001e62a6ee5f"
@@ -1103,29 +598,6 @@
"@babel/helper-annotate-as-pure" "7.0.0-beta.47"
"@babel/helper-plugin-utils" "7.0.0-beta.47"
-"@babel/plugin-transform-template-literals@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz#084f1952efe5b153ddae69eb8945f882c7a97c65"
- integrity sha512-vA6rkTCabRZu7Nbl9DfLZE1imj4tzdWcg5vtdQGvj+OH9itNNB6hxuRMHuIY8SGnEt1T9g5foqs9LnrHzsqEFg==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.0.0"
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-typeof-symbol@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0.tgz#4dcf1e52e943e5267b7313bff347fdbe0f81cec9"
- integrity sha512-1r1X5DO78WnaAIvs5uC48t41LLckxsYklJrZjNKcevyz83sF2l4RHbw29qrCPr/6ksFsdfRpT/ZgxNWHXRnffg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-typescript@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.1.0.tgz#81e7b4be90e7317cbd04bf1163ebf06b2adee60b"
- integrity sha512-TOTtVeT+fekAesiCHnPz+PSkYSdOSLyLn42DI45nxg6iCdlQY6LIj/tYqpMB0y+YicoTUiYiXqF8rG6SKfhw6Q==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-syntax-typescript" "^7.0.0"
-
"@babel/plugin-transform-unicode-regex@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0-beta.47.tgz#efed0b2f1dfbf28283502234a95b4be88f7fdcb6"
@@ -1135,97 +607,6 @@
"@babel/helper-regex" "7.0.0-beta.47"
regexpu-core "^4.1.3"
-"@babel/plugin-transform-unicode-regex@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz#c6780e5b1863a76fe792d90eded9fcd5b51d68fc"
- integrity sha512-uJBrJhBOEa3D033P95nPHu3nbFwFE9ZgXsfEitzoIXIwqAZWk7uXcg06yFKXz9FSxBH5ucgU/cYdX0IV8ldHKw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-regex" "^7.0.0"
- regexpu-core "^4.1.3"
-
-"@babel/polyfill@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.0.0.tgz#c8ff65c9ec3be6a1ba10113ebd40e8750fb90bff"
- integrity sha512-dnrMRkyyr74CRelJwvgnnSUDh2ge2NCTyHVwpOdvRMHtJUyxLtMAfhBN3s64pY41zdw0kgiLPh6S20eb1NcX6Q==
- dependencies:
- core-js "^2.5.7"
- regenerator-runtime "^0.11.1"
-
-"@babel/preset-env@^7.1.5":
- version "7.1.5"
- resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.1.5.tgz#a28b5482ca8bc2f2d0712234d6c690240b92495d"
- integrity sha512-pQ+2o0YyCp98XG0ODOHJd9z4GsSoV5jicSedRwCrU8uiqcJahwQiOq0asSZEb/m/lwyu6X5INvH/DSiwnQKncw==
- dependencies:
- "@babel/helper-module-imports" "^7.0.0"
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-proposal-async-generator-functions" "^7.1.0"
- "@babel/plugin-proposal-json-strings" "^7.0.0"
- "@babel/plugin-proposal-object-rest-spread" "^7.0.0"
- "@babel/plugin-proposal-optional-catch-binding" "^7.0.0"
- "@babel/plugin-proposal-unicode-property-regex" "^7.0.0"
- "@babel/plugin-syntax-async-generators" "^7.0.0"
- "@babel/plugin-syntax-object-rest-spread" "^7.0.0"
- "@babel/plugin-syntax-optional-catch-binding" "^7.0.0"
- "@babel/plugin-transform-arrow-functions" "^7.0.0"
- "@babel/plugin-transform-async-to-generator" "^7.1.0"
- "@babel/plugin-transform-block-scoped-functions" "^7.0.0"
- "@babel/plugin-transform-block-scoping" "^7.1.5"
- "@babel/plugin-transform-classes" "^7.1.0"
- "@babel/plugin-transform-computed-properties" "^7.0.0"
- "@babel/plugin-transform-destructuring" "^7.0.0"
- "@babel/plugin-transform-dotall-regex" "^7.0.0"
- "@babel/plugin-transform-duplicate-keys" "^7.0.0"
- "@babel/plugin-transform-exponentiation-operator" "^7.1.0"
- "@babel/plugin-transform-for-of" "^7.0.0"
- "@babel/plugin-transform-function-name" "^7.1.0"
- "@babel/plugin-transform-literals" "^7.0.0"
- "@babel/plugin-transform-modules-amd" "^7.1.0"
- "@babel/plugin-transform-modules-commonjs" "^7.1.0"
- "@babel/plugin-transform-modules-systemjs" "^7.0.0"
- "@babel/plugin-transform-modules-umd" "^7.1.0"
- "@babel/plugin-transform-new-target" "^7.0.0"
- "@babel/plugin-transform-object-super" "^7.1.0"
- "@babel/plugin-transform-parameters" "^7.1.0"
- "@babel/plugin-transform-regenerator" "^7.0.0"
- "@babel/plugin-transform-shorthand-properties" "^7.0.0"
- "@babel/plugin-transform-spread" "^7.0.0"
- "@babel/plugin-transform-sticky-regex" "^7.0.0"
- "@babel/plugin-transform-template-literals" "^7.0.0"
- "@babel/plugin-transform-typeof-symbol" "^7.0.0"
- "@babel/plugin-transform-unicode-regex" "^7.0.0"
- browserslist "^4.1.0"
- invariant "^2.2.2"
- js-levenshtein "^1.1.3"
- semver "^5.3.0"
-
-"@babel/preset-flow@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.0.0.tgz#afd764835d9535ec63d8c7d4caf1c06457263da2"
- integrity sha512-bJOHrYOPqJZCkPVbG1Lot2r5OSsB+iUOaxiHdlOeB1yPWS6evswVHwvkDLZ54WTaTRIk89ds0iHmGZSnxlPejQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-transform-flow-strip-types" "^7.0.0"
-
-"@babel/preset-react@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.0.0.tgz#e86b4b3d99433c7b3e9e91747e2653958bc6b3c0"
- integrity sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-transform-react-display-name" "^7.0.0"
- "@babel/plugin-transform-react-jsx" "^7.0.0"
- "@babel/plugin-transform-react-jsx-self" "^7.0.0"
- "@babel/plugin-transform-react-jsx-source" "^7.0.0"
-
-"@babel/preset-typescript@^7.1.0":
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.1.0.tgz#49ad6e2084ff0bfb5f1f7fb3b5e76c434d442c7f"
- integrity sha512-LYveByuF9AOM8WrsNne5+N79k1YxjNB6gmpCQsnuSBAcV8QUeB+ZUxQzL7Rz7HksPbahymKkq2qBR+o36ggFZA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-transform-typescript" "^7.1.0"
-
"@babel/register@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.0.0-beta.47.tgz#ac53bc357ca59979db0e306aa5d3121aa612a7a2"
@@ -1239,19 +620,6 @@
pirates "^3.0.1"
source-map-support "^0.4.2"
-"@babel/register@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.0.0.tgz#fa634bae1bfa429f60615b754fc1f1d745edd827"
- integrity sha512-f/+CRmaCe7rVEvcvPvxeA8j5aJhHC3aJie7YuqcMDhUOuyWLA7J/aNrTaHIzoWPEhpHA54mec4Mm8fv8KBlv3g==
- dependencies:
- core-js "^2.5.7"
- find-cache-dir "^1.0.0"
- home-or-tmp "^3.0.0"
- lodash "^4.17.10"
- mkdirp "^0.5.1"
- pirates "^4.0.0"
- source-map-support "^0.5.9"
-
"@babel/runtime@^7.1.2":
version "7.1.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.5.tgz#4170907641cf1f61508f563ece3725150cc6fe39"
@@ -1294,7 +662,7 @@
invariant "^2.2.0"
lodash "^4.17.5"
-"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.5":
+"@babel/traverse@^7.1.5":
version "7.1.5"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.5.tgz#5aafca2039aa058c104cf2bfeb9fc4a857ccbca9"
integrity sha512-eU6XokWypl0MVJo+MTSPUtlfPePkrqsF26O+l1qFGlCKWwmiYAYy2Sy44Qw8m2u/LbPCsxYt90rghmqhYMGpPA==
@@ -1309,21 +677,6 @@
globals "^11.1.0"
lodash "^4.17.10"
-"@babel/traverse@^7.1.0":
- version "7.1.4"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.4.tgz#f4f83b93d649b4b2c91121a9087fa2fa949ec2b4"
- integrity sha512-my9mdrAIGdDiSVBuMjpn/oXYpva0/EZwWL3sm3Wcy/AVWO2eXnsoZruOT9jOGNRXU8KbCIu5zsKnXcAJ6PcV6Q==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- "@babel/generator" "^7.1.3"
- "@babel/helper-function-name" "^7.1.0"
- "@babel/helper-split-export-declaration" "^7.0.0"
- "@babel/parser" "^7.1.3"
- "@babel/types" "^7.1.3"
- debug "^3.1.0"
- globals "^11.1.0"
- lodash "^4.17.10"
-
"@babel/types@7.0.0-beta.47":
version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.47.tgz#e6fcc1a691459002c2671d558a586706dddaeef8"
@@ -1333,7 +686,7 @@
lodash "^4.17.5"
to-fast-properties "^2.0.0"
-"@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.3":
+"@babel/types@^7.0.0", "@babel/types@^7.1.2":
version "7.1.3"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.3.tgz#3a767004567060c2f40fca49a304712c525ee37d"
integrity sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==
@@ -1351,29 +704,6 @@
lodash "^4.17.10"
to-fast-properties "^2.0.0"
-"@gimenete/type-writer@^0.1.3":
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/@gimenete/type-writer/-/type-writer-0.1.3.tgz#2d4f26118b18d71f5b34ca24fdd6d1fd455c05b6"
- integrity sha512-vhpvVfM/fYqb1aAnkgOvtDKoOgU3ZYIvDnKSDAFSoBvallmGURMlHOE0/VG/gqunUZVXGCFBGHxI8swjBh+sIA==
- dependencies:
- camelcase "^5.0.0"
- prettier "^1.13.7"
-
-"@octokit/rest@^15.2.6":
- version "15.10.0"
- resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-15.10.0.tgz#9baf7430e55edf1a1024c35ae72ed2f5fc6e90e9"
- integrity sha512-xZ4ejCZoqvKrIN3tQOKZlJ6nDQxaOdLcjRsamDnbckU7V5YTn2xheIqFXnQ2vLvxqVwyI8+2dfsODYbHxtwtSw==
- dependencies:
- "@gimenete/type-writer" "^0.1.3"
- 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"
-
"@sinonjs/commons@^1.2.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.3.0.tgz#50a2754016b6f30a994ceda6d9a0a8c36adda849"
@@ -1400,7 +730,21 @@
resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-2.1.2.tgz#16947fce5f57258d01f1688fdc32723093c55d3f"
integrity sha512-ZwTHAlC9akprWDinwEPD4kOuwaYZlyMwVJIANsKNC3QVp0AHB04m7RnB4eqeWfgmxw8MGTzS9uMaw93Z3QcZbw==
-"@types/chai@^4.1.7":
+"@types/chai-as-promised@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.0.tgz#010b04cde78eacfb6e72bfddb3e58fe23c2e78b9"
+ integrity sha512-MFiW54UOSt+f2bRw8J7LgQeIvE/9b4oGvwU7XW30S9QGAiHGnU/fmiOprsyMkdmH2rl8xSPc0/yrQw8juXU6bQ==
+ dependencies:
+ "@types/chai" "*"
+
+"@types/chai-spies@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@types/chai-spies/-/chai-spies-1.0.0.tgz#1442daa924d2a8c3f20253db5e5e8fdd1fd4f229"
+ integrity sha512-Bj/froHomMnlAPEYEeqhmSuNSjTWW/VuSvCVdhLdcb67+dy4ffjTR6fC0YYw9tHP6KR3U8fkF1mgzmzlChHc5Q==
+ dependencies:
+ "@types/chai" "*"
+
+"@types/chai@*", "@types/chai@^4.1.7":
version "4.1.7"
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a"
integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==
@@ -1410,6 +754,13 @@
resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.9.tgz#b5990152604c2ada749b7f88cab3476f21f39d7b"
integrity sha512-q6LuBI0t5u04f0Q4/R+cGBqIbZMtJkVvCSF+nTfFBBdQqQvJR/mNHeWjRkszyLl7oyf2rDoKUYMEjTw5AV0hiw==
+"@types/d3-geo@^1.11.0":
+ version "1.11.0"
+ resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-1.11.0.tgz#f7921c5c50d1a43df928846d8a7e47140455687f"
+ integrity sha512-/IbMHRG9cur+6hkWvBrRg3DnnUWtaSW8Bl6nu1OO1J8K25BxRYyLslyjIBbwlK0kV0haztlAR2LCIRuDc/U2LA==
+ dependencies:
+ "@types/geojson" "*"
+
"@types/enzyme-adapter-react-16@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.0.3.tgz#0cf7025b036694ca8d596fe38f24162e7117acf1"
@@ -1433,6 +784,16 @@
"@types/cheerio" "*"
"@types/react" "*"
+"@types/geojson@*":
+ version "7946.0.5"
+ resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.5.tgz#9aea839ea5af4b1bc079f1d9fa977d48665e02b0"
+ integrity sha512-rLlMXpd3rdlrp0+xsrda/hFfOpIxgqFcRpk005UKbHtcdFK+QXAjhBAPnvO58qF4O1LdDXrcaiJxMgstCIlcaw==
+
+"@types/history@*":
+ version "4.7.2"
+ resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.2.tgz#0e670ea254d559241b6eeb3894f8754991e73220"
+ integrity sha512-ui3WwXmjTaY73fOQ3/m3nnajU/Orhi6cEu5rzX+BrAAJxa3eITXZ5ch9suPqtM03OWhAHhPSyBGCN4UKoxO20Q==
+
"@types/jsdom@^12.2.0":
version "12.2.0"
resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-12.2.0.tgz#e898ec448a8f9a7418f0456d57b72b6dd51599b4"
@@ -1442,10 +803,17 @@
"@types/tough-cookie" "*"
parse5 "^4.0.0"
-"@types/lodash@4.14.116":
- version "4.14.116"
- resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.116.tgz#5ccf215653e3e8c786a58390751033a9adca0eb9"
- integrity sha512-lRnAtKnxMXcYYXqOiotTmJd74uawNWuPnsnPrrO7HiFuE3npE2iQhfABatbYDyxTNqZNuXzcKGhw37R7RjBFLg==
+"@types/lodash@4.14.118":
+ version "4.14.118"
+ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.118.tgz#247bab39bfcc6d910d4927c6e06cbc70ec376f27"
+ integrity sha512-iiJbKLZbhSa6FYRip/9ZDX6HXhayXLDGY2Fqws9cOkEQ6XeKfaxB0sC541mowZJueYyMnVUmmG+al5/4fCDrgw==
+
+"@types/mkdirp@^0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f"
+ integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==
+ dependencies:
+ "@types/node" "*"
"@types/mocha@^5.2.5":
version "5.2.5"
@@ -1474,6 +842,11 @@
dependencies:
"@types/react" "*"
+"@types/rbush@^2.0.2":
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/@types/rbush/-/rbush-2.0.2.tgz#d297564680491973ab9dc5ec3afd7470487f530a"
+ integrity sha1-0pdWRoBJGXOrncXsOv10cEh/Uwo=
+
"@types/react-dom@16.0.7":
version "16.0.7"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.0.7.tgz#54d0f867a76b90597e8432030d297982f25c20ba"
@@ -1489,6 +862,22 @@
dependencies:
"@types/react" "*"
+"@types/react-redux@^7.0.0":
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.0.0.tgz#8aaba50fb43739462c40e65e85f96eb8a550d494"
+ integrity sha512-p5/vXqS4+Gq7EYzNv4SMi/yy7cM/BUbZORlPXY6F8wCyo5EfPa3Gpf6CEQX+UtbK5g2mqgERqVYyutzZYKIpaQ==
+ dependencies:
+ "@types/react" "*"
+ redux "^4.0.0"
+
+"@types/react-router@^4.4.3":
+ version "4.4.3"
+ resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-4.4.3.tgz#ea68b4021cb576866f83365b2201411537423d50"
+ integrity sha512-8GmjakEBFNCLJbpg9jtDp1EDvFP0VkIPPKBpVwmB3Q+9whFoHu8rluMUXUE5SoGkEQvVOtgJzWmUsJojNpFMQQ==
+ dependencies:
+ "@types/history" "*"
+ "@types/react" "*"
+
"@types/react@*":
version "16.4.11"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.4.11.tgz#330f3d864300f71150dc2d125e48644c098f8770"
@@ -1504,19 +893,23 @@
dependencies:
csstype "^2.2.0"
-"@types/react@^16.4.18":
- version "16.4.18"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-16.4.18.tgz#2e28a2e7f92d3fa7d6a65f2b73275c3e3138a13d"
- integrity sha512-eFzJKEg6pdeaukVLVZ8Xb79CTl/ysX+ExmOfAAqcFlCCK5TgFDD9kWR0S18sglQ3EmM8U+80enjUqbfnUyqpdA==
- dependencies:
- "@types/prop-types" "*"
- csstype "^2.2.0"
+"@types/sinon@^7.0.5":
+ version "7.0.5"
+ resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.0.5.tgz#f7dea19400c193a3b36a804a7f1f4b26dacf452b"
+ integrity sha512-4DShbH857bZVOY4tPi1RQJNrLcf89hEtU0klZ9aYTMbtt95Ok4XdPqqcbtGOHIbAHMLSzQP8Uw/6qtBBqyloww==
"@types/tough-cookie@*":
version "2.3.3"
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.3.tgz#7f226d67d654ec9070e755f46daebf014628e9d9"
integrity sha512-MDQLxNFRLasqS4UlkWMSACMKeSm1x4Q3TxzUC7KQUsh6RK1ZrQ0VEyE3yzXcBu+K8ejVj4wuX32eUG02yNp+YQ==
+"@types/uuid@^3.4.4":
+ version "3.4.4"
+ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.4.tgz#7af69360fa65ef0decb41fd150bf4ca5c0cefdf5"
+ integrity sha512-tPIgT0GUmdJQNSHxp0X2jnpQfBSTfGxUMc/2CXBU2mnyTFVYVa2ojpoQ74w0U2yn2vw3jnC640+77lkFFpdVDw==
+ dependencies:
+ "@types/node" "*"
+
JSONStream@^1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
@@ -1556,23 +949,11 @@ acorn-globals@^4.3.0:
acorn "^6.0.1"
acorn-walk "^6.0.1"
-acorn-jsx@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e"
- integrity sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==
- dependencies:
- acorn "^5.0.3"
-
acorn-walk@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.0.tgz#c957f4a1460da46af4a0388ce28b4c99355b0cbc"
integrity sha512-ugTb7Lq7u4GfWSqqpwE0bGyoBZNMTok/zDBXxfEG0QM50jNlGhIWjRC1pPN7bvV1anhF+bs+/gNcRw+o55Evbg==
-acorn@^5.0.3, acorn@^5.6.0:
- version "5.7.1"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8"
- integrity sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==
-
acorn@^6.0.1, acorn@^6.0.2:
version "6.0.4"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754"
@@ -1583,14 +964,7 @@ after@0.8.2:
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=
-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"
- integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==
- dependencies:
- es6-promisify "^5.0.0"
-
-ajv-keywords@^3.0.0, ajv-keywords@^3.2.0:
+ajv-keywords@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a"
integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=
@@ -1605,7 +979,7 @@ ajv@^5.3.0:
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
-ajv@^6.0.1, ajv@^6.5.2:
+ajv@^6.5.2:
version "6.5.3"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9"
integrity sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==
@@ -1615,16 +989,6 @@ ajv@^6.0.1, ajv@^6.5.2:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
-ajv@^6.5.3:
- version "6.5.5"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1"
- integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg==
- dependencies:
- fast-deep-equal "^2.0.1"
- fast-json-stable-stringify "^2.0.0"
- 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"
@@ -1815,14 +1179,6 @@ array-from@^2.1.1:
resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195"
integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=
-array-includes@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d"
- integrity sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=
- dependencies:
- define-properties "^1.1.2"
- es-abstract "^1.7.0"
-
array-map@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
@@ -1838,18 +1194,6 @@ array-slice@^0.2.3:
resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5"
integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU=
-array-union@^1.0.1:
- 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.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
@@ -2012,18 +1356,6 @@ babel-core@^6.24.1, babel-core@^6.26.0, babel-core@^6.7.2:
slash "^1.0.0"
source-map "^0.5.7"
-babel-eslint@^10.0.1:
- version "10.0.1"
- resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed"
- integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- "@babel/parser" "^7.0.0"
- "@babel/traverse" "^7.0.0"
- "@babel/types" "^7.0.0"
- eslint-scope "3.7.1"
- eslint-visitor-keys "^1.0.0"
-
babel-generator@^6.26.0:
version "6.26.1"
resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90"
@@ -2389,15 +1721,6 @@ babel-plugin-transform-strict-mode@^6.24.1:
babel-runtime "^6.22.0"
babel-types "^6.24.1"
-babel-polyfill@^6.26.0:
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153"
- integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=
- dependencies:
- babel-runtime "^6.26.0"
- core-js "^2.5.0"
- regenerator-runtime "^0.10.5"
-
babel-preset-es2015-node@^6.1.1:
version "6.1.1"
resolved "https://registry.yarnpkg.com/babel-preset-es2015-node/-/babel-preset-es2015-node-6.1.1.tgz#60b23157024b0cfebf3a63554cb05ee035b4e55f"
@@ -2614,11 +1937,6 @@ 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"
- integrity sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==
-
better-assert@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522"
@@ -2626,7 +1944,7 @@ better-assert@~1.0.0:
dependencies:
callsite "1.0.0"
-big-integer@^1.6.17, big-integer@^1.6.7:
+big-integer@^1.6.7:
version "1.6.34"
resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.34.tgz#701affc8f0d73c490930a6b482dc23ed6ffc7484"
integrity sha512-+w6B0Uo0ZvTSzDkXjoBCTNK0oe+aVL+yPi7kwGZm8hd8+Nj1AFPoxoq1Bl/mEu/G/ivOkUc1LRqVR0XeWFUzuA==
@@ -2636,14 +1954,6 @@ binary-extensions@^1.0.0:
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205"
integrity sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=
-binary@~0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79"
- integrity sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=
- dependencies:
- buffers "~0.1.1"
- chainsaw "~0.1.0"
-
blob@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921"
@@ -2661,11 +1971,6 @@ bluebird@^3.5.0, bluebird@^3.5.1:
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
integrity sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==
-bluebird@~3.4.1:
- version "3.4.7"
- resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3"
- integrity sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=
-
boolbase@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
@@ -2799,15 +2104,6 @@ browser-sync@^2.26.3:
ua-parser-js "0.7.17"
yargs "6.4.0"
-browserslist@^4.1.0:
- version "4.3.2"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.2.tgz#a5479f20fd387357be2d01aefcbbdcaadffb4d75"
- integrity sha512-wgZJWlYcDvsjRtf8socmAHf1nXq88KrQLB/gMYHGPUc2bzPWsgltSXwPWYHx4Sw0G9E/XGNW5wJDaWlpHRMpjA==
- dependencies:
- caniuse-lite "^1.0.30000898"
- electron-to-chromium "^1.3.80"
- node-releases "^1.0.0-alpha.14"
-
bs-recipes@1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/bs-recipes/-/bs-recipes-1.3.4.tgz#0d2d4d48a718c8c044769fdc4f89592dc8b69585"
@@ -2825,11 +2121,6 @@ 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"
- integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc=
-
buffer-alloc-unsafe@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
@@ -2853,21 +2144,6 @@ buffer-from@^1.0.0, buffer-from@^1.1.0:
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
-buffer-indexof-polyfill@~1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.1.tgz#a9fb806ce8145d5428510ce72f278bb363a638bf"
- integrity sha1-qfuAbOgUXVQoUQznLyeLs2OmOL8=
-
-buffer-shims@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51"
- integrity sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=
-
-buffers@~0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb"
- integrity sha1-skV5w77U1tOWru5tmorn9Ugqt7s=
-
builder-util-runtime@4.4.1, builder-util-runtime@^4.4.1:
version "4.4.1"
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-4.4.1.tgz#2770d03241e51fde46acacc7ed3ed8a9f45f02cb"
@@ -2923,23 +2199,11 @@ cache-base@^1.0.1:
union-value "^1.0.0"
unset-value "^1.0.0"
-caller-path@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
- integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=
- dependencies:
- callsites "^0.2.0"
-
callsite@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA=
-callsites@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
- integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=
-
camelcase-keys@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
@@ -2963,16 +2227,6 @@ camelcase@^4.0.0, camelcase@^4.1.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
-camelcase@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42"
- integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==
-
-caniuse-lite@^1.0.30000898:
- version "1.0.30000898"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000898.tgz#651306e690ca83caca5814da5afa3eb4de0f86c2"
- integrity sha512-ytlTZqO4hYe4rNAJhMynUAIUI33jsP2Bb1two/9OVC39wZjPZ8exIO0eCLw5mqAtegOGiGF0kkTWTn3B02L+mw==
-
capture-exit@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f"
@@ -3014,13 +2268,6 @@ chai@^4.2.0:
pathval "^1.1.0"
type-detect "^4.0.5"
-chainsaw@~0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98"
- integrity sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=
- dependencies:
- traverse ">=0.3.0 <0.4"
-
chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@@ -3046,16 +2293,6 @@ chardet@^0.4.0:
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=
-chardet@^0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
- integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
-
-charenc@~0.0.1:
- version "0.0.2"
- resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
- integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
-
check-error@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
@@ -3108,11 +2345,6 @@ ci-info@^1.3.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.4.0.tgz#4841d53cad49f11b827b648ebde27a6e189b412f"
integrity sha512-Oqmw2pVfCl8sCL+1QgMywPfdxPJPkC51y4usw0iiE2S9qnEOAqXy8bwl1CpMpnoU39g4iKJTz6QZj+28FvOnjQ==
-circular-json@^0.3.1:
- version "0.3.3"
- resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
- integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==
-
class-utils@^0.3.5:
version "0.3.6"
resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
@@ -3203,11 +2435,6 @@ colors@0.5.x:
resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774"
integrity sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q=
-colors@^1.1.2:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.2.tgz#2df8ff573dfbf255af562f8ce7181d6b971a359b"
- integrity sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ==
-
combined-stream@1.0.6, combined-stream@~1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
@@ -3355,7 +2582,7 @@ core-js@^1.0.0:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
-core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0, core-js@^2.5.3, core-js@^2.5.7:
+core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0, core-js@^2.5.3:
version "2.5.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e"
integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==
@@ -3414,11 +2641,6 @@ cross-unzip@0.0.2:
resolved "https://registry.yarnpkg.com/cross-unzip/-/cross-unzip-0.0.2.tgz#5183bc47a09559befcf98cc4657964999359372f"
integrity sha1-UYO8R6CVWb78+YzEZXlkmZNZNy8=
-crypt@~0.0.1:
- version "0.0.2"
- resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
- integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
-
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"
@@ -3542,13 +2764,6 @@ debug@^3.0.0:
dependencies:
ms "^2.1.1"
-debug@^4.0.1:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87"
- integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==
- dependencies:
- ms "^2.1.1"
-
decamelize@^1.1.1, decamelize@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
@@ -3566,13 +2781,6 @@ decode-uri-component@^0.2.0:
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
-decompress-response@^3.2.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
- integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
- dependencies:
- mimic-response "^1.0.0"
-
deep-eql@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df"
@@ -3619,19 +2827,6 @@ define-property@^2.0.2:
is-descriptor "^1.0.2"
isobject "^3.0.1"
-del@^2.0.2:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
- integrity sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=
- dependencies:
- globby "^5.0.0"
- is-path-cwd "^1.0.0"
- is-path-in-cwd "^1.0.0"
- object-assign "^4.0.1"
- pify "^2.0.0"
- pinkie-promise "^2.0.0"
- rimraf "^2.2.8"
-
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
@@ -3703,13 +2898,6 @@ dmg-builder@5.3.0:
parse-color "^1.0.0"
sanitize-filename "^1.6.1"
-doctrine@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
- integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
- dependencies:
- esutils "^2.0.2"
-
dom-serializer@0, dom-serializer@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
@@ -3780,13 +2968,6 @@ dotenv@^6.0.0:
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.0.0.tgz#24e37c041741c5f4b25324958ebbc34bca965935"
integrity sha512-FlWbnhgjtwD+uNLUGHbMykMOYQaTivdHEmYwAKFjn6GKe/CqY0fNae93ZHTd20snh9ZLr8mTzIL9m0APQ1pjQg==
-duplexer2@~0.1.4:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
- integrity sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=
- dependencies:
- readable-stream "^2.0.2"
-
duplexer3@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
@@ -3914,11 +3095,6 @@ electron-publish@20.28.0:
lazy-val "^1.0.3"
mime "^2.3.1"
-electron-to-chromium@^1.3.80:
- version "1.3.81"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.81.tgz#32af69206ef78973b6a6771b0c8450c2ce253913"
- integrity sha512-+rym2xtzwPWmoi8AYRrCdW65QOT0vfUHjZb5mjgh0VLyj31pGM3CpP3znKhQNBzQaWujR/KEl/mfC2lnKYgADA==
-
electron-window@^0.8.0:
version "0.8.1"
resolved "https://registry.yarnpkg.com/electron-window/-/electron-window-0.8.1.tgz#16ca187eb4870b0679274fc8299c5960e6ab2c5e"
@@ -4065,7 +3241,7 @@ errorhandler@^1.5.0:
accepts "~1.3.3"
escape-html "~1.0.3"
-es-abstract@^1.10.0, es-abstract@^1.4.3, es-abstract@^1.5.0, es-abstract@^1.6.1, es-abstract@^1.7.0:
+es-abstract@^1.10.0, es-abstract@^1.4.3, es-abstract@^1.5.0, es-abstract@^1.6.1:
version "1.12.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165"
integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==
@@ -4085,18 +3261,6 @@ es-to-primitive@^1.1.1:
is-date-object "^1.0.1"
is-symbol "^1.0.1"
-es6-promise@^4.0.3:
- version "4.2.4"
- resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29"
- integrity sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==
-
-es6-promisify@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
- integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
- dependencies:
- es6-promise "^4.0.3"
-
escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
@@ -4119,114 +3283,6 @@ escodegen@^1.11.0:
optionalDependencies:
source-map "~0.6.1"
-eslint-config-prettier@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.1.0.tgz#2c26d2cdcfa3a05f0642cd7e6e4ef3316cdabfa2"
- integrity sha512-QYGfmzuc4q4J6XIhlp8vRKdI/fI0tQfQPy1dME3UOLprE+v4ssH/3W9LM2Q7h5qBcy5m0ehCrBDU2YF8q6OY8w==
- dependencies:
- get-stdin "^6.0.0"
-
-eslint-plugin-flowtype@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-3.2.0.tgz#824364ed5940a404b91326fdb5a313a2a74760df"
- integrity sha512-baJmzngM6UKbEkJ5OY3aGw2zjXBt5L2QKZvTsOlXX7yHKIjNRrlJx2ods8Rng6EdqPR9rVNIQNYHpTs0qfn2qA==
- dependencies:
- lodash "^4.17.10"
-
-eslint-plugin-promise@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2"
- integrity sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg==
-
-eslint-plugin-react@^7.10.0:
- version "7.11.1"
- resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz#c01a7af6f17519457d6116aa94fc6d2ccad5443c"
- integrity sha512-cVVyMadRyW7qsIUh3FHp3u6QHNhOgVrLQYdQEB1bPWBsgbNCHdFAeNMquBMCcZJu59eNthX053L70l7gRt4SCw==
- dependencies:
- array-includes "^3.0.3"
- doctrine "^2.1.0"
- has "^1.0.3"
- jsx-ast-utils "^2.0.1"
- prop-types "^15.6.2"
-
-eslint-scope@3.7.1:
- version "3.7.1"
- resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
- integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=
- dependencies:
- esrecurse "^4.1.0"
- estraverse "^4.1.1"
-
-eslint-scope@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172"
- integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==
- dependencies:
- esrecurse "^4.1.0"
- estraverse "^4.1.1"
-
-eslint-utils@^1.3.1:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512"
- integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==
-
-eslint-visitor-keys@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
- integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==
-
-eslint@^5.8.0:
- version "5.8.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.8.0.tgz#91fbf24f6e0471e8fdf681a4d9dd1b2c9f28309b"
- integrity sha512-Zok6Bru3y2JprqTNm14mgQ15YQu/SMDkWdnmHfFg770DIUlmMFd/gqqzCHekxzjHZJxXv3tmTpH0C1icaYJsRQ==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- ajv "^6.5.3"
- chalk "^2.1.0"
- cross-spawn "^6.0.5"
- debug "^4.0.1"
- doctrine "^2.1.0"
- eslint-scope "^4.0.0"
- eslint-utils "^1.3.1"
- eslint-visitor-keys "^1.0.0"
- espree "^4.0.0"
- esquery "^1.0.1"
- esutils "^2.0.2"
- file-entry-cache "^2.0.0"
- functional-red-black-tree "^1.0.1"
- glob "^7.1.2"
- globals "^11.7.0"
- ignore "^4.0.6"
- imurmurhash "^0.1.4"
- inquirer "^6.1.0"
- is-resolvable "^1.1.0"
- js-yaml "^3.12.0"
- json-stable-stringify-without-jsonify "^1.0.1"
- levn "^0.3.0"
- lodash "^4.17.5"
- minimatch "^3.0.4"
- mkdirp "^0.5.1"
- natural-compare "^1.4.0"
- optionator "^0.8.2"
- path-is-inside "^1.0.2"
- pluralize "^7.0.0"
- progress "^2.0.0"
- regexpp "^2.0.1"
- require-uncached "^1.0.3"
- semver "^5.5.1"
- strip-ansi "^4.0.0"
- strip-json-comments "^2.0.1"
- table "^5.0.2"
- text-table "^0.2.0"
-
-espree@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/espree/-/espree-4.0.0.tgz#253998f20a0f82db5d866385799d912a83a36634"
- integrity sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg==
- dependencies:
- acorn "^5.6.0"
- acorn-jsx "^4.1.1"
-
esprima@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
@@ -4237,21 +3293,7 @@ esprima@^4.0.0:
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
-esquery@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708"
- integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==
- dependencies:
- estraverse "^4.0.0"
-
-esrecurse@^4.1.0:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
- integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==
- dependencies:
- estraverse "^4.1.0"
-
-estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
+estraverse@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=
@@ -4377,15 +3419,6 @@ external-editor@^2.0.4:
iconv-lite "^0.4.17"
tmp "^0.0.33"
-external-editor@^3.0.0:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27"
- integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==
- dependencies:
- chardet "^0.7.0"
- iconv-lite "^0.4.24"
- tmp "^0.0.33"
-
extglob@^0.3.1:
version "0.3.2"
resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
@@ -4519,14 +3552,6 @@ figures@^2.0.0:
dependencies:
escape-string-regexp "^1.0.5"
-file-entry-cache@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361"
- integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=
- dependencies:
- flat-cache "^1.2.1"
- object-assign "^4.0.1"
-
filename-regex@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
@@ -4597,42 +3622,6 @@ find-up@^3.0.0:
dependencies:
locate-path "^3.0.0"
-flat-cache@^1.2.1:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481"
- integrity sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=
- dependencies:
- circular-json "^0.3.1"
- del "^2.0.2"
- graceful-fs "^4.1.2"
- write "^0.2.1"
-
-flow-bin@0.82:
- version "0.82.0"
- resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.82.0.tgz#fbec84c0d6cab7877565eca8214d655f3aefb8db"
- integrity sha512-D7ViTCVJSVv19CB6dFWS9k2iKQlavtkRXn9el0ofVTTpGuybe+EPE8DZwdyohzEt6wRhHV8gwkteWvxdcVuOzg==
-
-flow-typed@^2.5.1:
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/flow-typed/-/flow-typed-2.5.1.tgz#0ff565cc94d2af8c557744ba364b6f14726a6b9f"
- integrity sha1-D/VlzJTSr4xVd0S6NktvFHJqa58=
- dependencies:
- "@octokit/rest" "^15.2.6"
- babel-polyfill "^6.26.0"
- colors "^1.1.2"
- fs-extra "^5.0.0"
- glob "^7.1.2"
- got "^7.1.0"
- md5 "^2.1.0"
- mkdirp "^0.5.1"
- rimraf "^2.6.2"
- semver "^5.5.0"
- table "^4.0.2"
- through "^2.3.8"
- unzipper "^0.8.11"
- which "^1.3.0"
- yargs "^4.2.0"
-
follow-redirects@^1.2.5:
version "1.5.7"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.7.tgz#a39e4804dacb90202bca76a9e2ac10433ca6a69a"
@@ -4718,15 +3707,6 @@ fs-extra@^4.0.1:
jsonfile "^4.0.0"
universalify "^0.1.0"
-fs-extra@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd"
- integrity sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==
- dependencies:
- graceful-fs "^4.1.2"
- jsonfile "^4.0.0"
- universalify "^0.1.0"
-
fs-extra@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b"
@@ -4743,7 +3723,7 @@ fs-minipass@^1.2.5:
dependencies:
minipass "^2.2.1"
-fs-readdir-recursive@^1.0.0, fs-readdir-recursive@^1.1.0:
+fs-readdir-recursive@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==
@@ -4761,16 +3741,6 @@ fsevents@^1.2.2, fsevents@^1.2.3:
nan "^2.9.2"
node-pre-gyp "^0.10.0"
-fstream@~1.0.10:
- version "1.0.11"
- resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171"
- integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=
- dependencies:
- graceful-fs "^4.1.2"
- inherits "~2.0.0"
- mkdirp ">=0.5 0"
- rimraf "2"
-
function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
@@ -4785,11 +3755,6 @@ function.prototype.name@^1.1.0:
function-bind "^1.1.1"
is-callable "^1.1.3"
-functional-red-black-tree@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
- integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
-
gauge@~1.2.5:
version "1.2.7"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93"
@@ -4830,11 +3795,6 @@ get-stdin@^4.0.1:
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=
-get-stdin@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b"
- integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==
-
get-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
@@ -4875,7 +3835,7 @@ glob-parent@^3.1.0:
is-glob "^3.1.0"
path-dirname "^1.0.0"
-glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2:
+glob@7.1.2, glob@^7.0.0, glob@^7.0.5, glob@^7.1.1:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==
@@ -4902,7 +3862,7 @@ global@^4.3.0:
min-document "^2.19.0"
process "~0.5.1"
-globals@^11.1.0, globals@^11.7.0:
+globals@^11.1.0:
version "11.7.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673"
integrity sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==
@@ -4912,18 +3872,6 @@ globals@^9.18.0:
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==
-globby@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d"
- integrity sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=
- dependencies:
- array-union "^1.0.1"
- arrify "^1.0.0"
- glob "^7.0.3"
- object-assign "^4.0.1"
- pify "^2.0.0"
- pinkie-promise "^2.0.0"
-
got@^6.7.1:
version "6.7.1"
resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
@@ -4941,26 +3889,6 @@ got@^6.7.1:
unzip-response "^2.0.1"
url-parse-lax "^1.0.0"
-got@^7.1.0:
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a"
- integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==
- dependencies:
- decompress-response "^3.2.0"
- duplexer3 "^0.1.4"
- get-stream "^3.0.0"
- is-plain-obj "^1.1.0"
- is-retry-allowed "^1.0.0"
- is-stream "^1.0.0"
- isurl "^1.0.0-alpha5"
- lowercase-keys "^1.0.0"
- p-cancelable "^0.3.0"
- p-timeout "^1.1.1"
- safe-buffer "^5.0.1"
- timed-out "^4.0.0"
- url-parse-lax "^1.0.0"
- url-to-options "^1.0.1"
-
graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
@@ -5013,23 +3941,11 @@ has-flag@^3.0.0:
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
-has-symbol-support-x@^1.4.1:
- version "1.4.2"
- resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455"
- integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==
-
has-symbols@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=
-has-to-string-tag-x@^1.2.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d"
- integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==
- dependencies:
- has-symbol-support-x "^1.4.1"
-
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -5114,13 +4030,6 @@ home-or-tmp@^3.0.0:
resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-3.0.0.tgz#57a8fe24cf33cdd524860a15821ddc25c86671fb"
integrity sha1-V6j+JM8zzdUkhgoVgh3cJchmcfs=
-homedir-polyfill@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc"
- integrity sha1-TCu8inWJmP7r9e1oWA921GdotLw=
- dependencies:
- parse-passwd "^1.0.0"
-
hosted-git-info@^2.1.4, hosted-git-info@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047"
@@ -5155,14 +4064,6 @@ http-errors@1.6.3, http-errors@~1.6.2:
setprototypeof "1.1.0"
statuses ">= 1.4.0 < 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"
- integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==
- dependencies:
- agent-base "4"
- debug "3.1.0"
-
http-proxy@1.15.2:
version "1.15.2"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.15.2.tgz#642fdcaffe52d3448d2bda3b0079e9409064da31"
@@ -5180,14 +4081,6 @@ http-signature@~1.2.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
-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"
- integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==
- dependencies:
- agent-base "^4.1.0"
- debug "^3.1.0"
-
iconv-lite@0.4.23:
version "0.4.23"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
@@ -5195,7 +4088,7 @@ iconv-lite@0.4.23:
dependencies:
safer-buffer ">= 2.1.2 < 3"
-iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.23, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
+iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.23, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@@ -5209,11 +4102,6 @@ ignore-walk@^3.0.1:
dependencies:
minimatch "^3.0.4"
-ignore@^4.0.6:
- version "4.0.6"
- resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
- integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
-
image-size@^0.6.0:
version "0.6.3"
resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.3.tgz#e7e5c65bb534bd7cdcedd6cb5166272a85f75fb2"
@@ -5259,7 +4147,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
+inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
@@ -5294,25 +4182,6 @@ inquirer@^3.0.6:
strip-ansi "^4.0.0"
through "^2.3.6"
-inquirer@^6.1.0:
- version "6.2.0"
- resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8"
- integrity sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg==
- dependencies:
- ansi-escapes "^3.0.0"
- chalk "^2.0.0"
- cli-cursor "^2.1.0"
- cli-width "^2.0.0"
- external-editor "^3.0.0"
- figures "^2.0.0"
- lodash "^4.17.10"
- mute-stream "0.0.7"
- run-async "^2.2.0"
- rxjs "^6.1.0"
- string-width "^2.1.0"
- strip-ansi "^4.0.0"
- through "^2.3.6"
-
invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
@@ -5356,7 +4225,7 @@ is-boolean-object@^1.0.0:
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"
integrity sha1-mPiygDBoQhmpXzdc+9iM40Bd/5M=
-is-buffer@^1.1.5, is-buffer@~1.1.1:
+is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
@@ -5545,23 +4414,6 @@ is-obj@^1.0.0:
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
-is-object@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
- integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA=
-
-is-path-cwd@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
- integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=
-
-is-path-in-cwd@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52"
- integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==
- dependencies:
- is-path-inside "^1.0.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"
@@ -5608,11 +4460,6 @@ is-regex@^1.0.4:
dependencies:
has "^1.0.1"
-is-resolvable@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
- integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==
-
is-retry-allowed@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
@@ -5710,14 +4557,6 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
-isurl@^1.0.0-alpha5:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
- integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==
- dependencies:
- has-to-string-tag-x "^1.2.0"
- is-object "^1.0.1"
-
jest-docblock@23.0.1:
version "23.0.1"
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.0.1.tgz#deddd18333be5dc2415260a04ef3fce9276b5725"
@@ -5764,11 +4603,6 @@ jest-worker@^23.0.1:
dependencies:
merge-stream "^1.0.1"
-js-levenshtein@^1.1.3:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.4.tgz#3a56e3cbf589ca0081eb22cd9ba0b1290a16d26e"
- integrity sha512-PxfGzSs0ztShKrUYPIn5r0MtyAhYcCwmndozzpz8YObbPnD1jFxzlBGbRnX2mIu6Z13xN6+PTu05TQFnZFlzow==
-
js-tokens@^3.0.0, js-tokens@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
@@ -5859,11 +4693,6 @@ json-schema@0.2.3:
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
-json-stable-stringify-without-jsonify@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
- integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
-
json-stable-stringify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
@@ -5939,13 +4768,6 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"
-jsx-ast-utils@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f"
- integrity sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=
- dependencies:
- array-includes "^3.0.3"
-
just-extend@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-3.0.0.tgz#cee004031eaabf6406da03a7b84e4fe9d78ef288"
@@ -6016,7 +4838,7 @@ levenshtein-edit-distance@^2.0.2:
resolved "https://registry.yarnpkg.com/levenshtein-edit-distance/-/levenshtein-edit-distance-2.0.3.tgz#30b8d8b9ad94eabd4f8a9f5a10e2fd1f28c84bee"
integrity sha512-m/SHpXjfKnArO8E9/o5Fd5+N4TLHU/72+zk4s7OpowBGmZK5MqAsuQ0xuYDftIyXyfqU99dmeMfpujWxo8FIJg==
-levn@^0.3.0, levn@~0.3.0:
+levn@~0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=
@@ -6029,11 +4851,6 @@ limiter@^1.0.5:
resolved "https://registry.yarnpkg.com/limiter/-/limiter-1.1.3.tgz#32e2eb55b2324076943e5d04c1185ffb387968ef"
integrity sha512-zrycnIMsLw/3ZxTbW7HCez56rcFGecWTx5OZNplzcXUUmJLmoYArC6qdJzmAN5BWiNXGcpjhF9RQ1HSv5zebEw==
-listenercount@~1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937"
- integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=
-
load-json-file@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
@@ -6091,11 +4908,6 @@ locate-path@^3.0.0:
p-locate "^3.0.0"
path-exists "^3.0.0"
-lodash.assign@^4.0.3, lodash.assign@^4.0.6:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
- integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=
-
lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
@@ -6156,6 +4968,11 @@ lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5,
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
integrity sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==
+lodash@^4.17.11:
+ version "4.17.11"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
+ integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
+
lolex@^2.3.2:
version "2.7.5"
resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.5.tgz#113001d56bfc7e02d56e36291cc5c413d1aa0733"
@@ -6240,15 +5057,6 @@ math-random@^1.0.1:
resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac"
integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w=
-md5@^2.1.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"
- integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=
- dependencies:
- charenc "~0.0.1"
- crypt "~0.0.1"
- is-buffer "~1.1.1"
-
mem@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76"
@@ -6543,11 +5351,6 @@ mimic-fn@^1.0.0:
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
-mimic-response@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
- integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
-
min-document@^2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
@@ -6605,7 +5408,7 @@ mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
-mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1:
+mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
@@ -6694,11 +5497,6 @@ nanomatch@^1.2.9:
snapdragon "^0.8.1"
to-regex "^3.0.1"
-natural-compare@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
- integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
-
nearley@^2.7.10:
version "2.15.1"
resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.15.1.tgz#965e4e6ec9ed6b80fc81453e161efbcebb36d247"
@@ -6748,11 +5546,6 @@ node-fetch@^1.0.1, node-fetch@^1.3.3:
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"
- integrity sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA==
-
node-int64@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
@@ -6805,13 +5598,6 @@ node-pre-gyp@^0.11.0:
semver "^5.3.0"
tar "^4"
-node-releases@^1.0.0-alpha.14:
- version "1.0.0-alpha.15"
- resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.0-alpha.15.tgz#bdb08730287cc50ddbfa3c1a358366a4a2f5d397"
- integrity sha512-hKG6hd/g6a9OV/ARt2qrxbRhe/4WEMFohTLOB9PNyTYvvI59gICZFzt9/mMgpYUTts06qXlN8H6UjfbIRdnW8A==
- dependencies:
- semver "^5.3.0"
-
nomnom@~1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.6.2.tgz#84a66a260174408fc5b77a18f888eccc44fb6971"
@@ -7089,7 +5875,7 @@ optimist@^0.6.1:
minimist "~0.0.1"
wordwrap "~0.0.2"
-optionator@^0.8.1, optionator@^0.8.2:
+optionator@^0.8.1:
version "0.8.2"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=
@@ -7149,11 +5935,6 @@ output-file-sync@^2.0.0:
is-plain-obj "^1.1.0"
mkdirp "^0.5.1"
-p-cancelable@^0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"
- integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==
-
p-finally@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
@@ -7187,13 +5968,6 @@ p-locate@^3.0.0:
dependencies:
p-limit "^2.0.0"
-p-timeout@^1.1.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386"
- integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=
- dependencies:
- p-finally "^1.0.0"
-
p-try@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
@@ -7246,11 +6020,6 @@ parse-json@^4.0.0:
error-ex "^1.3.1"
json-parse-better-errors "^1.0.1"
-parse-passwd@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
- integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=
-
parse5@5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2"
@@ -7314,7 +6083,7 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1:
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, path-is-inside@^1.0.2:
+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=
@@ -7415,13 +6184,6 @@ pirates@^3.0.1:
dependencies:
node-modules-regexp "^1.0.0"
-pirates@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.0.tgz#850b18781b4ac6ec58a43c9ed9ec5fe6796addbd"
- integrity sha512-8t5BsXy1LUIjn3WWOlOuFDuKswhQb/tkak641lvBgmPOBUQHXveORtlMCp6OdPV1dtuTaEahKA8VNz6uLfKBtA==
- dependencies:
- node-modules-regexp "^1.0.0"
-
pkg-dir@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
@@ -7467,11 +6229,6 @@ plugin-error@^0.1.2:
arr-union "^2.0.1"
extend-shallow "^1.1.2"
-pluralize@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
- integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==
-
pn@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
@@ -7510,11 +6267,6 @@ prettier@1.15.3:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a"
integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==
-prettier@^1.13.7:
- version "1.14.2"
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.2.tgz#0ac1c6e1a90baa22a62925f41963c841983282f9"
- integrity sha512-McHPg0n1pIke+A/4VcaS2en+pTNjy4xF+Uuq86u/5dyDO59/TtFZtQ708QIRkEZ3qwKz3GVkVa6mpxK/CpB8Rg==
-
pretty-bytes@^1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-1.0.4.tgz#0a22e8210609ad35542f8c8d5d2159aff0751c84"
@@ -7533,11 +6285,6 @@ private@^0.1.6, private@^0.1.8:
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==
-process-nextick-args@~1.0.6:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
- integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=
-
process-nextick-args@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
@@ -7556,11 +6303,6 @@ progress-stream@^1.1.0:
speedometer "~0.1.2"
through2 "~0.2.3"
-progress@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
- integrity sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=
-
promise@^7.1.1:
version "7.3.1"
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
@@ -7702,15 +6444,15 @@ react-devtools-core@^3.2.2:
shell-quote "^1.6.1"
ws "^3.3.1"
-react-dom@^16.4.0:
- version "16.4.2"
- resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.4.2.tgz#4afed569689f2c561d2b8da0b819669c38a0bda4"
- integrity sha512-Usl73nQqzvmJN+89r97zmeUpQDKDlh58eX6Hbs/ERdDHzeBzWy+ENk7fsGQ+5KxArV1iOFPT46/VneklK9zoWw==
+react-dom@^16.5.0:
+ version "16.7.0"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0.tgz#a17b2a7ca89ee7390bc1ed5eb81783c7461748b8"
+ integrity sha512-D0Ufv1ExCAmF38P2Uh1lwpminZFRXEINJe53zRAbm4KPwSyd6DY/uDoS0Blj9jvPpn1+wivKpZYc8aAAN/nAkg==
dependencies:
- fbjs "^0.8.16"
loose-envify "^1.1.0"
object-assign "^4.1.1"
- prop-types "^15.6.0"
+ prop-types "^15.6.2"
+ scheduler "^0.12.0"
react-is@^16.3.2, react-is@^16.6.0, react-is@^16.6.1:
version "16.6.1"
@@ -7850,27 +6592,27 @@ react-transform-hmr@^1.0.4:
global "^4.3.0"
react-proxy "^1.1.7"
-react@^16.4.0:
- version "16.4.2"
- resolved "https://registry.yarnpkg.com/react/-/react-16.4.2.tgz#2cd90154e3a9d9dd8da2991149fdca3c260e129f"
- integrity sha512-dMv7YrbxO4y2aqnvA7f/ik9ibeLSHQJTI6TrYAenPSaQ6OXfb+Oti+oJiy8WBxgRzlKatYqtCjphTgDSCEiWFg==
+react@^16.5.0:
+ version "16.7.0"
+ resolved "https://registry.yarnpkg.com/react/-/react-16.7.0.tgz#b674ec396b0a5715873b350446f7ea0802ab6381"
+ integrity sha512-StCz3QY8lxTb5cl2HJxjwLFOXPIFQp+p+hxQfc8WE0QiLfCtIlKj8/+5tjjKm8uSTlAW+fCPaavGFS06V9Ar3A==
dependencies:
- fbjs "^0.8.16"
loose-envify "^1.1.0"
object-assign "^4.1.1"
- prop-types "^15.6.0"
+ prop-types "^15.6.2"
+ scheduler "^0.12.0"
-reactxp@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/reactxp/-/reactxp-1.4.0.tgz#35a308819ee5cc1175050d0d27aca1b3471502ff"
- integrity sha512-e5UqaECKH7Oiwql0R7TcNsXKjbOra13M+6TWnuK5IZmZ/GnW95RknT5za9oDi2wwI1JBvZAGtm3B8oMTbHQzTg==
+reactxp@^1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/reactxp/-/reactxp-1.5.0.tgz#aad1631fd2347c339715b051b0a6f2bfca2661ac"
+ integrity sha512-dmq/cStaBz7f9uUAgmTAK/NysRP+jun4aT1+KaixLEVGlhxE3PrEBfr+PCu5WEBYBo8EN1dE1kZdPYF8OizLZA==
dependencies:
- "@types/lodash" "4.14.116"
+ "@types/lodash" "4.14.118"
"@types/react" "16.3.18"
"@types/react-dom" "16.0.7"
"@types/react-native" "0.56.12"
assert "^1.4.1"
- lodash "^4.17.10"
+ lodash "^4.17.11"
prop-types "^15.6.2"
rebound "^0.1.0"
subscribableevent "^1.0.1"
@@ -7957,19 +6699,6 @@ readable-stream@~1.1.9:
isarray "0.0.1"
string_decoder "~0.10.x"
-readable-stream@~2.1.5:
- version "2.1.5"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0"
- integrity sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=
- dependencies:
- buffer-shims "^1.0.0"
- core-util-is "~1.0.0"
- inherits "~2.0.1"
- isarray "~1.0.0"
- process-nextick-args "~1.0.6"
- string_decoder "~0.10.x"
- util-deprecate "~1.0.1"
-
readdirp@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
@@ -7993,7 +6722,7 @@ redent@^1.0.0:
indent-string "^2.1.0"
strip-indent "^1.0.1"
-redux@^4.0.1:
+redux@^4.0.0, redux@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5"
integrity sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg==
@@ -8013,12 +6742,7 @@ regenerate@^1.2.1, regenerate@^1.4.0:
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
-regenerator-runtime@^0.10.5:
- version "0.10.5"
- resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
- integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=
-
-regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1:
+regenerator-runtime@^0.11.0:
version "0.11.1"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
@@ -8035,13 +6759,6 @@ regenerator-transform@^0.12.3:
dependencies:
private "^0.1.6"
-regenerator-transform@^0.13.3:
- version "0.13.3"
- resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb"
- integrity sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA==
- dependencies:
- private "^0.1.6"
-
regex-cache@^0.4.2:
version "0.4.4"
resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd"
@@ -8057,11 +6774,6 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2"
safe-regex "^1.1.0"
-regexpp@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
- integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==
-
regexpu-core@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240"
@@ -8071,7 +6783,7 @@ regexpu-core@^2.0.0:
regjsgen "^0.2.0"
regjsparser "^0.1.4"
-regexpu-core@^4.1.3, regexpu-core@^4.2.0:
+regexpu-core@^4.1.3:
version "4.2.0"
resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.2.0.tgz#a3744fa03806cffe146dea4421a3e73bdcc47b1d"
integrity sha512-Z835VSnJJ46CNBttalHD/dB+Sj2ezmY6Xp38npwU87peK6mqOzOpV8eYktdkLTEkzzD+JsTcxd84ozd8I14+rw==
@@ -8196,24 +6908,11 @@ require-main-filename@^1.0.1:
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=
-require-uncached@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
- integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=
- dependencies:
- caller-path "^0.1.0"
- resolve-from "^1.0.0"
-
requires-port@1.x.x, requires-port@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
-resolve-from@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
- integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=
-
resolve-pathname@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879"
@@ -8252,7 +6951,7 @@ ret@~0.1.10:
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
-rimraf@2, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2:
+rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==
@@ -8308,13 +7007,6 @@ rxjs@^5.5.6:
dependencies:
symbol-observable "1.0.1"
-rxjs@^6.1.0:
- version "6.3.3"
- resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55"
- integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==
- dependencies:
- tslib "^1.9.0"
-
safe-buffer@5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
@@ -8377,6 +7069,14 @@ saxes@^3.1.3:
dependencies:
xmlchars "^1.3.1"
+scheduler@^0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.12.0.tgz#8ab17699939c0aedc5a196a657743c496538647b"
+ integrity sha512-t7MBR28Akcp4Jm+QoR63XgAi9YgCUmgvDHqf5otgAj4QvdoBE4ImCX0ffehefePPG+aitiYHp0g/mW6s4Tp+dw==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+
seamless-immutable@^7.1.3:
version "7.1.4"
resolved "https://registry.yarnpkg.com/seamless-immutable/-/seamless-immutable-7.1.4.tgz#6e9536def083ddc4dea0207d722e0e80d0f372f8"
@@ -8394,7 +7094,7 @@ semver-diff@^2.0.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477"
integrity sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==
-semver@5.x, semver@^5.5.1, semver@^5.6.0:
+semver@5.x, semver@^5.6.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
@@ -8481,7 +7181,7 @@ set-value@^2.0.0:
is-plain-object "^2.0.3"
split-string "^3.0.1"
-setimmediate@^1.0.5, setimmediate@~1.0.4:
+setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
@@ -8564,13 +7264,6 @@ slash@^2.0.0:
resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==
-slice-ansi@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
- integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==
- dependencies:
- is-fullwidth-code-point "^2.0.0"
-
slide@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707"
@@ -8670,7 +7363,7 @@ source-map-support@^0.4.15, source-map-support@^0.4.2:
dependencies:
source-map "^0.5.6"
-source-map-support@^0.5.6, source-map-support@^0.5.8, source-map-support@^0.5.9:
+source-map-support@^0.5.6, source-map-support@^0.5.8:
version "0.5.9"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f"
integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==
@@ -8902,7 +7595,7 @@ strip-indent@^1.0.1:
dependencies:
get-stdin "^4.0.1"
-strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
+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=
@@ -8958,28 +7651,6 @@ synctasks@^0.3.3:
resolved "https://registry.yarnpkg.com/synctasks/-/synctasks-0.3.3.tgz#1e3dde423b39d28bc940fdb7698d8b4b7a741e77"
integrity sha512-8Gr8WHInZt5oU1q2N7ANqLSZ/TJn6bYlkqkwJJoGowFc5l81DRORgtHH9eJUpJGJsGJgYyWeVfKGVtUdTu4TEQ==
-table@^4.0.2:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc"
- integrity sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==
- dependencies:
- ajv "^6.0.1"
- ajv-keywords "^3.0.0"
- chalk "^2.1.0"
- lodash "^4.17.4"
- slice-ansi "1.0.0"
- string-width "^2.1.1"
-
-table@^5.0.2:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/table/-/table-5.1.0.tgz#69a54644f6f01ad1628f8178715b408dc6bf11f7"
- integrity sha512-e542in22ZLhD/fOIuXs/8yDZ9W61ltF8daM88rkRNtgTIct+vI2fTnAyu/Db2TCfEcI8i7mjZz6meLq0nW7TYg==
- dependencies:
- ajv "^6.5.3"
- lodash "^4.17.10"
- slice-ansi "1.0.0"
- string-width "^2.1.1"
-
tar@^4:
version "4.4.6"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b"
@@ -9023,11 +7694,6 @@ text-encoding@^0.6.4:
resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19"
integrity sha1-45mpgiV6J22uQou5KEXLcb3CbRk=
-text-table@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
- integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
-
tfunk@^3.0.1:
version "3.1.0"
resolved "https://registry.yarnpkg.com/tfunk/-/tfunk-3.1.0.tgz#38e4414fc64977d87afdaa72facb6d29f82f7b5b"
@@ -9062,7 +7728,7 @@ through2@~0.2.3:
readable-stream "~1.1.9"
xtend "~2.1.1"
-through@2, "through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.1:
+through@2, "through@>=2.2.7 <3", through@^2.3.6, through@~2.3, through@~2.3.1:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
@@ -9151,11 +7817,6 @@ tr46@^1.0.1:
dependencies:
punycode "^2.1.0"
-"traverse@>=0.3.0 <0.4":
- version "0.3.9"
- resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9"
- integrity sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=
-
trim-newlines@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
@@ -9187,20 +7848,20 @@ ts-node@^7.0.1:
source-map-support "^0.5.6"
yn "^2.0.0"
-tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0:
+tslib@^1.8.0, tslib@^1.8.1:
version "1.9.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
-tslint-config-prettier@^1.15.0:
- version "1.15.0"
- resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.15.0.tgz#76b9714399004ab6831fdcf76d89b73691c812cf"
- integrity sha512-06CgrHJxJmNYVgsmeMoa1KXzQRoOdvfkqnJth6XUkNeOz707qxN0WfxfhYwhL5kXHHbYJRby2bqAPKwThlZPhw==
+tslint-config-prettier@^1.17.0:
+ version "1.17.0"
+ resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.17.0.tgz#946ed6117f98f3659a65848279156d87628c33dc"
+ integrity sha512-NKWNkThwqE4Snn4Cm6SZB7lV5RMDDFsBwz6fWUkTxOKGjMx8ycOHnjIbhn7dZd5XmssW3CwqUjlANR6EhP9YQw==
-tslint@^5.11.0:
- version "5.11.0"
- resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.11.0.tgz#98f30c02eae3cde7006201e4c33cb08b48581eed"
- integrity sha1-mPMMAurjzecAYgHkwzywi0hYHu0=
+tslint@^5.12.1:
+ version "5.12.1"
+ resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.12.1.tgz#8cec9d454cf8a1de9b0a26d7bdbad6de362e52c1"
+ integrity sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==
dependencies:
babel-code-frame "^6.22.0"
builtin-modules "^1.1.1"
@@ -9251,10 +7912,10 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-typescript@^3.1.6:
- version "3.1.6"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.6.tgz#b6543a83cfc8c2befb3f4c8fba6896f5b0c9be68"
- integrity sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==
+typescript@^3.2.4:
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.4.tgz#c585cb952912263d915b462726ce244ba510ef3d"
+ integrity sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==
ua-parser-js@0.7.17:
version "0.7.17"
@@ -9352,21 +8013,6 @@ unzip-response@^2.0.1:
resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97"
integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=
-unzipper@^0.8.11:
- version "0.8.14"
- resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.8.14.tgz#ade0524cd2fc14d11b8de258be22f9d247d3f79b"
- integrity sha512-8rFtE7EP5ssOwGpN2dt1Q4njl0N1hUXJ7sSPz0leU2hRdq6+pra57z4YPBlVqm40vcgv6ooKZEAx48fMTv9x4w==
- dependencies:
- big-integer "^1.6.17"
- binary "~0.3.0"
- bluebird "~3.4.1"
- buffer-indexof-polyfill "~1.0.0"
- duplexer2 "~0.1.4"
- fstream "~1.0.10"
- listenercount "~1.0.1"
- readable-stream "~2.1.5"
- setimmediate "~1.0.4"
-
upath@^1.0.5:
version "1.1.0"
resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd"
@@ -9415,16 +8061,6 @@ url-parse@^1.2.0:
querystringify "^2.0.0"
requires-port "^1.0.0"
-url-template@^2.0.8:
- version "2.0.8"
- resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21"
- integrity sha1-/FZaPMy/93MMd19WQflVV5FDnyE=
-
-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"
- integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=
-
use@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
@@ -9462,13 +8098,6 @@ uuid@^3.0.1, uuid@^3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
-v8flags@^3.1.1:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.1.tgz#42259a1461c08397e37fe1d4f1cfb59cad85a053"
- integrity sha512-iw/1ViSEaff8NJ3HLyEjawk/8hjJib3E7pvG4pddVXfUg1983s3VGsiClDjhK64MQVDGqc1Q8r18S4VKQZS9EQ==
- dependencies:
- homedir-polyfill "^1.0.1"
-
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"
@@ -9667,13 +8296,6 @@ write-file-atomic@^2.0.0:
imurmurhash "^0.1.4"
signal-exit "^3.0.2"
-write@^0.2.1:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"
- integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=
- dependencies:
- mkdirp "^0.5.1"
-
ws@^1.1.0:
version "1.1.5"
resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51"
@@ -9798,14 +8420,6 @@ yargs-parser@^10.1.0:
dependencies:
camelcase "^4.1.0"
-yargs-parser@^2.4.1:
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4"
- integrity sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=
- dependencies:
- camelcase "^3.0.0"
- lodash.assign "^4.0.6"
-
yargs-parser@^4.1.0, yargs-parser@^4.2.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c"
@@ -9877,26 +8491,6 @@ yargs@^12.0.1:
y18n "^3.2.1 || ^4.0.0"
yargs-parser "^10.1.0"
-yargs@^4.2.0:
- version "4.8.1"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0"
- integrity sha1-wMQpJMpKqmsObaFznfshZDn53cA=
- dependencies:
- cliui "^3.2.0"
- decamelize "^1.1.1"
- get-caller-file "^1.0.1"
- lodash.assign "^4.0.3"
- os-locale "^1.4.0"
- read-pkg-up "^1.0.1"
- require-directory "^2.1.1"
- require-main-filename "^1.0.1"
- set-blocking "^2.0.0"
- string-width "^1.0.1"
- which-module "^1.0.0"
- window-size "^0.2.0"
- y18n "^3.2.1"
- yargs-parser "^2.4.1"
-
yargs@^9.0.0:
version "9.0.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c"