diff --git a/.github/workflows/build-extension.yml b/.github/workflows/build-extension.yml index 96425cc..0bf85b6 100644 --- a/.github/workflows/build-extension.yml +++ b/.github/workflows/build-extension.yml @@ -3,7 +3,7 @@ name: Build extension on: push: - tags: '**' + tags: ['**'] branches: - '*' - 'feature/**' @@ -23,65 +23,61 @@ jobs: timeout-minutes: 10 steps: - uses: actions/checkout@v2 - - name: Define variables - id: vars - run: | - SOURCE_NAME=${GITHUB_REF#refs/*/} - VSIX_NAME="vscode-sshfs-$SOURCE_NAME.vsix" - if [[ $GITHUB_REF == refs/tags/v* ]]; then - TAG_VERSION=${GITHUB_REF#refs/tags/v} - VSIX_NAME="vscode-sshfs-$TAG_VERSION.vsix" - echo ::set-output name=TAG_VERSION::$TAG_VERSION - elif [[ $GITHUB_REF == refs/pull/*/head || $GITHUB_REF == refs/pull/*/merge ]]; then - PR_NUMBER=${GITHUB_REF#refs/pull/} - PR_NUMBER=${PR_NUMBER%/head} - PR_NUMBER=${PR_NUMBER%/merge} - VSIX_NAME="vscode-sshfs-pr-$PR_NUMBER.vsix" - echo ::set-output name=PR_NUMBER::$PR_NUMBER - elif [[ -n $SOURCE_NAME ]]; then - VSIX_NAME="vscode-sshfs-$SOURCE_NAME.vsix" - fi - VSIX_NAME=${VSIX_NAME//"/"/"-"} - echo ::set-output name=VSIX_NAME::$VSIX_NAME - - name: Use Node.js 10.x + - name: Event Utilities + uses: SchoofsKelvin/event-utilities@v1 + id: utils + with: + artifact_prefix: "vscode-sshfs" + artifact_extension: "vsix" + - name: Use Node.js 12.x uses: actions/setup-node@v1 with: - node-version: 10.x + node-version: 12.x - name: Install VSCE run: | yarn global add vsce echo "$(yarn global bin)" >> $GITHUB_PATH + - name: Get Yarn cache directory + id: yarn-cache + run: echo "::set-output name=dir::$(yarn cache dir)" + - name: Yarn cache + uses: actions/cache@v2.1.4 + with: + path: ${{ steps.yarn-cache.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- - name: Install dependencies in / run: yarn --frozen-lockfile - name: Install dependencies in /webview/ working-directory: webview run: yarn --frozen-lockfile - name: Build extension - run: vsce package -o ${{ steps.vars.outputs.VSIX_NAME }} + run: vsce package -o ${{ steps.utils.outputs.artifact_name }} - name: Upload a Build Artifact uses: actions/upload-artifact@v2.2.1 with: - name: ${{ steps.vars.outputs.VSIX_NAME }} - path: ${{ steps.vars.outputs.VSIX_NAME }} + name: ${{ steps.utils.outputs.artifact_name }} + path: ${{ steps.utils.outputs.artifact_name }} if-no-files-found: error - name: Create release id: create_release - if: ${{ success() && steps.vars.outputs.TAG_VERSION }} + if: ${{ success() && steps.utils.outputs.tag_version }} uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref }} - release_name: Release ${{ steps.vars.outputs.TAG_VERSION }} + release_name: Release ${{ steps.utils.outputs.tag_version }} draft: true - name: Upload release asset id: upload_release_asset - if: ${{ success() && steps.vars.outputs.TAG_VERSION }} + if: ${{ success() && steps.utils.outputs.tag_version }} uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ${{ steps.vars.outputs.VSIX_NAME }} - asset_name: ${{ steps.vars.outputs.VSIX_NAME }} + asset_path: ${{ steps.utils.outputs.artifact_name }} + asset_name: ${{ steps.utils.outputs.artifact_name }} asset_content_type: application/vsix diff --git a/.github/workflows/publish-extension.yml b/.github/workflows/publish-extension.yml new file mode 100644 index 0000000..1aff0aa --- /dev/null +++ b/.github/workflows/publish-extension.yml @@ -0,0 +1,38 @@ +name: Publish extension + +on: + release: + types: [published] + +jobs: + openvsx: + name: "Open VSX Registry" + if: endsWith(github.event.release.assets[0].name, '.vsix') + runs-on: ubuntu-latest + steps: + - name: Download release artifact + run: "curl -L -H 'Authorization: token ${{ secrets.GITHUB_TOKEN }}' -H 'Accept: application/octet-stream' ${{ github.event.release.assets[0].url }} --output extension.vsix" + - name: Validate extension file + run: unzip -f extension.vsix extension/package.json + - name: Publish to Open VSX Registry + uses: HaaLeo/publish-vscode-extension@v0 + with: + pat: ${{ secrets.OPEN_VSX_TOKEN }} + extensionFile: extension.vsix + packagePath: '' + vs: + name: "Visual Studio Marketplace" + if: endsWith(github.event.release.assets[0].name, '.vsix') + runs-on: ubuntu-latest + steps: + - name: Download release artifact + run: "curl -L -H 'Authorization: token ${{ secrets.GITHUB_TOKEN }}' -H 'Accept: application/octet-stream' ${{ github.event.release.assets[0].url }} --output extension.vsix" + - name: Validate extension file + run: unzip -f extension.vsix extension/package.json + - name: Publish to Visual Studio Marketplace + uses: HaaLeo/publish-vscode-extension@v0 + with: + pat: ${{ secrets.VS_MARKETPLACE_TOKEN }} + registryUrl: https://marketplace.visualstudio.com + extensionFile: extension.vsix + packagePath: '' diff --git a/README.md b/README.md index f4e1d36..03a3078 100644 --- a/README.md +++ b/README.md @@ -1,71 +1,94 @@ # SSH FS - ![Logo](./resources/Logo.png) -[![GitHub package version](./media/github.png)](https://github.com/SchoofsKelvin/vscode-sshfs) -[![Visual Studio Marketplace](https://vsmarketplacebadge.apphb.com/version-short/Kelvin.vscode-sshfs.svg)](https://marketplace.visualstudio.com/items?itemName=Kelvin.vscode-sshfs) - [![Donate](./media/paypal.png)](https://www.paypal.me/KSchoofs) +[![GitHub package version](https://img.shields.io/github/v/release/SchoofsKelvin/vscode-sshfs?include_prereleases&label=GitHub%20version)](https://github.com/SchoofsKelvin/vscode-sshfs) +[![Visual Studio Marketplace](https://img.shields.io/visual-studio-marketplace/v/Kelvin.vscode-sshfs?label=VS%20Marketplace&logo=sdf)](https://marketplace.visualstudio.com/items?itemName=Kelvin.vscode-sshfs) +[![OpenVSX Registry](https://img.shields.io/open-vsx/v/Kelvin/vscode-sshfs?label=Open%20VSX)](https://open-vsx.org/extension/Kelvin/vscode-sshfs) +[![VS Market installs](https://img.shields.io/visual-studio-marketplace/i/Kelvin.vscode-sshfs?color=green&label=Installs)](https://marketplace.visualstudio.com/items?itemName=Kelvin.vscode-sshfs) +[![GitHub Sponsors](https://img.shields.io/github/sponsors/SchoofsKelvin?color=green&label=GitHub%20Sponsors)](https://github.com/sponsors/SchoofsKelvin) +[![Donate](./media/paypal.png)](https://www.paypal.me/KSchoofs) -This extension makes use of the new FileSystemProvider, added in version 1.23.0 of Visual Studio Code. It allows "mounting" a remote folder over SSH as a local Workspace folder. +This extension allows mounting remote folders as local workspace folders, launch integrated remote terminals and run `ssh-shell` tasks. -## Summary -* Use a remote directory (over SSH) as workspace folder -* Instantly create one or multiple terminals on the same host -* A built-in UI to add, edit and remove configurations -* Use agents, including Pageant and OpenSSH on Windows -* Use private keys (any supported by ssh2-streams, including PuTTY's PPK) -* Get prompted for a password/passphrase (plain text password aren't required) -* Easily create configurations that reference a PuTTY session/configuration -* Create tasks that run commands on a remote host (remote version of "shell" task type) -* Have multiple SSH (and regular) workspace folders at once -* Make use of SOCKS 4/5 and HTTP proxies and connection hopping +## Features -## Usage -Use the command `SSH FS: Create a SSH FS configuration`, or open the Settings UI using the `SSH FS: Open settings and edit configurations` and click Add: +### Config editor +The built-in config editor makes it easy to create and edit configurations: +![Config editor](./media/config-editor.png) -![Create a new configuration](./media/screenshot-create-config.png) +The config editors stores this, by default, in your User Settings (`settings.json`) as: +```json +"sshfs.configs": [ + { + "name": "hetzner", + "putty": "Hetzner", + "label": "Hetzner", + "hop": "hetzner2", + "root": "/root" + } +], +``` +This config is configured to copy settings (e.g. username, host, ...) from my PuTTY session. Due to me having loaded my private key in Pageant (PuTTY's agent), this config allows me to create a connection without having to provide a password/passphrase. It also specifies that all file operations _(`ssh://hetzner/some/file.js`)_ are relative to the `/root` directory on the server. -In this UI, you can also edit/delete existing configurations: +Configurations are read from your global User Settings, the current workspace's settings, and any JSON files configured with `sshfs.configpaths`. Even when the workspace overrides this setting, the globally-configured paths will still be read. The workspace versions do have higher priority for merging or ignoring duplicates. -![Config Editor](./media/screenshot-config-editor.png) +### Terminals +Using a simple button or the command palette, a remote terminal can be started: +![Terminals](./media/terminals.png) -To connect, either rightclick the name in the Explorer tab, or use the command panel: +_Uses `$SHELL` by default to launch your default user shell. A config option exists to change this, e.g. `"ksh -"` or `"exec .special-profile; $SHELL"`_ -![Connect](./media/screenshot-connect.png) +If a connection is already opened for a configuration, there is no need to reauthenticate. As long as the configuration hasn't changed, existing connections (both for workspace folders and terminals) will be reused. -This will add a Workspace folder linked to a SSH (SFTP) session: +### Remote shell tasks +A new task type `ssh-shell` is added to run shell commands remotely: +![Remote shell tasks](./media/shell-tasks.png) -![Workspace folder added](./media/screenshot-explorer.png) +The task terminal opens a full PTY terminal on the server. -## Changelog 1.18.0 -Starting from version 1.18.0 of the extension, a few new features are added: +### Remote workspace folders +Using a simple button or the command palette, we can mount a remote workspace folder as a regular local workspace folder: +![Remote workspace folder](./media/workspace-folder.png) -### Terminals -The configurations for SSH file systems can now also be used to spawn terminals: +_Same configuration used as from the [Config editor](#Config%20editor) above._ -![Terminals](./media/terminals.png) +This works seamlessly with extensions using the `vscode.workspace.fs` API _(added in VS Code 1.37.0)_, although not all extensions switched over, especially ones making use of binary files. + +As can be seen, right-clicking a remote directory gives the option to instantly open a remote terminal in this directory. + +The extension supports any `ssh://` URI. I actually opened `ssh://hetzner/ng-ui` as my folder, which resolves to `/root/ng-ui` on my remote server. By default, the button/command opens `ssh://hetzner/` which would then mount `/root`, as that is what my `Root` config field is set to. You can set it to whatever, including `~/path`. + +### Miscellaneous +The extension comes with a bunch of other improvements/features. Internally the [ssh2](https://www.npmjs.com/package/ssh2) package is used. The raw config JSON objects _(as seen in [Config editor](#Config%20editor))_ is, apart from some special fields, a one-on-one mapping of the config options supported by this package. Power users can edit their `settings.json` to e.g. make use of the `algorithms.cipher` field to specify a list of ciphers to use. + +Some other features worth mentioning: + +#### Prompt host/username/password/... for every connection +![Prompt username](./media/prompt-username.png) -Opening a terminal automatically sets the working directory to the `root` directory, unless a directory was explicitly selected to open the terminal in: +Active connections are reused to minimize prompts. A connection gets closed if there's no terminal or file system using it for over 5 seconds. -![Explorer Terminal](./media/explorer-terminal.png) +#### Proxy settings +Several proxy types (SSH hopping, HTTP and SOCKS 4/5) are supported: -This replaces the built-in "Open terminal" context menu option that isn't provided for remote field systems. For non-ssh:// file systems, the original "Open terminal" menu item is still displayed, the remote version only affects ssh:// file systems. +![Proxy settings](./media/proxy-settings.png) -### New task type -This extension adds a new task type `ssh-shell` which can be used to run commands on a configured remote host: +`SSH Hop` refers to using another configuration to hop through, similar to OpenSSH's `ProxyJump`: -![Tasks](./media/tasks.png) +![Hop config field](./media/hop-config.png) -Currently only the `command` field is supported. The goal is to replicate part of the `shell` task structure, e.g. an `args` array, support for `${workspaceFolder}`, ... +#### SFTP Command/Sudo and Terminal command +![SFTP and Terminal Command config fields](./media/sftp-config.png) -### Connection reuse -The way the extension connects to the remote hosts is reworked. The extension tries to only keep one connection per host active, with one connection supporting the file system access and a bunch of terminals. If the saved configuration has changed after a connection has been established, the next terminal/filesystem will start a new connection, but leave the first one alive and fine. +The extension supports using a custom `sftp` subsystem command. By default, it uses the `sftp` subsystem as indicated by the remote SSH server. In reality, this usually results in `/usr/lib/openssh/sftp-server` being used. -A handy enhancement this brings is that prompts (e.g. for passwords) should only happen once. As long as a connection is open (either by having a connected file system or terminal to the host), opening e.g. a new terminal skips the whole authentication phase and is basically instant. +The `SFTP Command` setting allows specifying to use a certain command instead of the default subsystem. The `SFTP Sudo` setting makes the extension try to create a sudo shell _(for the given user, or whatever sudo defaults to)_ and run `SFTP Command` _(or `/usr/lib/openssh/sftp-server` by default)_. For most users, setting this to `` should allow operating on the remote file system as `root`. Power users with esoteric setups can resort to changing `SFTP Command` to e.g. `sudo /some-sftp-server`, but might run into trouble with password prompts. -Connections without an active file system or terminals will automatically be closed somewhere after 5 seconds. If you're planning on running a bunch of tasks on a host without having a workspace folder connected to it, keeping a terminal open is handy and advised. +The `Terminal command` option, as mentioned in [Terminals](#Terminals), allows overriding the command used to launch the remote shell. By default, the extension launches a remote shell over the SSH connection, runs `cd ...` if necessary, followed by `$SHELL` to start the user's default shell. This config option allows to replace this `$SHELL` with a custom way way of starting the shell, or configuring the provided default SSH shell. -### Logging -Logging has slightly improved, resulting in better logs that help with resolving issues. \ No newline at end of file +## Links +- [GitHub](https://github.com/SchoofsKelvin/vscode-sshfs) ([Issues](https://github.com/SchoofsKelvin/vscode-sshfs/issues) | [(Pre)-releases](https://github.com/SchoofsKelvin/vscode-sshfs/releases) | [Roadmap](https://github.com/SchoofsKelvin/vscode-sshfs/projects/1) | [Sponsor](https://github.com/sponsors/SchoofsKelvin)) +- [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=Kelvin.vscode-sshfs) +- [Open VSX Registry](https://open-vsx.org/extension/Kelvin/vscode-sshfs) diff --git a/media/add-workspace-folder.png b/media/add-workspace-folder.png new file mode 100644 index 0000000..ce16bb5 Binary files /dev/null and b/media/add-workspace-folder.png differ diff --git a/media/config-editor.png b/media/config-editor.png new file mode 100644 index 0000000..de00d5a Binary files /dev/null and b/media/config-editor.png differ diff --git a/media/explorer-terminal.png b/media/explorer-terminal.png deleted file mode 100644 index bf443d2..0000000 Binary files a/media/explorer-terminal.png and /dev/null differ diff --git a/media/github.png b/media/github.png deleted file mode 100644 index 67125a2..0000000 Binary files a/media/github.png and /dev/null differ diff --git a/media/hop-config.png b/media/hop-config.png new file mode 100644 index 0000000..7224449 Binary files /dev/null and b/media/hop-config.png differ diff --git a/media/prompt-username.png b/media/prompt-username.png new file mode 100644 index 0000000..3e50adc Binary files /dev/null and b/media/prompt-username.png differ diff --git a/media/proxy-settings.png b/media/proxy-settings.png new file mode 100644 index 0000000..669db95 Binary files /dev/null and b/media/proxy-settings.png differ diff --git a/media/screenshot-commandpanel.png b/media/screenshot-commandpanel.png deleted file mode 100644 index a676684..0000000 Binary files a/media/screenshot-commandpanel.png and /dev/null differ diff --git a/media/screenshot-config-editor.png b/media/screenshot-config-editor.png deleted file mode 100644 index 889ca82..0000000 Binary files a/media/screenshot-config-editor.png and /dev/null differ diff --git a/media/screenshot-connect.png b/media/screenshot-connect.png deleted file mode 100644 index a979414..0000000 Binary files a/media/screenshot-connect.png and /dev/null differ diff --git a/media/screenshot-create-config.png b/media/screenshot-create-config.png deleted file mode 100644 index e86fd44..0000000 Binary files a/media/screenshot-create-config.png and /dev/null differ diff --git a/media/screenshot-explorer.png b/media/screenshot-explorer.png deleted file mode 100644 index 3cf9d45..0000000 Binary files a/media/screenshot-explorer.png and /dev/null differ diff --git a/media/sftp-config.png b/media/sftp-config.png new file mode 100644 index 0000000..34745a6 Binary files /dev/null and b/media/sftp-config.png differ diff --git a/media/shell-tasks.png b/media/shell-tasks.png new file mode 100644 index 0000000..e87c911 Binary files /dev/null and b/media/shell-tasks.png differ diff --git a/media/tasks.png b/media/tasks.png deleted file mode 100644 index d465905..0000000 Binary files a/media/tasks.png and /dev/null differ diff --git a/media/terminals.png b/media/terminals.png index d8a68f5..c661f5d 100644 Binary files a/media/terminals.png and b/media/terminals.png differ diff --git a/media/workspace-folder.png b/media/workspace-folder.png new file mode 100644 index 0000000..7ac859e Binary files /dev/null and b/media/workspace-folder.png differ diff --git a/package.json b/package.json index 104068c..5006fb1 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "vscode-sshfs", "displayName": "SSH FS", - "description": "File system provider using SSH", + "description": "File system, terminal and task provider using SSH", "publisher": "Kelvin", - "version": "1.19.1", + "version": "1.20.0", "engines": { "vscode": "^1.49.0" }, @@ -28,6 +28,7 @@ "onCommand:sshfs.refresh" ], "main": "./dist/extension.js", + "homepage": "https://github.com/SchoofsKelvin/vscode-sshfs", "author": { "name": "Kelvin Schoofs", "email": "schoofs.kelvin@gmail.com", @@ -48,7 +49,31 @@ "sshfs", "sync", "filesystem", - "terminal" + "terminal", + "sftp", + "scp" + ], + "badges": [ + { + "url": "https://img.shields.io/github/v/release/SchoofsKelvin/vscode-sshfs?include_prereleases&label=GitHub%20version", + "href": "https://github.com/SchoofsKelvin/vscode-sshfs/releases", + "description": "Releases on GitHub" + }, + { + "url": "https://img.shields.io/open-vsx/v/Kelvin/vscode-sshfs?label=Open%20VSX", + "href": "https://open-vsx.org/extension/Kelvin/vscode-sshfs", + "description": "Open VSX Registry" + }, + { + "url": "https://img.shields.io/visual-studio-marketplace/v/Kelvin.vscode-sshfs?label=VS%20Marketplace&logo=sdf", + "href": "https://marketplace.visualstudio.com/items?itemName=Kelvin.vscode-sshfs", + "description": "Visual Studio Marketplace" + }, + { + "url": "https://img.shields.io/visual-studio-marketplace/i/Kelvin.vscode-sshfs?label=Installs", + "href": "https://marketplace.visualstudio.com/items?itemName=Kelvin.vscode-sshfs", + "description": "Unique installs using Visual Studio Marketplace" + } ], "contributes": { "views": { @@ -300,6 +325,13 @@ "password": "CorrectHorseBatteryStaple" } ] + }, + "sshfs.flags": { + "title": "List of special flags to enable/disable certain fixes/features", + "description": "Flags are usually used for issues or beta testing. Flags can disappear/change anytime!", + "type": "array", + "items": "string", + "default": [] } } }, @@ -344,7 +376,7 @@ "clean-webpack-plugin": "^2.0.0", "source-map-support": "^0.5.19", "ts-loader": "^7.0.5", - "typescript": "^4.0.2", + "typescript": "^4.2.3", "webpack": "^4.29.6", "webpack-cli": "^3.2.3" }, @@ -354,5 +386,8 @@ "socks": "^2.2.0", "ssh2": "^0.8.9", "winreg": "^1.2.4" + }, + "resolutions": { + "ssh2-streams": "Timmmm/ssh2-streams#patch-1" } } \ No newline at end of file diff --git a/src/config.ts b/src/config.ts index 122243a..fdb7444 100644 --- a/src/config.ts +++ b/src/config.ts @@ -2,7 +2,7 @@ import { readFile, writeFile } from 'fs'; import { parse as parseJsonc, ParseError } from 'jsonc-parser'; import * as vscode from 'vscode'; -import { ConfigLocation, FileSystemConfig, invalidConfigName } from './fileSystemConfig'; +import { ConfigLocation, FileSystemConfig, invalidConfigName, parseConnectionString } from './fileSystemConfig'; import { Logging } from './logging'; import { toPromise } from './toPromise'; @@ -283,9 +283,32 @@ export async function deleteConfig(config: FileSystemConfig) { }); } -export function getConfig(name: string) { - if (name === '') return null; - return getConfigs().find(c => c.name === name); +/** If a loaded config with the given name exists (case insensitive), it is returned. + * Otherwise, if it contains a `@`, we parse it as a connection string. + * If this results in no (valid) configuration, `undefined` is returned. + */ +export function getConfig(input: string): FileSystemConfig | undefined { + const lower = input.toLowerCase(); + const loaded = getConfigs().find(c => c.name.toLowerCase() === lower); + if (loaded) return loaded; + if (!input.includes('@')) return undefined; + const parseString = parseConnectionString(input); + if (typeof parseString === 'string') return undefined; + const [parsed] = parseString; + // If we're using the instant connection string, the host name might be a config name + const existing = getConfigs().find(c => c.name.toLowerCase() === parsed.host!.toLowerCase()); + if (existing) { + Logging.info(`getConfig('${input}') led to '${parsed.name}' which matches config '${existing.name}'`); + // Take the existing config, but (more or less) override it with the values present in `parsed` + // `name` be the same as in `parsed`, meaning it can be reused with `getConfig` on window reload. + return { + ...existing, ...parsed, + host: existing.host || parsed.host, // `parsed.host` is the session name, which might not be the actual hostname + _location: undefined, // Since this is a merged config, we have to flag it as such + _locations: [...existing._locations, ...parsed._locations], // Merge locations + }; + } + return parsed; } function valueMatches(a: any, b: any): boolean { @@ -318,3 +341,103 @@ vscode.workspace.onDidChangeConfiguration(async (e) => { return loadConfigs(); }); loadConfigs(); + + +export type FlagValue = string | boolean | null; +export type FlagCombo = [value: FlagValue, origin: string]; +export const DEFAULT_FLAGS: string[] = ['-DF-GE']; +let cachedFlags: Record = {}; +function calculateFlags(): Record { + const flags: Record = {}; + const config = vscode.workspace.getConfiguration('sshfs').inspect('flags'); + if (!config) throw new Error(`Could not inspect "sshfs.flags" config field`); + function parseList(list: string[] | undefined, origin: string) { + if (list === undefined) return; + if (!Array.isArray(list)) throw new Error(`Expected string array for flags, but got: ${list}`); + const scope: Record = {}; + for (const flag of list) { + let name: string = flag; + let value: FlagValue = null; + const eq = flag.indexOf('='); + if (eq !== -1) { + name = flag.substring(0, eq); + value = flag.substring(eq + 1); + } else if (flag.startsWith('+')) { + name = flag.substring(1); + value = true; + } else if (flag.startsWith('-')) { + name = flag.substring(1); + value = false; + } + name = name.toLocaleLowerCase(); + if (name in scope) continue; + scope[name] = [value, origin]; + } + // Override if necessary (since workspace settings come after global settings) + // Per "location", we still ignore duplicate flag names + Object.assign(flags, scope); + } + parseList(DEFAULT_FLAGS, 'Built-in Default'); + parseList(config.defaultValue, 'Default Settings'); + // Electron v11 crashes for DiffieHellman GroupExchange, although it's fixed in 11.3.0 + if ((process.versions as { electron?: string }).electron?.match(/^11\.(0|1|2)\./)) { + parseList(['+DF-GE'], 'Fix for issue #239') + } + parseList(config.globalValue, 'Global Settings'); + parseList(config.workspaceValue, 'Workspace Settings'); + parseList(config.workspaceFolderValue, 'WorkspaceFolder Settings'); + Logging.info(`Calculated config flags: ${JSON.stringify(flags)}`); + return cachedFlags = flags; +} + +vscode.workspace.onDidChangeConfiguration(event => { + if (event.affectsConfiguration('sshfs.flags')) calculateFlags(); +}); +calculateFlags(); + +/** Returns a cached version. Gets updated by ConfigurationChangeEvent events */ +export function getFlags(): Record { return cachedFlags; } + +/** + * Checks the `sshfs.flags` config (overridable by e.g. workspace settings). + * - Flag names are case-insensitive + * - If a flag appears twice, the first mention of it is used + * - If a flag appears as "NAME", `null` is returned + * - If a flag appears as "FLAG=VALUE", `VALUE` is returned as a string + * - If a flag appears as `+FLAG` (and no `=`), `true` is returned (as a boolean) + * - If a flag appears as `-FLAG` (and no `=`), `false` is returned (as a boolean) + * - If a flag is missing, `undefined` is returned (different from `null`!) + * + * For `undefined`, an actual `undefined` is returned. For all other cases, a FlagCombo + * is returned, e.g. "NAME" returns `[null, "someOrigin"]` and `"+F"` returns `[true, "someOrigin"]` + * @param target The name of the flag to look for + */ +export function getFlag(target: string): FlagCombo | undefined { + return calculateFlags()[target.toLowerCase()]; +} + +/** + * Built on top of getFlag. Tries to convert the flag value to a boolean using these rules: + * - If the flag isn't present, `missingValue` is returned + * Although this probably means I'm using a flag that I never added to `DEFAULT_FLAGS` + * - Booleans are kept + * - `null` is counted as `true` (means a flag like "NAME" was present without any value or prefix) + * - Strings try to get converted in a case-insensitive way: + * - `true/t/yes/y` becomes true + * - `false/f/no/n` becomes false + * - All other strings result in an error + * @param target The name of the flag to look for + * @param defaultValue The value to return when no flag with the given name is present + * @returns The matching FlagCombo or `[missingValue, 'missing']` instead + */ +export function getFlagBoolean(target: string, missingValue: boolean): FlagCombo { + const combo = getFlag(target); + if (!combo) return [missingValue, 'missing']; + const [value, reason] = combo; + if (value == null) return [true, reason]; + if (typeof value === 'boolean') return combo; + const lower = value.toLowerCase(); + if (lower === 'true' || lower === 't' || lower === 'yes' || lower === 'y') return [true, reason]; + if (lower === 'false' || lower === 'f' || lower === 'no' || lower === 'n') return [false, reason]; + throw new Error(`Could not convert '${value}' for flag '${target}' to a boolean!`); +} diff --git a/src/connect.ts b/src/connect.ts index 49f272f..aab6c78 100644 --- a/src/connect.ts +++ b/src/connect.ts @@ -4,9 +4,10 @@ import { userInfo } from 'os'; import { Client, ClientChannel, ConnectConfig, SFTPWrapper as SFTPWrapperReal } from 'ssh2'; import { SFTPStream } from 'ssh2-streams'; import * as vscode from 'vscode'; -import { getConfigs } from './config'; +import { getConfig, getFlag, getFlagBoolean } from './config'; import type { FileSystemConfig } from './fileSystemConfig'; import { censorConfig, Logging } from './logging'; +import type { PuttySession } from './putty'; import { toPromise } from './toPromise'; // tslint:disable-next-line:variable-name @@ -33,8 +34,8 @@ const PROMPT_FIELDS: Partial> = { host: ['Host', c => `Host for ${c.name}`, true], username: ['Username', c => `Username for ${c.name}`, true], - password: ['Password', c => `Password for ${c.username}@${c.name}`, false, true], - passphrase: ['Passphrase', c => `Passphrase for provided export/private key for ${c.username}@${c.name}`, false, true], + password: ['Password', c => `Password for '${c.username}' for ${c.name}`, false, true], + passphrase: ['Passphrase', c => `Passphrase for provided export/private key for '${c.username}' for ${c.name}`, false, true], }; async function promptFields(config: FileSystemConfig, ...fields: (keyof FileSystemConfig)[]): Promise { @@ -63,60 +64,84 @@ export async function calculateActualConfig(config: FileSystemConfig): Promise= 1) { - config.username = session.hostname.substr(0, session.hostname.indexOf('@')); + const { getCachedFinder } = await import('./putty'); + const getSession = await getCachedFinder(); + const cUsername = config.username === '$USER' ? undefined : config.username; + const tryPutty = config.instantConnection || config.putty === ''; + let session: PuttySession | undefined; + if (tryPutty) { + // If we're trying to find one, we also check whether `config.host` represents the name of a PuTTY session + session = await getSession(config.host); + logging.info(`\ttryPutty is true, tried finding a config named '${config.host}' and found ${session ? `'${session.name}'` : 'no match'}`); } - config.host = config.host || session.hostname; - config.port = session.portnumber || config.port; - config.agent = config.agent || (session.tryagent ? 'pageant' : undefined); - if (session.usernamefromenvironment) { - config.username = process.env.USERNAME || process.env.USER; - if (!config.username) throw new Error(`Trying to use the system username, but process.env.USERNAME or process.env.USER is missing`); + if (!session) { + let nameOnly = true; + if (config.putty === true) { + await promptFields(config, 'host'); + // TODO: `config.putty === true` without config.host should prompt the user with *all* PuTTY sessions + if (!config.host) throw new Error(`'putty' was true but 'host' is empty/missing`); + config.putty = config.host; + nameOnly = false; + } else { + config.putty = replaceVariables(config.putty); + } + session = await getSession(config.putty, config.host, cUsername, nameOnly); } - config.privateKeyPath = config.privateKeyPath || (!config.agent && session.publickeyfile) || undefined; - switch (session.proxymethod) { - case 0: - break; - case 1: - case 2: - case 3: - if (!session.proxyhost) throw new Error(`Proxymethod is SOCKS 4/5 or HTTP but 'proxyhost' is missing`); - config.proxy = { - host: session.proxyhost, - port: session.proxyport, - type: session.proxymethod === 1 ? 'socks4' : (session.proxymethod === 2 ? 'socks5' : 'http'), - }; - break; - default: - throw new Error(`The requested PuTTY session uses an unsupported proxy method`); + if (session) { + if (session.protocol !== 'ssh') throw new Error(`The requested PuTTY session isn't a SSH session`); + config.username = cUsername || session.username; + if (!config.username && session.hostname && session.hostname.indexOf('@') >= 1) { + config.username = session.hostname.substr(0, session.hostname.indexOf('@')); + } + // Used to be `config.host || session.hostname`, but `config.host` could've been just the session name + config.host = session.hostname.replace(/^.*?@/, ''); + config.port = session.portnumber || config.port; + config.agent = config.agent || (session.tryagent ? 'pageant' : undefined); + if (session.usernamefromenvironment) config.username = '$USER'; + config.privateKeyPath = config.privateKeyPath || (!config.agent && session.publickeyfile) || undefined; + switch (session.proxymethod) { + case 0: + break; + case 1: + case 2: + case 3: + if (!session.proxyhost) throw new Error(`Proxymethod is SOCKS 4/5 or HTTP but 'proxyhost' is missing`); + config.proxy = { + host: session.proxyhost, + port: session.proxyport, + type: session.proxymethod === 1 ? 'socks4' : (session.proxymethod === 2 ? 'socks5' : 'http'), + }; + break; + default: + throw new Error(`The requested PuTTY session uses an unsupported proxy method`); + } + logging.debug(`\tReading PuTTY configuration lead to the following configuration:\n${JSON.stringify(config, null, 4)}`); + } else if (!tryPutty) { + throw new Error(`Couldn't find the requested PuTTY session`); + } else { + logging.debug(`\tConfig suggested finding a PuTTY configuration, did not find one`); } - logging.debug(`\tReading PuTTY configuration lead to the following configuration:\n${JSON.stringify(config, null, 4)}`); } + // If the username is (still) `$USER` at this point, use the local user's username + if (config.username === '$USER') config.username = userInfo().username; if (config.sshConfig) { await promptFields(config, 'host'); let paths = vscode.workspace.getConfiguration('sshfs').get('paths.ssh'); @@ -160,6 +185,11 @@ export async function calculateActualConfig(config: FileSystemConfig): Promise c.name === config.hop); + const hop = getConfig(config.hop); if (!hop) throw new Error(`A SSH FS configuration with the name '${config.hop}' doesn't exist`); const ssh = await createSSH(hop); if (!ssh) { @@ -242,8 +272,22 @@ export async function createSSH(config: FileSystemConfig, sock?: NodeJS.Readable reject(error); }); try { - logging.info(`Creating SSH session over the opened socket`); - client.connect(Object.assign(config, { sock }, DEFAULT_CONFIG)); + const finalConfig: ConnectConfig = { ...config, sock, ...DEFAULT_CONFIG }; + if (config.debug || getFlag('DEBUG_SSH2') !== undefined) { + const scope = Logging.scope(`ssh2(${config.name})`); + finalConfig.debug = (msg: string) => scope.debug(msg); + } + // Unless the flag 'DF-GE' is specified, disable DiffieHellman groupex algorithms (issue #239) + // Note: If the config already specifies a custom `algorithms.key`, ignore it (trust the user?) + const [flagV, flagR] = getFlagBoolean('DF-GE', false); + if (flagV) { + logging.info(`Flag "DF-GE" enabled due to '${flagR}', disabling DiffieHellman kex groupex algorithms`); + let kex: string[] = require('ssh2-streams/lib/constants').ALGORITHMS.KEX; + kex = kex.filter(algo => !algo.includes('diffie-hellman-group-exchange')); + logging.debug(`\tResulting algorithms.kex: ${kex}`); + finalConfig.algorithms = { ...finalConfig.algorithms, kex }; + } + client.connect(finalConfig); } catch (e) { reject(e); } @@ -337,7 +381,7 @@ export async function getSFTP(client: Client, config: FileSystemConfig): Promise if (config.sftpSudo) await startSudo(shell, config, config.sftpSudo); shell.write(`echo SFTP READY\n`); // Wait until we see "SFTP READY" (skipping welcome messages etc) - await new Promise((ready, nvm) => { + await new Promise((ready, nvm) => { const handler = (data: string | Buffer) => { if (data.toString().trim() !== 'SFTP READY') return; shell.stdout.removeListener('data', handler); diff --git a/src/extension.ts b/src/extension.ts index 446c8b3..8051265 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -12,7 +12,7 @@ import { pickComplex, PickComplexOptions, pickConnection, setAsAbsolutePath } fr function getVersion(): string | undefined { const ext = vscode.extensions.getExtension('Kelvin.vscode-sshfs'); - return ext && ext.packageJSON && ext.packageJSON.version; + return ext?.packageJSON?.version; } interface CommandHandler { @@ -31,6 +31,17 @@ export function activate(context: vscode.ExtensionContext) { setDebug(context.extensionMode !== vscode.ExtensionMode.Production); + // Likely that we'll have a breaking change in the future that requires users to check + // their configs, or at least reconfigure already existing workspaces with new URIs. + // See https://github.com/SchoofsKelvin/vscode-sshfs/issues/198#issuecomment-785926352 + const previousVersion = context.globalState.get('lastVersion'); + context.globalState.update('lastVersion', getVersion()); + if (!previousVersion) { + Logging.info('No previous version detected. Fresh or pre-v1.21.0 installation?'); + } else if (previousVersion !== getVersion()) { + Logging.info(`Previously used version ${previousVersion}, first run after install.`); + } + // Really too bad we *need* the ExtensionContext for relative resources // I really don't like having to pass context to *everything*, so let's do it this way setAsAbsolutePath(context.asAbsolutePath.bind(context)); @@ -74,7 +85,7 @@ export function activate(context: vscode.ExtensionContext) { // sshfs.add(target?: string | FileSystemConfig) registerCommandHandler('sshfs.add', { - promptOptions: { promptConfigs: true }, + promptOptions: { promptConfigs: true, promptConnections: true, promptInstantConnection: true }, handleConfig: config => manager.commandConnect(config), }); @@ -95,7 +106,7 @@ export function activate(context: vscode.ExtensionContext) { // sshfs.termninal(target?: string | FileSystemConfig | Connection | vscode.Uri) registerCommandHandler('sshfs.terminal', { - promptOptions: { promptConfigs: true, promptConnections: true }, + promptOptions: { promptConfigs: true, promptConnections: true, promptInstantConnection: true }, handleConfig: config => manager.commandTerminal(config), handleConnection: con => manager.commandTerminal(con), handleUri: async uri => { diff --git a/src/fileSystemConfig.ts b/src/fileSystemConfig.ts index 75bbb8e..2d6b35a 100644 --- a/src/fileSystemConfig.ts +++ b/src/fileSystemConfig.ts @@ -100,8 +100,12 @@ export interface FileSystemConfig extends ConnectConfig { sftpSudo?: string | boolean; /** The command(s) to run when a new SSH terminal gets created. Defaults to `$SHELL`. Internally the command `cd ...` is run first */ terminalCommand?: string | string[]; + /** The command(s) to run when a `ssh-shell` task gets run. Defaults to the placeholder `$COMMAND`. Internally the command `cd ...` is run first */ + taskCommand?: string | string[]; /** The filemode to assign to created files */ newFileMode?: number | string; + /** Whether this config was created from an instant connection string. Enables fuzzy matching for e.g. PuTTY, config-by-host, ... */ + instantConnection?: boolean; /** Internal property saying where this config comes from. Undefined if this config is merged or something */ _location?: ConfigLocation; /** Internal property keeping track of where this config comes from (including merges) */ @@ -115,3 +119,35 @@ export function invalidConfigName(name: string) { if (name.match(/^[\w_\\/.@\-+]+$/)) return null; return `A SSH FS name can only exists of lowercase alphanumeric characters, slashes and any of these: _.+-@`; } + +/** + * https://regexr.com/5m3gl (mostly based on https://tools.ietf.org/html/draft-ietf-secsh-scp-sftp-ssh-uri-04) + * Supports several formats, the first one being the "full" format, with others being partial: + * - `user;abc=def,a-b=1-5@server.example.com:22/some/file.ext` + * - `user@server.example.com/directory` + * - `server:22/directory` + * - `user@server` + * - `server` + * - `@server/path` - Unlike OpenSSH, we allow a @ (and connection parameters) without a username + * + * The resulting FileSystemConfig will have as name basically the input, but without the path. If there is no + * username given, the name will start with `@`, as to differentiate between connection strings and config names. + */ +const CONNECTION_REGEX = /^((?\w+)?(;[\w-]+=[\w\d-]+(,[\w\d-]+=[\w\d-]+)*)?@)?(?[^@\\/:,=]+)(:(?\d+))?(?\/.*)?$/; + +export function parseConnectionString(input: string): [config: FileSystemConfig, path?: string] | string { + input = input.trim(); + const match = input.match(CONNECTION_REGEX); + if (!match) return 'Invalid format, expected something like "user@example.com:22/some/path"'; + const { user, host, path } = match.groups!; + const portStr = match.groups!.port; + const port = portStr ? Number.parseInt(portStr) : undefined; + if (portStr && (!port || port < 1 || port > 65535)) return `The string '${port}' is not a valid port number`; + const name = `${user || ''}@${host}${port ? `:${port}` : ''}${path || ''}`; + return [{ + name, host, port, + instantConnection: true, + username: user || '$USERNAME', + _locations: [], + }, path]; +} diff --git a/src/logging.ts b/src/logging.ts index 0200f49..09f6474 100644 --- a/src/logging.ts +++ b/src/logging.ts @@ -1,7 +1,9 @@ import * as vscode from 'vscode'; import type { FileSystemConfig } from './fileSystemConfig'; -// Since the Extension Development Host runs with debugger, we can use this to detect if we're debugging +// Since the Extension Development Host runs with debugger, we can use this to detect if we're debugging. +// The only things it currently does is copying Logging messages to the console, while also enabling +// the webview (Settings UI) from trying a local dev server first instead of the pre-built version. export let DEBUG: boolean = false; export function setDebug(debug: boolean) { console.warn(`[vscode-sshfs] Debug mode set to ${debug}`); @@ -161,3 +163,12 @@ export function censorConfig(config: FileSystemConfig): CensoredFileSystemConfig export const Logging = new (Logger as any) as Logger; Logging.info('Created output channel for vscode-sshfs'); +Logging.info(`When posting your logs somewhere, keep the following in mind: + - While the logging tries to censor your passwords/passphrases/..., double check! + Maybe you also want to censor out e.g. the hostname/IP you're connecting to. + - If you want to report an issue regarding authentication or something else that + seems to be more of an issue with the actual SSH2 connection, it might be handy + to reconnect with this added to your User Settings (settings.json) first: + "sshfs.flags": [ "DEBUG_SSH2" ], + This will (for new connections) also enable internal SSH2 logging. +`); diff --git a/src/manager.ts b/src/manager.ts index 8325dd5..01c04ab 100644 --- a/src/manager.ts +++ b/src/manager.ts @@ -2,10 +2,10 @@ import * as path from 'path'; import type { Client, ClientChannel } from 'ssh2'; import * as vscode from 'vscode'; -import { getConfig, getConfigs, loadConfigsRaw } from './config'; +import { getConfig, loadConfigsRaw } from './config'; import { Connection, ConnectionManager } from './connection'; import type { FileSystemConfig } from './fileSystemConfig'; -import { Logging } from './logging'; +import { Logging, LOGGING_NO_STACKTRACE } from './logging'; import { isSSHPseudoTerminal } from './pseudoTerminal'; import type { SSHFileSystem } from './sshFileSystem'; import { catchingPromise, toPromise } from './toPromise'; @@ -29,7 +29,7 @@ function commandArgumentToName(arg?: string | FileSystemConfig | Connection): st return `FileSystemConfig(${arg.name})`; } -interface SSHShellTaskOptions { +interface SSHShellTaskOptions extends vscode.TaskDefinition { host: string; command: string; workingDirectory?: string; @@ -63,7 +63,7 @@ export class Manager implements vscode.TaskProvider, vscode.TerminalLinkProvider if (existing) return existing; let con: Connection | undefined; return this.creatingFileSystems[name] ||= catchingPromise(async (resolve, reject) => { - config = config || getConfigs().find(c => c.name === name); + config ||= getConfig(name); if (!config) throw new Error(`Couldn't find a configuration with the name '${name}'`); const con = await this.connectionManager.createConnection(name, config); this.connectionManager.update(con, con => con.pendingUserCount++); @@ -126,7 +126,7 @@ export class Manager implements vscode.TaskProvider, vscode.TerminalLinkProvider if (chosen === 'Retry') { this.createFileSystem(name).catch(() => { }); } else if (chosen === 'Configure') { - this.commandConfigure(name); + this.commandConfigure(config || name); } else { this.commandDisconnect(name); } @@ -134,7 +134,12 @@ export class Manager implements vscode.TaskProvider, vscode.TerminalLinkProvider throw e; }); } - public getRemotePath(config: FileSystemConfig, relativePath: string) { + public getRemotePath(config: FileSystemConfig, relativePath: string | vscode.Uri) { + if (relativePath instanceof vscode.Uri) { + if (relativePath.authority !== config.name) + throw new Error(`Uri authority for '${relativePath}' does not match config with name '${config.name}'`); + relativePath = relativePath.path; + } if (relativePath.startsWith('/')) relativePath = relativePath.substr(1); if (!config.root) return '/' + relativePath; const result = path.posix.join(config.root, relativePath); @@ -147,8 +152,7 @@ export class Manager implements vscode.TaskProvider, vscode.TerminalLinkProvider // Create connection (early so we have .actualConfig.root) const con = (config && 'client' in config) ? config : await this.connectionManager.createConnection(name, config); // Calculate working directory if applicable - let workingDirectory: string | undefined = uri && uri.path; - if (workingDirectory) workingDirectory = this.getRemotePath(con.actualConfig, workingDirectory); + const workingDirectory = uri && this.getRemotePath(con.actualConfig, uri); // Create pseudo terminal this.connectionManager.update(con, con => con.pendingUserCount++); const pty = await createTerminal({ client: con.client, config: con.actualConfig, workingDirectory }); @@ -169,41 +173,146 @@ export class Manager implements vscode.TaskProvider, vscode.TerminalLinkProvider } public async promptReconnect(name: string) { const config = getConfig(name); - console.log('config', name, config); if (!config) return; const choice = await vscode.window.showWarningMessage(`SSH FS ${config.label || config.name} disconnected`, 'Ignore', 'Disconnect'); if (choice === 'Disconnect') this.commandDisconnect(name); } /* TaskProvider */ + protected async replaceTaskVariables(value: string, config: FileSystemConfig): Promise { + return value.replace(/\$\{(.*?)\}/g, (str, match: string) => { + if (!match.startsWith('remote')) return str; // Our variables always start with "remote" + // https://github.com/microsoft/vscode/blob/bebd06640734c37f6d5f1a82b13297ce1d297dd1/src/vs/workbench/services/configurationResolver/common/variableResolver.ts#L156 + const [key, argument] = match.split(':') as [string, string?]; + const getFilePath = (): vscode.Uri => { + const uri = vscode.window.activeTextEditor?.document?.uri; + if (uri && uri.scheme === 'ssh') return uri; + if (uri) throw new Error(`Variable ${str}: Active editor is not a ssh:// file`); + throw new Error(`Variable ${str} can not be resolved. Please open an editor.`); + } + const getFolderPathForFile = (): vscode.Uri => { + const filePath = getFilePath(); + const uri = vscode.workspace.getWorkspaceFolder(filePath)?.uri; + if (uri) return uri; + throw new Error(`Variable ${str}: can not find workspace folder of '${filePath}'.`); + } + const { workspaceFolders = [] } = vscode.workspace; + const sshFolders = workspaceFolders.filter(ws => ws.uri.scheme === 'ssh'); + const sshFolder = sshFolders.length === 1 ? sshFolders[0] : undefined; + const getFolderUri = (): vscode.Uri => { + const { workspaceFolders = [] } = vscode.workspace; + if (argument) { + const uri = workspaceFolders.find(ws => ws.name === argument)?.uri; + if (uri && uri.scheme === 'ssh') return uri; + if (uri) throw new Error(`Variable ${str}: Workspace folder '${argument}' is not a ssh:// folder`); + throw new Error(`Variable ${str} can not be resolved. No such folder '${argument}'.`); + } + if (sshFolder) return sshFolder.uri; + if (sshFolders.length > 1) { + throw new Error(`Variable ${str} can not be resolved in a multi ssh:// folder workspace. Scope this variable using ':' and a workspace folder name.`); + } + throw new Error(`Variable ${str} can not be resolved. Please open an ssh:// folder.`); + }; + switch (key) { + case 'remoteWorkspaceRoot': + case 'remoteWorkspaceFolder': + return this.getRemotePath(config, getFolderUri()); + case 'remoteWorkspaceRootFolderName': + case 'remoteWorkspaceFolderBasename': + return path.basename(getFolderUri().path); + case 'remoteFile': + return this.getRemotePath(config, getFilePath()); + case 'remoteFileWorkspaceFolder': + return this.getRemotePath(config, getFolderPathForFile()); + case 'remoteRelativeFile': + if (sshFolder || argument) + return path.relative(getFolderUri().path, getFilePath().path); + return getFilePath().path; + case 'remoteRelativeFileDirname': { + const dirname = path.dirname(getFilePath().path); + if (sshFolder || argument) { + const relative = path.relative(getFolderUri().path, dirname); + return relative.length === 0 ? '.' : relative; + } + return dirname; + } + case 'remoteFileDirname': + return path.dirname(getFilePath().path); + case 'remoteFileExtname': + return path.extname(getFilePath().path); + case 'remoteFileBasename': + return path.basename(getFilePath().path); + case 'remoteFileBasenameNoExtension': { + const basename = path.basename(getFilePath().path); + return (basename.slice(0, basename.length - path.extname(basename).length)); + } + case 'remoteFileDirnameBasename': + return path.basename(path.dirname(getFilePath().path)); + case 'remotePathSeparator': + // Not sure if we even need/want this variable, but sure + return path.posix.sep; + default: + const msg = `Unrecognized task variable '${str}' starting with 'remote', ignoring`; + Logging.warning(msg, LOGGING_NO_STACKTRACE); + vscode.window.showWarningMessage(msg); + return str; + } + }); + } + protected async replaceTaskVariablesRecursive(object: T, handler: (value: string) => string | Promise): Promise { + if (typeof object === 'string') return handler(object) as any; + if (Array.isArray(object)) return object.map(v => this.replaceTaskVariablesRecursive(v, handler)) as any; + if (typeof object == 'object' && object !== null && !(object instanceof RegExp) && !(object instanceof Date)) { + // ^ Same requirements VS Code applies: https://github.com/microsoft/vscode/blob/bebd06640734c37f6d5f1a82b13297ce1d297dd1/src/vs/base/common/types.ts#L34 + const result: any = {}; + for (let key in object) { + const value = await this.replaceTaskVariablesRecursive(object[key], handler); + key = await this.replaceTaskVariablesRecursive(key, handler); + result[key] = value; + } + return result; + } + return object; + } public provideTasks(token?: vscode.CancellationToken | undefined): vscode.ProviderResult { return []; } public async resolveTask(task: vscode.Task, token?: vscode.CancellationToken | undefined): Promise { - let { host, command, workingDirectory } = task.definition as unknown as SSHShellTaskOptions; - if (!host) throw new Error('Missing field \'host\' for ssh-shell task'); - if (!command) throw new Error('Missing field \'command\' for ssh-shell task'); - const config = getConfig(host); - if (!config) throw new Error(`No configuration with the name '${host}' found for ssh-shell task`); - // Calculate working directory if applicable - if (workingDirectory) workingDirectory = this.getRemotePath(config, workingDirectory); return new vscode.Task( - task.definition, + task.definition, // Can't replace/modify this, otherwise we're not contributing to "this" task vscode.TaskScope.Workspace, - `SSH Task '${task.name}' for ${host}`, + `SSH Task '${task.name}'`, 'ssh', - new vscode.CustomExecution(async () => { - const connection = await this.connectionManager.createConnection(host); - this.connectionManager.update(connection, con => con.pendingUserCount++); - const { createTerminal } = await import('./pseudoTerminal'); - const pty = await createTerminal({ - command, workingDirectory, - client: connection.client, - config: connection.actualConfig, - }); - this.connectionManager.update(connection, con => (con.pendingUserCount--, con.terminals.push(pty))); - pty.onDidClose(() => this.connectionManager.update(connection, - con => con.terminals = con.terminals.filter(t => t !== pty))); - return pty; + new vscode.CustomExecution(async (resolved: SSHShellTaskOptions) => { + const { createTerminal, createTextTerminal, joinCommands } = await import('./pseudoTerminal'); + try { + if (!resolved.host) throw new Error('Missing field \'host\' in task description'); + if (!resolved.command) throw new Error('Missing field \'command\' in task description'); + const connection = await this.connectionManager.createConnection(resolved.host); + resolved = await this.replaceTaskVariablesRecursive(resolved, value => this.replaceTaskVariables(value, connection.actualConfig)); + let { command, workingDirectory } = resolved; + let { taskCommand = '$COMMAND' } = connection.actualConfig; + taskCommand = joinCommands(taskCommand)!; + if (taskCommand.includes('$COMMAND')) { + command = taskCommand.replace(/\$COMMAND/g, command); + } else { + const message = `The taskCommand '${taskCommand}' is missing the '$COMMAND' placeholder!`; + Logging.warning(message, LOGGING_NO_STACKTRACE); + command = `echo "Missing '$COMMAND' placeholder"`; + } + //if (workingDirectory) workingDirectory = this.getRemotePath(config, workingDirectory); + this.connectionManager.update(connection, con => con.pendingUserCount++); + const pty = await createTerminal({ + command, workingDirectory, + client: connection.client, + config: connection.actualConfig, + }); + this.connectionManager.update(connection, con => (con.pendingUserCount--, con.terminals.push(pty))); + pty.onDidClose(() => this.connectionManager.update(connection, + con => con.terminals = con.terminals.filter(t => t !== pty))); + return pty; + } catch (e) { + return createTextTerminal(`Error: ${e.message || e}`); + } }) ) } @@ -216,7 +325,6 @@ export class Manager implements vscode.TaskProvider, vscode.TerminalLinkProvider if (!isSSHPseudoTerminal(pty)) return; const conn = this.connectionManager.getActiveConnections().find(c => c.terminals.includes(pty)); if (!conn) return; // Connection died, which means the terminal should also be closed already? - console.log('provideTerminalLinks', line, pty.config.root, conn ? conn.filesystems.length : 'No connection?'); const links: TerminalLinkUri[] = []; const PATH_REGEX = /\/\S+/g; while (true) { @@ -298,13 +406,20 @@ export class Manager implements vscode.TaskProvider, vscode.TerminalLinkProvider public async commandConfigure(target: string | FileSystemConfig) { Logging.info(`Command received to configure ${typeof target === 'string' ? target : target.name}`); if (typeof target === 'object') { + if (!target._location && !target._locations.length) { + vscode.window.showErrorMessage('Cannot configure a config-less connection!'); + return; + } this.openSettings({ config: target, type: 'editconfig' }); return; } target = target.toLowerCase(); let configs = await loadConfigsRaw(); configs = configs.filter(c => c.name === target); - if (configs.length === 0) throw new Error('Unexpectedly found no matching configs?'); + if (configs.length === 0) { + vscode.window.showErrorMessage(`Found no matching configs for '${target}'`); + return Logging.error(`Unexpectedly found no matching configs for '${target}' in commandConfigure?`); + } const config = configs.length === 1 ? configs[0] : configs; this.openSettings({ config, type: 'editconfig' }); } diff --git a/src/pseudoTerminal.ts b/src/pseudoTerminal.ts index c4ef2d1..b774ef5 100644 --- a/src/pseudoTerminal.ts +++ b/src/pseudoTerminal.ts @@ -36,10 +36,10 @@ export interface TerminalOptions { command?: string; } -function joinCommands(commands?: string | string[]): string | undefined { +export function joinCommands(commands?: string | string[]): string | undefined { if (!commands) return undefined; if (typeof commands === 'string') return commands; - return commands.join(';'); + return commands.join('; '); } export async function createTerminal(options: TerminalOptions): Promise { @@ -116,3 +116,24 @@ export async function createTerminal(options: TerminalOptions): Promise; // Redeclaring that it isn't undefined + onDidOpen: vscode.Event; +} + +export function createTextTerminal(initialText?: string): TextTerminal { + const onDidWrite = new vscode.EventEmitter(); + const onDidClose = new vscode.EventEmitter(); + const onDidOpen = new vscode.EventEmitter(); + return { + write: onDidWrite.fire.bind(onDidWrite), + close: onDidClose.fire.bind(onDidClose), + onDidWrite: onDidWrite.event, + onDidClose: onDidClose.event, + onDidOpen: onDidOpen.event, + open: () => initialText && (onDidWrite.fire(initialText + '\r\n'), onDidClose.fire(1)), + }; +} diff --git a/src/putty.ts b/src/putty.ts index 718f403..a01b54b 100644 --- a/src/putty.ts +++ b/src/putty.ts @@ -10,7 +10,7 @@ const winreg = new Winreg({ export type NumberAsBoolean = 0 | 1; export interface PuttySession { - [key: string]: string | number | undefined; + //[key: string]: string | number | undefined; // General settings name: string; hostname: string; @@ -24,7 +24,7 @@ export interface PuttySession { proxyhost?: string; proxyport: number; proxylocalhost: NumberAsBoolean; - proxymethod: number; // Key of ['None', 'SOCKS 4', 'SOCKS 5', 'HTTP', 'Telnet', 'Local'] // Only checked first 3 + proxymethod: number; // Key of ['None', 'SOCKS 4', 'SOCKS 5', 'HTTP', 'Telnet', 'Local'] } function valueFromItem(item: Winreg.RegistryItem) { @@ -37,11 +37,22 @@ function valueFromItem(item: Winreg.RegistryItem) { throw new Error(`Unknown RegistryItem type: '${item.type}'`); } +const FORMATTED_FIELDS: (keyof PuttySession)[] = [ + 'name', 'hostname', 'protocol', 'portnumber', + 'username', 'usernamefromenvironment', 'tryagent', 'publickeyfile', + 'proxyhost', 'proxyport', 'proxylocalhost', 'proxymethod', +]; +export function formatSession(session: PuttySession): string { + const partial: Partial = {}; + for (const field of FORMATTED_FIELDS) partial[field] = session[field] as any; + return JSON.stringify(partial); +} + export async function getSessions() { Logging.info(`Fetching PuTTY sessions from registry`); const values = await toPromise(cb => winreg.keys(cb)); const sessions: PuttySession[] = []; - await Promise.all(values.map(regSession => (async (res, rej) => { + await Promise.all(values.map(regSession => (async () => { const name = decodeURIComponent(regSession.key.substr(winreg.key.length)); const props = await toPromise(cb => regSession.values(cb)); const properties: { [key: string]: string | number } = {}; @@ -49,21 +60,30 @@ export async function getSessions() { sessions.push({ name, ...(properties as any) }); })())); Logging.debug(`\tFound ${sessions.length} sessions:`); - sessions.forEach(s => Logging.debug(`\t${JSON.stringify(s)}`)); + sessions.forEach(s => Logging.debug(`\t- ${formatSession(s)}`)); return sessions; } -export async function getSession(name?: string, host?: string, username?: string, nameOnly = false): Promise { - const sessions = await getSessions(); +export async function findSession(sessions: PuttySession[], name?: string, host?: string, username?: string, nameOnly = true): Promise { if (name) { name = name.toLowerCase(); - const session = sessions.find(s => s.name.toLowerCase() === name) || null; + const session = sessions.find(s => s.name.toLowerCase() === name); if (nameOnly || session) return session; } - if (!host) return null; + if (!host) return undefined; host = host.toLowerCase(); const hosts = sessions.filter(s => s.hostname && s.hostname.toLowerCase() === host); if (!username) return hosts[0] || null; username = username.toLowerCase(); - return hosts.find(s => !s.username || s.username.toLowerCase() === username) || null; + return hosts.find(s => !s.username || s.username.toLowerCase() === username); +} + +export async function getSession(name?: string, host?: string, username?: string, nameOnly = true): Promise { + const sessions = await getSessions(); + return findSession(sessions, name, host, username, nameOnly); +} + +export async function getCachedFinder(): Promise { + const sessions = await getSessions(); + return (...args) => findSession(sessions, ...args); } diff --git a/src/sshFileSystem.ts b/src/sshFileSystem.ts index 9324d17..8c58249 100644 --- a/src/sshFileSystem.ts +++ b/src/sshFileSystem.ts @@ -11,7 +11,7 @@ import { Logger, Logging, LOGGING_NO_STACKTRACE, LOGGING_SINGLE_LINE_STACKTRACE, // (usually the errors we report on happen deep inside ssh2 or ssh2-streams, we don't really care that much about it) const LOGGING_HANDLE_ERROR = withStacktraceOffset(1, { ...LOGGING_SINGLE_LINE_STACKTRACE, maxErrorStack: 4 }); -// All absolute paths (relative to the FS root) +// All absolute paths (relative to the FS root or a workspace root) // If it ends with /, .startsWith is used, otherwise a raw equal const IGNORE_NOT_FOUND: string[] = [ '/.vscode', @@ -19,9 +19,17 @@ const IGNORE_NOT_FOUND: string[] = [ '/.git/', '/node_modules', '/pom.xml', + '/app/src/main/AndroidManifest.xml', ]; -function shouldIgnoreNotFound(path: string) { - return IGNORE_NOT_FOUND.some(entry => entry === path || entry.endsWith('/') && path.startsWith(entry)); +function shouldIgnoreNotFound(target: string) { + if (IGNORE_NOT_FOUND.some(entry => entry === target || entry.endsWith('/') && target.startsWith(entry))) return true; + for (const { uri: { path: wsPath } } of vscode.workspace.workspaceFolders || []) { + if (!target.startsWith(wsPath)) continue; + let local = path.posix.relative(wsPath, target); + if (!local.startsWith('/')) local = `/${local}`; + if (IGNORE_NOT_FOUND.some(entry => entry === local || entry.endsWith('/') && local.startsWith(entry))) return true; + } + return false; } export class SSHFileSystem implements vscode.FileSystemProvider { @@ -58,7 +66,7 @@ export class SSHFileSystem implements vscode.FileSystemProvider { this.waitForContinue = false; if (this.closed) return reject(new Error('Connection closed')); try { - const canContinue = func((err, res) => err ? reject(err) : resolve(res)); + const canContinue = func((err, res) => err ? reject(err) : resolve(res!)); if (!canContinue) this.waitForContinue = true; } catch (e) { reject(e); diff --git a/src/toPromise.ts b/src/toPromise.ts index 48df32f..086d78b 100644 --- a/src/toPromise.ts +++ b/src/toPromise.ts @@ -3,7 +3,7 @@ export type toPromiseCallback = (err?: Error | null, res?: T) => void; export async function toPromise(func: (cb: toPromiseCallback) => void): Promise { return new Promise((resolve, reject) => { try { - func((err, res) => err ? reject(err) : resolve(res)); + func((err, res) => err ? reject(err) : resolve(res!)); } catch (e) { reject(e); } diff --git a/src/ui-utils.ts b/src/ui-utils.ts index 048756e..9ef1924 100644 --- a/src/ui-utils.ts +++ b/src/ui-utils.ts @@ -2,7 +2,7 @@ import * as vscode from 'vscode'; import { getConfigs } from './config'; import type { Connection } from './connection'; -import type { FileSystemConfig } from './fileSystemConfig'; +import { parseConnectionString, FileSystemConfig } from './fileSystemConfig'; import type { Manager } from './manager'; import type { SSHPseudoTerminal } from './pseudoTerminal'; import type { SSHFileSystem } from './sshFileSystem'; @@ -70,6 +70,8 @@ export interface PickComplexOptions { immediateReturn?: boolean; /** If true, add all connections. If this is a string, filter by config name first */ promptConnections?: boolean | string; + /** If true, add an option to enter a connection string */ + promptInstantConnection?: boolean; /** If true, add all configurations. If this is a string, filter by config name first */ promptConfigs?: boolean | string; /** If true, add all terminals. If this is a string, filter by config name first */ @@ -78,10 +80,27 @@ export interface PickComplexOptions { nameFilter?: string; } +async function inputInstantConnection(value?: string): Promise { + const valueSelection = value ? [value.length, value.length] as [number, number] : undefined; + const name = await vscode.window.showInputBox({ + value, valueSelection, + placeHolder: 'user@host:/home/user', + prompt: 'SSH connection string', + validateInput(value: string) { + const result = parseConnectionString(value); + return typeof result === 'string' ? result : undefined; + } + }); + if (!name) return; + const result = parseConnectionString(name); + if (typeof result === 'string') return; + return result[0]; +} + export async function pickComplex(manager: Manager, options: PickComplexOptions): Promise { - return new Promise((resolve) => { - const { promptConnections, promptConfigs, promptTerminals, immediateReturn, nameFilter } = options; + return new Promise((resolve) => { + const { promptConnections, promptConfigs, nameFilter } = options; const items: QuickPickItemWithItem[] = []; const toSelect: string[] = []; if (promptConnections) { @@ -98,7 +117,7 @@ export async function pickComplex(manager: Manager, options: PickComplexOptions) items.push(...configs.map(config => formatItem(config, true))); toSelect.push('configuration'); } - if (promptTerminals) { + if (options.promptTerminals) { let cons = manager.connectionManager.getActiveConnections(); if (typeof promptConnections === 'string') cons = cons.filter(con => con.actualConfig.name === promptConnections); if (nameFilter) cons = cons.filter(con => con.actualConfig.name === nameFilter); @@ -106,16 +125,27 @@ export async function pickComplex(manager: Manager, options: PickComplexOptions) items.push(...terminals.map(config => formatItem(config, true))); toSelect.push('terminal'); } - if (immediateReturn && items.length <= 1) return resolve(items[0]?.item); + if (options.promptInstantConnection) { + items.unshift({ + label: '$(terminal) Create instant connection', + detail: 'Opens an input box where you can type e.g. `user@host:22/home/user`', + picked: true, alwaysShow: true, + item: inputInstantConnection, + }); + } + if (options.immediateReturn && items.length <= 1) return resolve(items[0]?.item); const quickPick = vscode.window.createQuickPick(); quickPick.items = items; quickPick.title = 'Select ' + toSelect.join(' / '); quickPick.onDidAccept(() => { - const value = quickPick.activeItems[0]?.item; + let value = quickPick.activeItems[0]?.item; quickPick.hide(); + if (typeof value === 'function') { + value = value(quickPick.value); + } resolve(value); }); - quickPick.onDidHide(() => resolve()); + quickPick.onDidHide(() => resolve(undefined)); quickPick.show(); }); } diff --git a/tsconfig.json b/tsconfig.json index 73b968c..25531c3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,10 +3,10 @@ "strictNullChecks": true, "module": "esnext", "moduleResolution": "node", - "target": "es6", + "target": "ES2019", "outDir": "out", "lib": [ - "es6" + "ES2019" ], "sourceMap": true, "rootDir": "src" diff --git a/webview/src/ConfigEditor/fields.tsx b/webview/src/ConfigEditor/fields.tsx index 0ad6a85..fba0647 100644 --- a/webview/src/ConfigEditor/fields.tsx +++ b/webview/src/ConfigEditor/fields.tsx @@ -34,15 +34,15 @@ export function merge(config: FileSystemConfig, onChange: FSCChanged<'merge'>): } export function label(config: FileSystemConfig, onChange: FSCChanged<'label'>): React.ReactElement { - const callback = (value?: string) => onChange('label', value); + const callback = (newValue?: string) => onChange('label', newValue); const description = 'Label to display in some UI places (e.g. popups)'; - return + return } export function group(config: FileSystemConfig, onChange: FSCChanged<'group'>): React.ReactElement { const callback = (newValue: string) => onChange('group', newValue); const description = 'Group for this config, to group configs together in some UI places. Allows subgroups, in the format "Group1.SubGroup1.Subgroup2"'; - return + return } export function putty(config: FileSystemConfig, onChange: FSCChanged<'putty'>): React.ReactElement { @@ -50,7 +50,7 @@ export function putty(config: FileSystemConfig, onChange: FSCChanged<'putty'>): const description = 'A name of a PuTTY session, or `true` to find the PuTTY session from the host address'; const values = ['']; const value = config.putty === true ? '' : config.putty || undefined; - return + return } export function host(config: FileSystemConfig, onChange: FSCChanged<'host'>): React.ReactElement { @@ -58,26 +58,26 @@ export function host(config: FileSystemConfig, onChange: FSCChanged<'host'>): Re const description = 'Hostname or IP address of the server. Supports environment variables, e.g. $HOST'; const values = ['']; const value = (config.host as any) === true ? '' : config.host; - return + return } export function port(config: FileSystemConfig, onChange: FSCChanged<'port'>): React.ReactElement { const callback = (value: number) => onChange('port', value); const description = 'Port number of the server. Supports environment variables, e.g. $PORT'; - return + return } export function root(config: FileSystemConfig, onChange: FSCChanged<'root'>): React.ReactElement { const callback = (value: string) => onChange('root', value); const description = 'Path on the remote server where the root path in vscode should point to. Defaults to /'; - return + return } export function agent(config: FileSystemConfig, onChange: FSCChanged<'agent'>): React.ReactElement { const callback = (newValue: string) => onChange('agent', newValue); const description = `Path to ssh-agent's UNIX socket for ssh-agent-based user authentication. Supports 'pageant' for PuTTY's Pagent, and environment variables, e.g. $SSH_AUTH_SOCK`; const values = ['pageant', '//./pipe/openssh-ssh-agent', '$SSH_AUTH_SOCK']; - return + return } export function username(config: FileSystemConfig, onChange: FSCChanged<'username'>): React.ReactElement { @@ -85,7 +85,7 @@ export function username(config: FileSystemConfig, onChange: FSCChanged<'usernam const description = 'Username for authentication. Supports environment variables, e.g. $USERNAME'; const values = ['', '$USERNAME']; const value = (config.username as any) === true ? '' : config.username; - return + return } export function password(config: FileSystemConfig, onChange: FSCChanged<'password'>): React.ReactElement { @@ -93,13 +93,13 @@ export function password(config: FileSystemConfig, onChange: FSCChanged<'passwor const description = 'Password for password-based user authentication. Supports env variables. This gets saved in plaintext! Using prompts or private keys is recommended!'; const values = ['']; const value = (config.password as any) === true ? '' : config.password; - return + return } export function privateKeyPath(config: FileSystemConfig, onChange: FSCChanged<'privateKeyPath'>): React.ReactElement { - const callback = (value?: string) => onChange('privateKeyPath', value); + const callback = (newValue?: string) => onChange('privateKeyPath', newValue); const description = 'A path to a private key. Supports environment variables, e.g. `$USERPROFILE/.ssh/myKey.ppk` or `$HOME/.ssh/myKey`'; - return + return } export function passphrase(config: FileSystemConfig, onChange: FSCChanged<'passphrase'>): React.ReactElement { @@ -107,21 +107,21 @@ export function passphrase(config: FileSystemConfig, onChange: FSCChanged<'passp const description = 'Passphrase for unlocking an encrypted private key. Supports env variables. This gets saved in plaintext! Using prompts or private keys is recommended!'; const values = ['']; const value = (config.passphrase as any) === true ? '' : config.passphrase; - return + return } export function sftpCommand(config: FileSystemConfig, onChange: FSCChanged<'sftpCommand'>): React.ReactElement { const callback = (newValue?: string) => onChange('sftpCommand', newValue); const description = 'A command to run on the remote SSH session to start a SFTP session (defaults to sftp subsystem)'; - return + return } export function sftpSudo(config: FileSystemConfig, onChange: FSCChanged<'sftpSudo'>): React.ReactElement { const callback = (newValue?: string) => onChange('sftpSudo', newValue === '' ? true : newValue); const description = 'Whether to use a sudo shell (and for which user) to run the sftpCommand in (if present, gets passed as -u to sudo)'; const values = ['']; - const value = (config.sftpSudo && typeof config.sftpSudo === 'string') ? config.sftpSudo : ''; - return + const value = config.sftpSudo === true ? '' : (typeof config.sftpSudo === 'string' ? config.sftpSudo : undefined); + return } export function terminalCommand(config: FileSystemConfig, onChange: FSCChanged<'terminalCommand'>): React.ReactElement { @@ -130,12 +130,21 @@ export function terminalCommand(config: FileSystemConfig, onChange: FSCChanged<' const values = ['$SHELL', '/usr/bin/bash', '/usr/bin/sh']; let value = config.terminalCommand === '$SHELL' ? '' : config.terminalCommand || ''; if (Array.isArray(value)) value = value.join('; '); - return + return +} + +export function taskCommand(config: FileSystemConfig, onChange: FSCChanged<'taskCommand'>): React.ReactElement { + const callback = (newValue?: string) => onChange('taskCommand', newValue); + const description = 'The command(s) to run when a `ssh-shell` task gets run. Defaults to the placeholder `$COMMAND`. Internally the command `cd ...` is run first'; + const values = ['$COMMAND']; + let value = config.taskCommand; + if (Array.isArray(value)) value = value.join('; '); + return } export type FieldFactory = (config: FileSystemConfig, onChange: FSCChanged, onChangeMultiple: FSCChangedMultiple) => React.ReactElement | null; export const FIELDS: FieldFactory[] = [ name, merge, label, group, putty, host, port, root, agent, username, password, privateKeyPath, passphrase, - sftpCommand, sftpSudo, terminalCommand, + sftpCommand, sftpSudo, terminalCommand, taskCommand, PROXY_FIELD]; diff --git a/webview/src/ConfigEditor/index.tsx b/webview/src/ConfigEditor/index.tsx index fb1090a..443a01d 100644 --- a/webview/src/ConfigEditor/index.tsx +++ b/webview/src/ConfigEditor/index.tsx @@ -25,7 +25,7 @@ class ConfigEditor extends React.Component { return
- +

{oldConfig.label || oldConfig.name}

{formatConfigLocation(oldConfig._location!)}

diff --git a/webview/src/types/fileSystemConfig.ts b/webview/src/types/fileSystemConfig.ts index 4ea92d6..b444964 100644 --- a/webview/src/types/fileSystemConfig.ts +++ b/webview/src/types/fileSystemConfig.ts @@ -98,8 +98,12 @@ export interface FileSystemConfig extends ConnectConfig { sftpSudo?: string | boolean; /** The command(s) to run when a new SSH terminal gets created. Defaults to `$SHELL`. Internally the command `cd ...` is run first */ terminalCommand?: string | string[]; + /** The command(s) to run when a `ssh-shell` task gets run. Defaults to the placeholder `$COMMAND`. Internally the command `cd ...` is run first */ + taskCommand?: string | string[]; /** The filemode to assign to created files */ newFileMode?: number | string; + /** Whether this config was created from an instant connection string. Enables fuzzy matching for e.g. PuTTY, config-by-host, ... */ + instantConnection?: boolean; /** Internal property saying where this config comes from. Undefined if this config is merged or something */ _location?: ConfigLocation; /** Internal property keeping track of where this config comes from (including merges) */ @@ -113,3 +117,35 @@ export function invalidConfigName(name: string) { if (name.match(/^[\w_\\/.@\-+]+$/)) return null; return `A SSH FS name can only exists of lowercase alphanumeric characters, slashes and any of these: _.+-@`; } + +/** + * https://regexr.com/5m3gl (mostly based on https://tools.ietf.org/html/draft-ietf-secsh-scp-sftp-ssh-uri-04) + * Supports several formats, the first one being the "full" format, with others being partial: + * - `user;abc=def,a-b=1-5@server.example.com:22/some/file.ext` + * - `user@server.example.com/directory` + * - `server:22/directory` + * - `user@server` + * - `server` + * - `@server/path` - Unlike OpenSSH, we allow a @ (and connection parameters) without a username + * + * The resulting FileSystemConfig will have as name basically the input, but without the path. If there is no + * username given, the name will start with `@`, as to differentiate between connection strings and config names. + */ +const CONNECTION_REGEX = /^((?\w+)?(;[\w-]+=[\w\d-]+(,[\w\d-]+=[\w\d-]+)*)?@)?(?[^@\\/:,=]+)(:(?\d+))?(?\/.*)?$/; + +export function parseConnectionString(input: string): [config: FileSystemConfig, path?: string] | string { + input = input.trim(); + const match = input.match(CONNECTION_REGEX); + if (!match) return 'Invalid format, expected something like "user@example.com:22/some/path"'; + const { user, host, path } = match.groups!; + const portStr = match.groups!.port; + const port = portStr ? Number.parseInt(portStr) : undefined; + if (portStr && (!port || port < 1 || port > 65535)) return `The string '${port}' is not a valid port number`; + const name = `${user || ''}@${host}${port ? `:${port}` : ''}${path || ''}`; + return [{ + name, host, port, + instantConnection: true, + username: user || '$USERNAME', + _locations: [], + }, path]; +} diff --git a/yarn.lock b/yarn.lock index 98d8b4b..5969751 100644 --- a/yarn.lock +++ b/yarn.lock @@ -32,19 +32,19 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "13.9.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.2.tgz#ace1880c03594cc3e80206d96847157d8e7fa349" - integrity sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg== + version "14.14.35" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.35.tgz#42c953a4e2b18ab931f72477e7012172f4ffa313" + integrity sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag== "@types/node@^12.7.12": - version "12.7.12" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.12.tgz#7c6c571cc2f3f3ac4a59a5f2bd48f5bdbc8653cc" - integrity sha512-KPYGmfD0/b1eXurQ59fXD1GBzhSQfz6/lKBxkaHX9dKTzjXbK68Zt7yGUxUsCS1jeTy/8aL+d9JEr+S54mpkWQ== + version "12.20.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.6.tgz#7b73cce37352936e628c5ba40326193443cfba25" + integrity sha512-sRVq8d+ApGslmkE9e3i+D3gFGk7aZHAT+G4cIpIEdLJYPsWiSPwcAnJEjddLQQDqV3Ra2jOclX/Sv6YrvGYiWA== "@types/request@^2.48.1": - version "2.48.4" - resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.4.tgz#df3d43d7b9ed3550feaa1286c6eabf0738e6cf7e" - integrity sha512-W1t1MTKYR8PxICH+A4HgEIPuAC3sbljoEVfyZbeFJJDbr30guDspJri2XOaM2E+Un7ZjrihaDi7cf6fPa2tbgw== + version "2.48.5" + resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.5.tgz#019b8536b402069f6d11bee1b2c03e7f232937a0" + integrity sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ== dependencies: "@types/caseless" "*" "@types/node" "*" @@ -57,34 +57,34 @@ integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== "@types/ssh2-streams@*": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@types/ssh2-streams/-/ssh2-streams-0.1.6.tgz#1ff5b1fe50c15f282efe9fd092c68494f8702bc2" - integrity sha512-NB+SYftagfHTDPdgVyvSZCeg5MURyHECd/PycGIW9hwhnEbTFxIdDbFtf3jxUO3rRnfr0lfdtkZFiv28T1cAsg== + version "0.1.8" + resolved "https://registry.yarnpkg.com/@types/ssh2-streams/-/ssh2-streams-0.1.8.tgz#142af404dae059931aea7fcd1511b5478964feb6" + integrity sha512-I7gixRPUvVIyJuCEvnmhr3KvA2dC0639kKswqD4H5b4/FOcnPtNU+qWLiXdKIqqX9twUvi5j0U1mwKE5CUsrfA== dependencies: "@types/node" "*" "@types/ssh2@^0.5.41": - version "0.5.41" - resolved "https://registry.yarnpkg.com/@types/ssh2/-/ssh2-0.5.41.tgz#70d52dcdc20da5ca373948b287766b0cae73801f" - integrity sha512-C661JCfu/yXUoF3EDKatfNhb8z1iD0NUuVOLfrmQ9fOSp1ClntmnicY2u3sBG7zl2FAvjBKkdvM7j03LZXjQXQ== + version "0.5.46" + resolved "https://registry.yarnpkg.com/@types/ssh2/-/ssh2-0.5.46.tgz#e12341a242aea0e98ac2dec89e039bf421fd3584" + integrity sha512-1pC8FHrMPYdkLoUOwTYYifnSEPzAFZRsp3JFC/vokQ+dRrVI+hDBwz0SNmQ3pL6h39OSZlPs0uCG7wKJkftnaA== dependencies: "@types/node" "*" "@types/ssh2-streams" "*" "@types/tapable@*": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.5.tgz#9adbc12950582aa65ead76bffdf39fe0c27a3c02" - integrity sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ== + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" + integrity sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA== "@types/tough-cookie@*": - version "2.3.6" - resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.6.tgz#c880579e087d7a0db13777ff8af689f4ffc7b0d5" - integrity sha512-wHNBMnkoEBiRAd3s8KTKwIuO9biFtTf0LehITzBhSco+HQI0xkXZbLOD55SW3Aqw3oUkHstkm5SPv58yaAdFPQ== + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d" + integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A== "@types/uglify-js@*": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082" - integrity sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ== + version "3.13.0" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.13.0.tgz#1cad8df1fb0b143c5aba08de5712ea9d1ff71124" + integrity sha512-EGkrJD5Uy+Pg0NUR8uA4bJ5WMfljyad0G+784vLCNUkD+QwOJXUbBYExXfVGf7YtyzdQp3L/XMYcliB987kL5Q== dependencies: source-map "^0.6.1" @@ -94,18 +94,18 @@ integrity sha512-wfNQmLmm1VdMBr6iuNdprWmC1YdrgZ9dQzadv+l2eSjJlElOdJw8OTm4RU4oGTBcfvG6RZI2jOcppkdSS18mZw== "@types/webpack-sources@*": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.6.tgz#3d21dfc2ec0ad0c77758e79362426a9ba7d7cbcb" - integrity sha512-FtAWR7wR5ocJ9+nP137DV81tveD/ZgB1sadnJ/axUGM3BUVfRPx8oQNMtv3JNfTeHx3VP7cXiyfR/jmtEsVHsQ== + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-2.1.0.tgz#8882b0bd62d1e0ce62f183d0d01b72e6e82e8c10" + integrity sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg== dependencies: "@types/node" "*" "@types/source-list-map" "*" - source-map "^0.6.1" + source-map "^0.7.3" "@types/webpack@^4.4.25": - version "4.41.7" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.7.tgz#22be27dbd4362b01c3954ca9b021dbc9328d9511" - integrity sha512-OQG9viYwO0V1NaNV7d0n79V+n6mjOV30CwgFPIfTzwmk8DHbt+C4f2aBGdCYbo3yFyYD6sjXfqqOjwkl1j+ulA== + version "4.41.26" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.26.tgz#27a30d7d531e16489f9c7607c747be6bc1a459ef" + integrity sha512-7ZyTfxjCRwexh+EJFwRUM+CDB2XvgHl4vfuqf1ZKrgGvcS5BrNvPQqJh3tsZ0P6h6Aa1qClVHaJZszLPzpqHeA== dependencies: "@types/anymatch" "*" "@types/node" "*" @@ -119,150 +119,149 @@ resolved "https://registry.yarnpkg.com/@types/winreg/-/winreg-1.2.30.tgz#91d6710e536d345b9c9b017c574cf6a8da64c518" integrity sha1-kdZxDlNtNFucmwF8V0z2qNpkxRg= -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== - dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== - -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== - -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== - -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== - dependencies: - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== - -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== - dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== - -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== - -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" "@xtuc/long" "4.2.2" -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -275,10 +274,10 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -acorn@^6.2.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" - integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== +acorn@^6.4.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== ajv-errors@^1.0.0: version "1.0.1" @@ -286,14 +285,14 @@ ajv-errors@^1.0.0: integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" - integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== ajv@^6.1.0, ajv@^6.10.2: - version "6.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" - integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" @@ -320,6 +319,14 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -357,14 +364,15 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== dependencies: bn.js "^4.0.0" inherits "^2.0.1" minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" asn1@~0.2.0: version "0.2.4" @@ -407,9 +415,9 @@ balanced-match@^1.0.0: integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base@^0.11.1: version "0.11.2" @@ -441,6 +449,11 @@ binary-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" @@ -453,10 +466,15 @@ bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.0.0, bn.js@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== brace-expansion@^1.1.7: version "1.1.11" @@ -482,14 +500,14 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.1: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" -brorand@^1.0.1: +brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= @@ -525,26 +543,28 @@ browserify-des@^1.0.0: inherits "^2.0.1" safe-buffer "^5.1.2" -browserify-rsa@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: - bn.js "^4.1.0" + bn.js "^5.0.0" randombytes "^2.0.1" browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" browserify-zlib@^0.2.0: version "0.2.0" @@ -578,9 +598,9 @@ builtin-status-codes@^3.0.0: integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= cacache@^12.0.2: - version "12.0.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" - integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== dependencies: bluebird "^3.5.5" chownr "^1.1.1" @@ -618,7 +638,7 @@ camelcase@^5.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -chalk@2.4.2, chalk@^2.3.0: +chalk@^2.3.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -627,7 +647,7 @@ chalk@2.4.2, chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chokidar@^2.0.2: +chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== @@ -646,6 +666,21 @@ chokidar@^2.0.2: optionalDependencies: fsevents "^1.2.7" +chokidar@^3.4.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.3.1" + chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -782,14 +817,14 @@ core-util-is@~1.0.0: integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== dependencies: bn.js "^4.1.0" - elliptic "^6.0.0" + elliptic "^6.5.3" -create-hash@^1.1.0, create-hash@^1.1.2: +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== @@ -800,7 +835,7 @@ create-hash@^1.1.0, create-hash@^1.1.2: ripemd160 "^2.0.1" sha.js "^2.4.0" -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== @@ -812,7 +847,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" -cross-spawn@6.0.5, cross-spawn@^6.0.0: +cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -944,29 +979,24 @@ duplexify@^3.4.2, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" -elliptic@^6.0.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" - integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== +elliptic@^6.5.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" + bn.js "^4.11.9" + brorand "^1.1.0" hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" emoji-regex@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== -emojis-list@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" - integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= - emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" @@ -979,15 +1009,6 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhanced-resolve@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" - integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" - tapable "^1.0.0" - enhanced-resolve@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz#5d43bda4a0fd447cb0ebbe71bef8deff8805ad0d" @@ -997,19 +1018,19 @@ enhanced-resolve@^4.0.0: memory-fs "^0.5.0" tapable "^1.0.0" -enhanced-resolve@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" - integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== +enhanced-resolve@^4.1.1, enhanced-resolve@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== dependencies: graceful-fs "^4.1.2" memory-fs "^0.5.0" tapable "^1.0.0" errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== dependencies: prr "~1.0.1" @@ -1027,17 +1048,22 @@ eslint-scope@^4.0.3: estraverse "^4.1.1" 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== + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: - estraverse "^4.1.0" + estraverse "^5.2.0" -estraverse@^4.1.0, estraverse@^4.1.1: +estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== +estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + event-stream@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-4.0.1.tgz#4092808ec995d0dd75ea4580c1df6a74db2cde65" @@ -1052,9 +1078,9 @@ event-stream@^4.0.1: through "^2.3.8" events@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" - integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" @@ -1064,19 +1090,6 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -1127,9 +1140,9 @@ extglob@^2.0.4: to-regex "^3.0.1" fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-json-stable-stringify@^2.0.0: version "2.1.0" @@ -1137,9 +1150,9 @@ fast-json-stable-stringify@^2.0.0: integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== figgy-pudding@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" - integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== file-uri-to-path@1.0.0: version "1.0.0" @@ -1179,7 +1192,7 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -findup-sync@3.0.0: +findup-sync@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== @@ -1247,25 +1260,23 @@ fs.realpath@^1.0.0: integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.2.7: - version "1.2.12" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.12.tgz#db7e0d8ec3b0b45724fd4d83d43554a8f1f0de5c" - integrity sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q== + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== dependencies: bindings "^1.5.0" nan "^2.12.1" +fsevents@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -1279,6 +1290,13 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" +glob-parent@~5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + glob@^7.0.3, glob@^7.1.3, glob@^7.1.4: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" @@ -1291,13 +1309,6 @@ glob@^7.0.3, glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -global-modules@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" - integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== - dependencies: - global-prefix "^3.0.0" - global-modules@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" @@ -1307,6 +1318,13 @@ global-modules@^1.0.0: is-windows "^1.0.1" resolve-dir "^1.0.0" +global-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + global-prefix@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" @@ -1339,9 +1357,9 @@ globby@^6.1.0: pinkie-promise "^2.0.0" graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== has-flag@^3.0.0: version "3.0.0" @@ -1380,12 +1398,13 @@ has-values@^1.0.0: kind-of "^4.0.0" hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" @@ -1395,7 +1414,7 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hmac-drbg@^1.0.0: +hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= @@ -1417,16 +1436,16 @@ https-browserify@^1.0.0: integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== iferr@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= -import-local@2.0.0: +import-local@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== @@ -1452,7 +1471,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -1468,21 +1487,16 @@ inherits@2.0.3: integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= ini@^1.3.4, ini@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -interpret@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" - integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== +interpret@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== -ip@1.1.5: +ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= @@ -1508,6 +1522,13 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -1574,7 +1595,7 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" -is-glob@^4.0.0: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== @@ -1619,11 +1640,6 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -1674,9 +1690,9 @@ json5@^1.0.1: minimist "^1.2.0" jsonc-parser@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.2.1.tgz#db73cd59d78cce28723199466b2a03d1be1df2bc" - integrity sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w== + version "2.3.1" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.3.1.tgz#59549150b133f2efacca48fe9ce1ec0659af2342" + integrity sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg== kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" @@ -1702,28 +1718,12 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== -loader-utils@1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" - integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== - dependencies: - big.js "^5.2.2" - emojis-list "^2.0.0" - json5 "^1.0.1" - -loader-utils@^1.0.2, loader-utils@^1.2.3: +loader-utils@^1.0.2, loader-utils@^1.2.3, loader-utils@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== @@ -1755,18 +1755,6 @@ make-dir@^2.0.0: pify "^4.0.1" semver "^5.6.0" -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -1793,16 +1781,7 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - -memory-fs@^0.4.0, memory-fs@^0.4.1: +memory-fs@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= @@ -1853,29 +1832,24 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.43.0: - version "1.43.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" - integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== +mime-db@1.46.0: + version "1.46.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee" + integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ== mime-types@^2.1.12: - version "2.1.26" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" - integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== + version "2.1.29" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2" + integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ== dependencies: - mime-db "1.43.0" - -mimic-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + mime-db "1.46.0" minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: +minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= @@ -1916,10 +1890,10 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.1: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.3.tgz#5a514b7179259287952881e94410ec5465659f8c" - integrity sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg== +mkdirp@^0.5.1, mkdirp@^0.5.3: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" @@ -1941,9 +1915,9 @@ ms@2.0.0: integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= nan@^2.12.1: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + version "2.14.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== nanomatch@^1.2.9: version "1.2.13" @@ -1963,9 +1937,9 @@ nanomatch@^1.2.9: to-regex "^3.0.1" neo-async@^2.5.0, neo-async@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== nice-try@^1.0.4: version "1.0.5" @@ -2008,18 +1982,11 @@ normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" -normalize-path@^3.0.0: +normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2060,34 +2027,10 @@ os-browserify@^0.3.0: resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= -os-locale@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - p-limit@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" @@ -2122,14 +2065,13 @@ parallel-transform@^1.1.0: inherits "^2.0.3" readable-stream "^2.1.5" -parse-asn1@^5.0.0: - version "5.1.5" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" - integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== dependencies: - asn1.js "^4.0.0" + asn1.js "^5.2.0" browserify-aes "^1.0.0" - create-hash "^1.1.0" evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" safe-buffer "^5.1.1" @@ -2169,7 +2111,7 @@ path-is-inside@^1.0.2: resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= -path-key@^2.0.0, path-key@^2.0.1: +path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= @@ -2182,9 +2124,9 @@ pause-stream@^0.0.11: through "~2.3" pbkdf2@^3.0.3: - version "3.0.17" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" - integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + version "3.1.1" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" + integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -2192,7 +2134,7 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" -picomatch@^2.0.5: +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== @@ -2313,7 +2255,7 @@ querystring@0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== @@ -2341,6 +2283,15 @@ randomfill@^1.0.3: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -2350,6 +2301,13 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -2435,10 +2393,10 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" @@ -2452,7 +2410,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -safer-buffer@~2.1.0: +safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -2476,10 +2434,12 @@ semver@^6.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -serialize-javascript@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" - integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" set-blocking@^2.0.0: version "2.0.0" @@ -2521,11 +2481,6 @@ shebang-regex@^1.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= -signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - smart-buffer@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" @@ -2562,11 +2517,11 @@ snapdragon@^0.8.1: use "^3.1.0" socks@^2.2.0: - version "2.3.3" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3" - integrity sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA== + version "2.6.0" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.0.tgz#6b984928461d39871b3666754b9000ecf39dfac2" + integrity sha512-mNmr9owlinMplev0Wd7UHFlqI4ofnBnNzFuzrm63PPaHgbkqCFe4T5LzwKmtQ/f2tX0NTpcdVLyD/FHxFBstYw== dependencies: - ip "1.1.5" + ip "^1.1.5" smart-buffer "^4.1.0" source-list-map@^2.0.0: @@ -2585,7 +2540,7 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.5.19: +source-map-support@^0.5.19, source-map-support@~0.5.12: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== @@ -2593,18 +2548,10 @@ source-map-support@^0.5.19: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@~0.5.12: - version "0.5.16" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" - integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== source-map@^0.5.6: version "0.5.7" @@ -2616,6 +2563,11 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -2630,10 +2582,9 @@ split@^1.0.1: dependencies: through "2" -ssh2-streams@~0.4.10: +ssh2-streams@Timmmm/ssh2-streams#patch-1, ssh2-streams@~0.4.10: version "0.4.10" - resolved "https://registry.yarnpkg.com/ssh2-streams/-/ssh2-streams-0.4.10.tgz#48ef7e8a0e39d8f2921c30521d56dacb31d23a34" - integrity sha512-8pnlMjvnIZJvmTzUIIA5nT4jr2ZWNNVHwyXfMGdRJbug9TpI3kd99ffglgfSWqujVv/0gxwMsDn9j9RVst8yhQ== + resolved "https://codeload.github.com/Timmmm/ssh2-streams/tar.gz/75f6d3425d071ac73a18fd46e2f5e738bfe897c5" dependencies: asn1 "~0.2.0" bcrypt-pbkdf "^1.0.2" @@ -2715,7 +2666,7 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string_decoder@^1.0.0: +string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -2736,18 +2687,6 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -supports-color@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -2755,30 +2694,37 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== terser-webpack-plugin@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" - integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== + version "1.4.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" + integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== dependencies: cacache "^12.0.2" find-cache-dir "^2.1.0" is-wsl "^1.1.0" schema-utils "^1.0.0" - serialize-javascript "^2.1.2" + serialize-javascript "^4.0.0" source-map "^0.6.1" terser "^4.1.2" webpack-sources "^1.4.0" worker-farm "^1.7.0" terser@^4.1.2: - version "4.6.7" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.7.tgz#478d7f9394ec1907f0e488c5f6a6a9a2bad55e72" - integrity sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g== + version "4.8.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" + integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== dependencies: commander "^2.20.0" source-map "~0.6.1" @@ -2798,9 +2744,9 @@ through@2, through@^2.3.8, through@~2.3, through@~2.3.4: integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= timers-browserify@^2.0.4: - version "2.0.11" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" - integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== dependencies: setimmediate "^1.0.4" @@ -2853,9 +2799,9 @@ ts-loader@^7.0.5: semver "^6.0.0" tslib@^1.9.0: - version "1.11.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" - integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tty-browserify@0.0.0: version "0.0.0" @@ -2872,10 +2818,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.2.tgz#7ea7c88777c723c681e33bf7988be5d008d05ac2" - integrity sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ== +typescript@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" + integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== union-value@^1.0.0: version "1.0.1" @@ -2915,9 +2861,9 @@ upath@^1.1.1: integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" @@ -2939,7 +2885,7 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -2958,41 +2904,50 @@ util@^0.11.0: dependencies: inherits "2.0.3" -v8-compile-cache@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" - integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== +v8-compile-cache@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -watchpack@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== + dependencies: + chokidar "^2.1.8" + +watchpack@^1.7.4: + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== dependencies: - chokidar "^2.0.2" graceful-fs "^4.1.2" neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.1" + watchpack-chokidar2 "^2.0.1" webpack-cli@^3.2.3: - version "3.3.11" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.11.tgz#3bf21889bf597b5d82c38f215135a411edfdc631" - integrity sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g== - dependencies: - chalk "2.4.2" - cross-spawn "6.0.5" - enhanced-resolve "4.1.0" - findup-sync "3.0.0" - global-modules "2.0.0" - import-local "2.0.0" - interpret "1.2.0" - loader-utils "1.2.3" - supports-color "6.1.0" - v8-compile-cache "2.0.3" - yargs "13.2.4" + version "3.3.12" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.12.tgz#94e9ada081453cd0aa609c99e500012fd3ad2d4a" + integrity sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag== + dependencies: + chalk "^2.4.2" + cross-spawn "^6.0.5" + enhanced-resolve "^4.1.1" + findup-sync "^3.0.0" + global-modules "^2.0.0" + import-local "^2.0.0" + interpret "^1.4.0" + loader-utils "^1.4.0" + supports-color "^6.1.0" + v8-compile-cache "^2.1.1" + yargs "^13.3.2" webpack-sources@^1.4.0, webpack-sources@^1.4.1: version "1.4.3" @@ -3003,32 +2958,32 @@ webpack-sources@^1.4.0, webpack-sources@^1.4.1: source-map "~0.6.1" webpack@^4.29.6: - version "4.42.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.42.0.tgz#b901635dd6179391d90740a63c93f76f39883eb8" - integrity sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.2.1" + version "4.46.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" + integrity sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" ajv "^6.10.2" ajv-keywords "^3.4.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^4.1.0" + enhanced-resolve "^4.5.0" eslint-scope "^4.0.3" json-parse-better-errors "^1.0.2" loader-runner "^2.4.0" loader-utils "^1.2.3" memory-fs "^0.4.1" micromatch "^3.1.10" - mkdirp "^0.5.1" + mkdirp "^0.5.3" neo-async "^2.6.1" node-libs-browser "^2.2.1" schema-utils "^1.0.0" tapable "^1.1.3" terser-webpack-plugin "^1.4.3" - watchpack "^1.6.0" + watchpack "^1.7.4" webpack-sources "^1.4.1" which-module@^2.0.0: @@ -3075,16 +3030,16 @@ xtend@^4.0.0, xtend@~4.0.1: integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + version "4.0.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" + integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yargs-parser@^13.1.0: +yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== @@ -3092,19 +3047,18 @@ yargs-parser@^13.1.0: camelcase "^5.0.0" decamelize "^1.2.0" -yargs@13.2.4: - version "13.2.4" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" - integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== +yargs@^13.3.2: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== dependencies: cliui "^5.0.0" find-up "^3.0.0" get-caller-file "^2.0.1" - os-locale "^3.1.0" require-directory "^2.1.1" require-main-filename "^2.0.0" set-blocking "^2.0.0" string-width "^3.0.0" which-module "^2.0.0" y18n "^4.0.0" - yargs-parser "^13.1.0" + yargs-parser "^13.1.2"