diff --git a/README.md b/README.md index c9975c7f..37eb1f77 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,9 @@ yarn add dotenv-azure #### Configuring App Configuration 1. [Create an app configuration store via Azure portal or CLI](https://docs.microsoft.com/en-us/azure/azure-app-configuration/quickstart-aspnet-core-app#create-an-app-configuration-store). -2. Set **AZURE_APP_CONFIG_URL** and **AZURE_APP_CONFIG_CONNECTION_STRING** as environment variables using bash or put them in a `.env` file: - -> In production, if you are using [Azure Managed Identities](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview), you just have to set **AZURE_APP_CONFIG_URL**. +2. Set **AZURE_APP_CONFIG_CONNECTION_STRING** as environment variable using bash or put them in a `.env` file: ```bash -AZURE_APP_CONFIG_URL="https://your-app-config.azconfig.io" AZURE_APP_CONFIG_CONNECTION_STRING="generated-app-config-conneciton-string" ``` @@ -60,14 +57,15 @@ AZURE_CLIENT_SECRET="random-password" AZURE_TENANT_ID="tenant-ID" ``` -If you have a configuration in Azure App Configuration with a value starting with `kv:`, `dotenv-azure` will try to load them from key vault. +If you have a configuration in App Configuration with the content type `application/vnd.microsoft.appconfig.keyvaultref+json;charset=utf-8` then `dotenv-azure` will try to load it from Key Vault. -Let's assume you have created a secret in Key Vault, copied the secret url and created a new configuration in App Configuration with a value of the url of your secret: -```bash -DATABASE_URL=kv:https://your.vault.azure.net/secrets/DatabaseUrl/7091540ce97143deb08790a53fc2a75d -``` +You can [add a Key Vault reference](https://docs.microsoft.com/en-us/azure/azure-app-configuration/use-key-vault-references-dotnet-core) to App Configuration in the Azure portal: + +1. Sign in to the Azure portal. Select All resources, and then select the App Configuration store instance that you created in the quickstart +2. Select Configuration Explorer +3. Select + Create > Key vault reference -After calling `.config()` method, the value of your key vault scret will be set to process.env: +Now when you call the `.config()` method, the value of your key vault secret will be set to process.env: ```javascript const { DotenvAzure } = require('dotenv-azure') diff --git a/config-safe.js b/config-safe.js index e3eee627..acef8f75 100644 --- a/config-safe.js +++ b/config-safe.js @@ -2,12 +2,9 @@ const forceSync = require('sync-rpc') const { populateProcessEnv } = require('./dist/lib/utils') const configSync = forceSync(require.resolve('./config-rpc')) -try { - const { parsed } = configSync({ - safe: true, - allowEmptyValues: true - }) - populateProcessEnv(parsed) -} catch { - // noop -} +const { parsed } = configSync({ + safe: true, + allowEmptyValues: true +}) + +populateProcessEnv(parsed) diff --git a/config.js b/config.js index b081e2d8..f83d4ab6 100644 --- a/config.js +++ b/config.js @@ -2,9 +2,5 @@ const forceSync = require('sync-rpc') const { populateProcessEnv } = require('./dist/lib/utils') const configSync = forceSync(require.resolve('./config-rpc')) -try { - const { parsed } = configSync() - populateProcessEnv(parsed) -} catch { - // noop -} +const { parsed } = configSync() +populateProcessEnv(parsed) diff --git a/package.json b/package.json index 6f7ae88c..c1f4a3f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dotenv-azure", - "version": "1.0.1-beta.1", + "version": "1.0.0-beta.6", "description": "Load environment variables from Azure's services App Configuration, Key Vault or a .env file", "keywords": [ "azure", @@ -77,44 +77,47 @@ "@commitlint/config-conventional" ] }, + "resolutions": { + "typescript": "^3.7.2" + }, "devDependencies": { - "@commitlint/cli": "^8.1.0", - "@commitlint/config-conventional": "^8.1.0", - "@semantic-release/changelog": "^3.0.4", + "@commitlint/cli": "^8.2.0", + "@commitlint/config-conventional": "^8.2.0", + "@semantic-release/changelog": "^3.0.5", "@semantic-release/git": "^7.1.0-beta.3", "@types/dotenv": "^8.2.0", - "@types/jest": "^24.0.18", - "@types/node": "^12", - "@typescript-eslint/eslint-plugin": "^2.3.0", - "@typescript-eslint/parser": "^2.3.0", - "codecov": "^3.5.0", + "@types/jest": "^24.0.22", + "@types/node": "^12.12.6", + "@typescript-eslint/eslint-plugin": "^2.6.1", + "@typescript-eslint/parser": "^2.6.1", + "codecov": "^3.6.1", "commitizen": "^4.0.3", "cz-conventional-changelog": "^3.0.2", - "eslint": "^6.4.0", - "eslint-config-prettier": "^6.3.0", + "eslint": "^6.6.0", + "eslint-config-prettier": "^6.5.0", "eslint-config-standard": "^14.1.0", "eslint-plugin-import": "^2.18.2", "eslint-plugin-node": "^10.0.0", "eslint-plugin-promise": "^4.2.1", "eslint-plugin-standard": "^4.0.1", - "husky": "^3.0.5", + "husky": "^3.0.9", "jest": "^24.9.0", "jest-config": "^24.9.0", - "lint-staged": "^9.2.5", + "lint-staged": "^9.4.2", "prettier": "^1.18.2", "rimraf": "^3.0.0", "semantic-release": "^16.0.0-beta.24", "ts-jest": "^24.1.0", "ts-node": "^8.4.1", "typedoc": "^0.15.0", - "typescript": "^3.6.3" + "typescript": "^3.7.2" }, "dependencies": { - "@azure/app-configuration": "1.0.0-preview.3", - "@azure/identity": "1.0.0-preview.5", - "@azure/keyvault-secrets": "4.0.0-preview.8", + "@azure/app-configuration": "1.0.0-preview.7", + "@azure/identity": "1.0.0", + "@azure/keyvault-secrets": "4.0.0", "bottleneck": "^2.19.5", - "dotenv": "^8.1.0", + "dotenv": "^8.2.0", "sync-rpc": "^1.3.6" } } diff --git a/src/dotenv-azure.ts b/src/dotenv-azure.ts index 4cd3647e..be345638 100644 --- a/src/dotenv-azure.ts +++ b/src/dotenv-azure.ts @@ -1,10 +1,10 @@ import * as fs from 'fs' import Bottleneck from 'bottleneck' -import dotenv, { DotenvParseOptions } from 'dotenv' +import dotenv, { DotenvParseOptions, DotenvParseOutput } from 'dotenv' import { ManagedIdentityCredential, ClientSecretCredential } from '@azure/identity' -import { SecretsClient } from '@azure/keyvault-secrets' -import { AppConfigurationClient, ModelConfigurationSetting } from '@azure/app-configuration' -import { testIfValueIsVaultSecret, compact, difference, populateProcessEnv } from './utils' +import { SecretClient } from '@azure/keyvault-secrets' +import { AppConfigurationClient, ConfigurationSetting } from '@azure/app-configuration' +import { compact, difference, populateProcessEnv } from './utils' import { MissingEnvVarsError, InvalidKeyVaultUrlError, MissingAppConfigCredentialsError } from './errors' import { DotenvAzureOptions, @@ -12,23 +12,32 @@ import { DotenvAzureConfigOutput, DotenvAzureParseOutput, VariablesObject, - AzureCredentials + AzureCredentials, + AppConfigurations, + KeyVaultReferenceInfo, + KeyVaultReferences } from './types' export default class DotenvAzure { - private readonly rateLimitMinTime: number - private readonly appConfigUrl?: string + private readonly keyVaultRateLimitMinTime: number + private readonly connectionString?: string + private readonly tenantId?: string + private readonly clientId?: string + private readonly clientSecret?: string private readonly keyVaultClients: { - [vaultURL: string]: SecretsClient + [vaultURL: string]: SecretClient } /** * Initializes a new instance of the DotenvAzure class. */ - constructor({ appConfigUrl, rateLimit = 45 }: DotenvAzureOptions = {}) { + constructor({ rateLimit = 45, tenantId, clientId, clientSecret, connectionString }: DotenvAzureOptions = {}) { + this.keyVaultRateLimitMinTime = Math.ceil(1000 / rateLimit) + this.connectionString = connectionString + this.tenantId = tenantId + this.clientId = clientId + this.clientSecret = clientSecret this.keyVaultClients = {} - this.appConfigUrl = appConfigUrl - this.rateLimitMinTime = Math.ceil(1000 / rateLimit) } /** @@ -73,14 +82,14 @@ export default class DotenvAzure { /** * Loads your Azure App Configuration and Key Vault variables. * It does not change {@link https://nodejs.org/api/process.html#process_process_env | `process.env`}. - * @param vars - an optional object with azure creadentials variables + * @param dotenvVars - dotenv parse() output containing azure credentials variables * @returns an object with keys and values */ - async loadFromAzure(vars?: VariablesObject): Promise { - const credentials = this.getAuthVariables(vars) - const appConfigClient = this.getAppConfigClient(credentials) - const appConfigVars = await this.getVariablesFromAppConfig(appConfigClient) - const keyVaultSecrets = await this.getSecretsFromKeyVault(credentials, appConfigVars) + async loadFromAzure(dotenvVars?: DotenvParseOutput): Promise { + const credentials = this.getAzureCredentials(dotenvVars) + const appConfigClient = new AppConfigurationClient(credentials.connectionString) + const { appConfigVars, keyVaultReferences: keyvaultReferences } = await this.getAppConfigurations(appConfigClient) + const keyVaultSecrets = await this.getSecretsFromKeyVault(credentials, keyvaultReferences) return { ...appConfigVars, ...keyVaultSecrets } } @@ -94,91 +103,93 @@ export default class DotenvAzure { } } - protected async getVariablesFromAppConfig(client: AppConfigurationClient): Promise { - let vars: VariablesObject = {} - const request = await client.listConfigurationSettings() - const body = request._response.parsedBody - - if (body.items) { - vars = body.items - .filter(item => item.key) - .reduce( - (acc, item: ModelConfigurationSetting) => ({ - ...acc, - [item.key || Symbol('key')]: item.value || '' - }), - {} as VariablesObject - ) + protected async getAppConfigurations(client: AppConfigurationClient): Promise { + const appConfigVars: VariablesObject = {} + const keyVaultReferences: KeyVaultReferences = {} + + for await (const config of client.listConfigurationSettings()) { + if (this.isKeyVaultReference(config)) { + keyVaultReferences[config.key] = this.getKeyVaultReferenceInfo(config) + } else { + appConfigVars[config.key] = config.value + } } - return vars + return { appConfigVars, keyVaultReferences } } protected async getSecretsFromKeyVault( credentials: AzureCredentials, - vars: VariablesObject + vars: KeyVaultReferences ): Promise { const secrets: VariablesObject = {} // limit requests to avoid Azure AD rate limiting - const limiter = new Bottleneck({ minTime: this.rateLimitMinTime }) - - const getSecret = async (key: string, value: string): Promise => { - const keyVaultUrl = testIfValueIsVaultSecret(value) - if (!keyVaultUrl) return + const limiter = new Bottleneck({ minTime: this.keyVaultRateLimitMinTime }) - const [, , secretName, secretVersion] = keyVaultUrl.pathname.split('/') - if (!secretName || !secretVersion) { - throw new InvalidKeyVaultUrlError(key.replace('kv:', '')) - } - - const keyVaultClient = this.getKeyVaultClient(credentials, keyVaultUrl.origin) - const response = await keyVaultClient.getSecret(secretName, { version: secretVersion }) - secrets[key] = response.value || '' + const getSecret = async (key: string, info: KeyVaultReferenceInfo): Promise => { + const keyVaultClient = this.getKeyVaultClient(credentials, info.vaultUrl.href) + const response = await keyVaultClient.getSecret(info.secretName, { version: info.secretVersion }) + secrets[key] = response.value } - await Promise.all(Object.entries(vars).map(([key, val]) => limiter.schedule(() => getSecret(key, val)))) - + const secretsPromises = Object.entries(vars).map(([key, val]) => limiter.schedule(() => getSecret(key, val))) + await Promise.all(secretsPromises) return secrets } - protected getAppConfigClient(credentials: AzureCredentials): AppConfigurationClient { - const { appConfigUrl = '', appConfigConnectionString } = credentials - if (appConfigConnectionString) { - return new AppConfigurationClient(appConfigConnectionString) - } else { - return new AppConfigurationClient(appConfigUrl, new ManagedIdentityCredential()) - } - } - - protected getKeyVaultClient(credentials: AzureCredentials, vaultURL: string): SecretsClient { + protected getKeyVaultClient(credentials: AzureCredentials, vaultURL: string): SecretClient { const { tenantId, clientId, clientSecret } = credentials if (!this.keyVaultClients[vaultURL]) { if (tenantId && clientId && clientSecret) { - this.keyVaultClients[vaultURL] = new SecretsClient( + this.keyVaultClients[vaultURL] = new SecretClient( vaultURL, new ClientSecretCredential(tenantId, clientId, clientSecret) ) } else { - this.keyVaultClients[vaultURL] = new SecretsClient(vaultURL, new ManagedIdentityCredential()) + this.keyVaultClients[vaultURL] = new SecretClient(vaultURL, new ManagedIdentityCredential()) } } return this.keyVaultClients[vaultURL] } - private getAuthVariables(dotenvVars: VariablesObject = {}): AzureCredentials { + protected getKeyVaultReferenceInfo({ key, value }: ConfigurationSetting): KeyVaultReferenceInfo { + try { + const obj = value && JSON.parse(value) + const keyVaultUrl = new URL(obj.uri) + const [, , secretName, secretVersion] = keyVaultUrl.pathname.split('/') + if (!secretName) { + throw new Error('KeyVault URL does not have a secret name') + } + return { + vaultUrl: new URL(keyVaultUrl.origin), + secretUrl: keyVaultUrl, + secretName, + secretVersion + } + } catch { + throw new InvalidKeyVaultUrlError(key) + } + } + + protected isKeyVaultReference(config: ConfigurationSetting): boolean { + return config.contentType === 'application/vnd.microsoft.appconfig.keyvaultref+json;charset=utf-8' + } + + private getAzureCredentials(dotenvVars: DotenvParseOutput = {}): AzureCredentials { const vars = { ...dotenvVars, ...process.env } - if (!vars.AZURE_APP_CONFIG_URL && !vars.AZURE_APP_CONFIG_CONNECTION_STRING && !this.appConfigUrl) { + const connectionString = this.connectionString || vars.AZURE_APP_CONFIG_CONNECTION_STRING + + if (!connectionString) { throw new MissingAppConfigCredentialsError() } return { - appConfigUrl: this.appConfigUrl || vars.AZURE_APP_CONFIG_URL, - appConfigConnectionString: vars.AZURE_APP_CONFIG_CONNECTION_STRING, - tenantId: vars.AZURE_TENANT_ID, - clientId: vars.AZURE_CLIENT_ID, - clientSecret: vars.AZURE_CLIENT_SECRET + connectionString, + tenantId: this.tenantId || vars.AZURE_TENANT_ID, + clientId: this.clientId || vars.AZURE_CLIENT_ID, + clientSecret: this.clientSecret || vars.AZURE_CLIENT_SECRET } } } diff --git a/src/types.ts b/src/types.ts index f26b5ef9..0bd6c587 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,8 +1,7 @@ import { DotenvConfigOptions, DotenvConfigOutput } from 'dotenv' export interface AzureCredentials { - appConfigUrl?: string - appConfigConnectionString?: string + connectionString: string clientId?: string clientSecret?: string tenantId?: string @@ -12,14 +11,46 @@ export interface AzureCredentials { * An object with keys and values */ export type VariablesObject = { - [name: string]: string + [key: string]: string | undefined +} + +export interface AppConfigurations { + appConfigVars: VariablesObject + keyVaultReferences: KeyVaultReferences +} + +export interface KeyVaultReferenceInfo { + vaultUrl: URL + secretUrl: URL + secretName: string + secretVersion?: string +} + +export interface KeyVaultReferences { + [key: string]: KeyVaultReferenceInfo } export interface DotenvAzureOptions { /** - * You can pass the url of the App Configuration intstead of the environment variable AZURE_APP_CONFIG_URL + * You can pass the connection string of the App Configuration + * intstead of the environment variable AZURE_APP_CONFIG_CONNECTION_STRING + */ + connectionString?: string + /** + * You can pass the id of the principal's Azure Active Directory tenant + * intstead of the environment variable AZURE_TENANT_ID */ - appConfigUrl?: string + tenantId?: string + /** + * You can pass the service principal's app id + * intstead of the environment variable AZURE_CLIENT_ID + */ + clientId?: string + /** + * You can pass one of the service principal's client secrets + * intstead of the environment variable AZURE_CLIENT_SECRET + */ + clientSecret?: string /** * Number of requests per second to avoid Azure AD rate limiter. Default: 45 */ diff --git a/src/utils.ts b/src/utils.ts index 58804fb4..75924059 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,14 +1,10 @@ import { VariablesObject } from './types' -interface ProcessEnv { - [key: string]: string | undefined -} - export function difference(arrA: string[], arrB: string[]): string[] { return arrA.filter(a => !arrB.includes(a)) } -export function compact(obj: ProcessEnv): VariablesObject { +export function compact(obj: VariablesObject): VariablesObject { const result: VariablesObject = {} Object.entries(obj).forEach(([key, val]) => { if (val) { @@ -18,17 +14,6 @@ export function compact(obj: ProcessEnv): VariablesObject { return result } -export function testIfValueIsVaultSecret(value: string): URL | undefined { - const result = /^kv:(.+)/.exec(value) - let keyVaultUrl - try { - keyVaultUrl = result ? new URL(result[1]) : undefined - } catch { - // noop - } - return keyVaultUrl -} - /** * Add variable if does not exist in process.env * @param variables - an object with keys and values diff --git a/test/azure.mock.ts b/test/azure.mock.ts index 2d8c705d..2cbea5cd 100644 --- a/test/azure.mock.ts +++ b/test/azure.mock.ts @@ -1,25 +1,29 @@ +import { ConfigurationSetting } from '@azure/app-configuration' +import { GetSecretOptions, KeyVaultSecret } from '@azure/keyvault-secrets' + export interface AppConfigListItemMock { key: string value: string } -export function mockAppConfigListResponse(items: AppConfigListItemMock[]) { - return { - _response: { - parsedBody: { items } - } +export async function* mockAppConfigListResponse(items: ConfigurationSetting[]) { + for (const item of items) { + yield item } } export const appConfigListMock = jest.fn(() => mockAppConfigListResponse([ { + readOnly: false, key: 'APP_CONFIG_VAR', value: 'ok' }, { + readOnly: true, key: 'KEY_VAULT_VAR', - value: 'kv:https://key.vault.azure.net/secrets/DatabaseUrl/7091540ce97143deb08790a53fc2a75d' + value: '{"uri": "https://key.vault.azure.net/secrets/DatabaseUrl/7091540ce97143deb08790a53fc2a75d"}', + contentType: 'application/vnd.microsoft.appconfig.keyvaultref+json;charset=utf-8' } ]) ) @@ -34,13 +38,18 @@ export const AppConfigurationClientMock = jest.mock('@azure/app-configuration', })) export const secretsClientMock = jest.mock('@azure/keyvault-secrets', () => ({ - SecretsClient: class SecretsClient { + SecretClient: class SecretClient { getSecret: any constructor() { - this.getSecret = () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + this.getSecret = async (secretName: string, options?: GetSecretOptions): Promise => { return { - key: 'DatabaseUrl', - value: 'ok' + name: secretName, + value: 'ok', + properties: { + vaultUrl: 'https://key.vault.azure.net', + name: 'DatabaseUrl' + } } } } diff --git a/test/dotenv-azure.test.ts b/test/dotenv-azure.test.ts index c927a904..c66885bb 100644 --- a/test/dotenv-azure.test.ts +++ b/test/dotenv-azure.test.ts @@ -14,13 +14,12 @@ const mockReadFileSync = readFileSync as jest.Mock describe('DotenvAzure', () => { const OLD_ENV = process.env - const AZURE_APP_CONFIG_URL = 'https://test.azconfig.io' const AZURE_APP_CONFIG_CONNECTION_STRING = 'app-config-conneciton-string' const AZURE_TENANT_ID = 'tenant-id' const AZURE_CLIENT_ID = 'client-id' const AZURE_CLIENT_SECRET = 'client-secret' const dotenvAzure = new DotenvAzure({ - appConfigUrl: AZURE_APP_CONFIG_URL + connectionString: AZURE_APP_CONFIG_CONNECTION_STRING }) beforeEach(() => { @@ -35,12 +34,6 @@ describe('DotenvAzure', () => { }) describe('config()', () => { - it('does not throw when AZURE_APP_CONFIG_URL is defined', async () => { - process.env = { ...OLD_ENV, AZURE_APP_CONFIG_URL } - const dotenvAzure = new DotenvAzure() - expect(await dotenvAzure.config()).toBeDefined() - }) - it('does not throw when AZURE_APP_CONFIG_CONNECTION_STRING is defined', async () => { process.env = { ...OLD_ENV, AZURE_APP_CONFIG_CONNECTION_STRING } const dotenvAzure = new DotenvAzure() @@ -65,44 +58,19 @@ describe('DotenvAzure', () => { expect(azure).toEqual(azureVars) }) - it('ignores variables with `kv:` prefix that does not have a valid url', async () => { - appConfigListMock.mockReturnValueOnce( - mockAppConfigListResponse([ - { - key: 'APP_CONFIG_VAR', - value: 'ok' - }, - { - key: 'KEY_VAULT_VAR', - value: 'kv:invalid_url' - }, - { - key: 'KEY_VAULT_VAR_2', - value: 'kv:another_invalid_url' - } - ]) - ) - - const { parsed } = await dotenvAzure.config() - - expect(parsed).toEqual({ - ...dotenvVars, - ...appConfigVars, - KEY_VAULT_VAR: 'kv:invalid_url', - KEY_VAULT_VAR_2: 'kv:another_invalid_url' - }) - }) - - it('throws when variables with `kv:` prefix have an invalid KeyVault url', () => { + it('throws when variables have an invalid KeyVault url', () => { appConfigListMock.mockReturnValueOnce( mockAppConfigListResponse([ { + readOnly: true, key: 'APP_CONFIG_VAR', value: 'ok' }, { + readOnly: false, key: 'KEY_VAULT_VAR', - value: 'kv:https://key.vault.azure.net/secrets/DatabaseUrl' + value: '{"uri": "https://key.vault.azure.net/secrets/"}', + contentType: 'application/vnd.microsoft.appconfig.keyvaultref+json;charset=utf-8' } ]) ) @@ -149,10 +117,12 @@ describe('DotenvAzure', () => { appConfigListMock.mockReturnValueOnce( mockAppConfigListResponse([ { + readOnly: false, key: 'DATABASE_URL', value: 'from_appconfig' }, { + readOnly: false, key: 'PASSWORD', value: 'from_appconfig' } @@ -180,10 +150,12 @@ describe('DotenvAzure', () => { appConfigListMock.mockReturnValueOnce( mockAppConfigListResponse([ { + readOnly: false, key: 'DATABASE_URL', value: 'from_appconfig' }, { + readOnly: false, key: 'PASSWORD', value: 'from_appconfig' } diff --git a/yarn.lock b/yarn.lock index e969b97b..02a4d2e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,59 +2,47 @@ # yarn lockfile v1 -"@azure/abort-controller@1.0.0-preview.2": - version "1.0.0-preview.2" - resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.0.0-preview.2.tgz#4cbe53ea5294317e4f50fa4270ab459486b9fbfa" - integrity sha512-pd2MVcHaitEC0ZoeixSTkJqTJFkIUVglosV//P2C/VwLg+9moGyx/P+WH2onDYukEOL5CCEuF0LBDfnTeL0gVA== - dependencies: - tslib "^1.9.3" - -"@azure/app-configuration@1.0.0-preview.3": - version "1.0.0-preview.3" - resolved "https://registry.yarnpkg.com/@azure/app-configuration/-/app-configuration-1.0.0-preview.3.tgz#cdcd99fbf77066762411840adbb1140d0f3006f8" - integrity sha512-4ED3tPlEFlR5ekOMIQ+fWVbIIfNdEmtkVaMAUtXltSEa4WYJIUCoNRG460w5sjuwMT85W8vxCtdQPittHKA/BA== - dependencies: - "@azure/core-arm" "1.0.0-preview.3" - "@azure/core-http" "1.0.0-preview.3" - tslib "^1.9.3" - -"@azure/core-arm@1.0.0-preview.3": - version "1.0.0-preview.3" - resolved "https://registry.yarnpkg.com/@azure/core-arm/-/core-arm-1.0.0-preview.3.tgz#b1a240a726e52cd1fa37378ae15b29079a0070aa" - integrity sha512-YZZM1EIcJnH7ahIBy0wAZDTXeeNZiPYJnRMWl3wZ2PblSHUVdq1D2ZRZWwQWeWlgrNXhsO2HC/9ZAwq8OihRFw== +"@azure/abort-controller@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.0.0.tgz#75798c58fb486db20050c3ca00c5f2d7232f921a" + integrity sha512-U4RM+AuCxlwq1GDP+VSswfzxvsmQ2hUAAhii2Em2xf0e00/6CsZAoQnQCxhvLDe39pebjivobU29LioN9x+DJQ== dependencies: - "@azure/core-http" "1.0.0-preview.3" tslib "^1.9.3" -"@azure/core-arm@1.0.0-preview.5": - version "1.0.0-preview.5" - resolved "https://registry.yarnpkg.com/@azure/core-arm/-/core-arm-1.0.0-preview.5.tgz#91d78e05c9abc6dd40dcbd884455403c1d66d81e" - integrity sha512-lxxKxQdmq1bzo60VpZCdBqPH/v0Zffz047uvUjVIQ27/c7VtOUyMX3tseUWXCI62RyTzR7gK+Iw7Buij9fEzHg== +"@azure/app-configuration@1.0.0-preview.7": + version "1.0.0-preview.7" + resolved "https://registry.yarnpkg.com/@azure/app-configuration/-/app-configuration-1.0.0-preview.7.tgz#5043957ee686c45d21e8bb8fdac3861aaf395755" + integrity sha512-2mnBiTSyDi3HC7nJ2gVXRXLmPvbMP3RXnJ5NE5MASNSEVvg0eeGOU+oW5CG3Cm1LipFOIXxC+4/2slK+vLWrsg== dependencies: - "@azure/core-http" "1.0.0-preview.5" + "@azure/core-asynciterator-polyfill" "^1.0.0" + "@azure/core-http" "^1.0.0" + "@azure/core-paging" "^1.0.0" + "@azure/core-tracing" "1.0.0-preview.5" tslib "^1.9.3" -"@azure/core-asynciterator-polyfill@1.0.0-preview.1": - version "1.0.0-preview.1" - resolved "https://registry.yarnpkg.com/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.0-preview.1.tgz#ad7c726cfd73c946dbfbc3e485338ccf678fc75a" - integrity sha512-hMp0y+j/odkAyTa5TYewn4hUlFdEe3sR9uTd2Oq+se61RtuDsqM7UWrNNlyylPyjIENSZHJVWN7jte/jvvMN2Q== +"@azure/core-asynciterator-polyfill@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.0.tgz#dcccebb88406e5c76e0e1d52e8cc4c43a68b3ee7" + integrity sha512-kmv8CGrPfN9SwMwrkiBK9VTQYxdFQEGe0BmQk+M8io56P9KNzpAxcWE/1fxJj7uouwN4kXF0BHW8DNlgx+wtCg== -"@azure/core-auth@1.0.0-preview.3": - version "1.0.0-preview.3" - resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.0.0-preview.3.tgz#3f52e07942fb934c03e861987d6a1bfd35d538b6" - integrity sha512-SUG/ccOMGjPVUwKvwAW6r543bd66UOHu66N/jycr0hMVLI/46TuMZJIMjA2AN2+Gc+IrxSXQeJbN2VBFiJBWvA== +"@azure/core-auth@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.0.0.tgz#e1012ec8919abb88baac6365892dc7d485b02115" + integrity sha512-DcXqxt0O0HDhYTcrN16e/hJutFkFTM8fQq6bJbHuDh5AUbDUKFrF64hj5RXATukThOszGFrR1MWJOGZPSo7fiA== dependencies: - "@azure/abort-controller" "1.0.0-preview.2" + "@azure/abort-controller" "^1.0.0" + "@azure/core-tracing" "1.0.0-preview.5" tslib "^1.9.3" -"@azure/core-http@1.0.0-preview.3": - version "1.0.0-preview.3" - resolved "https://registry.yarnpkg.com/@azure/core-http/-/core-http-1.0.0-preview.3.tgz#890e4dedc7a33398175bbabc3488d779b301ae6e" - integrity sha512-YxZPXG0xYRvBhkAtNVD18VG3i6JyS2dH7QtkiYoi9yAc/x7HUMcKg7FmOD/Nf/++OVGoTQcJ9QpG34MggWuHEQ== +"@azure/core-http@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@azure/core-http/-/core-http-1.0.0.tgz#d599cd48034916b84babec0478d357a30f0a92e2" + integrity sha512-vUVrALCoxY0gRfGWbEdiaFGK7qJMV/ZjZucN+LWZZGy/NdP5Iv6nVrxeb7YYIhPDsmcRvABYHrZUt01TB/8aAQ== dependencies: - "@azure/abort-controller" "1.0.0-preview.2" - "@azure/core-auth" "1.0.0-preview.3" - "@azure/core-tracing" "1.0.0-preview.2" + "@azure/abort-controller" "^1.0.0" + "@azure/core-auth" "^1.0.0" + "@azure/core-tracing" "1.0.0-preview.5" + "@azure/logger" "^1.0.0" "@types/node-fetch" "^2.5.0" "@types/tunnel" "^0.0.1" form-data "^2.5.0" @@ -66,54 +54,39 @@ uuid "^3.3.2" xml2js "^0.4.19" -"@azure/core-http@1.0.0-preview.5": - version "1.0.0-preview.5" - resolved "https://registry.yarnpkg.com/@azure/core-http/-/core-http-1.0.0-preview.5.tgz#81b9e3755725b676b32add0587ffe80ee2d6d626" - integrity sha512-xbbd1HotVW+PKlImSMCEFeT93HhLMSWnroMJ8N24i3K/rP4kGjZn8NoGvMbp+ckJIYOH+/JPYOaXTs+1rJVvsA== +"@azure/core-lro@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@azure/core-lro/-/core-lro-1.0.0.tgz#9837398e03aa04b5b0b09158f4338861348dcce4" + integrity sha512-l4abIb8S9qmlv3bJkonLvgGSVQcSXq5jByA7Z28GRGJaQN/mSFal9YQOuLvVag+JXQJsoftuxJFrZiggF2TwOg== dependencies: - "@azure/abort-controller" "1.0.0-preview.2" - "@azure/core-auth" "1.0.0-preview.3" - "@azure/core-tracing" "1.0.0-preview.4" - "@types/node-fetch" "^2.5.0" - "@types/tunnel" "^0.0.1" - form-data "^2.5.0" - node-fetch "^2.6.0" - process "^0.11.10" - tough-cookie "^3.0.1" + "@azure/abort-controller" "^1.0.0" + "@azure/core-http" "^1.0.0" + events "^3.0.0" tslib "^1.9.3" - tunnel "^0.0.6" - uuid "^3.3.2" - xml2js "^0.4.19" - -"@azure/core-paging@1.0.0-preview.2": - version "1.0.0-preview.2" - resolved "https://registry.yarnpkg.com/@azure/core-paging/-/core-paging-1.0.0-preview.2.tgz#a555bd6df3fdae9fb35ab704f157ef73a1e17b10" - integrity sha512-D0oiOmg82AnhTT3xkIyTpEhCesHtlpV2rTVVlCQmQPbfzAWh8eBZp1QAgNQcBdF6uXZrp69znpXSnICmtfH23Q== - dependencies: - "@azure/core-asynciterator-polyfill" "1.0.0-preview.1" -"@azure/core-tracing@1.0.0-preview.2": - version "1.0.0-preview.2" - resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.2.tgz#4f589dcac7841c8bcb65995d9592105e3d3f8ad2" - integrity sha512-ID/kDVax0uYlw1HVBNsLv6JuE8NbgLUrKrmvVqyuvtbNk+Gk+IKbpUbrDMAoauDAd1CHifs+fkg210LD2JWSEQ== +"@azure/core-paging@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@azure/core-paging/-/core-paging-1.0.0.tgz#3aa3855582154260326feea97f9f8322cbfe56d9" + integrity sha512-CzaT7LwxU97PZ+/Pn7uAbNGXY2mJ/3b56kmLsZzbR9stfrNfzlILxR94WHG/D1jZEQOk4lUNiaqJ2zP7nSGJhA== dependencies: - tslib "^1.9.3" + "@azure/core-asynciterator-polyfill" "^1.0.0" -"@azure/core-tracing@1.0.0-preview.4": - version "1.0.0-preview.4" - resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.4.tgz#244686bd7e48a49c67e1b840d80ea9edda22884c" - integrity sha512-xl6mAe1dqVxD1PH2Qnx/XFlblQcItG/lNUcPa1qp7+MrLKP4Wb7hoOK1mZfCkGKZZW4SGkRxwS9b+dR4R4x8Uw== +"@azure/core-tracing@1.0.0-preview.5": + version "1.0.0-preview.5" + resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.5.tgz#656892565a9d1920be2008c9609429e37e13443c" + integrity sha512-i3hF4EQucZmn2l4zXscwG5bilnboKHtnLMFVuzXk55dt487/9EJ5uMOP3eyTFpULGjn6xubgYFAJVpUJGVQv4w== dependencies: "@opencensus/web-types" "0.0.7" tslib "^1.9.3" -"@azure/identity@1.0.0-preview.5": - version "1.0.0-preview.5" - resolved "https://registry.yarnpkg.com/@azure/identity/-/identity-1.0.0-preview.5.tgz#9c4918dd2096151797dd879c5a9206fb114717df" - integrity sha512-ScJYcSWxnM/ScfcWI7p/awCOhMz98HbQZN2WrxnzpQ76lVD8d2luJq0AV/YUJvoroCgi9LTRdv4W2sMVNDUtNA== +"@azure/identity@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@azure/identity/-/identity-1.0.0.tgz#6d74ae2e831948f17162a1ab0b179ed01c8d76a9" + integrity sha512-IyxddNpAlvLYmtNgzedYhJPnlmJpfyJ3S+fmiVHWhCMLvJI3x1011noZu8wyJektQN7NIANKDD77H4OLjf+DUQ== dependencies: - "@azure/core-http" "1.0.0-preview.5" - "@azure/core-tracing" "1.0.0-preview.4" + "@azure/core-http" "^1.0.0" + "@azure/core-tracing" "1.0.0-preview.5" + "@azure/logger" "^1.0.0" events "^3.0.0" jws "^3.2.2" msal "^1.0.2" @@ -121,17 +94,24 @@ tslib "^1.9.3" uuid "^3.3.2" -"@azure/keyvault-secrets@4.0.0-preview.8": - version "4.0.0-preview.8" - resolved "https://registry.yarnpkg.com/@azure/keyvault-secrets/-/keyvault-secrets-4.0.0-preview.8.tgz#c43295b9a5cc6a896d385b519c19c1b0c5426176" - integrity sha512-nB/lkHU1PCmRV2WUPdTecVZTSrrNzgJTbVtg+6AAnfEzlRvlg4w+DpjDzqKlPN2KrVdVXHEA4x/r7zjMfAdMaw== - dependencies: - "@azure/abort-controller" "1.0.0-preview.2" - "@azure/core-arm" "1.0.0-preview.5" - "@azure/core-http" "1.0.0-preview.5" - "@azure/core-paging" "1.0.0-preview.2" - "@azure/core-tracing" "1.0.0-preview.4" - "@azure/identity" "1.0.0-preview.5" +"@azure/keyvault-secrets@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@azure/keyvault-secrets/-/keyvault-secrets-4.0.0.tgz#f6c892cf3ddf0925e9cf6b1bef039468d255d227" + integrity sha512-C22NfIL+Lm1rEdg28DyhCZPZ1CQm0o6U79oNnjFV2fsgaR/wRyrM/zfDJ4dok8yrhKX8+O1SLmGHDkp0ro+mBQ== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-http" "^1.0.0" + "@azure/core-lro" "^1.0.0" + "@azure/core-paging" "^1.0.0" + "@azure/core-tracing" "1.0.0-preview.5" + "@azure/logger" "^1.0.0" + tslib "^1.9.3" + +"@azure/logger@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.0.tgz#48b371dfb34288c8797e5c104f6c4fb45bf1772c" + integrity sha512-g2qLDgvmhyIxR3JVS8N67CyIOeFRKQlX/llxYJQr1OSGQqM3HTpVP8MjmjcEKbL/OIt2N9C9UFaNQuKOw1laOA== + dependencies: tslib "^1.9.3" "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": @@ -276,7 +256,7 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@commitlint/cli@^8.1.0": +"@commitlint/cli@^8.2.0": version "8.2.0" resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-8.2.0.tgz#fbf9969e04e2162d985eaa644fdad6ce807aadb6" integrity sha512-8fJ5pmytc38yw2QWbTTJmXLfSiWPwMkHH4govo9zJ/+ERPBF2jvlxD/dQvk24ezcizjKc6LFka2edYC4OQ+Dgw== @@ -293,7 +273,7 @@ resolve-from "5.0.0" resolve-global "1.0.0" -"@commitlint/config-conventional@^8.1.0": +"@commitlint/config-conventional@^8.2.0": version "8.2.0" resolved "https://registry.yarnpkg.com/@commitlint/config-conventional/-/config-conventional-8.2.0.tgz#886a5538e3708e017ec2871e0cbce00f635d3102" integrity sha512-HuwlHQ3DyVhpK9GHgTMhJXD8Zp8PGIQVpQGYh/iTrEU6TVxdRC61BxIDZvfWatCaiG617Z/U8maRAFrqFM4TqA== @@ -656,10 +636,10 @@ dependencies: any-observable "^0.3.0" -"@semantic-release/changelog@^3.0.4": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@semantic-release/changelog/-/changelog-3.0.4.tgz#8fc578b76bca5b23c3000694277c38e0fa835edd" - integrity sha512-UqEPahcZSW0IKtzOglyjeEZCN99ku6Wb/yH/iOKEBJ7Vkw0/+Fc3VRiGoXTkMfHSFUJk+4UkoQKTlYuwf61C2w== +"@semantic-release/changelog@^3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@semantic-release/changelog/-/changelog-3.0.5.tgz#37423eee40f550acb8e09ff1d951ba79263e3b2d" + integrity sha512-/U44eK5qL2olevbEi+GrJxq1lNGUABChqK58A3SkiDsZS6AoGO8CJHQ7OG0zx+spxwkY4TevZ85Whz/hYyO+5w== dependencies: "@semantic-release/error" "^2.1.0" aggregate-error "^3.0.0" @@ -841,10 +821,10 @@ resolved "https://registry.yarnpkg.com/@types/jest-diff/-/jest-diff-20.0.1.tgz#35cc15b9c4f30a18ef21852e255fdb02f6d59b89" integrity sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA== -"@types/jest@^24.0.18": - version "24.0.20" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.0.20.tgz#729d5fe8684e7fb06368d3bd557ac6d91289d861" - integrity sha512-M8ebEkOpykGdLoRrmew7UowTZ1DANeeP0HiSIChl/4DGgmnSC1ntitNtkyNSXjMTsZvXuaxJrxjImEnRWNPsPw== +"@types/jest@^24.0.22": + version "24.0.22" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.0.22.tgz#08a50be08e78aba850a1185626e71d31e2336145" + integrity sha512-t2OvhNZnrNjlzi2i0/cxbLVM59WN15I2r1Qtb7wDv28PnV9IzrPtagFRey/S9ezdLD0zyh1XGMQIEQND2YEfrw== dependencies: "@types/jest-diff" "*" @@ -865,11 +845,16 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@^12", "@types/node@^12.0.2": +"@types/node@*", "@types/node@^12.0.2": version "12.11.7" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a" integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA== +"@types/node@^12.12.6": + version "12.12.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.6.tgz#a47240c10d86a9a57bb0c633f0b2e0aea9ce9253" + integrity sha512-FjsYUPzEJdGXjwKqSpE0/9QEh6kzhTAeObA54rn6j3rR4C/mzpI9L0KNfoeASSPMMdxIsoJuCLDWcM/rVjIsSA== + "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" @@ -909,46 +894,47 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^2.3.0": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.6.0.tgz#e82ed43fc4527b21bfe35c20a2d6e4ed49fc7957" - integrity sha512-iCcXREU4RciLmLniwKLRPCOFVXrkF7z27XuHq5DrykpREv/mz6ztKAyLg2fdkM0hQC7659p5ZF5uStH7uzAJ/w== +"@typescript-eslint/eslint-plugin@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.6.1.tgz#e34972a24f8aba0861f9ccf7130acd74fd11e079" + integrity sha512-Z0rddsGqioKbvqfohg7BwkFC3PuNLsB+GE9QkFza7tiDzuHoy0y823Y+oGNDzxNZrYyLjqkZtCTl4vCqOmEN4g== dependencies: - "@typescript-eslint/experimental-utils" "2.6.0" + "@typescript-eslint/experimental-utils" "2.6.1" eslint-utils "^1.4.2" functional-red-black-tree "^1.0.1" regexpp "^2.0.1" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@2.6.0": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.6.0.tgz#ed70bef72822bff54031ff0615fc888b9e2b6e8a" - integrity sha512-34BAFpNOwHXeqT+AvdalLxOvcPYnCxA5JGmBAFL64RGMdP0u65rXjii7l/nwpgk5aLEE1LaqF+SsCU0/Cb64xA== +"@typescript-eslint/experimental-utils@2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.6.1.tgz#eddaca17a399ebf93a8628923233b4f93793acfd" + integrity sha512-EVrrUhl5yBt7fC7c62lWmriq4MIc49zpN3JmrKqfiFXPXCM5ErfEcZYfKOhZXkW6MBjFcJ5kGZqu1b+lyyExUw== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "2.6.0" + "@typescript-eslint/typescript-estree" "2.6.1" eslint-scope "^5.0.0" -"@typescript-eslint/parser@^2.3.0": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.6.0.tgz#5106295c6a7056287b4719e24aae8d6293d5af49" - integrity sha512-AvLejMmkcjRTJ2KD72v565W4slSrrzUIzkReu1JN34b8JnsEsxx7S9Xx/qXEuMQas0mkdUfETr0j3zOhq2DIqQ== +"@typescript-eslint/parser@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.6.1.tgz#3c00116baa0d696bc334ca18ac5286b34793993c" + integrity sha512-PDPkUkZ4c7yA+FWqigjwf3ngPUgoLaGjMlFh6TRtbjhqxFBnkElDfckSjm98q9cMr4xRzZ15VrS/xKm6QHYf0w== dependencies: "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "2.6.0" - "@typescript-eslint/typescript-estree" "2.6.0" + "@typescript-eslint/experimental-utils" "2.6.1" + "@typescript-eslint/typescript-estree" "2.6.1" eslint-visitor-keys "^1.1.0" -"@typescript-eslint/typescript-estree@2.6.0": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.6.0.tgz#d3e9d8e001492e2b9124c4d4bd4e7f03c0fd7254" - integrity sha512-A3lSBVIdj2Gp0lFEL6in2eSPqJ33uAc3Ko+Y4brhjkxzjbzLnwBH22CwsW2sCo+iwogfIyvb56/AJri15H0u5Q== +"@typescript-eslint/typescript-estree@2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.6.1.tgz#fb363dd4ca23384745c5ea4b7f4c867432b00d31" + integrity sha512-+sTnssW6bcbDZKE8Ce7VV6LdzkQz2Bxk7jzk1J8H1rovoTxnm6iXvYIyncvNsaB/kBCOM63j/LNJfm27bNdUoA== dependencies: debug "^4.1.1" glob "^7.1.4" is-glob "^4.0.1" lodash.unescape "4.0.1" semver "^6.3.0" + tsutils "^3.17.1" JSONStream@^1.0.4, JSONStream@^1.3.4, JSONStream@^1.3.5: version "1.3.5" @@ -1781,7 +1767,7 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -codecov@^3.5.0: +codecov@^3.6.1: version "3.6.1" resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.6.1.tgz#f39fc49413445555f81f8e3ca5730992843b4517" integrity sha512-IUJB6WG47nWK7o50etF8jBadxdMw7DmoQg05yIljstXFBGB6clOZsIj6iD4P82T2YaIU3qq+FFu8K9pxgkCJDQ== @@ -2386,7 +2372,7 @@ dot-prop@^4.1.0: dependencies: is-obj "^1.0.0" -dotenv@*, dotenv@^8.1.0: +dotenv@*, dotenv@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== @@ -2553,7 +2539,7 @@ escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^6.3.0: +eslint-config-prettier@^6.5.0: version "6.5.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.5.0.tgz#aaf9a495e2a816865e541bfdbb73a65cc162b3eb" integrity sha512-cjXp8SbO9VFGW/Z7mbTydqS9to8Z58E5aYhj3e1+Hx7lS9s6gL5ILKNpCqZAFOVYRcSkWPFYljHrEh8QFEK5EQ== @@ -2648,7 +2634,7 @@ eslint-visitor-keys@^1.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint@^6.4.0: +eslint@^6.6.0: version "6.6.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.6.0.tgz#4a01a2fb48d32aacef5530ee9c5a78f11a8afd04" integrity sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g== @@ -3011,7 +2997,7 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -find-up@^4.0.0, find-up@^4.1.0: +find-up@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -3577,7 +3563,7 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" -husky@^3.0.5: +husky@^3.0.9: version "3.0.9" resolved "https://registry.yarnpkg.com/husky/-/husky-3.0.9.tgz#a2c3e9829bfd6b4957509a9500d2eef5dbfc8044" integrity sha512-Yolhupm7le2/MqC1VYLk/cNmYxsSsqKkTyBhzQHhPK1jFnC89mmmNVuGtLNabjDI6Aj8UNIr0KpRNuBkiC4+sg== @@ -4873,7 +4859,7 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -lint-staged@^9.2.5: +lint-staged@^9.4.2: version "9.4.2" resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-9.4.2.tgz#14cb577a9512f520691f8b5aefce6a8f7ead6c04" integrity sha512-OFyGokJSWTn2M6vngnlLXjaHhi8n83VIZZ5/1Z26SULRUWgR3ITWpAEQC9Pnm3MC/EpCxlwts/mQWDHNji2+zA== @@ -6712,15 +6698,6 @@ read-pkg-up@^6.0.0: read-pkg "^5.1.1" type-fest "^0.5.0" -read-pkg-up@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.0.tgz#3f3e53858ec5ae5e6fe14bc479da0a7c98f85ff3" - integrity sha512-t2ODkS/vTTcRlKwZiZsaLGb5iwfx9Urp924aGzVyboU6+7Z2i6eGr/G1Z4mjvwLLQV3uFOBKobNRGM3ux2PD/w== - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - read-pkg@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" @@ -8031,11 +8008,6 @@ type-fest@^0.6.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -8068,15 +8040,10 @@ typedoc@^0.15.0: typedoc-default-themes "^0.6.0" typescript "3.5.x" -typescript@3.5.x: - version "3.5.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977" - integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g== - -typescript@^3.6.3: - version "3.6.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.4.tgz#b18752bb3792bc1a0281335f7f6ebf1bbfc5b91d" - integrity sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg== +typescript@3.5.x, typescript@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.2.tgz#27e489b95fa5909445e9fef5ee48d81697ad18fb" + integrity sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ== uglify-js@^3.1.4: version "3.6.0"